{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/andrewhuot/headless-chat-sdk/schemas/ui-catalog-manifest.schema.json",
  "title": "A2UI catalog component manifest",
  "description": "Per-component manifest for the A2UI surface preset catalog. Each component under a2ui-catalog/<name>/ ships a manifest.ts (typed source of truth) and a generated manifest.json (this shape).",
  "type": "object",
  "required": [
    "id",
    "name",
    "category",
    "version",
    "protocolVersion",
    "lifecycle",
    "description",
    "peerCatalogs",
    "dataModelSchema",
    "actionPolicy",
    "screenshots",
    "agentPrompt",
    "i18n",
    "files",
    "integrity"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^ui:[a-z][a-z0-9-]+$",
      "description": "Globally unique catalog id with the ui: prefix. Must match the directory name a2ui-catalog/<name>/ where name = id.slice(3)."
    },
    "name": {
      "type": "string",
      "description": "Human-readable component name."
    },
    "category": {
      "type": "string",
      "enum": ["commerce", "support", "scheduling", "forms", "feedback", "logistics", "identity", "content"]
    },
    "version": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$",
      "description": "Semver version of this catalog entry."
    },
    "protocolVersion": {
      "type": "string",
      "const": "v0.9",
      "description": "A2UI protocol version the preset targets."
    },
    "lifecycle": {
      "type": "string",
      "enum": ["experimental", "stable", "deprecated"]
    },
    "description": {
      "type": "string"
    },
    "peerCatalogs": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string", "format": "uri" },
      "description": "A2UI catalogIds that the host must register. Default: https://a2ui.org/specification/v0_9/basic_catalog.json"
    },
    "requiresCustomPrimitives": {
      "type": "boolean",
      "description": "True when the surface requires primitives not in basicCatalog and a host-rendered React renderer carries the visual weight."
    },
    "dataModelSchema": {
      "type": "object",
      "description": "Inline JSON Schema (subset: type/required/properties/items/enum/const/minimum/maximum/pattern/oneOf) for the dataModel of this surface."
    },
    "actionPolicy": {
      "type": "object",
      "required": ["allow", "confirm"],
      "properties": {
        "allow": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Action envelope names that are allowed without confirmation."
        },
        "confirm": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Action envelope names that require user confirmation."
        }
      },
      "additionalProperties": false
    },
    "screenshots": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["state", "viewport"],
        "properties": {
          "state": { "type": "string", "description": "Logical render state identifier (e.g. 'ready', 'submitted')." },
          "viewport": {
            "type": "string",
            "enum": ["desktop", "tablet", "mobile"]
          }
        },
        "additionalProperties": false
      }
    },
    "agentPrompt": {
      "type": "string",
      "description": "Prompt fragment teaching an LLM when to emit this surface."
    },
    "i18n": {
      "type": "object",
      "required": ["defaultLocale", "keys"],
      "properties": {
        "defaultLocale": { "type": "string" },
        "keys": {
          "type": "array",
          "items": { "type": "string" }
        }
      },
      "additionalProperties": false
    },
    "files": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string" },
      "description": "Files copied to the host project when this component is installed."
    },
    "dependencies": {
      "type": "array",
      "items": { "type": "string" },
      "description": "npm package names that the host project must add."
    },
    "integrity": {
      "type": "object",
      "required": ["sha256"],
      "properties": {
        "sha256": {
          "type": "string",
          "pattern": "^[a-f0-9]{64}$",
          "description": "SHA-256 hash computed at build time over the contents of files[]."
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
