{"version":3,"file":"sessionConfig-M1M9PNQI.mjs","names":["deepFreeze"],"sources":["../src/services/doomConfigService/index.ts","../src/services/sessionConfig/index.ts"],"sourcesContent":["import { type Context, Service } from '@deepseek-ai/cordis';\n\nimport {\n  DOOM_CONFIG_SERVICE,\n  type DeepReadonly,\n  type DoomConfig,\n  type DoomConfigContext,\n  type DoomConfigLoader,\n  type IDoomConfigService,\n} from '../../types/config';\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n  if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n    return value as DeepReadonly<TValue>;\n  }\n  for (const child of Object.values(value)) deepFreeze(child);\n  return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\n/**\n * Doom configuration published on the shared cordis Context.\n *\n * Every extension resolves the same instance by name, so configuration stays\n * one read per session instead of one per consumer, and the registration is\n * removed with the fiber that created it. The loader is injected so this stays\n * free of filesystem access.\n */\nexport class DoomConfigService extends Service implements IDoomConfigService {\n  readonly generation: string;\n  private snapshot: DoomConfigContext;\n\n  constructor(\n    ctx: Context,\n    snapshot: DoomConfigContext,\n    private readonly loadConfig: DoomConfigLoader,\n    generation = `doom-config:${crypto.randomUUID()}`,\n  ) {\n    super(ctx, DOOM_CONFIG_SERVICE);\n    this.snapshot = deepFreeze(snapshot) as DoomConfigContext;\n    this.generation = generation;\n  }\n\n  getSnapshot(): DoomConfigContext {\n    return this.snapshot;\n  }\n\n  replaceSnapshot(context: DoomConfigContext): DoomConfigContext {\n    this.snapshot = deepFreeze(context) as DoomConfigContext;\n    return this.snapshot;\n  }\n\n  load(repoRoot: string, homeDirectory?: string): DoomConfig {\n    return this.loadConfig(repoRoot, homeDirectory);\n  }\n}\n","import type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, SessionEntry } from '@earendil-works/pi-coding-agent';\n\nimport type {\n  DoomConfigSelection as ConfigSelection,\n  DeepReadonly,\n  DoomConfigContext,\n  DoomConfigPendingSelection,\n  DoomConfigTransitionRecord,\n  DoomConfigTransitionStrategy,\n  HarnessState,\n  IDoomConfigService,\n} from '../../types/config';\nimport { DOOM_CONFIG_SERVICE } from '../../types/config';\nimport { loadDoomConfig, loadDoomConfigAsync } from '../config';\nimport { DoomConfigService } from '../doomConfigService';\nimport { getHarnessState } from '../harnessStore';\n\nexport const DOOM_CONFIG_ENTRY_TYPE = 'doom-pi:config:v1';\nexport const DOOM_CONFIG_TRANSITION_ENTRY_TYPE = 'doom-pi:transition:v1';\n\nexport type DoomConfigSelection = ConfigSelection;\n\ntype DoomConfigTransitionEntry = DoomConfigTransitionRecord;\n\nfunction isSelection(value: unknown): value is DoomConfigSelection {\n  if (typeof value !== 'object' || value === null) return false;\n  const selection = value as Partial<DoomConfigSelection>;\n  return (\n    selection.version === 1 &&\n    typeof selection.majorMode === 'string' &&\n    Array.isArray(selection.domains) &&\n    selection.domains.every((domain) => typeof domain === 'string') &&\n    (selection.profile === undefined || typeof selection.profile === 'string') &&\n    (selection.compositionFingerprint === undefined || typeof selection.compositionFingerprint === 'string')\n  );\n}\n\nfunction branchSelection(entries: readonly SessionEntry[]): DoomConfigSelection | undefined {\n  for (let index = entries.length - 1; index >= 0; index -= 1) {\n    const entry = entries[index];\n    if (entry?.type === 'custom' && entry.customType === DOOM_CONFIG_ENTRY_TYPE && isSelection(entry.data)) {\n      return entry.data;\n    }\n  }\n  return undefined;\n}\n\nfunction isTransitionStrategy(value: unknown): value is DoomConfigTransitionStrategy {\n  return value === 'pi-reload' || value === 'process-relaunch';\n}\n\nfunction isTransition(value: unknown): value is DoomConfigTransitionEntry {\n  if (typeof value !== 'object' || value === null) return false;\n  const transition = value as Partial<DoomConfigTransitionEntry>;\n  return (\n    transition.version === 1 &&\n    typeof transition.operationId === 'string' &&\n    isSelection(transition.active) &&\n    isSelection(transition.target) &&\n    isTransitionStrategy(transition.strategy) &&\n    (transition.phase === 'pending' ||\n      transition.phase === 'applied' ||\n      transition.phase === 'aborted' ||\n      transition.phase === 'superseded')\n  );\n}\n\nfunction branchTransition(entries: readonly SessionEntry[]): DoomConfigTransitionEntry | undefined {\n  for (let index = entries.length - 1; index >= 0; index -= 1) {\n    const entry = entries[index];\n    if (\n      entry?.type === 'custom' &&\n      entry.customType === DOOM_CONFIG_TRANSITION_ENTRY_TYPE &&\n      isTransition(entry.data)\n    ) {\n      return entry.data;\n    }\n  }\n  return undefined;\n}\n\nfunction sameSelection(left: DoomConfigSelection, state: HarnessState): boolean {\n  return (\n    left.majorMode === state.majorMode &&\n    left.profile === state.profile &&\n    (left.compositionFingerprint === undefined || left.compositionFingerprint === state.compositionFingerprint) &&\n    left.domains.length === state.domains.length &&\n    left.domains.every((domain, index) => domain === state.domains[index])\n  );\n}\n\nfunction isActiveTransitionTarget(target: DoomConfigSelection, state: HarnessState): boolean {\n  return (\n    target.compositionFingerprint !== undefined &&\n    target.compositionFingerprint === state.compositionFingerprint &&\n    sameSelection(target, state)\n  );\n}\n\nfunction pendingFromTransition(transition: DoomConfigTransitionEntry): DoomConfigPendingSelection | undefined {\n  if (transition.phase !== 'pending') return undefined;\n  return { ...transition, phase: 'pending' };\n}\n\nfunction pendingFromLegacySelection(\n  selection: DoomConfigSelection,\n  bootstrap: HarnessState,\n): DoomConfigPendingSelection | undefined {\n  if (sameSelection(selection, bootstrap)) return undefined;\n  const active: DoomConfigSelection = {\n    version: 1,\n    majorMode: bootstrap.majorMode,\n    domains: [...bootstrap.domains],\n    profile: bootstrap.profile,\n    compositionFingerprint: bootstrap.compositionFingerprint,\n  };\n  return {\n    version: 1,\n    operationId: 'legacy-config-selection',\n    active,\n    target: selection,\n    strategy: 'process-relaunch',\n    phase: 'pending',\n  };\n}\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n  if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n    return value as DeepReadonly<TValue>;\n  }\n  for (const child of Object.values(value)) deepFreeze(child);\n  return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\nexport function readDoomConfigSelection(\n  ctx: Pick<ExtensionContext, 'sessionManager'>,\n): DoomConfigSelection | undefined {\n  return branchSelection(ctx.sessionManager.getBranch());\n}\n\nfunction resolveContextState(ctx: Pick<ExtensionContext, 'sessionManager'>): {\n  harness: HarnessState;\n  pendingSelection: DoomConfigPendingSelection | undefined;\n  requiresRelaunch: boolean;\n  root: string | undefined;\n} {\n  const bootstrap = getHarnessState();\n  const entries = ctx.sessionManager.getBranch();\n  const selection = branchSelection(entries);\n  const transition = branchTransition(entries);\n  const transitionPending = transition ? pendingFromTransition(transition) : undefined;\n  const pendingSelection = transition\n    ? transitionPending\n    : selection\n      ? pendingFromLegacySelection(selection, bootstrap)\n      : undefined;\n  return {\n    harness: bootstrap,\n    pendingSelection,\n    requiresRelaunch:\n      pendingSelection !== undefined &&\n      (transitionPending === undefined || !isActiveTransitionTarget(pendingSelection.target, bootstrap)),\n    root: bootstrap.root,\n  };\n}\n\nexport function createDoomConfigContext(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): DoomConfigContext {\n  const { harness, pendingSelection, requiresRelaunch, root } = resolveContextState(ctx);\n  return deepFreeze({ settings: loadDoomConfig(root ?? ctx.cwd), harness, pendingSelection, requiresRelaunch });\n}\n\nexport async function createDoomConfigContextAsync(\n  ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>,\n): Promise<DoomConfigContext> {\n  const { harness, pendingSelection, requiresRelaunch, root } = resolveContextState(ctx);\n  const settings = await loadDoomConfigAsync(root ?? ctx.cwd);\n  return deepFreeze({ settings, harness, pendingSelection, requiresRelaunch });\n}\n\nexport function appendDoomConfigSelection(pi: Pick<ExtensionAPI, 'appendEntry'>, selection: DoomConfigSelection): void {\n  pi.appendEntry(DOOM_CONFIG_ENTRY_TYPE, selection);\n}\n\n/** Journals the live selection, defaulting to whatever the harness store holds. */\nexport function persistHarnessSelection(\n  pi: Pick<ExtensionAPI, 'appendEntry'>,\n  state: {\n    readonly majorMode: string;\n    readonly domains: readonly string[];\n    readonly profile?: string;\n    readonly compositionFingerprint?: string;\n  } = getHarnessState(),\n): void {\n  appendDoomConfigSelection(pi, {\n    version: 1,\n    majorMode: state.majorMode,\n    domains: state.domains,\n    profile: state.profile,\n    compositionFingerprint: state.compositionFingerprint,\n  });\n}\n\nexport function appendDoomConfigTransition(\n  pi: Pick<ExtensionAPI, 'appendEntry'>,\n  transition: DoomConfigTransitionRecord,\n): void {\n  pi.appendEntry(DOOM_CONFIG_TRANSITION_ENTRY_TYPE, transition);\n}\n\nexport function supersedeDoomConfigTransition(\n  pi: Pick<ExtensionAPI, 'appendEntry'>,\n  transition: DoomConfigPendingSelection,\n): void {\n  pi.appendEntry(DOOM_CONFIG_TRANSITION_ENTRY_TYPE, { ...transition, phase: 'superseded' });\n}\n\n/** Acknowledges the latest pending transition from a fresh session that owns its exact target composition. */\nexport function acknowledgeDoomConfigTransition(\n  pi: Pick<ExtensionAPI, 'appendEntry'>,\n  ctx: Pick<ExtensionContext, 'sessionManager'>,\n  harness: HarnessState,\n): boolean {\n  const transition = branchTransition(ctx.sessionManager.getBranch());\n  if (!transition || transition.phase !== 'pending' || !isActiveTransitionTarget(transition.target, harness)) {\n    return false;\n  }\n  appendDoomConfigTransition(pi, { ...transition, phase: 'applied' });\n  return true;\n}\n\nexport function readDoomConfigPendingSelection(\n  ctx: Pick<ExtensionContext, 'sessionManager'>,\n): DoomConfigPendingSelection | undefined {\n  const bootstrap = getHarnessState();\n  const transition = branchTransition(ctx.sessionManager.getBranch());\n  const transitionPending = transition ? pendingFromTransition(transition) : undefined;\n  if (transition) return transitionPending;\n  const selection = branchSelection(ctx.sessionManager.getBranch());\n  return selection ? pendingFromLegacySelection(selection, bootstrap) : undefined;\n}\n\nexport function provideDoomConfigContext(\n  ctx: Context,\n  context: DoomConfigContext,\n  generation = `doom-config:${crypto.randomUUID()}`,\n): IDoomConfigService {\n  return new DoomConfigService(ctx, deepFreeze(context) as DoomConfigContext, loadDoomConfig, generation);\n}\n\n/** Returns the binding identity used to fence in-flight transitions. */\nexport function readDoomConfigContextGeneration(ctx: Context): string | undefined {\n  return readDoomConfigService(ctx)?.generation;\n}\n\n/** Precomputes an immutable context before a transaction reaches publication. */\nexport function freezeDoomConfigContext(context: DoomConfigContext): DoomConfigContext {\n  return deepFreeze(context);\n}\n\n/** Replaces a live binding with a deeply frozen context after publication. */\nexport function replaceDoomConfigContext(ctx: Context, context: DoomConfigContext): DoomConfigContext {\n  const next = deepFreeze(context);\n  return requireDoomConfigService(ctx).replaceSnapshot(next as DoomConfigContext);\n}\n\nexport function readDoomConfigService(ctx: Context): IDoomConfigService | undefined {\n  return ctx.get(DOOM_CONFIG_SERVICE) as IDoomConfigService | undefined;\n}\n\nexport function requireDoomConfigService(ctx: Context): IDoomConfigService {\n  const service = readDoomConfigService(ctx);\n  if (!service) throw new Error('Doom config service is unavailable. Load @agimon-ai/doompi-config/extensions/pi.');\n  return service;\n}\n\nexport function requireDoomConfigContext(ctx: Context): DoomConfigContext {\n  return requireDoomConfigService(ctx).getSnapshot();\n}\n"],"mappings":"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"}