{"version":3,"file":"config.cjs","names":["Type"],"sources":["../../src/schemas/config.ts"],"sourcesContent":["/**\n * Configuration surfaces, contributed by every extension that owns settings.\n *\n * Doom settings live in one YAML file but are owned by many extensions, and for\n * a long time the only way to change any of them was to edit that file by hand.\n * The one exception, an editor-command prompt, asked for a value with no way to\n * see what a valid one looked like.\n *\n * So configuration is published rather than centralised: an extension describes\n * its own fields, one renderer draws them all, and the extension still performs\n * every write. Nothing here knows what a voice model or an editor command is.\n *\n * Deliberately the same shape as the mode and footer contracts next door, since\n * the problem is the same one: several extensions sharing one surface. The UI\n * hub invokes an owner's registered action directly, because unlike a status\n * strip this surface is written to as well as read.\n */\n\nimport { type Static, Type } from 'typebox';\n\n/** Canonical Cordis key for the session-owned Doom configuration service. */\nexport const DOOM_CONFIG_SERVICE = 'doom/config';\n\n/**\n * Cross-package service contract for the immutable configuration snapshot.\n *\n * The provider supplies the concrete snapshot and file-config types. Keeping\n * this contract generic lets independently bundled consumers share the Cordis\n * service definition without making the contracts package depend on config.\n */\nexport interface IDoomConfigService<TSnapshot = unknown, TFileConfig = unknown> {\n  /** Identifies the currently published session service for stale-work fencing. */\n  readonly generation: string;\n  /** Returns the immutable snapshot currently visible to consumers. */\n  getSnapshot(): TSnapshot;\n  /** Atomically replaces the immutable live snapshot after a successful transition. */\n  replaceSnapshot(snapshot: TSnapshot): TSnapshot;\n  /** Loads the package's file configuration outside the live session snapshot. */\n  load(repoRoot: string, homeDirectory?: string): TFileConfig;\n}\n\n/** Matches the leader contract's source rule: package names, addressable and spoof-checkable. */\nexport const ConfigSourceSchema = Type.String({\n  minLength: 1,\n  maxLength: 128,\n  pattern: '^[A-Za-z0-9@][A-Za-z0-9@/._:-]*$',\n});\n\nconst ConfigIdSchema = Type.String({ minLength: 1, maxLength: 128, pattern: '^[a-z0-9][a-z0-9._:-]*$' });\n\n/**\n * How ready a value is to be used, as opposed to whether it is merely set.\n * `blocked` covers a choice that needs something else first, such as a model\n * whose engine is not installed.\n */\nexport const ConfigStatusSchema = Type.Union([\n  Type.Literal('ready'),\n  Type.Literal('available'),\n  Type.Literal('blocked'),\n]);\nexport type ConfigStatus = Static<typeof ConfigStatusSchema>;\n\nexport const ConfigFieldKindSchema = Type.Union([\n  /** Free text, edited in place. */\n  Type.Literal('text'),\n  /** A short closed set, cycled in place. */\n  Type.Literal('enum'),\n  /** A long set worth its own screen, with per-entry status and actions. */\n  Type.Literal('choice'),\n  /** Read-only. Resolution results, derived values, preflight checks. */\n  Type.Literal('info'),\n]);\nexport type ConfigFieldKind = Static<typeof ConfigFieldKindSchema>;\n\n/**\n * A key the renderer offers on the focused field, sent back verbatim as an\n * action. Owners use this for confirmations, so the pending question survives a\n * panel that is closed and reopened.\n */\nexport const ConfigActionSchema = Type.Object(\n  {\n    key: Type.String({ minLength: 1, maxLength: 1 }),\n    label: Type.String({ minLength: 1, maxLength: 24 }),\n    action: ConfigIdSchema,\n  },\n  { additionalProperties: false },\n);\nexport type ConfigAction = Static<typeof ConfigActionSchema>;\n\nexport const ConfigChoiceSchema = Type.Object(\n  {\n    id: Type.String({ minLength: 1, maxLength: 256 }),\n    label: Type.String({ minLength: 1, maxLength: 96 }),\n    /** Right-aligned by the renderer. Sizes, ids, anything narrow. */\n    detail: Type.Optional(Type.String({ minLength: 1, maxLength: 96 })),\n    /** Groups entries under a heading the cursor skips over. */\n    group: Type.Optional(Type.String({ minLength: 1, maxLength: 48 })),\n    status: Type.Optional(ConfigStatusSchema),\n    statusText: Type.Optional(Type.String({ minLength: 1, maxLength: 96 })),\n    /**\n     * What enter does on this entry. Carrying it per-entry is what lets one list\n     * hold both an installed model that only needs selecting and an absent one\n     * that needs fetching, without the renderer knowing the difference.\n     */\n    action: Type.Optional(ConfigIdSchema),\n  },\n  { additionalProperties: false },\n);\nexport type ConfigChoice = Static<typeof ConfigChoiceSchema>;\n\n/**\n * One line of a multi-step operation.\n *\n * Published as a list rather than a single \"current step\" string so the panel can\n * show what already ran alongside what is left. During an install that is the\n * difference between \"something is happening\" and knowing a package manager\n * already finished and a download is now underway.\n */\nexport const ConfigStepSchema = Type.Object(\n  {\n    label: Type.String({ minLength: 1, maxLength: 96 }),\n    state: Type.Union([\n      Type.Literal('pending'),\n      /** Already true of this machine, so nothing will run for it. */\n      Type.Literal('satisfied'),\n      Type.Literal('running'),\n      Type.Literal('done'),\n      Type.Literal('failed'),\n    ]),\n    detail: Type.Optional(Type.String({ minLength: 1, maxLength: 160 })),\n  },\n  { additionalProperties: false },\n);\nexport type ConfigStep = Static<typeof ConfigStepSchema>;\n\nexport const ConfigProgressSchema = Type.Object(\n  {\n    label: Type.String({ minLength: 1, maxLength: 96 }),\n    /** 0 to 1. Omitted when the work has no measurable total. */\n    ratio: Type.Optional(Type.Number({ minimum: 0, maximum: 1 })),\n  },\n  { additionalProperties: false },\n);\nexport type ConfigProgress = Static<typeof ConfigProgressSchema>;\n\nexport const ConfigFieldSchema = Type.Object(\n  {\n    id: ConfigIdSchema,\n    label: Type.String({ minLength: 1, maxLength: 48 }),\n    kind: ConfigFieldKindSchema,\n    /** Absent means unset; the renderer shows `placeholder` instead. */\n    value: Type.Optional(Type.String({ minLength: 1, maxLength: 4096 })),\n    placeholder: Type.Optional(Type.String({ minLength: 1, maxLength: 96 })),\n    /** One line of help for the focused field. */\n    detail: Type.Optional(Type.String({ minLength: 1, maxLength: 240 })),\n    /** The config key this writes, shown under the focused field so the file stays legible. */\n    keyPath: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),\n    status: Type.Optional(ConfigStatusSchema),\n    /** Doubles as the error line: a rejected edit comes back as the old value plus this. */\n    statusText: Type.Optional(Type.String({ minLength: 1, maxLength: 240 })),\n    choices: Type.Optional(Type.Array(ConfigChoiceSchema, { maxItems: 128 })),\n    actions: Type.Optional(Type.Array(ConfigActionSchema, { maxItems: 4 })),\n    /** Work is running; the renderer dims the field and offers abort. */\n    busy: Type.Optional(Type.Boolean()),\n    progress: Type.Optional(ConfigProgressSchema),\n    steps: Type.Optional(Type.Array(ConfigStepSchema, { maxItems: 24 })),\n    /**\n     * The tail of a running command's terminal output.\n     *\n     * A tail rather than the whole scrollback: the field is a few rows of a\n     * shared pane, and what matters is the question a package manager just\n     * asked, not what it printed a minute ago.\n     */\n    output: Type.Optional(Type.Array(Type.String({ maxLength: 512 }), { maxItems: 64 })),\n    /**\n     * The command is waiting on the user. The renderer offers a line to type\n     * into, which comes back as an owner-defined action carrying the text.\n     */\n    awaitingInput: Type.Optional(Type.Boolean()),\n  },\n  { additionalProperties: false },\n);\nexport type ConfigField = Static<typeof ConfigFieldSchema>;\n\nexport const ConfigSectionSchema = Type.Object(\n  {\n    id: ConfigIdSchema,\n    title: Type.String({ minLength: 1, maxLength: 32 }),\n    detail: Type.Optional(Type.String({ minLength: 1, maxLength: 96 })),\n    order: Type.Integer({ minimum: 0, maximum: 1000 }),\n    /** Section-wide state: readiness, or why a write failed. */\n    notice: Type.Optional(Type.String({ minLength: 1, maxLength: 240 })),\n    noticeLevel: Type.Optional(Type.Union([Type.Literal('info'), Type.Literal('error')])),\n    fields: Type.Array(ConfigFieldSchema, { maxItems: 64 }),\n  },\n  { additionalProperties: false },\n);\nexport type ConfigSection = Static<typeof ConfigSectionSchema>;\n\nconst ConfigSourceRefSchema = Type.Object(\n  { source: ConfigSourceSchema, generation: Type.String({ minLength: 1 }) },\n  { additionalProperties: false },\n);\n\nconst ConfigSnapshotSchema = Type.Object(\n  { ...ConfigSourceRefSchema.properties, sections: Type.Array(ConfigSectionSchema, { maxItems: 32 }) },\n  { additionalProperties: false },\n);\nexport type ConfigSnapshot = Static<typeof ConfigSnapshotSchema>;\nexport type ConfigSourceRef = Static<typeof ConfigSourceRefSchema>;\n\nexport const CONFIG_ACTION = {\n  set: 'set',\n  clear: 'clear',\n} as const;\n\nexport interface DoomExtensionContext {\n  sessionManager: { getSessionId(): string };\n}\n\nexport interface DoomConfigSectionView extends ConfigSection {\n  source: string;\n}\n\nexport interface DoomConfigInvocation {\n  source: string;\n  sectionId: string;\n  fieldId: string;\n  action: string;\n  value?: string;\n}\n\nexport interface DoomConfigActionInput<Context extends DoomExtensionContext = DoomExtensionContext> {\n  ctx: Context;\n  sectionId: string;\n  fieldId: string;\n  value?: string;\n}\n\nexport interface DoomConfigContributionOptions<Context extends DoomExtensionContext = DoomExtensionContext> {\n  source: string;\n  listSections: () => readonly ConfigSection[];\n  handlers: Readonly<Record<string, (input: DoomConfigActionInput<Context>) => void | Promise<void>>>;\n  onError: (error: unknown, actionName: string, ctx: Context) => void;\n}\n\nexport interface DoomConfigContributionHandle {\n  update(): void;\n  dispose(): void;\n}\n"],"mappings":"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"}