{"version":3,"file":"configPolicy-CeiDS_fY.cjs","names":["parseYaml"],"sources":["../src/services/configPolicy/index.ts"],"sourcesContent":["import { parse as parseYaml } from 'yaml';\n\nimport type {\n  AutocompactModeConfig,\n  AutocompactOverrideConfig,\n  AutocompactThresholdConfig,\n  ComputerUseConfig,\n  ConfigDiagnostic,\n  DoomConfig,\n  DoomSelectionConfig,\n  EditorConfig,\n  LenientParseOptions,\n  LenientParseResult,\n  PlanningAgentConfig,\n  PlanningModeConfig,\n  PlanningThinkingLevel,\n  ProjectTrust,\n  ResolvedVoiceConfig,\n  VoiceAdapterConfig,\n  VoiceAutoCaptureConfig,\n  VoiceConfig,\n  VoiceEngine,\n  VoiceMode,\n  VoiceModelConfig,\n  VoiceTtsConfig,\n  VoiceTtsEngine,\n} from '../../types/config';\nimport type { PersonaVoiceOverride } from '../../types/profiles';\n\nconst DEFAULT_PROJECT_TRUST: ProjectTrust = 'ask';\nconst DEFAULT_VOICE_MODE: VoiceMode = 'legacy';\nconst DEFAULT_VOICE_ENGINE: VoiceEngine = 'auto';\nconst DEFAULT_VOICE_LANGUAGE = 'auto';\nconst DEFAULT_RECORDER_DEVICE = 'none:default';\nconst ROOT_KEYS = ['modes', 'computerUse', 'projectTrust', 'editor', 'voice', 'selection', 'web'] as const;\nconst SELECTION_KEYS = ['majorMode', 'domains', 'profile'] as const;\nconst MODE_KEYS = ['planning', 'autocompact'] as const;\nconst PLANNING_KEYS = ['main', 'subagents', 'plansDirectory'] as const;\nconst AGENT_KEYS = ['model', 'thinking'] as const;\nconst AUTOCOMPACT_KEYS = ['enabled', 'model', 'thinking', 'thresholds', 'overrides'] as const;\nconst AUTOCOMPACT_THRESHOLD_KEYS = ['pass1', 'pass2', 'pass3'] as const;\nconst AUTOCOMPACT_OVERRIDE_KEYS = ['model', 'tokens'] as const;\nconst COMPUTER_USE_KEYS = ['enabled'] as const;\n/** A pass that fires below this is noise; one above it never fires before Pi compacts natively. */\nconst MIN_AUTOCOMPACT_RATIO = 0.05;\nconst MAX_AUTOCOMPACT_RATIO = 0.99;\n/**\n * A checkpoint at zero tokens fires before the session has said anything. There is\n * deliberately no ceiling: the package takes the lower of the ratio and the token\n * value, so one larger than the window is inert rather than dangerous.\n */\nconst MIN_AUTOCOMPACT_TOKENS = 1;\nconst EDITOR_KEYS = ['command'] as const;\nconst VOICE_KEYS = ['mode', 'engine', 'language', 'recorder', 'adapters', 'autoCapture'] as const;\nconst RECORDER_KEYS = ['binary', 'device'] as const;\nconst WHISPER_CPP_ENGINE = 'whisper-cpp' as const;\nconst OPENAI_WHISPER_ENGINE = 'openai-whisper' as const;\nconst MLX_WHISPER_ENGINE = 'mlx-whisper' as const;\nconst MACOS_SAY_TTS_ENGINE = 'macos-say' as const;\nconst ADAPTERS_KEYS = [WHISPER_CPP_ENGINE, OPENAI_WHISPER_ENGINE, MLX_WHISPER_ENGINE] as const;\nconst ADAPTER_KEYS = ['binary', 'model'] as const;\nconst MODEL_KEYS = ['path', 'id'] as const;\nconst AUTO_CAPTURE_KEYS = [\n  'model',\n  'startPhrases',\n  'stopPhrases',\n  'composeOpenPhrases',\n  'composeSendPhrases',\n  'composeCancelPhrases',\n  'utteranceIdleMs',\n  'composeUtteranceIdleMs',\n  'composeNudgeMs',\n  'transcriptionTimeoutMs',\n  'tts',\n] as const;\nconst TTS_KEYS = ['engine', 'voice', 'rate'] as const;\nconst DEFAULT_UTTERANCE_IDLE_MS = 3_000;\nconst MIN_UTTERANCE_IDLE_MS = 1_500;\nconst MAX_UTTERANCE_IDLE_MS = 10_000;\n/**\n * The endpoint window used while a composition draft is collecting.\n *\n * Shorter than `utteranceIdleMs` on purpose. A turn produces exactly one transcript, so\n * with the ordinary ~3 s window a short command spoken after a brief pause arrives glued\n * to the end of the preceding sentence and can never be read as a command. Roughly twice\n * the VAD's own 600 ms trailing-silence window: long enough that ordinary speech rhythm\n * does not split a sentence, short enough that a deliberate pause does. Over-splitting is\n * harmless here and only here, because draft segments are joined back together with a\n * space.\n */\nconst DEFAULT_COMPOSE_UTTERANCE_IDLE_MS = 1_200;\nconst MIN_COMPOSE_UTTERANCE_IDLE_MS = 800;\nconst MAX_COMPOSE_UTTERANCE_IDLE_MS = 3_000;\n/** Silence before Voice reminds the user a draft is still open. `0` disables it. */\nconst DEFAULT_COMPOSE_NUDGE_MS = 10_000;\nconst MIN_COMPOSE_NUDGE_MS = 5_000;\nconst MAX_COMPOSE_NUDGE_MS = 60_000;\n/**\n * Defaults kept as lists so the phrases that shipped first keep working.\n *\n * `hey doom` and `that's it` read as speech; `doom prompt` and `doom send` are what\n * existing users have in their fingers. Dropping the originals would break them for no\n * gain, and the cost of carrying both is two extra comparisons per command candidate.\n */\nconst DEFAULT_COMPOSE_OPEN_PHRASES = ['hey doom', 'doom prompt'] as const;\nconst DEFAULT_COMPOSE_SEND_PHRASES = [\"that's it\", 'doom send'] as const;\nconst DEFAULT_COMPOSE_CANCEL_PHRASES = ['doom cancel', 'scratch that'] as const;\nconst DEFAULT_TRANSCRIPTION_TIMEOUT_MS = 120_000;\nconst MIN_TRANSCRIPTION_TIMEOUT_MS = 1_000;\nconst MAX_TRANSCRIPTION_TIMEOUT_MS = 120_000;\nconst MAX_CONTROL_PHRASES = 16;\nconst MAX_CONTROL_PHRASE_LENGTH = 64;\nconst MAX_TTS_VOICE_LENGTH = 64;\nconst MIN_TTS_RATE = 80;\nconst MAX_TTS_RATE = 500;\nconst MODEL_REFERENCE_PATTERN = /^[^/\\s]+\\/[^/\\s]+(?:\\/[^/\\s]+)*$/u;\nconst PHRASE_PUNCTUATION_PATTERN = /[\\p{P}\\p{S}]+/gu;\n/**\n * The accepted values, in the order a picker should offer them.\n *\n * Exported because the config UI has to offer exactly what the parser accepts,\n * and a second hand-written list in the contributing package would drift. The\n * validating Sets below are built from these for the same reason.\n */\nexport const DOOM_PLANNING_THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const;\nexport const DOOM_VOICE_MODES = [DEFAULT_VOICE_MODE, 'live'] as const;\nexport const DOOM_VOICE_ENGINES = [\n  DEFAULT_VOICE_ENGINE,\n  WHISPER_CPP_ENGINE,\n  OPENAI_WHISPER_ENGINE,\n  MLX_WHISPER_ENGINE,\n] as const;\nexport const DOOM_VOICE_TTS_ENGINES = [MACOS_SAY_TTS_ENGINE] as const;\n\nconst THINKING_VALUES = new Set<PlanningThinkingLevel>(DOOM_PLANNING_THINKING_LEVELS);\nconst TRUST_VALUES = new Set<ProjectTrust>(['ask', 'always', 'never']);\nconst VOICE_MODE_VALUES = new Set<VoiceMode>(DOOM_VOICE_MODES);\nconst ENGINE_VALUES = new Set<VoiceEngine>(DOOM_VOICE_ENGINES);\nconst TTS_ENGINE_VALUES = new Set<VoiceTtsEngine>(DOOM_VOICE_TTS_ENGINES);\ntype ConfigObject = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is ConfigObject {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n/**\n * Where a lenient parse collects unknown keys instead of throwing.\n *\n * Module scope rather than a parameter threaded through the twelve nested\n * parsers: `assertKeys` is the only reader, parsing is synchronous end to end,\n * and `parseDoomConfig` owns the whole window in a try/finally. Threading would\n * touch every parser to change behaviour in one of them.\n */\nlet unknownKeySink: ConfigDiagnostic[] | undefined;\n\nfunction assertKeys(value: ConfigObject, allowed: readonly string[], location: string, filePath: string): void {\n  const unknown = Object.keys(value).filter((key) => !allowed.includes(key));\n  if (unknown.length === 0) return;\n  if (unknownKeySink !== undefined) {\n    // Left on the object rather than deleted: every parser reads the fields it\n    // knows by name, so an unknown sibling is already inert.\n    for (const key of unknown) {\n      unknownKeySink.push({\n        filePath,\n        path: location === 'root' ? key : `${location}.${key}`,\n        message: `unsupported ${location} field`,\n      });\n    }\n    return;\n  }\n  throw new Error(`Doom config at ${filePath} has unsupported ${location} field(s): ${unknown.join(', ')}`);\n}\nfunction optionalString(value: unknown, location: string, filePath: string): string | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value !== 'string' || value.trim().length === 0)\n    throw new Error(`Doom config at ${filePath} requires ${location} to be a non-empty string`);\n  return value.trim();\n}\nfunction hasControlCharacters(value: string): boolean {\n  for (const character of value) {\n    const codePoint = character.codePointAt(0);\n    if (codePoint !== undefined && (codePoint <= 0x1f || codePoint === 0x7f)) return true;\n  }\n  return false;\n}\nfunction boundedOptionalString(\n  value: unknown,\n  location: string,\n  filePath: string,\n  maximumLength: number,\n): string | undefined {\n  const text = optionalString(value, location, filePath);\n  if (!text) return undefined;\n  if (text.length > maximumLength)\n    throw new Error(`Doom config at ${filePath} requires ${location} to be at most ${maximumLength} characters`);\n  if (hasControlCharacters(text))\n    throw new Error(`Doom config at ${filePath} does not allow control characters in ${location}`);\n  return text;\n}\nfunction parseModelReference(value: unknown, filePath: string): string {\n  const location = 'voice.autoCapture.model';\n  const model = optionalString(value, location, filePath);\n  if (!model || !MODEL_REFERENCE_PATTERN.test(model))\n    throw new Error(`Doom config at ${filePath} requires ${location} in provider/model-id form`);\n  return model;\n}\nfunction normalizeControlPhrase(value: string): string {\n  return value\n    .normalize('NFKC')\n    .toLocaleLowerCase('en-US')\n    .replace(PHRASE_PUNCTUATION_PATTERN, ' ')\n    .replace(/\\s+/gu, ' ')\n    .trim();\n}\nfunction parseControlPhrases(value: unknown, location: string, filePath: string): string[] | undefined {\n  if (value === undefined) return undefined;\n  if (!Array.isArray(value) || value.some((phrase) => typeof phrase !== 'string'))\n    throw new Error(`Doom config at ${filePath} requires ${location} to be an array of strings`);\n  if (value.length > MAX_CONTROL_PHRASES)\n    throw new Error(\n      `Doom config at ${filePath} requires ${location} to contain at most ${MAX_CONTROL_PHRASES} phrases`,\n    );\n  const phrases = value.map((phrase) => phrase.trim());\n  const normalized = new Set<string>();\n  for (const phrase of phrases) {\n    if (phrase.length === 0)\n      throw new Error(`Doom config at ${filePath} requires ${location} to contain non-empty strings`);\n    if (phrase.length > MAX_CONTROL_PHRASE_LENGTH)\n      throw new Error(\n        `Doom config at ${filePath} requires ${location} phrases to be at most ${MAX_CONTROL_PHRASE_LENGTH} characters`,\n      );\n    if (hasControlCharacters(phrase))\n      throw new Error(`Doom config at ${filePath} does not allow control characters in ${location}`);\n    const key = normalizeControlPhrase(phrase);\n    if (!key) throw new Error(`Doom config at ${filePath} requires ${location} to contain words`);\n    if (normalized.has(key))\n      throw new Error(`Doom config at ${filePath} does not allow normalized duplicates in ${location}`);\n    normalized.add(key);\n  }\n  return phrases;\n}\nfunction parseBoundedInteger(\n  value: unknown,\n  location: string,\n  filePath: string,\n  minimum: number,\n  maximum: number,\n): number | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value !== 'number' || !Number.isInteger(value) || value < minimum || value > maximum)\n    throw new Error(`Doom config at ${filePath} requires ${location} to be an integer from ${minimum} to ${maximum}`);\n  return value;\n}\n/**\n * Rejects a phrase claimed by two control roles at once.\n *\n * Composition commands are adjudicated before stop phrases and before leading\n * start-phrase removal, so a phrase shared with a later role is not ambiguous, it is\n * silently unreachable. Without a screen there is nothing to show which role won.\n */\nfunction assertDisjointPhrases(\n  left: readonly string[] | undefined,\n  right: readonly string[] | undefined,\n  leftName: string,\n  rightName: string,\n  filePath: string,\n): void {\n  const keys = new Set((left ?? []).map(normalizeControlPhrase));\n  if ((right ?? []).some((phrase) => keys.has(normalizeControlPhrase(phrase))))\n    throw new Error(`Doom config at ${filePath} does not allow a phrase in both ${leftName} and ${rightName}`);\n}\nfunction parseTtsConfig(value: unknown, filePath: string): VoiceTtsConfig {\n  const location = 'voice.autoCapture.tts';\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, TTS_KEYS, location, filePath);\n  if (typeof value.engine !== 'string' || !TTS_ENGINE_VALUES.has(value.engine as VoiceTtsEngine))\n    throw new Error(\n      `Doom config at ${filePath} requires ${location}.engine to be one of: ${[...TTS_ENGINE_VALUES].join(', ')}`,\n    );\n  const voice = boundedOptionalString(value.voice, `${location}.voice`, filePath, MAX_TTS_VOICE_LENGTH);\n  const rate = value.rate;\n  if (\n    rate !== undefined &&\n    (typeof rate !== 'number' || !Number.isInteger(rate) || rate < MIN_TTS_RATE || rate > MAX_TTS_RATE)\n  ) {\n    throw new Error(\n      `Doom config at ${filePath} requires ${location}.rate to be an integer from ${MIN_TTS_RATE} to ${MAX_TTS_RATE}`,\n    );\n  }\n  return {\n    engine: value.engine as VoiceTtsEngine,\n    ...(voice ? { voice } : {}),\n    ...(rate === undefined ? {} : { rate }),\n  };\n}\nfunction parseAutoCapture(value: unknown, filePath: string): VoiceAutoCaptureConfig | undefined {\n  if (value === undefined) return undefined;\n  const location = 'voice.autoCapture';\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, AUTO_CAPTURE_KEYS, location, filePath);\n  const startPhrases = parseControlPhrases(value.startPhrases, `${location}.startPhrases`, filePath);\n  const stopPhrases = parseControlPhrases(value.stopPhrases, `${location}.stopPhrases`, filePath);\n  const composeOpenPhrases = parseControlPhrases(value.composeOpenPhrases, `${location}.composeOpenPhrases`, filePath);\n  const composeSendPhrases = parseControlPhrases(value.composeSendPhrases, `${location}.composeSendPhrases`, filePath);\n  const composeCancelPhrases = parseControlPhrases(\n    value.composeCancelPhrases,\n    `${location}.composeCancelPhrases`,\n    filePath,\n  );\n  const utteranceIdleMs = parseBoundedInteger(\n    value.utteranceIdleMs,\n    `${location}.utteranceIdleMs`,\n    filePath,\n    MIN_UTTERANCE_IDLE_MS,\n    MAX_UTTERANCE_IDLE_MS,\n  );\n  const composeUtteranceIdleMs = parseBoundedInteger(\n    value.composeUtteranceIdleMs,\n    `${location}.composeUtteranceIdleMs`,\n    filePath,\n    MIN_COMPOSE_UTTERANCE_IDLE_MS,\n    MAX_COMPOSE_UTTERANCE_IDLE_MS,\n  );\n  // Zero is the documented off switch, so it is accepted outside the range rather than\n  // forcing a separate boolean that could disagree with the interval.\n  const composeNudgeMs =\n    value.composeNudgeMs === 0\n      ? 0\n      : parseBoundedInteger(\n          value.composeNudgeMs,\n          `${location}.composeNudgeMs`,\n          filePath,\n          MIN_COMPOSE_NUDGE_MS,\n          MAX_COMPOSE_NUDGE_MS,\n        );\n  const transcriptionTimeoutMs = parseBoundedInteger(\n    value.transcriptionTimeoutMs,\n    `${location}.transcriptionTimeoutMs`,\n    filePath,\n    MIN_TRANSCRIPTION_TIMEOUT_MS,\n    MAX_TRANSCRIPTION_TIMEOUT_MS,\n  );\n  assertDisjointPhrases(startPhrases, stopPhrases, 'startPhrases', 'stopPhrases', filePath);\n  // `composeOpenPhrases` may overlap `startPhrases`: addressing the agent and opening a\n  // draft are the same gesture, composition is adjudicated first, and the shipped\n  // defaults deliberately share `hey doom`.\n  assertDisjointPhrases(\n    composeSendPhrases,\n    composeCancelPhrases,\n    'composeSendPhrases',\n    'composeCancelPhrases',\n    filePath,\n  );\n  assertDisjointPhrases(composeOpenPhrases, composeSendPhrases, 'composeOpenPhrases', 'composeSendPhrases', filePath);\n  assertDisjointPhrases(\n    composeOpenPhrases,\n    composeCancelPhrases,\n    'composeOpenPhrases',\n    'composeCancelPhrases',\n    filePath,\n  );\n  assertDisjointPhrases(stopPhrases, composeSendPhrases, 'stopPhrases', 'composeSendPhrases', filePath);\n  assertDisjointPhrases(stopPhrases, composeCancelPhrases, 'stopPhrases', 'composeCancelPhrases', filePath);\n  return {\n    model: parseModelReference(value.model, filePath),\n    ...(startPhrases ? { startPhrases } : {}),\n    ...(stopPhrases ? { stopPhrases } : {}),\n    ...(composeOpenPhrases ? { composeOpenPhrases } : {}),\n    ...(composeSendPhrases ? { composeSendPhrases } : {}),\n    ...(composeCancelPhrases ? { composeCancelPhrases } : {}),\n    ...(utteranceIdleMs === undefined ? {} : { utteranceIdleMs }),\n    ...(composeUtteranceIdleMs === undefined ? {} : { composeUtteranceIdleMs }),\n    ...(composeNudgeMs === undefined ? {} : { composeNudgeMs }),\n    ...(transcriptionTimeoutMs === undefined ? {} : { transcriptionTimeoutMs }),\n    tts: parseTtsConfig(value.tts, filePath),\n  };\n}\nfunction parseThinking(value: unknown, location: string, filePath: string): PlanningThinkingLevel | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value !== 'string' || !THINKING_VALUES.has(value as PlanningThinkingLevel)) {\n    throw new Error(\n      `Doom config at ${filePath} requires ${location}.thinking to be one of: ${[...THINKING_VALUES].join(', ')}`,\n    );\n  }\n  return value as PlanningThinkingLevel;\n}\nfunction parseAgent(value: unknown, location: string, filePath: string): PlanningAgentConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, AGENT_KEYS, location, filePath);\n  const thinking = parseThinking(value.thinking, location, filePath);\n  const model = optionalString(value.model, `${location}.model`, filePath);\n  return { ...(model ? { model } : {}), ...(thinking ? { thinking } : {}) };\n}\n/**\n * A flag the cockpit can write.\n *\n * The settings page writes strings and nothing else, so `'true'` has to mean\n * what a hand-edited `true` means. Anything else is rejected rather than\n * treated as false, because a typo that silently disables a feature is the\n * worst reading of it.\n */\nfunction parseFlexibleBoolean(value: unknown, location: string, filePath: string): boolean | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value === 'boolean') return value;\n  if (value === 'true') return true;\n  if (value === 'false') return false;\n  throw new Error(`Doom config at ${filePath} requires ${location} to be true or false`);\n}\n/** Same story as the flag: a number, or the string form the settings page writes. */\nfunction parseFlexibleRatio(value: unknown, location: string, filePath: string): number | undefined {\n  if (value === undefined) return undefined;\n  const ratio = typeof value === 'string' ? Number(value.trim()) : value;\n  if (\n    typeof ratio !== 'number' ||\n    !Number.isFinite(ratio) ||\n    ratio < MIN_AUTOCOMPACT_RATIO ||\n    ratio > MAX_AUTOCOMPACT_RATIO\n  ) {\n    throw new Error(\n      `Doom config at ${filePath} requires ${location} to be a number from ${MIN_AUTOCOMPACT_RATIO} to ${MAX_AUTOCOMPACT_RATIO}`,\n    );\n  }\n  return ratio;\n}\nfunction parseAutocompactThresholds(\n  value: unknown,\n  location: string,\n  filePath: string,\n): AutocompactThresholdConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, AUTOCOMPACT_THRESHOLD_KEYS, location, filePath);\n  const pass1 = parseFlexibleRatio(value.pass1, `${location}.pass1`, filePath);\n  const pass2 = parseFlexibleRatio(value.pass2, `${location}.pass2`, filePath);\n  const pass3 = parseFlexibleRatio(value.pass3, `${location}.pass3`, filePath);\n  return {\n    ...(pass1 === undefined ? {} : { pass1 }),\n    ...(pass2 === undefined ? {} : { pass2 }),\n    ...(pass3 === undefined ? {} : { pass3 }),\n  };\n}\n/** Absolute token counts, unlike the ratios, are only ever written by hand, so no string form is accepted. */\nfunction parseAutocompactTokenCount(value: unknown, location: string, filePath: string): number | undefined {\n  if (value === undefined) return undefined;\n  if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < MIN_AUTOCOMPACT_TOKENS)\n    throw new Error(\n      `Doom config at ${filePath} requires ${location} to be an integer of at least ${MIN_AUTOCOMPACT_TOKENS}`,\n    );\n  return value;\n}\nfunction parseAutocompactOverrideEntry(value: unknown, location: string, filePath: string): AutocompactOverrideConfig {\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, AUTOCOMPACT_OVERRIDE_KEYS, location, filePath);\n  const model = optionalString(value.model, `${location}.model`, filePath);\n  if (!model) throw new Error(`Doom config at ${filePath} requires ${location}.model`);\n  if (!isObject(value.tokens))\n    throw new Error(`Doom config at ${filePath} requires ${location}.tokens to be an object`);\n  assertKeys(value.tokens, AUTOCOMPACT_THRESHOLD_KEYS, `${location}.tokens`, filePath);\n  const pass1 = parseAutocompactTokenCount(value.tokens.pass1, `${location}.tokens.pass1`, filePath);\n  const pass2 = parseAutocompactTokenCount(value.tokens.pass2, `${location}.tokens.pass2`, filePath);\n  const pass3 = parseAutocompactTokenCount(value.tokens.pass3, `${location}.tokens.pass3`, filePath);\n  // An entry that pins nothing is a typo rather than a way to say \"leave this model alone\":\n  // omitting the entry already does that, and a silent no-op reads like the override worked.\n  if (pass1 === undefined && pass2 === undefined && pass3 === undefined)\n    throw new Error(`Doom config at ${filePath} requires one of ${location}.tokens.pass1, pass2, or pass3`);\n  return {\n    model,\n    tokens: {\n      ...(pass1 === undefined ? {} : { pass1 }),\n      ...(pass2 === undefined ? {} : { pass2 }),\n      ...(pass3 === undefined ? {} : { pass3 }),\n    },\n  };\n}\nfunction parseAutocompactOverrides(\n  value: unknown,\n  location: string,\n  filePath: string,\n): AutocompactOverrideConfig[] | undefined {\n  if (value === undefined) return undefined;\n  if (!Array.isArray(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be a list`);\n  return value.map((entry, index) => parseAutocompactOverrideEntry(entry, `${location}[${index}]`, filePath));\n}\nexport function parseAutocompactModeConfig(\n  value: unknown,\n  filePath: string,\n  location = 'modes.autocompact',\n): AutocompactModeConfig {\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, AUTOCOMPACT_KEYS, location, filePath);\n  const enabled = parseFlexibleBoolean(value.enabled, `${location}.enabled`, filePath);\n  const model = optionalString(value.model, `${location}.model`, filePath);\n  const thinking = parseThinking(value.thinking, location, filePath);\n  const thresholds = parseAutocompactThresholds(value.thresholds, `${location}.thresholds`, filePath);\n  const overrides = parseAutocompactOverrides(value.overrides, `${location}.overrides`, filePath);\n  return {\n    ...(enabled === undefined ? {} : { enabled }),\n    ...(model ? { model } : {}),\n    ...(thinking ? { thinking } : {}),\n    ...(thresholds ? { thresholds } : {}),\n    ...(overrides ? { overrides } : {}),\n  };\n}\nexport function parsePlanningModeConfig(\n  value: unknown,\n  filePath: string,\n  location = 'modes.planning',\n): PlanningModeConfig {\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, PLANNING_KEYS, location, filePath);\n  return {\n    main: parseAgent(value.main, `${location}.main`, filePath),\n    subagents: parseAgent(value.subagents, `${location}.subagents`, filePath),\n    plansDirectory: optionalString(value.plansDirectory, `${location}.plansDirectory`, filePath),\n  };\n}\nfunction parseModel(value: unknown, location: string, filePath: string, allowId: boolean): VoiceModelConfig {\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, MODEL_KEYS, location, filePath);\n  const modelPath = optionalString(value.path, `${location}.path`, filePath);\n  const id = optionalString(value.id, `${location}.id`, filePath);\n  if (Boolean(modelPath) === Boolean(id))\n    throw new Error(`Doom config at ${filePath} requires exactly one of ${location}.path or ${location}.id`);\n  if (id && !allowId) throw new Error(`Doom config at ${filePath} does not support ${location}.id for whisper-cpp`);\n  return { ...(modelPath ? { path: modelPath } : {}), ...(id ? { id } : {}) };\n}\nfunction parseAdapter(\n  value: unknown,\n  location: string,\n  filePath: string,\n  allowId: boolean,\n): VoiceAdapterConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires ${location} to be an object`);\n  assertKeys(value, ADAPTER_KEYS, location, filePath);\n  const binary = optionalString(value.binary, `${location}.binary`, filePath);\n  return { ...(binary ? { binary } : {}), model: parseModel(value.model, `${location}.model`, filePath, allowId) };\n}\nfunction parseVoice(value: unknown, filePath: string): VoiceConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires voice to be an object`);\n  assertKeys(value, VOICE_KEYS, 'voice', filePath);\n  const result: VoiceConfig = {};\n  if (value.mode !== undefined) {\n    if (typeof value.mode !== 'string' || !VOICE_MODE_VALUES.has(value.mode as VoiceMode))\n      throw new Error(\n        `Doom config at ${filePath} requires voice.mode to be one of: ${[...VOICE_MODE_VALUES].join(', ')}`,\n      );\n    result.mode = value.mode as VoiceMode;\n  }\n  if (value.engine !== undefined) {\n    if (typeof value.engine !== 'string' || !ENGINE_VALUES.has(value.engine as VoiceEngine))\n      throw new Error(\n        `Doom config at ${filePath} requires voice.engine to be one of: ${[...ENGINE_VALUES].join(', ')}`,\n      );\n    result.engine = value.engine as VoiceEngine;\n  }\n  const language = optionalString(value.language, 'voice.language', filePath);\n  if (language) result.language = language;\n  if (value.recorder !== undefined) {\n    if (!isObject(value.recorder))\n      throw new Error(`Doom config at ${filePath} requires voice.recorder to be an object`);\n    assertKeys(value.recorder, RECORDER_KEYS, 'voice.recorder', filePath);\n    result.recorder = {};\n    const binary = optionalString(value.recorder.binary, 'voice.recorder.binary', filePath);\n    const device = optionalString(value.recorder.device, 'voice.recorder.device', filePath);\n    if (binary) result.recorder.binary = binary;\n    if (device) result.recorder.device = device;\n  }\n  if (value.adapters !== undefined) {\n    if (!isObject(value.adapters))\n      throw new Error(`Doom config at ${filePath} requires voice.adapters to be an object`);\n    assertKeys(value.adapters, ADAPTERS_KEYS, 'voice.adapters', filePath);\n    result.adapters = {\n      [WHISPER_CPP_ENGINE]: parseAdapter(\n        value.adapters[WHISPER_CPP_ENGINE],\n        `voice.adapters.${WHISPER_CPP_ENGINE}`,\n        filePath,\n        false,\n      ),\n      [OPENAI_WHISPER_ENGINE]: parseAdapter(\n        value.adapters[OPENAI_WHISPER_ENGINE],\n        `voice.adapters.${OPENAI_WHISPER_ENGINE}`,\n        filePath,\n        true,\n      ),\n      [MLX_WHISPER_ENGINE]: parseAdapter(\n        value.adapters[MLX_WHISPER_ENGINE],\n        `voice.adapters.${MLX_WHISPER_ENGINE}`,\n        filePath,\n        true,\n      ),\n    };\n  }\n  const autoCapture = parseAutoCapture(value.autoCapture, filePath);\n  if (autoCapture) result.autoCapture = autoCapture;\n  return result;\n}\nfunction parseSelection(value: unknown, filePath: string): DoomSelectionConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires selection to be an object`);\n  assertKeys(value, SELECTION_KEYS, 'selection', filePath);\n  const domains = value.domains;\n  if (domains !== undefined && (!Array.isArray(domains) || domains.some((name) => typeof name !== 'string'))) {\n    throw new Error(`Doom config at ${filePath} requires selection.domains to be an array of strings`);\n  }\n  return {\n    majorMode: optionalString(value.majorMode, 'selection.majorMode', filePath),\n    // An empty list is meaningful: it selects no content domains at all.\n    domains: domains as string[] | undefined,\n    profile: optionalString(value.profile, 'selection.profile', filePath),\n  };\n}\nfunction parseEditor(value: unknown, filePath: string): EditorConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires editor to be an object`);\n  assertKeys(value, EDITOR_KEYS, 'editor', filePath);\n  return { command: optionalString(value.command, 'editor.command', filePath) };\n}\n\nfunction parseWeb(value: unknown, filePath: string): DoomConfig['web'] {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires web to be an object`);\n  assertKeys(value, ['template'], 'web', filePath);\n  if (value.template === undefined) return {};\n  const template = optionalString(value.template, 'web.template', filePath);\n  if (!template || template.length > 160 || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(template)) {\n    throw new Error(`Doom config at ${filePath} requires web.template to be a kebab-case template identifier`);\n  }\n  return { template };\n}\nfunction parseComputerUse(value: unknown, filePath: string): ComputerUseConfig | undefined {\n  if (value === undefined) return undefined;\n  if (!isObject(value)) throw new Error(`Doom config at ${filePath} requires computerUse to be an object`);\n  assertKeys(value, COMPUTER_USE_KEYS, 'computerUse', filePath);\n  const enabled = parseFlexibleBoolean(value.enabled, 'computerUse.enabled', filePath);\n  return enabled === undefined ? {} : { enabled };\n}\n/**\n * Reads one Doom config file.\n *\n * The two-argument form is the strict contract every harness-launch consumer\n * relies on: an unknown key is a hard error. `doompi sync` opts into the\n * lenient form so a config written for a different version cannot break a\n * build; `doompi doctor` is the strict check that still reports those keys.\n * Invalid values for known keys throw in both modes.\n */\nexport function parseDoomConfig(content: string, filePath: string): DoomConfig;\nexport function parseDoomConfig(content: string, filePath: string, options: LenientParseOptions): LenientParseResult;\nexport function parseDoomConfig(\n  content: string,\n  filePath: string,\n  options?: LenientParseOptions,\n): DoomConfig | LenientParseResult {\n  if (options?.lenient !== true) return parseStrict(content, filePath);\n  const diagnostics: ConfigDiagnostic[] = [];\n  const previous = unknownKeySink;\n  unknownKeySink = diagnostics;\n  try {\n    return { config: parseStrict(content, filePath), diagnostics };\n  } finally {\n    unknownKeySink = previous;\n  }\n}\n\nfunction parseStrict(content: string, filePath: string): DoomConfig {\n  let parsed: unknown;\n  try {\n    parsed = parseYaml(content) ?? {};\n  } catch (error) {\n    throw new Error(`Could not parse Doom config at ${filePath}`, { cause: error });\n  }\n  if (!isObject(parsed)) throw new Error(`Doom config at ${filePath} must be a YAML object`);\n  assertKeys(parsed, ROOT_KEYS, 'root', filePath);\n  let modes: DoomConfig['modes'];\n  if (parsed.modes !== undefined) {\n    if (!isObject(parsed.modes)) throw new Error(`Doom config at ${filePath} requires modes to be an object`);\n    assertKeys(parsed.modes, MODE_KEYS, 'modes', filePath);\n    modes = {\n      ...(parsed.modes.planning === undefined\n        ? {}\n        : { planning: parsePlanningModeConfig(parsed.modes.planning, filePath) }),\n      ...(parsed.modes.autocompact === undefined\n        ? {}\n        : { autocompact: parseAutocompactModeConfig(parsed.modes.autocompact, filePath) }),\n    };\n  }\n  const trust = parsed.projectTrust === undefined ? DEFAULT_PROJECT_TRUST : parsed.projectTrust;\n  if (typeof trust !== 'string' || !TRUST_VALUES.has(trust as ProjectTrust))\n    throw new Error(`Doom config at ${filePath} projectTrust must be ask, always, or never`);\n  return {\n    modes,\n    computerUse: parseComputerUse(parsed.computerUse, filePath),\n    projectTrust: trust as ProjectTrust,\n    editor: parseEditor(parsed.editor, filePath),\n    voice: parseVoice(parsed.voice, filePath),\n    selection: parseSelection(parsed.selection, filePath),\n    web: parseWeb(parsed.web, filePath),\n  };\n}\nfunction mergeAgent(\n  globalValue?: PlanningAgentConfig,\n  repositoryValue?: PlanningAgentConfig,\n): PlanningAgentConfig | undefined {\n  return globalValue || repositoryValue ? { ...globalValue, ...repositoryValue } : undefined;\n}\nexport function mergeDoomConfigs(globalConfig: DoomConfig, repositoryConfig: DoomConfig): DoomConfig {\n  if (repositoryConfig.voice?.mode)\n    throw new Error('Repository Doom config voice.mode is global-only; configure it in ~/.pi/.doom/config.yaml');\n  if (repositoryConfig.voice?.autoCapture)\n    throw new Error('Repository Doom config voice.autoCapture is global-only; configure it in ~/.pi/.doom/config.yaml');\n  if (repositoryConfig.computerUse)\n    throw new Error('Repository Doom config computerUse is global-only; configure it in ~/.pi/.doom/config.yaml');\n  const globalPlanning = globalConfig.modes?.planning;\n  const repositoryPlanning = repositoryConfig.modes?.planning;\n  const planning =\n    globalPlanning || repositoryPlanning\n      ? {\n          main: mergeAgent(globalPlanning?.main, repositoryPlanning?.main),\n          subagents: mergeAgent(globalPlanning?.subagents, repositoryPlanning?.subagents),\n          plansDirectory: repositoryPlanning?.plansDirectory ?? globalPlanning?.plansDirectory,\n        }\n      : undefined;\n  const globalAutocompact = globalConfig.modes?.autocompact;\n  const repositoryAutocompact = repositoryConfig.modes?.autocompact;\n  // Per key, so a repository can pin the model and inherit the ladder, or the\n  // other way round. `overrides` is deliberately not merged that way: the spread\n  // below lets a repository list replace the global one whole, because the rules\n  // are first-match-wins and interleaving two files a reader cannot see together\n  // would decide precedence somewhere neither of them says.\n  const autocompact =\n    globalAutocompact || repositoryAutocompact\n      ? {\n          ...globalAutocompact,\n          ...repositoryAutocompact,\n          ...(globalAutocompact?.thresholds || repositoryAutocompact?.thresholds\n            ? { thresholds: { ...globalAutocompact?.thresholds, ...repositoryAutocompact?.thresholds } }\n            : {}),\n        }\n      : undefined;\n  const voice = mergeVoice(globalConfig.voice, repositoryConfig.voice);\n  return {\n    modes:\n      planning || autocompact\n        ? { ...(planning ? { planning } : {}), ...(autocompact ? { autocompact } : {}) }\n        : undefined,\n    computerUse: globalConfig.computerUse,\n    projectTrust: repositoryConfig.projectTrust,\n    editor: globalConfig.editor,\n    voice,\n    web:\n      globalConfig.web || repositoryConfig.web\n        ? { template: repositoryConfig.web?.template ?? globalConfig.web?.template }\n        : undefined,\n    // Per key, so a repository can pin one axis and inherit the rest.\n    selection:\n      globalConfig.selection || repositoryConfig.selection\n        ? { ...globalConfig.selection, ...repositoryConfig.selection }\n        : undefined,\n  };\n}\nfunction mergeAdapter(\n  globalValue?: VoiceAdapterConfig,\n  repositoryValue?: VoiceAdapterConfig,\n): VoiceAdapterConfig | undefined {\n  if (!globalValue && !repositoryValue) return undefined;\n  return { ...globalValue, ...repositoryValue, model: repositoryValue?.model ?? globalValue!.model };\n}\nfunction mergeVoice(globalValue?: VoiceConfig, repositoryValue?: VoiceConfig): VoiceConfig | undefined {\n  if (!globalValue && !repositoryValue) return undefined;\n  return {\n    ...globalValue,\n    ...repositoryValue,\n    ...(globalValue?.mode ? { mode: globalValue.mode } : {}),\n    recorder:\n      globalValue?.recorder || repositoryValue?.recorder\n        ? { ...globalValue?.recorder, ...repositoryValue?.recorder }\n        : undefined,\n    adapters:\n      globalValue?.adapters || repositoryValue?.adapters\n        ? {\n            [WHISPER_CPP_ENGINE]: mergeAdapter(\n              globalValue?.adapters?.[WHISPER_CPP_ENGINE],\n              repositoryValue?.adapters?.[WHISPER_CPP_ENGINE],\n            ),\n            [OPENAI_WHISPER_ENGINE]: mergeAdapter(\n              globalValue?.adapters?.[OPENAI_WHISPER_ENGINE],\n              repositoryValue?.adapters?.[OPENAI_WHISPER_ENGINE],\n            ),\n            [MLX_WHISPER_ENGINE]: mergeAdapter(\n              globalValue?.adapters?.[MLX_WHISPER_ENGINE],\n              repositoryValue?.adapters?.[MLX_WHISPER_ENGINE],\n            ),\n          }\n        : undefined,\n    ...(globalValue?.autoCapture ? { autoCapture: globalValue.autoCapture } : {}),\n  };\n}\n/**\n * Resolves voice settings, optionally shadowed by the active profile's override.\n *\n * The override is per field, so a persona that sets only `rate` keeps the voice\n * from config.yaml. `engine` is deliberately not overridable: it selects the\n * synthesiser binary, which is a machine-level fact rather than a persona's.\n *\n * The result is read once when autonomous voice activates, because\n * `VoiceNarrationPlayback.config` is assigned in `activate()` and has no setter.\n * That is sufficient today only because every profile switch reloads the\n * session, which deactivates and reactivates voice. A future in-place profile\n * switch would leave the spoken voice stale until the next activation.\n */\nexport function resolveVoiceConfig(config: VoiceConfig, ttsOverride?: PersonaVoiceOverride): ResolvedVoiceConfig {\n  return {\n    mode: config.mode ?? DEFAULT_VOICE_MODE,\n    engine: config.engine ?? DEFAULT_VOICE_ENGINE,\n    language: config.language ?? DEFAULT_VOICE_LANGUAGE,\n    recorder: { ...config.recorder, device: config.recorder?.device ?? DEFAULT_RECORDER_DEVICE },\n    adapters: config.adapters ?? {},\n    ...(config.autoCapture\n      ? {\n          autoCapture: {\n            ...config.autoCapture,\n            startPhrases: [...(config.autoCapture.startPhrases ?? [])],\n            stopPhrases: [...(config.autoCapture.stopPhrases ?? [])],\n            // Unlike start and stop phrases, these default to a non-empty list: without\n            // a send phrase a draft could be opened and never submitted.\n            composeOpenPhrases: [...(config.autoCapture.composeOpenPhrases ?? DEFAULT_COMPOSE_OPEN_PHRASES)],\n            composeSendPhrases: [...(config.autoCapture.composeSendPhrases ?? DEFAULT_COMPOSE_SEND_PHRASES)],\n            composeCancelPhrases: [...(config.autoCapture.composeCancelPhrases ?? DEFAULT_COMPOSE_CANCEL_PHRASES)],\n            utteranceIdleMs: config.autoCapture.utteranceIdleMs ?? DEFAULT_UTTERANCE_IDLE_MS,\n            composeUtteranceIdleMs: config.autoCapture.composeUtteranceIdleMs ?? DEFAULT_COMPOSE_UTTERANCE_IDLE_MS,\n            composeNudgeMs: config.autoCapture.composeNudgeMs ?? DEFAULT_COMPOSE_NUDGE_MS,\n            transcriptionTimeoutMs: config.autoCapture.transcriptionTimeoutMs ?? DEFAULT_TRANSCRIPTION_TIMEOUT_MS,\n            tts: {\n              ...config.autoCapture.tts,\n              ...(ttsOverride?.voice === undefined ? {} : { voice: ttsOverride.voice }),\n              ...(ttsOverride?.rate === undefined ? {} : { rate: ttsOverride.rate }),\n            },\n          },\n        }\n      : {}),\n  };\n}\n\n/**\n * Which files a key may be written to.\n *\n * `mergeDoomConfigs` above already decides this per field, but it decides it by\n * doing it: `editor` reads only from the global side, `projectTrust` only from\n * the repository side, and repository `voice.mode` or `voice.autoCapture`\n * declarations throw outright. A caller holding a key path has no way to ask.\n * surface offers writes that throw, or worse, writes that land in a file the\n * merge will ignore, so the change appears to do nothing.\n *\n * Declared here rather than beside the writer because the rule is a property of\n * the merge, not of the filesystem, and a test asserts the two agree.\n */\nexport type ConfigKeyScope = 'global' | 'repository' | 'both';\n\n/** Root keys the merge reads from one side only. */\nconst GLOBAL_ONLY_ROOTS: readonly string[] = ['computerUse', 'editor'];\nconst REPOSITORY_ONLY_ROOTS: readonly string[] = ['projectTrust'];\n/** Nested exceptions; a repository declaration of either throws in the merge. */\nconst GLOBAL_ONLY_PATHS: readonly (readonly string[])[] = [\n  ['voice', 'mode'],\n  ['voice', 'autoCapture'],\n];\n\nfunction startsWith(keyPath: readonly string[], prefix: readonly string[]): boolean {\n  return prefix.length <= keyPath.length && prefix.every((segment, index) => keyPath[index] === segment);\n}\n\n/**\n * The scopes a key path accepts. An unknown root answers `both` rather than\n * throwing: the parser is what rejects unsupported keys, and it reports them\n * far better than a scope lookup could.\n */\nexport function configScopeOf(keyPath: readonly string[]): ConfigKeyScope {\n  if (keyPath.length === 0) return 'both';\n  if (GLOBAL_ONLY_PATHS.some((prefix) => startsWith(keyPath, prefix))) return 'global';\n  const root = keyPath[0]!;\n  if (GLOBAL_ONLY_ROOTS.includes(root)) return 'global';\n  if (REPOSITORY_ONLY_ROOTS.includes(root)) return 'repository';\n  return 'both';\n}\n\n/** Every root key the config accepts, so a caller can enumerate without importing the parser's internals. */\nexport function configRootKeys(): readonly string[] {\n  return ROOT_KEYS;\n}\n\nconst KEY_SEPARATOR = '.';\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Every key path a parsed document actually sets, as dotted strings.\n *\n * A settings surface needs to tell \"this file set this key\" from \"this file is\n * silent about it\", and the parsed `DoomConfig` cannot answer: an absent file\n * reads as `{ projectTrust: 'ask' }` and `parseDoomConfig` always returns all\n * known root keys, some undefined. So the question is asked of the raw document\n * instead, before any defaulting has happened.\n *\n * Leaves only. A list is a leaf because it is replaced whole, and an empty\n * record sets nothing.\n */\nexport function configLeafKeys(value: unknown, prefix: readonly string[] = []): string[] {\n  if (!isPlainRecord(value)) return prefix.length > 0 ? [prefix.join(KEY_SEPARATOR)] : [];\n  const keys = Object.keys(value);\n  if (keys.length === 0) return prefix.length > 0 ? [prefix.join(KEY_SEPARATOR)] : [];\n  return keys.flatMap((key) => configLeafKeys(value[key], [...prefix, key]));\n}\n\n/** The value a key path points at, or undefined when any step is missing. */\nexport function valueAtKeyPath(value: unknown, keyPath: readonly string[]): unknown {\n  let current: unknown = value;\n  for (const segment of keyPath) {\n    if (!isPlainRecord(current)) return undefined;\n    current = current[segment];\n  }\n  return current;\n}\n"],"mappings":"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"}