{"version":3,"file":"schema.mjs","names":[],"sources":["../../src/config/schema.ts"],"sourcesContent":["export type ThinkingLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n\nexport interface IncludeFilesTouchedSettings {\n\tinCompactionSummary: boolean;\n\tinBranchSummary: boolean;\n}\n\nexport interface PresetConfig {\n\tmodel: string;\n\tthinkingLevel?: ThinkingLevel;\n}\n\nexport interface LiveCompactionConfig {\n\tincludeFilesTouched: IncludeFilesTouchedSettings;\n\tdefaultPreset: string;\n\tfallbackPreset?: string;\n\tpresets: Record<string, PresetConfig>;\n\t/**\n\t * Which scope the /live-compaction settings panel opens to by\n\t * default. The shipped default is \"global\" so settings reads/writes\n\t * default to durable global state and explicit project overrides are\n\t * an opt-in. `\"project\"` falls back to global when no project session\n\t * is active.\n\t */\n\tdefaultPanelScope: PanelScope;\n\t/**\n\t * When true, ignore the configured `defaultPreset` for an automatic\n\t * /compact run and always summarise with the current session model and\n\t * thinking level instead. Off by default. An explicit `/compact\n\t * --preset NAME` directive and a template `preset:` frontmatter both\n\t * still win over this flag, since those are deliberate per-run choices.\n\t */\n\tinheritSessionModel: boolean;\n}\n\nexport type ConfigScope = 'global' | 'project';\n/**\n * Panel-scope preference. Same shape as ConfigScope today, kept as a\n * separate alias so adding new modes later (e.g. `\"last-used\"`) does not\n * require touching every ConfigScope consumer.\n */\nexport type PanelScope = ConfigScope;\nexport type PromptKind = 'compaction' | 'branch-summary';\n\nexport interface LiveCompactionPaths {\n\tglobal: {\n\t\tscope: 'global';\n\t\trootDir: string;\n\t\tconfigPath: string;\n\t\tcompactionPromptPath: string;\n\t\tbranchSummaryPromptPath: string;\n\t};\n\tproject?: {\n\t\tscope: 'project';\n\t\trootDir: string;\n\t\tconfigPath: string;\n\t\tcompactionPromptPath: string;\n\t\tbranchSummaryPromptPath: string;\n\t};\n}\n\nexport interface PromptResolution {\n\tsource: ConfigScope | 'default';\n\ttext?: string;\n\tisOverride: boolean;\n\tisBlankOverride: boolean;\n}\n\ntype JsonObject = Record<string, unknown>;\n\nexport const CURRENT_PRESET_SENTINEL = 'current';\n\nconst DEFAULT_INCLUDE_FILES_TOUCHED_SETTINGS: IncludeFilesTouchedSettings = {\n\tinCompactionSummary: true,\n\tinBranchSummary: true,\n};\n\nexport const PANEL_SCOPE_VALUES: readonly PanelScope[] = ['global', 'project'];\n\nexport const DEFAULT_CONFIG: LiveCompactionConfig = {\n\tincludeFilesTouched: DEFAULT_INCLUDE_FILES_TOUCHED_SETTINGS,\n\tdefaultPreset: CURRENT_PRESET_SENTINEL,\n\tfallbackPreset: CURRENT_PRESET_SENTINEL,\n\tpresets: {},\n\tdefaultPanelScope: 'global',\n\tinheritSessionModel: false,\n};\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parsePanelScope(value: unknown): PanelScope {\n\tif (value === undefined) {\n\t\treturn DEFAULT_CONFIG.defaultPanelScope;\n\t}\n\tif (typeof value !== 'string') {\n\t\tthrow new Error(\n\t\t\t\"Invalid live-compaction config: defaultPanelScope must be one of 'global' or 'project'\",\n\t\t);\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\t// Legacy \"auto\" maps onto \"project\" since the runtime semantics already\n\t// fall back to global when no project session is active.\n\tif (normalized === 'auto') {\n\t\treturn 'project';\n\t}\n\tif (normalized === 'global' || normalized === 'project') {\n\t\treturn normalized;\n\t}\n\tthrow new Error(\n\t\t\"Invalid live-compaction config: defaultPanelScope must be one of 'global' or 'project'\",\n\t);\n}\n\nexport function normalizeThinkingLevel(value: unknown): ThinkingLevel | undefined {\n\tif (typeof value !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\tif (\n\t\tnormalized === 'off' ||\n\t\tnormalized === 'minimal' ||\n\t\tnormalized === 'low' ||\n\t\tnormalized === 'medium' ||\n\t\tnormalized === 'high' ||\n\t\tnormalized === 'xhigh'\n\t) {\n\t\treturn normalized;\n\t}\n\treturn undefined;\n}\n\nexport function normalizeOptionalText(value?: string): string | undefined {\n\tconst trimmed = value?.trim();\n\treturn trimmed || undefined;\n}\n\nfunction expectBoolean(value: unknown, key: string): boolean {\n\tif (typeof value !== 'boolean') {\n\t\tthrow new Error(`Invalid live-compaction config: ${key} must be a boolean`);\n\t}\n\treturn value;\n}\n\nfunction parseIncludeFilesTouchedSettings(value: unknown): IncludeFilesTouchedSettings {\n\tif (value === undefined) {\n\t\treturn structuredClone(DEFAULT_INCLUDE_FILES_TOUCHED_SETTINGS);\n\t}\n\tif (typeof value === 'boolean') {\n\t\treturn {\n\t\t\tinCompactionSummary: value,\n\t\t\tinBranchSummary: value,\n\t\t};\n\t}\n\tif (!isObject(value)) {\n\t\tthrow new Error(\n\t\t\t'Invalid live-compaction config: includeFilesTouched must be a boolean or an object with inCompactionSummary and inBranchSummary',\n\t\t);\n\t}\n\treturn {\n\t\tinCompactionSummary: expectBoolean(\n\t\t\tvalue.inCompactionSummary,\n\t\t\t'includeFilesTouched.inCompactionSummary',\n\t\t),\n\t\tinBranchSummary: expectBoolean(value.inBranchSummary, 'includeFilesTouched.inBranchSummary'),\n\t};\n}\n\nexport function parseConfig(value: unknown): LiveCompactionConfig {\n\tif (!isObject(value)) {\n\t\tthrow new Error('Invalid live-compaction config: top-level value must be an object');\n\t}\n\n\tconst includeFilesTouched = parseIncludeFilesTouchedSettings(value.includeFilesTouched);\n\n\tconst defaultPreset =\n\t\tvalue.defaultPreset === undefined\n\t\t\t? DEFAULT_CONFIG.defaultPreset\n\t\t\t: typeof value.defaultPreset === 'string' && value.defaultPreset.trim()\n\t\t\t\t? value.defaultPreset.trim()\n\t\t\t\t: (() => {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Invalid live-compaction config: defaultPreset must be a non-empty string',\n\t\t\t\t\t\t);\n\t\t\t\t\t})();\n\n\tconst fallbackPreset =\n\t\tvalue.fallbackPreset === undefined\n\t\t\t? DEFAULT_CONFIG.fallbackPreset\n\t\t\t: typeof value.fallbackPreset === 'string' && value.fallbackPreset.trim()\n\t\t\t\t? value.fallbackPreset.trim()\n\t\t\t\t: (() => {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Invalid live-compaction config: fallbackPreset must be a non-empty string when provided',\n\t\t\t\t\t\t);\n\t\t\t\t\t})();\n\n\tconst presetsValue = value.presets === undefined ? {} : value.presets;\n\tif (!isObject(presetsValue)) {\n\t\tthrow new Error('Invalid live-compaction config: presets must be an object');\n\t}\n\n\tconst presets: Record<string, PresetConfig> = {};\n\tfor (const [presetName, presetValue] of Object.entries(presetsValue)) {\n\t\tif (!presetName.trim()) {\n\t\t\tthrow new Error('Invalid live-compaction config: preset names must be non-empty strings');\n\t\t}\n\t\tif (!isObject(presetValue)) {\n\t\t\tthrow new Error(`Invalid live-compaction config: preset '${presetName}' must be an object`);\n\t\t}\n\t\tif (typeof presetValue.model !== 'string' || !presetValue.model.trim()) {\n\t\t\tthrow new Error(`Invalid live-compaction config: preset '${presetName}' must define model`);\n\t\t}\n\t\tconst thinkingLevel =\n\t\t\tpresetValue.thinkingLevel === undefined\n\t\t\t\t? undefined\n\t\t\t\t: normalizeThinkingLevel(presetValue.thinkingLevel);\n\t\tif (presetValue.thinkingLevel !== undefined && !thinkingLevel) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid live-compaction config: preset '${presetName}' has an invalid thinkingLevel`,\n\t\t\t);\n\t\t}\n\t\tpresets[presetName] = {\n\t\t\tmodel: presetValue.model.trim(),\n\t\t\tthinkingLevel,\n\t\t};\n\t}\n\n\tif (defaultPreset !== CURRENT_PRESET_SENTINEL && !presets[defaultPreset]) {\n\t\tthrow new Error(\n\t\t\t`Invalid live-compaction config: defaultPreset '${defaultPreset}' was not found in presets`,\n\t\t);\n\t}\n\n\tif (\n\t\tfallbackPreset !== undefined &&\n\t\tfallbackPreset !== CURRENT_PRESET_SENTINEL &&\n\t\t!presets[fallbackPreset]\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid live-compaction config: fallbackPreset '${fallbackPreset}' was not found in presets`,\n\t\t);\n\t}\n\n\tconst defaultPanelScope = parsePanelScope(value.defaultPanelScope);\n\n\tconst inheritSessionModel =\n\t\tvalue.inheritSessionModel === undefined\n\t\t\t? DEFAULT_CONFIG.inheritSessionModel\n\t\t\t: expectBoolean(value.inheritSessionModel, 'inheritSessionModel');\n\n\treturn {\n\t\tincludeFilesTouched,\n\t\tdefaultPreset,\n\t\tfallbackPreset,\n\t\tpresets,\n\t\tdefaultPanelScope,\n\t\tinheritSessionModel,\n\t};\n}\n"],"mappings":"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"}