{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/builders/cli/bootstrapLocator/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 { readSyncRegistration } from '@agimon-ai/doompi-core/sync-registration';\nimport { BUNDLED_PRECOMPILE_STRATEGY, PRECOMPILE_STATE_VERSION } from '@agimon-ai/doompi-core/sync-state-contract';\n\nimport { inputsAreFresh, parseInputFingerprint, type InputFingerprint } from '../../../compiler/inputs';\nimport { resolveDoomConfigurationRoot } from '../../../composition/repository';\nimport { readSyncState } from '../../../composition/syncState';\nimport { ownEntry } from '../entryResolution';\n\nconst BOOTSTRAP_ENTRY_ENV = 'DOOMPI_BOOTSTRAP_ENTRY';\nconst SHA256 = /^[a-f0-9]{64}$/u;\n\ninterface CompilerManifest {\n  output: string;\n  artifacts: string[];\n  entries: string[];\n  inputs: InputFingerprint[];\n  artifactInputs?: InputFingerprint[];\n}\n\ninterface BootstrapState {\n  statePath: string;\n  generatedDirectory: string;\n  bootstrap?: string;\n  bundles: Record<string, string>;\n  precompile?: {\n    version: number;\n    strategy: 'bundle';\n    bootstrapEntry: string;\n    bootstrapManifest: string;\n    bundleManifests: Record<string, string>;\n  };\n}\n\nexport interface BootstrapStatus {\n  bootstrap?: string;\n  fresh: boolean;\n}\n\nexport interface BundleStatus {\n  bundle?: string;\n  fresh: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringRecord(value: unknown): Record<string, string> {\n  if (!isRecord(value)) return {};\n  return Object.fromEntries(\n    Object.entries(value).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n  );\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\nfunction parseFingerprints(value: unknown): InputFingerprint[] | undefined {\n  if (!Array.isArray(value)) return undefined;\n  const fingerprints = value.map(parseInputFingerprint);\n  return fingerprints.some((fingerprint) => fingerprint === undefined)\n    ? undefined\n    : (fingerprints as InputFingerprint[]);\n}\n\nfunction packagedDoomEntry(): string {\n  return process.env[BOOTSTRAP_ENTRY_ENV] || ownEntry('composedPi');\n}\n\nfunction locationHasState(repoRoot: string, homeDirectory: string): boolean {\n  return readSyncRegistration(repoRoot, homeDirectory) !== undefined;\n}\n\n/** Finds the nearest configured repository with generated Doom sync state. */\nexport function findSyncedRoot(cwd: string, homeDirectory: string = os.homedir()): string | undefined {\n  if (locationHasState(cwd, homeDirectory)) return canonicalPath(cwd);\n  const root = resolveDoomConfigurationRoot(cwd, homeDirectory);\n  return locationHasState(root, homeDirectory) ? canonicalPath(root) : undefined;\n}\n\nfunction readBootstrapState(repoRoot: string, homeDirectory: string = os.homedir()): BootstrapState | undefined {\n  const registration = readSyncRegistration(repoRoot, homeDirectory);\n  if (!registration) return undefined;\n  const statePath = registration.statePath;\n  const generatedDirectory = registration.generationRoot;\n  const state = readSyncState(repoRoot, homeDirectory);\n  if (!state) return undefined;\n  const bootstrap = typeof state.bootstrap === 'string' ? state.bootstrap : undefined;\n  if (bootstrap && !isInside(generatedDirectory, bootstrap)) {\n    throw new Error(`Doom bootstrap must stay inside ${generatedDirectory}: ${bootstrap}`);\n  }\n\n  let precompile: BootstrapState['precompile'];\n  if (state.precompile !== undefined) {\n    const value = state.precompile;\n    if (\n      !isRecord(value) ||\n      typeof value.version !== 'number' ||\n      value.strategy !== BUNDLED_PRECOMPILE_STRATEGY ||\n      typeof value.bootstrapEntry !== 'string' ||\n      typeof value.bootstrapManifest !== 'string' ||\n      !isRecord(value.bundleManifests) ||\n      Object.values(value.bundleManifests).some((manifest) => typeof manifest !== 'string')\n    ) {\n      throw new Error(`Doom sync state at ${statePath} has an invalid precompile record`);\n    }\n    precompile = {\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\n  return {\n    statePath,\n    generatedDirectory,\n    bootstrap,\n    bundles: stringRecord(state.bundles),\n    precompile,\n  };\n}\n\nfunction readCompilerManifest(manifestPath: string, generatedDirectory: string): CompilerManifest | undefined {\n  if (!isInside(generatedDirectory, manifestPath)) return undefined;\n  try {\n    const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as unknown;\n    if (\n      !isRecord(parsed) ||\n      typeof parsed.output !== 'string' ||\n      !Array.isArray(parsed.artifacts) ||\n      parsed.artifacts.some((artifact) => typeof artifact !== 'string') ||\n      !Array.isArray(parsed.entries) ||\n      parsed.entries.some((entry) => typeof entry !== 'string') ||\n      !Array.isArray(parsed.inputs) ||\n      (parsed.artifactInputs !== undefined && !Array.isArray(parsed.artifactInputs))\n    ) {\n      return undefined;\n    }\n    const inputs = parseFingerprints(parsed.inputs);\n    const artifactInputs = parsed.artifactInputs === undefined ? undefined : parseFingerprints(parsed.artifactInputs);\n    if (!inputs || (parsed.artifactInputs !== undefined && !artifactInputs)) return undefined;\n    const artifacts = parsed.artifacts as string[];\n    const entries = parsed.entries as string[];\n    if (\n      !isInside(generatedDirectory, parsed.output) ||\n      artifacts.some((artifact) => !isInside(generatedDirectory, artifact))\n    ) {\n      return undefined;\n    }\n    return { output: parsed.output, artifacts, entries, inputs, ...(artifactInputs ? { artifactInputs } : {}) };\n  } catch {\n    return undefined;\n  }\n}\n\nfunction artifactInputsAreIntact(manifest: CompilerManifest, generatedDirectory: string): boolean {\n  try {\n    if (!manifest.artifactInputs || manifest.artifactInputs.length === 0) return false;\n    const expected = new Set([manifest.output, ...manifest.artifacts].map(canonicalPath));\n    const seen = new Set<string>();\n    for (const input of manifest.artifactInputs) {\n      if (!SHA256.test(input.sha256) || !isInside(generatedDirectory, input.path)) return false;\n      const target = canonicalPath(input.path);\n      if (!expected.has(target)) return false;\n      const stat = fs.statSync(target);\n      if (!stat.isFile() || stat.size !== input.size) return false;\n      if (crypto.createHash('sha256').update(fs.readFileSync(target)).digest('hex') !== input.sha256) return false;\n      seen.add(target);\n    }\n    return seen.size === expected.size;\n  } catch {\n    return false;\n  }\n}\n\nfunction compilerManifestIsUsable(manifest: CompilerManifest, generatedDirectory: string): boolean {\n  return artifactInputsAreIntact(manifest, generatedDirectory);\n}\n\nfunction compilerManifestIsFresh(manifest: CompilerManifest, generatedDirectory: string): boolean {\n  return compilerManifestIsUsable(manifest, generatedDirectory) && inputsAreFresh(manifest.inputs);\n}\n\nfunction bootstrapRecord(\n  state: BootstrapState,\n  expectedBootstrapEntry: string,\n  requireFreshInputs: boolean,\n): CompilerManifest | undefined {\n  if (!state.bootstrap || !state.precompile) return undefined;\n  if (\n    state.precompile.version !== PRECOMPILE_STATE_VERSION ||\n    canonicalPath(state.precompile.bootstrapEntry) !== canonicalPath(expectedBootstrapEntry)\n  ) {\n    return undefined;\n  }\n  const record = readCompilerManifest(state.precompile.bootstrapManifest, state.generatedDirectory);\n  if (\n    !record ||\n    !compilerManifestIsUsable(record, state.generatedDirectory) ||\n    (requireFreshInputs && !compilerManifestIsFresh(record, state.generatedDirectory)) ||\n    record.output !== state.bootstrap ||\n    record.entries.length !== 1 ||\n    canonicalPath(record.entries[0] ?? '') !== canonicalPath(expectedBootstrapEntry)\n  ) {\n    return undefined;\n  }\n  return record;\n}\n\nfunction usableBootstrapRecord(state: BootstrapState, expectedBootstrapEntry: string): CompilerManifest | undefined {\n  return bootstrapRecord(state, expectedBootstrapEntry, false);\n}\n\nfunction freshBootstrapRecord(state: BootstrapState, expectedBootstrapEntry: string): CompilerManifest | undefined {\n  return bootstrapRecord(state, expectedBootstrapEntry, true);\n}\n\n/** Validates only the bootstrap graph needed before the generated bootstrap is imported. */\nexport function readStartupBootstrapStatus(\n  repoRoot: string,\n  expectedBootstrapEntry?: string,\n  homeDirectory: string = os.homedir(),\n): BootstrapStatus {\n  const state = readBootstrapState(repoRoot, homeDirectory);\n  const expected = expectedBootstrapEntry ?? packagedDoomEntry();\n  if (!state) return { bootstrap: undefined, fresh: false };\n  return {\n    bootstrap: state.bootstrap,\n    fresh: usableBootstrapRecord(state, expected) !== undefined,\n  };\n}\n\n/** Validates one selected composition without touching any inactive bundle inputs. */\nexport function readBundleStatus(\n  repoRoot: string,\n  compositionFingerprint: string,\n  homeDirectory: string = os.homedir(),\n): BundleStatus {\n  const state = readBootstrapState(repoRoot, homeDirectory);\n  const bundle = state?.bundles[compositionFingerprint];\n  const manifestPath = state?.precompile?.bundleManifests[compositionFingerprint];\n  if (!state || state.precompile?.version !== PRECOMPILE_STATE_VERSION || !bundle || !manifestPath) {\n    return { bundle, fresh: false };\n  }\n  const manifest = readCompilerManifest(manifestPath, state.generatedDirectory);\n  return {\n    bundle,\n    fresh: Boolean(\n      manifest && manifest.output === bundle && compilerManifestIsUsable(manifest, state.generatedDirectory),\n    ),\n  };\n}\n\n/** Validates the bootstrap and every bundle for `doompi sync --check` diagnostics. */\nexport function readBootstrapStatus(\n  repoRoot: string,\n  expectedBootstrapEntry?: string,\n  homeDirectory: string = os.homedir(),\n): BootstrapStatus {\n  const state = readBootstrapState(repoRoot, homeDirectory);\n  const expected = expectedBootstrapEntry ?? packagedDoomEntry();\n  if (!state?.bootstrap || !state.precompile || !freshBootstrapRecord(state, expected)) {\n    return { bootstrap: state?.bootstrap, fresh: false };\n  }\n  const manifests = Object.values(state.precompile.bundleManifests);\n  if (new Set(manifests).size !== manifests.length) return { bootstrap: state.bootstrap, fresh: false };\n  const fresh = Object.entries(state.bundles).every(([fingerprint, bundle]) => {\n    const manifestPath = state.precompile?.bundleManifests[fingerprint];\n    if (!manifestPath) return false;\n    const manifest = readCompilerManifest(manifestPath, state.generatedDirectory);\n    return Boolean(\n      manifest && manifest.output === bundle && compilerManifestIsFresh(manifest, state.generatedDirectory),\n    );\n  });\n  return { bootstrap: state.bootstrap, fresh };\n}\n\n/** Reads only the generated bootstrap pointer while retaining state validation. */\nexport function readBootstrapPointer(repoRoot: string, homeDirectory: string = os.homedir()): string | undefined {\n  return readBootstrapState(repoRoot, homeDirectory)?.bootstrap;\n}\n"],"mappings":"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"}