{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://overseer.studio/schemas/plugin/manifest.json",
  "title": "Overseer Plugin Manifest",
  "description": "Schema for the manifest.json file at the root of an Overseer plugin package",
  "type": "object",
  "required": ["id", "name", "version", "category"],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string",
      "description": "Reference to this schema"
    },
    "id": {
      "type": "string",
      "pattern": "^@[a-z0-9-]+/[a-z0-9-]+$",
      "description": "Unique plugin identifier in scoped format, e.g. @my-scope/my-plugin"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "description": "Human-readable plugin name"
    },
    "version": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+\\.\\d+$",
      "description": "Plugin version in strict X.Y.Z semver format"
    },
    "category": {
      "type": "string",
      "enum": ["utilities", "content", "maps", "dice", "audio", "themes", "reference", "other"],
      "description": "Marketplace category slug for this plugin"
    },
    "description": {
      "oneOf": [
        { "type": "string", "description": "Short description of the plugin" },
        {
          "type": "object",
          "required": ["$ref"],
          "additionalProperties": false,
          "properties": {
            "$ref": { "type": "string", "description": "Relative path to a description file" }
          }
        }
      ],
      "description": "Short description of the plugin, or a $ref to a markdown file"
    },
    "changelog": {
      "type": "object",
      "required": ["$ref"],
      "additionalProperties": false,
      "properties": {
        "$ref": {
          "type": "string",
          "description": "Relative path to the changelog file for this version"
        }
      },
      "description": "Changelog for this version, resolved and sent as a separate API field"
    },
    "subtitle": {
      "type": "string",
      "maxLength": 80,
      "description": "Short tagline shown on marketplace cards"
    },
    "system": {
      "type": "string",
      "minLength": 1,
      "description": "TTRPG system slug this plugin targets (e.g. dnd-5e)"
    },
    "author": {
      "type": "string",
      "description": "Primary author of the plugin"
    },
    "homepage": {
      "type": "string",
      "format": "uri",
      "description": "Plugin homepage URL"
    },
    "license": {
      "oneOf": [
        { "type": "string", "description": "SPDX license identifier, e.g. MIT" },
        {
          "type": "object",
          "required": ["$ref"],
          "additionalProperties": false,
          "properties": {
            "$ref": { "type": "string", "description": "Relative path to a license file" }
          }
        }
      ],
      "description": "License of the plugin"
    },
    "acknowledgements": {
      "oneOf": [
        { "type": "string" },
        {
          "type": "object",
          "required": ["$ref"],
          "additionalProperties": false,
          "properties": {
            "$ref": { "type": "string", "description": "Relative path to an acknowledgements file" }
          }
        }
      ],
      "description": "Acknowledgements text or reference file"
    },
    "icon": {
      "type": "object",
      "required": ["$ref"],
      "additionalProperties": false,
      "properties": {
        "$ref": { "type": "string", "description": "Relative path to the icon file" }
      },
      "description": "Plugin icon reference"
    },
    "compatibleVersion": {
      "oneOf": [
        { "type": "string", "description": "Semver constraint string, e.g. ^1.0.0" },
        {
          "type": "object",
          "required": ["min", "max"],
          "additionalProperties": false,
          "properties": {
            "min": { "type": "string" },
            "max": { "type": "string" }
          },
          "description": "Version range with explicit min/max constraints"
        }
      ],
      "description": "Overseer app version(s) this plugin is compatible with"
    },
    "visible": {
      "type": "boolean",
      "default": true,
      "description": "Whether the plugin is visible in the plugin list"
    },
    "extensions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["$ref"],
        "additionalProperties": false,
        "properties": {
          "$ref": { "type": "string", "description": "Relative path to an extension manifest.json" }
        }
      },
      "description": "Extensions provided by this plugin"
    },
    "datasets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["$ref"],
        "additionalProperties": false,
        "properties": {
          "$ref": { "type": "string", "description": "Relative path to a dataset manifest" }
        }
      },
      "description": "Datasets exposed by this plugin"
    },
    "presets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["$ref"],
        "additionalProperties": false,
        "properties": {
          "$ref": { "type": "string", "description": "Relative path to a preset file" }
        }
      },
      "description": "Presets bundled with this plugin"
    },
    "themes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "label", "src"],
        "additionalProperties": false,
        "properties": {
          "id": { "type": "string", "minLength": 1 },
          "label": { "type": "string", "minLength": 1 },
          "src": {
            "oneOf": [
              { "type": "string" },
              {
                "type": "object",
                "required": ["$ref"],
                "additionalProperties": false,
                "properties": { "$ref": { "type": "string" } }
              }
            ]
          }
        }
      },
      "description": "Themes provided by this plugin"
    },
    "locales": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "label", "src"],
        "additionalProperties": false,
        "properties": {
          "id": { "type": "string", "minLength": 1 },
          "label": { "type": "string", "minLength": 1 },
          "src": {
            "oneOf": [
              { "type": "string" },
              {
                "type": "object",
                "required": ["$ref"],
                "additionalProperties": false,
                "properties": { "$ref": { "type": "string" } }
              }
            ]
          }
        }
      },
      "description": "Locale files provided by this plugin"
    }
  }
}
