{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/composition/syncState/index.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { loadDomains, resolvePluginEntries } from '@agimon-ai/doompi-config/domains';\nimport type { LayerResolvers, MajorModesConfig } from '@agimon-ai/doompi-config/majorModes';\nimport { loadProfiles, PERSONA_FILES } from '@agimon-ai/doompi-config/profiles';\nimport type { HarnessState } from '@agimon-ai/doompi-config/types';\nimport { isDoomMcpProjection, type DoomMcpProjection } from '@agimon-ai/doompi-core/mcp-projection';\nimport { isRecord } from '@agimon-ai/doompi-core/runtime-json';\nimport type { JsonObject } from '@agimon-ai/doompi-core/runtime-json';\nimport {\n  assertSyncLocationSafe,\n  resolveSyncLocation,\n  type SyncIdentity,\n  type SyncLocation,\n} from '@agimon-ai/doompi-core/sync-location';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/sync-registration';\nimport { PRECOMPILE_STATE_VERSION, SYNC_STATE_VERSION } from '@agimon-ai/doompi-core/sync-state-contract';\n\nimport {\n  assembleChildExtensions,\n  assembleExtensions,\n  type ExtensionLayerResolvers,\n  LAYER_RESOLVERS,\n  OLLAMA_PRESET,\n  PERSONA_ENTRY,\n} from '../../builders/cli/extensionAssembler';\n\nexport { SYNC_STATE_VERSION } from '@agimon-ai/doompi-core/sync-state-contract';\n\n/**\n * The file `doom-pi sync` writes and the doom-pi Pi extension reads back.\n *\n * This is the whole contract between the two halves of the synced path. Sync\n * runs in plain Node, where module resolution and the repository config are\n * available; the extension runs inside a Pi session, where neither can be\n * relied on. Everything the extension needs is therefore resolved once here,\n * and everything in this file has to survive JSON.\n */\n\nconst PI_DIRECTORY = '.pi';\n/** The `.doom` config directory name, under both the repo root and `~/.pi`. */\nconst DOOM_CONFIG_DIRECTORY = '.doom';\nconst RUN_DIRECTORY = 'run';\nconst DEFAULT_PRESET = 'default';\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst OWN_PREFIX = 'own:';\nconst PACKAGE_PREFIX = 'pkg:';\nconst LOCAL_PREFIX = 'local:';\nconst LOCAL_PACKAGE_NAME_PREFIX = 'local-package-name:';\nconst ENTRY_INDEX_SEPARATOR = ':entry:';\nconst COMPOSITION_FINGERPRINT = /^[a-f0-9]{64}$/u;\nconst PLUGIN_MCP_CONFIG_FILES = ['.mcp.json', 'mcp.json'] as const;\nconst PACKAGE_MANIFEST_FILE = 'package.json';\n/** Folder the cockpit bundler compiles straight from each installed package. */\nconst WEB_PLUGIN_DIRECTORY = 'web';\n\n/** Config that feeds a sync, in the order the hash reads it. */\nconst HASHED_CONFIG_FILES = ['config.yaml', 'modes.yaml', 'domains.yaml', 'profiles.yaml', 'hooks.yaml'] as const;\n\nexport interface SyncSelection {\n  majorMode: string;\n  domains: string[];\n  profile?: string;\n  preset: string;\n}\n\n/** Paths to the resources sync staged, before any live switch replaces them. */\nexport interface SyncBaseline {\n  mcpConfigPath?: string;\n  personaFile?: string;\n  themePath: string;\n  themeName: string;\n}\n\nexport interface SyncPrecompileState {\n  /** Version of the lightweight freshness contract used by package startup. */\n  version: number;\n  strategy: 'bundle';\n  /** Package entry the generated bootstrap bundles. */\n  bootstrapEntry: string;\n  /** Compiler manifest whose output is the graph-bundled package bootstrap. */\n  bootstrapManifest: string;\n  /** Compiler manifest for each graph-bundled composition. */\n  bundleManifests: Record<string, string>;\n}\n\nexport interface SyncServerBundleState {\n  descriptorPath: string;\n  fingerprint: string;\n  compilerManifests: Record<string, string>;\n  sourcesHash: string;\n}\n\nexport interface SyncMcpBundleState {\n  descriptorPath: string;\n  fingerprint: string;\n  compilerManifests: Record<string, string>;\n  sourcesHash: string;\n}\n\nexport interface SyncState {\n  version: number;\n  root: string;\n  /** Canonical repository and worktree namespace that owns this state. */\n  identity: SyncIdentity;\n  /** Hash of the config that produced this state, for the staleness warning. */\n  inputsHash: string;\n  /**\n   * Hash of the cockpit sources and package versions this state was built from.\n   *\n   * Absent in a state written before cockpit sources were tracked, which reads\n   * as \"cannot be compared\" rather than as a change, so an old state does not\n   * force a resync on sight.\n   */\n  webSourcesHash?: string;\n  /** Canonical composition selected when this state was recorded. */\n  compositionFingerprint: string;\n  selection: SyncSelection;\n  /** Harness environment the extension applies when the values are unset. */\n  env: Record<string, string>;\n  /**\n   * State the environment does not carry, so it has to be recorded on its own.\n   *\n   * Plugin hooks, the profile's environment defaults, and the neutral MCP\n   * projection live in the session state file rather than in variables.\n   */\n  fileState: Pick<HarnessState, 'profileEnvironment' | 'pluginHooks'> & {\n    mcpProjection: DoomMcpProjection;\n  };\n  /** Entry name to absolute path, covering every layer, not just the selected mode's. */\n  resolved: Record<string, string>;\n  /**\n   * The same entries after TypeScript ones were bundled to plain ESM.\n   *\n   * Kept apart from `resolved` so the staleness check still compares resolution\n   * against resolution; a state written before this existed simply has none and\n   * falls back to loading the source.\n   */\n  compiled?: Record<string, string>;\n  /** Aggregate entry by canonical composition fingerprint. */\n  bundles?: Record<string, string>;\n  /** Graph-compiled synced bootstrap dynamically loaded by the package entry. */\n  bootstrap?: string;\n  /** Inputs used to validate generated artifacts without loading the compiler. */\n  precompile?: SyncPrecompileState;\n  /** Absent only in generations produced before the server descriptor cutover. */\n  serverBundle?: SyncServerBundleState;\n  /** Explicit remote-only session capabilities staged with this generation. */\n  mcpBundle?: SyncMcpBundleState;\n  baseline: SyncBaseline;\n}\n\nexport function syncDirectory(repoRoot: string, homeDirectory: string = os.homedir()): string {\n  return resolveSyncLocation(repoRoot, homeDirectory).directory;\n}\n\nexport function syncStatePath(repoRoot: string, homeDirectory: string = os.homedir()): string {\n  return (\n    readSyncRegistration(repoRoot, homeDirectory)?.statePath ?? resolveSyncLocation(repoRoot, homeDirectory).statePath\n  );\n}\n\nexport function legacySyncDirectory(repoRoot: string): string {\n  return resolveSyncLocation(repoRoot).legacyDirectory;\n}\n\nexport function legacySyncStatePath(repoRoot: string): string {\n  return resolveSyncLocation(repoRoot).legacyStatePath;\n}\n\nfunction canonicalPath(target: string): string {\n  const absolute = path.resolve(target);\n  try {\n    return fs.realpathSync(absolute);\n  } catch {\n    const parent = path.dirname(absolute);\n    if (parent === absolute) return absolute;\n    return path.join(canonicalPath(parent), path.basename(absolute));\n  }\n}\n\nfunction isInside(directory: string, target: string): boolean {\n  const relative = path.relative(canonicalPath(directory), canonicalPath(target));\n  return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\n/** Whether generated state belongs to the repository that is reading it. */\nexport function syncStateRootMatches(repoRoot: string, stateRoot: string): boolean {\n  return canonicalPath(repoRoot) === canonicalPath(stateRoot);\n}\n\n/**\n * Per-process scratch directory for live `/domains` and `/profile` switches.\n *\n * Switching rewrites the MCP config and the persona prompt. Writing those back\n * into the synced directory would both mutate the pinned baseline and let two\n * Pi sessions in one repository overwrite each other, which the launcher avoids\n * by giving every run its own temporary directory.\n */\nexport function runDirectory(\n  repoRoot: string,\n  processId: number = process.pid,\n  homeDirectory: string = os.homedir(),\n): string {\n  return path.join(syncDirectory(repoRoot, homeDirectory), RUN_DIRECTORY, String(processId));\n}\n\n/**\n * How a Pi project settings file should refer to a generated path.\n *\n * Relative to `.pi` when the target lives in the repository, which keeps the\n * committed settings file identical on every machine. A doom-pi installed\n * outside the repository stays absolute: Pi accepts both, and a relative path\n * climbing out of the project would be neither portable nor readable.\n */\nexport function settingsRelativePath(repoRoot: string, target: string): string {\n  const relative = path.relative(repoRoot, target);\n  if (relative.startsWith('..') || path.isAbsolute(relative)) return target;\n  return path.relative(path.join(repoRoot, PI_DIRECTORY), target).split(path.sep).join('/');\n}\n\nfunction readIfPresent(filePath: string): string {\n  return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';\n}\n\nfunction updateFramedHash(hash: ReturnType<typeof crypto.createHash>, label: string, value: string | Buffer): void {\n  const bytes = typeof value === 'string' ? Buffer.from(value) : value;\n  hash.update(`${String(label.length)}:${label}:${String(bytes.byteLength)}:`);\n  hash.update(bytes);\n}\n\n/** Hashes path, existence, and bytes without making absent and empty files aliases. */\nfunction updateFileInputHash(hash: ReturnType<typeof crypto.createHash>, filePath: string): void {\n  const absolutePath = path.resolve(filePath);\n  updateFramedHash(hash, 'path', absolutePath);\n  if (!fs.existsSync(absolutePath)) {\n    updateFramedHash(hash, 'state', 'missing');\n    return;\n  }\n  updateFramedHash(hash, 'state', 'present');\n  updateFramedHash(hash, 'contents', fs.readFileSync(absolutePath));\n}\n\n/** Package root owning a resolved entry, or undefined when it sits outside one. */\nfunction owningPackageRoot(entryPath: string): string | undefined {\n  // The resolved map also carries package-name metadata. Relative metadata must\n  // not become a filesystem path whose meaning changes with process.cwd().\n  if (!path.isAbsolute(entryPath)) return undefined;\n  let directory = path.dirname(entryPath);\n  for (;;) {\n    if (fs.existsSync(path.join(directory, PACKAGE_MANIFEST_FILE))) return directory;\n    const parent = path.dirname(directory);\n    if (parent === directory) return undefined;\n    directory = parent;\n  }\n}\n\n/** Every regular file under a directory, as absolute paths in a stable order. */\nfunction filesUnder(directory: string): string[] {\n  if (!fs.existsSync(directory)) return [];\n  const found: string[] = [];\n  const walk = (current: string): void => {\n    for (const entry of fs.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {\n      const full = path.join(current, entry.name);\n      if (entry.isDirectory()) walk(full);\n      else if (entry.isFile()) found.push(full);\n    }\n  };\n  walk(directory);\n  return found;\n}\n\n/**\n * Hashes the cockpit sources and package versions a sync compiled.\n *\n * The cockpit bundle is built from each installed package's `web/` folder by\n * `syncWebBundle`, straight from source, with no compiler manifest recording\n * what went in. Nothing else in the drift check reads those files, so editing a\n * plugin surface and rebuilding left the hub serving the previously bundled\n * cockpit with nothing reporting a reason. Compiled entries are covered\n * elsewhere, by the content digests in their compiler manifests, so only the\n * entry identity and its package version are folded in here.\n *\n * Bounded on purpose: the web sources of a full composition are a few hundred\n * small files, which is cheap enough for the hub to poll.\n */\nexport function computeWebSourcesHash(resolved: Record<string, string>): string {\n  const hash = crypto.createHash('sha256');\n  const roots = [...new Set(Object.values(resolved).flatMap((entry) => owningPackageRoot(entry) ?? []))].sort();\n  for (const root of roots) {\n    updateFramedHash(hash, 'package', root);\n    const manifestPath = path.join(root, PACKAGE_MANIFEST_FILE);\n    let manifest: { name?: unknown; version?: unknown } = {};\n    try {\n      manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { name?: unknown; version?: unknown };\n    } catch {\n      // An unreadable manifest still contributes its path above, so the package\n      // is not silently dropped from the hash; the version simply reads empty\n      // and any later repair shows up as a change.\n      manifest = {};\n    }\n    updateFramedHash(hash, 'name', typeof manifest.name === 'string' ? manifest.name : '');\n    updateFramedHash(hash, 'version', typeof manifest.version === 'string' ? manifest.version : '');\n    for (const file of filesUnder(path.join(root, WEB_PLUGIN_DIRECTORY))) updateFileInputHash(hash, file);\n  }\n  for (const [name, entry] of Object.entries(resolved).sort(([left], [right]) => left.localeCompare(right))) {\n    updateFramedHash(hash, 'entry', `${name}\u0000${entry}`);\n  }\n  return hash.digest('hex');\n}\n\n/** Include declaration changes even for packages that did not previously expose a server facet. */\nexport function computeServerSourcesHash(resolved: Record<string, string>): string {\n  const hash = crypto.createHash('sha256');\n  const roots = [...new Set(Object.values(resolved).flatMap((entry) => owningPackageRoot(entry) ?? []))].sort();\n  for (const root of roots) {\n    const manifestPath = path.join(root, PACKAGE_MANIFEST_FILE);\n    updateFileInputHash(hash, manifestPath);\n    const manifest: unknown = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n    if (!isRecord(manifest) || !isRecord(manifest.doompiServer) || !isRecord(manifest.doompiServer.contracts)) continue;\n    // Include missing declarations too: building or repairing a contract must invalidate an incomplete generation.\n    for (const file of [manifest.doompiServer.contracts.entry, manifest.doompiServer.contracts.dist]) {\n      if (typeof file !== 'string' || !file.startsWith('./') || file.split('/').includes('..') || /[\\\\%?#]/u.test(file))\n        continue;\n      updateFileInputHash(hash, path.join(root, file));\n    }\n  }\n  for (const [name, entry] of Object.entries(resolved).sort(([left], [right]) => left.localeCompare(right))) {\n    updateFramedHash(hash, 'entry', JSON.stringify([name, entry]));\n  }\n  return hash.digest('hex');\n}\n\n/** Include MCP declarations and their attributed source files in sync freshness. */\nexport function computeMcpSourcesHash(resolved: Record<string, string>): string {\n  const hash = crypto.createHash('sha256');\n  const roots = [...new Set(Object.values(resolved).flatMap((entry) => owningPackageRoot(entry) ?? []))].sort();\n  for (const root of roots) {\n    const manifestPath = path.join(root, PACKAGE_MANIFEST_FILE);\n    updateFileInputHash(hash, manifestPath);\n    const manifest: unknown = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n    if (!isRecord(manifest) || !isRecord(manifest.doompiMcp)) continue;\n    for (const file of [manifest.doompiMcp.entry, manifest.doompiMcp.dist]) {\n      if (typeof file !== 'string' || !file.startsWith('./') || file.split('/').includes('..') || /[\\\\%?#]/u.test(file))\n        continue;\n      updateFileInputHash(hash, path.join(root, file));\n    }\n  }\n  for (const [name, entry] of Object.entries(resolved).sort(([left], [right]) => left.localeCompare(right))) {\n    updateFramedHash(hash, 'entry', JSON.stringify([name, entry]));\n  }\n  return hash.digest('hex');\n}\n\n/**\n * Hashes the configuration a sync consumed.\n *\n * Deliberately cheap: the extension recomputes this on every session start, so\n * it reads config, marketplace, local plugin manifests, and profile persona text\n * without downloading plugins or re-resolving packages. A dependency upgrade that\n * moves a package path therefore does not show up here; `doom-pi sync --check`\n * re-resolves and is the check that catches that.\n */\nexport function computeInputsHash(\n  repoRoot: string,\n  selection: SyncSelection,\n  homeDirectory: string = os.homedir(),\n): string {\n  // Match sync publication, including callers that reach the repository through a symlink.\n  repoRoot = resolveSyncLocation(repoRoot, homeDirectory).root;\n  const hash = crypto.createHash('sha256');\n  hash.update(JSON.stringify({ ...selection, domains: [...selection.domains].sort() }));\n  // Every .doom document layers the global copy under the repository one, so an\n  // edit in either location is a real change.\n  for (const directory of [\n    path.join(homeDirectory, PI_DIRECTORY, DOOM_CONFIG_DIRECTORY),\n    path.join(repoRoot, DOOM_CONFIG_DIRECTORY),\n  ]) {\n    for (const fileName of HASHED_CONFIG_FILES) hash.update(readIfPresent(path.join(directory, fileName)));\n  }\n  updateFileInputHash(hash, path.join(repoRoot, '.mcp.json'));\n\n  const catalog = loadDomains(repoRoot, homeDirectory).plugins;\n  for (const root of catalog.roots) hash.update(root);\n  for (const diagnostic of catalog.diagnostics) hash.update(diagnostic);\n  for (const marketplace of catalog.marketplaces) {\n    hash.update(marketplace);\n    hash.update(readIfPresent(marketplace));\n  }\n  for (const [name, plugin] of Object.entries(catalog.entries).sort(([left], [right]) => left.localeCompare(right))) {\n    hash.update(name);\n    hash.update(JSON.stringify(plugin.source));\n    if (plugin.manifest) {\n      hash.update(plugin.manifest.path);\n      hash.update(readIfPresent(plugin.manifest.path));\n    }\n  }\n\n  let selectedPluginDirectories: string[] = [];\n  try {\n    selectedPluginDirectories = [\n      ...new Set(\n        resolvePluginEntries(repoRoot, selection.domains, [], homeDirectory)\n          .filter((plugin) => plugin.mcp !== false)\n          .map((plugin) => path.resolve(plugin.directory)),\n      ),\n    ].sort();\n  } catch {\n    // The surrounding .doom inputs already make an invalid or removed domain\n    // selection stale. Keep this lightweight check readable for old state\n    // instead of turning that expected staleness into a startup exception.\n  }\n  for (const directory of selectedPluginDirectories) {\n    for (const fileName of PLUGIN_MCP_CONFIG_FILES) {\n      updateFileInputHash(hash, path.join(directory, fileName));\n    }\n  }\n\n  for (const profile of loadProfiles(repoRoot, homeDirectory)) {\n    hash.update(profile.name);\n    hash.update(profile.personaRoot);\n    hash.update(profile.persona);\n    hash.update(JSON.stringify(profile.env));\n    const personaDirectory = path.resolve(profile.personaRoot, profile.persona);\n    for (const fileName of PERSONA_FILES) {\n      const filePath = path.join(personaDirectory, fileName);\n      hash.update(filePath);\n      hash.update(readIfPresent(filePath));\n    }\n  }\n  return hash.digest('hex');\n}\n\nfunction stringRecord(value: unknown, field: string, statePath: string): Record<string, string> {\n  if (!isRecord(value)) throw new Error(`Doom sync state at ${statePath} requires ${field} to be an object`);\n  return Object.fromEntries(\n    Object.entries(value).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n  );\n}\n\nfunction parsePrecompileState(value: unknown, statePath: string): SyncPrecompileState {\n  if (\n    !isRecord(value) ||\n    value.version !== PRECOMPILE_STATE_VERSION ||\n    value.strategy !== 'bundle' ||\n    typeof value.bootstrapEntry !== 'string' ||\n    typeof value.bootstrapManifest !== 'string' ||\n    !isRecord(value.bundleManifests) ||\n    Object.entries(value.bundleManifests).some(\n      ([fingerprint, manifest]) => !COMPOSITION_FINGERPRINT.test(fingerprint) || typeof manifest !== 'string',\n    )\n  ) {\n    throw new Error(`Doom sync state at ${statePath} has an invalid precompile record`);\n  }\n  return {\n    version: value.version,\n    strategy: value.strategy,\n    bootstrapEntry: value.bootstrapEntry,\n    bootstrapManifest: value.bootstrapManifest,\n    bundleManifests: value.bundleManifests as Record<string, string>,\n  };\n}\n\nfunction precompileMatchesBundles(\n  precompile: SyncPrecompileState,\n  bundles: Record<string, string> | undefined,\n): boolean {\n  const bundleFingerprints = Object.keys(bundles ?? {}).sort();\n  const manifestFingerprints = Object.keys(precompile.bundleManifests).sort();\n  return (\n    bundleFingerprints.length === manifestFingerprints.length &&\n    bundleFingerprints.every((fingerprint, index) => fingerprint === manifestFingerprints[index])\n  );\n}\n\ninterface ParseSyncStateOptions {\n  repoRoot: string;\n  location: SyncLocation;\n  legacy: boolean;\n}\n\nfunction identityMatches(left: SyncIdentity, right: SyncIdentity): boolean {\n  return left.repositoryId === right.repositoryId && left.worktreeId === right.worktreeId;\n}\n\nfunction parseSyncIdentity(value: unknown, statePath: string): SyncIdentity {\n  if (!isRecord(value) || typeof value.repositoryId !== 'string' || typeof value.worktreeId !== 'string') {\n    throw new Error(`Doom sync state at ${statePath} requires repository and worktree identity`);\n  }\n  return { repositoryId: value.repositoryId, worktreeId: value.worktreeId };\n}\n\nfunction parseSyncState(source: string, statePath: string, options: ParseSyncStateOptions): SyncState {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(source);\n  } catch (error) {\n    throw new Error(`Doom sync state at ${statePath} is not valid JSON`, { cause: error });\n  }\n  if (!isRecord(parsed)) throw new Error(`Doom sync state at ${statePath} must be an object`);\n  if (typeof parsed.version !== 'number' || parsed.version !== SYNC_STATE_VERSION) {\n    throw new Error(\n      `Doom sync state at ${statePath} has version ${String(parsed.version)}, expected ${SYNC_STATE_VERSION}. Run doompi sync.`,\n    );\n  }\n  if (typeof parsed.root !== 'string' || typeof parsed.inputsHash !== 'string') {\n    throw new Error(`Doom sync state at ${statePath} requires string root and inputsHash`);\n  }\n  if (\n    typeof parsed.compositionFingerprint !== 'string' ||\n    !COMPOSITION_FINGERPRINT.test(parsed.compositionFingerprint)\n  ) {\n    throw new Error(`Doom sync state at ${statePath} requires a canonical compositionFingerprint`);\n  }\n  if (parsed.nativeGraphs !== undefined) {\n    throw new Error(`Doom sync state at ${statePath} contains removed native graph state. Run doompi sync.`);\n  }\n  if (!syncStateRootMatches(options.repoRoot, parsed.root)) {\n    throw new Error(`Doom sync state at ${statePath} belongs to a different repository: ${parsed.root}`);\n  }\n  const identity = parseSyncIdentity(parsed.identity, statePath);\n  if (!identityMatches(identity, options.location.identity)) {\n    throw new Error(`Doom sync state at ${statePath} belongs to a different repository or worktree identity`);\n  }\n  if (!isRecord(parsed.selection) || typeof parsed.selection.majorMode !== 'string') {\n    throw new Error(`Doom sync state at ${statePath} requires a selection with a majorMode`);\n  }\n  if (!isRecord(parsed.baseline) || typeof parsed.baseline.themePath !== 'string') {\n    throw new Error(`Doom sync state at ${statePath} requires a baseline with a themePath`);\n  }\n  const { majorMode, domains, profile, preset } = parsed.selection;\n  const fileState = isRecord(parsed.fileState) ? parsed.fileState : {};\n  if (!isDoomMcpProjection(fileState.mcpProjection)) {\n    throw new Error(`Doom sync state at ${statePath} requires a valid MCP projection. Run doompi sync.`);\n  }\n  if (!syncStateRootMatches(parsed.root, fileState.mcpProjection.repoRoot)) {\n    throw new Error(`Doom sync state at ${statePath} contains an MCP projection for a different repository`);\n  }\n  const generatedDirectory = options.legacy ? options.location.legacyDirectory : options.location.directory;\n  const compiled = parsed.compiled === undefined ? undefined : stringRecord(parsed.compiled, 'compiled', statePath);\n  const bundles = parsed.bundles === undefined ? undefined : stringRecord(parsed.bundles, 'bundles', statePath);\n  const precompile = parsed.precompile === undefined ? undefined : parsePrecompileState(parsed.precompile, statePath);\n  if (precompile && !precompileMatchesBundles(precompile, bundles)) {\n    throw new Error(`Doom sync state at ${statePath} has an invalid precompile record`);\n  }\n  let serverBundle: SyncServerBundleState | undefined;\n  if (parsed.serverBundle !== undefined) {\n    const value = parsed.serverBundle;\n    if (\n      !isRecord(value) ||\n      typeof value.descriptorPath !== 'string' ||\n      typeof value.fingerprint !== 'string' ||\n      !COMPOSITION_FINGERPRINT.test(value.fingerprint) ||\n      typeof value.sourcesHash !== 'string' ||\n      !COMPOSITION_FINGERPRINT.test(value.sourcesHash)\n    ) {\n      throw new Error(`Doom sync state at ${statePath} has an invalid server bundle record`);\n    }\n    const compilerManifests = stringRecord(value.compilerManifests, 'server compiler manifests', statePath);\n    if (\n      [value.descriptorPath, ...Object.values(compilerManifests)].some((entry) => !isInside(generatedDirectory, entry))\n    ) {\n      throw new Error(`Doom sync state at ${statePath} references server material outside ${generatedDirectory}`);\n    }\n    serverBundle = {\n      descriptorPath: value.descriptorPath,\n      fingerprint: value.fingerprint,\n      compilerManifests,\n      sourcesHash: value.sourcesHash,\n    };\n  }\n  let mcpBundle: SyncMcpBundleState | undefined;\n  if (parsed.mcpBundle !== undefined) {\n    const value = parsed.mcpBundle;\n    if (\n      !isRecord(value) ||\n      typeof value.descriptorPath !== 'string' ||\n      typeof value.fingerprint !== 'string' ||\n      !COMPOSITION_FINGERPRINT.test(value.fingerprint) ||\n      typeof value.sourcesHash !== 'string' ||\n      !COMPOSITION_FINGERPRINT.test(value.sourcesHash)\n    ) {\n      throw new Error(`Doom sync state at ${statePath} has an invalid MCP bundle record`);\n    }\n    const compilerManifests = stringRecord(value.compilerManifests, 'MCP compiler manifests', statePath);\n    if (\n      [value.descriptorPath, ...Object.values(compilerManifests)].some((entry) => !isInside(generatedDirectory, entry))\n    ) {\n      throw new Error(`Doom sync state at ${statePath} references MCP material outside ${generatedDirectory}`);\n    }\n    mcpBundle = {\n      descriptorPath: value.descriptorPath,\n      fingerprint: value.fingerprint,\n      compilerManifests,\n      sourcesHash: value.sourcesHash,\n    };\n  }\n  const bootstrap = typeof parsed.bootstrap === 'string' ? parsed.bootstrap : undefined;\n  const generatedPaths = [bootstrap, ...Object.values(compiled ?? {}), ...Object.values(bundles ?? {})].filter(\n    (entry): entry is string => entry !== undefined,\n  );\n  if (generatedPaths.some((entry) => !isInside(generatedDirectory, entry))) {\n    throw new Error(`Doom sync state at ${statePath} references generated material outside ${generatedDirectory}`);\n  }\n  return {\n    version: parsed.version,\n    root: parsed.root,\n    identity,\n    inputsHash: parsed.inputsHash,\n    webSourcesHash: typeof parsed.webSourcesHash === 'string' ? parsed.webSourcesHash : undefined,\n    compositionFingerprint: parsed.compositionFingerprint,\n    selection: {\n      majorMode,\n      domains: Array.isArray(domains) ? domains.filter((name): name is string => typeof name === 'string') : [],\n      profile: typeof profile === 'string' ? profile : undefined,\n      preset: typeof preset === 'string' ? preset : DEFAULT_PRESET,\n    },\n    env: stringRecord(parsed.env, 'env', statePath),\n    fileState: {\n      profileEnvironment: isRecord(fileState.profileEnvironment)\n        ? (fileState.profileEnvironment as Record<string, string>)\n        : {},\n      pluginHooks: Array.isArray(fileState.pluginHooks) ? (fileState.pluginHooks as HarnessState['pluginHooks']) : [],\n      mcpProjection: fileState.mcpProjection,\n    },\n    resolved: stringRecord(parsed.resolved, 'resolved', statePath),\n    compiled,\n    bundles,\n    bootstrap,\n    precompile,\n    ...(serverBundle ? { serverBundle } : {}),\n    ...(mcpBundle ? { mcpBundle } : {}),\n    baseline: parsed.baseline as unknown as SyncBaseline,\n  };\n}\n\nexport interface LocatedSyncState {\n  state: SyncState;\n  location: SyncLocation;\n  layout: 'global';\n}\n\n/** Reads only state reached through this repository/worktree's validated registration. */\nexport function readLocatedSyncState(\n  repoRoot: string,\n  homeDirectory: string = os.homedir(),\n): LocatedSyncState | undefined {\n  const location = resolveSyncLocation(repoRoot, homeDirectory);\n  const registration = readSyncRegistration(repoRoot, homeDirectory);\n  if (!registration) return undefined;\n  return {\n    state: parseSyncState(fs.readFileSync(registration.statePath, 'utf8'), registration.statePath, {\n      repoRoot,\n      location,\n      legacy: false,\n    }),\n    location,\n    layout: 'global',\n  };\n}\n\n/** Reads the synced state, or undefined when the repository was never synced. */\nexport function readSyncState(repoRoot: string, homeDirectory: string = os.homedir()): SyncState | undefined {\n  return readLocatedSyncState(repoRoot, homeDirectory)?.state;\n}\n\nexport function serializeSyncState(state: SyncState): string {\n  return `${JSON.stringify(state, null, 2)}\\n`;\n}\n\nexport async function writeSyncState(\n  repoRoot: string,\n  state: SyncState,\n  homeDirectory: string = os.homedir(),\n  targetPath?: string,\n): Promise<string> {\n  const location = resolveSyncLocation(repoRoot, homeDirectory);\n  const statePath = targetPath ?? location.statePath;\n  if (state.version !== SYNC_STATE_VERSION) {\n    throw new Error(`Doom sync state writes require version ${SYNC_STATE_VERSION}`);\n  }\n  if (!COMPOSITION_FINGERPRINT.test(state.compositionFingerprint)) {\n    throw new Error('Doom sync state writes require a canonical composition fingerprint');\n  }\n  if (!isDoomMcpProjection(state.fileState.mcpProjection)) {\n    throw new Error('Doom sync state writes require a valid MCP projection');\n  }\n  if (!syncStateRootMatches(state.root, state.fileState.mcpProjection.repoRoot)) {\n    throw new Error('Refusing to write a Doom sync state whose MCP projection belongs to another repository');\n  }\n  if (!syncStateRootMatches(repoRoot, state.root) || !identityMatches(state.identity, location.identity)) {\n    throw new Error('Refusing to write Doom sync state for a different repository or worktree');\n  }\n  if (state.precompile) {\n    const precompile = parsePrecompileState(state.precompile, statePath);\n    if (!precompileMatchesBundles(precompile, state.bundles)) {\n      throw new Error(`Doom sync state at ${statePath} has an invalid precompile record`);\n    }\n  }\n  if (!isInside(location.directory, statePath)) {\n    throw new Error(`Refusing to write Doom sync state outside ${location.directory}`);\n  }\n  assertSyncLocationSafe(location);\n  await fs.promises.mkdir(path.dirname(statePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n  const temporaryPath = `${statePath}.${process.pid}.${crypto.randomUUID()}.tmp`;\n  try {\n    await fs.promises.writeFile(temporaryPath, serializeSyncState(state), { mode: PRIVATE_FILE_MODE });\n    await fs.promises.rename(temporaryPath, statePath);\n  } catch (error) {\n    await fs.promises.rm(temporaryPath, { force: true });\n    throw error;\n  }\n  return statePath;\n}\n\nexport function ownKey(name: string): string {\n  return `${OWN_PREFIX}${name}`;\n}\n\nexport function packageKey(specifier: string): string {\n  return `${PACKAGE_PREFIX}${specifier}`;\n}\n\nexport function packageEntryKey(specifier: string, index: number): string {\n  return index === 0 ? packageKey(specifier) : `${packageKey(specifier)}${ENTRY_INDEX_SEPARATOR}${index}`;\n}\n\n/**\n * Keyed by the absolute target, because the same relative specifier means\n * different files under the repository and the global config directory.\n */\nexport function localKey(specifier: string, baseDirectory: string): string {\n  return `${LOCAL_PREFIX}${path.resolve(baseDirectory, specifier)}`;\n}\n\nexport function localEntryKey(specifier: string, baseDirectory: string, index: number): string {\n  return index === 0\n    ? localKey(specifier, baseDirectory)\n    : `${localKey(specifier, baseDirectory)}${ENTRY_INDEX_SEPARATOR}${index}`;\n}\n\nexport function localPackageNameKey(specifier: string, baseDirectory: string): string {\n  return `${LOCAL_PACKAGE_NAME_PREFIX}${path.resolve(baseDirectory, specifier)}`;\n}\n\nexport interface RecordingResolvers extends ExtensionLayerResolvers {\n  /** Every name this resolver was asked for, keyed for the state file. */\n  readonly resolved: Record<string, string>;\n  packageEntries(name: string): string[];\n  optionalPackageEntries(name: string): string[] | undefined;\n  localEntries(specifier: string, baseDirectory: string): string[] | undefined;\n}\n\n/**\n * Resolvers that record what they resolve.\n *\n * Sync composes once with every layer selected and hands the recording to the\n * state file, so the extension never has to resolve a specifier itself.\n */\nexport function createRecordingResolvers(base: LayerResolvers = LAYER_RESOLVERS): RecordingResolvers {\n  const resolved: Record<string, string> = {};\n  const extensionBase = base as ExtensionLayerResolvers;\n  const recordEntries = (entries: string[], keyFor: (index: number) => string): string[] => {\n    entries.forEach((entry, index) => {\n      resolved[keyFor(index)] = entry;\n    });\n    return entries;\n  };\n  return {\n    resolved,\n    ownEntry(name) {\n      const entry = base.ownEntry(name);\n      resolved[ownKey(name)] = entry;\n      return entry;\n    },\n    packageEntry(name) {\n      const entry = base.packageEntry(name);\n      resolved[packageKey(name)] = entry;\n      return entry;\n    },\n    optionalPackageEntry(name) {\n      const entry = base.optionalPackageEntry(name);\n      // A miss is recorded by omission, which is what later makes the extension\n      // treat it as absent instead of failing the whole composition.\n      if (entry) resolved[packageKey(name)] = entry;\n      return entry;\n    },\n    packageEntries(name) {\n      const entries = extensionBase.packageEntries?.(name) ?? [base.packageEntry(name)];\n      return recordEntries(entries, (index) => packageEntryKey(name, index));\n    },\n    optionalPackageEntries(name) {\n      let entries = extensionBase.optionalPackageEntries?.(name);\n      if (entries === undefined) {\n        const entry = base.optionalPackageEntry(name);\n        entries = entry ? [entry] : undefined;\n      }\n      return entries ? recordEntries(entries, (index) => packageEntryKey(name, index)) : undefined;\n    },\n    localEntry(specifier, baseDirectory) {\n      const entry = base.localEntry(specifier, baseDirectory);\n      if (entry) resolved[localKey(specifier, baseDirectory)] = entry;\n      return entry;\n    },\n    localEntries(specifier, baseDirectory) {\n      let entries = extensionBase.localEntries?.(specifier, baseDirectory);\n      if (entries === undefined) {\n        const entry = base.localEntry(specifier, baseDirectory);\n        entries = entry ? [entry] : undefined;\n      }\n      return entries ? recordEntries(entries, (index) => localEntryKey(specifier, baseDirectory, index)) : undefined;\n    },\n    localPackageName(specifier, baseDirectory) {\n      const name = extensionBase.localPackageName?.(specifier, baseDirectory);\n      if (name) resolved[localPackageNameKey(specifier, baseDirectory)] = name;\n      return name;\n    },\n  };\n}\n\n/**\n * Resolves every entry any layer could contribute, in one pass.\n *\n * Composing with every layer selected and the widest options is what makes the\n * map complete: a later `/mode` switch inside a Pi session can then pick a\n * different set without resolving anything itself. The persona entry is asked\n * for separately because it remains a fixed host entry rather than a layer.\n */\nexport function recordResolvedEntries(\n  majorModesConfig: MajorModesConfig,\n  base: LayerResolvers = LAYER_RESOLVERS,\n): Record<string, string> {\n  const recording = createRecordingResolvers(base);\n  recording.packageEntry(PERSONA_ENTRY);\n  assembleExtensions({\n    agents: true,\n    autoStop: true,\n    mute: false,\n    // The one preset that contributes an extension of its own.\n    preset: OLLAMA_PRESET,\n    layers: Object.keys(majorModesConfig.layers),\n    majorModesConfig,\n    resolvers: recording,\n  });\n  assembleChildExtensions({\n    agents: false,\n    autoStop: false,\n    mute: true,\n    preset: OLLAMA_PRESET,\n    layers: Object.keys(majorModesConfig.layers),\n    majorModesConfig,\n    resolvers: recording,\n  });\n  return recording.resolved;\n}\n\n/** Resolvers backed by a synced map, for composing inside a Pi session. */\nexport function createMapResolvers(\n  resolved: Record<string, string>,\n  compiled: Record<string, string> = {},\n): ExtensionLayerResolvers {\n  // The compiled bundle when this entry has one, the source otherwise.\n  const entryFor = (key: string): string | undefined => compiled[key] ?? resolved[key];\n  const lookup = (key: string, name: string): string => {\n    const entry = entryFor(key);\n    if (!entry) throw new Error(`${name} is missing from the doompi sync state. Run doompi sync.`);\n    return entry;\n  };\n  const indexedEntries = (keyFor: (index: number) => string): string[] | undefined => {\n    const first = entryFor(keyFor(0));\n    if (!first) return undefined;\n    const entries = [first];\n    for (let index = 1; ; index += 1) {\n      const entry = entryFor(keyFor(index));\n      if (!entry) break;\n      entries.push(entry);\n    }\n    return entries;\n  };\n  return {\n    ownEntry: (name) => lookup(ownKey(name), name),\n    packageEntry: (name) => lookup(packageKey(name), name),\n    optionalPackageEntry: (name) => entryFor(packageKey(name)),\n    packageEntries: (name) => {\n      const entries = indexedEntries((index) => packageEntryKey(name, index));\n      if (!entries) throw new Error(`${name} is missing from the doompi sync state. Run doompi sync.`);\n      return entries;\n    },\n    optionalPackageEntries: (name) => indexedEntries((index) => packageEntryKey(name, index)),\n    localEntry: (specifier, baseDirectory) => entryFor(localKey(specifier, baseDirectory)),\n    localEntries: (specifier, baseDirectory) =>\n      indexedEntries((index) => localEntryKey(specifier, baseDirectory, index)),\n    localPackageName: (specifier, baseDirectory) => resolved[localPackageNameKey(specifier, baseDirectory)],\n  };\n}\n\n/** Reads the resolved MCP servers back out of a generated config. */\nexport function readMcpServerNames(configPath: string): string[] {\n  if (!fs.existsSync(configPath)) return [];\n  const config = JSON.parse(fs.readFileSync(configPath, 'utf8')) as JsonObject;\n  return isRecord(config.mcpServers) ? Object.keys(config.mcpServers) : [];\n}\n"],"mappings":"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"}