{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tabularium.wiki/manifest.schema.json",
  "title": "Tabularium plugin manifest",
  "description": "Plugin authors drop a .tabularium / .tabularium.yaml / .tabularium.yml / .tabularium.json at the repo root.",
  "type": "object",
  "required": ["name", "version"],
  "properties": {
    "name": {
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[a-z][a-z0-9-]*$",
      "description": "URL slug, canonical package name, and default display title. Must start with a letter; lowercase alphanumerics + hyphens only. REQUIRED — pinned at first submit; changing it later does not rename the existing slug. Use the README for prose / branding; no separate display-name field.",
      "type": "string"
    },
    "version": {
      "minLength": 1,
      "maxLength": 40,
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$",
      "description": "Semantic version of this plugin release (no leading \"v\"). REQUIRED — must match the release tag stripped of any \"v\" prefix. The registry rejects ingests whose tag and manifest version disagree, so a manifest version bump is the single source of truth for \"this is a new release\".",
      "type": "string"
    },
    "description": {
      "maxLength": 280,
      "description": "One-line summary shown on the plugin card and search results. Keep it under 280 characters and write it like a tagline, not a paragraph.",
      "type": "string"
    },
    "category": {
      "maxLength": 40,
      "description": "Free-form category label. Used for grouping plugins on the registry home page.",
      "type": "string"
    },
    "kind": {
      "minLength": 1,
      "maxLength": 40,
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "description": "Plugin kind slug (must match one of the registry's configured kinds — see the per-kind sections below). Drives which extension fields apply and whether your plugin appears on the catalogue page for that kind.",
      "type": "string"
    },
    "tags": {
      "maxItems": 16,
      "description": "Searchable tags. Used by the registry's search index; max 16 tags, 30 chars each.",
      "type": "array",
      "items": {
        "maxLength": 30,
        "type": "string"
      }
    },
    "license": {
      "maxLength": 40,
      "description": "SPDX identifier (e.g. \"MIT\", \"Apache-2.0\", \"GPL-3.0-only\"). Plain text accepted; SPDX is strongly recommended.",
      "type": "string"
    },
    "icon": {
      "maxLength": 500,
      "description": "URL to the plugin icon. Renders next to the plugin name on cards and detail pages. PNG/SVG recommended, 256×256 or vector.",
      "type": "string"
    },
    "screenshots": {
      "maxItems": 12,
      "description": "Up to 12 screenshots shown in the plugin detail gallery.",
      "type": "array",
      "items": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": {
            "minLength": 1,
            "maxLength": 500,
            "description": "Image URL.",
            "type": "string"
          },
          "caption": {
            "maxLength": 200,
            "description": "Optional caption shown under the screenshot.",
            "type": "string"
          },
          "alt": {
            "maxLength": 200,
            "description": "Accessible alt text for screen readers.",
            "type": "string"
          }
        }
      }
    },
    "readme": {
      "maxLength": 500,
      "description": "Repo-relative path or URL to the README markdown file. Rendered on the plugin detail page.",
      "type": "string"
    },
    "readmes": {
      "description": "Per-locale README overrides. Map keys are BCP-47 locale codes (e.g. \"en\", \"de\", \"zh-CN\"); values are the same shape as `readme`.",
      "type": "object",
      "patternProperties": {
        "^[a-z]{2}(-[A-Z]{2})?$": {
          "maxLength": 500,
          "type": "string"
        }
      }
    },
    "documentation_url": {
      "pattern": "^https?://.+",
      "description": "Link to standalone documentation site (Vitepress, MkDocs, GitHub Pages, etc.). Surfaces as an \"Open docs\" CTA.",
      "type": "string"
    },
    "homepage": {
      "pattern": "^https?://.+",
      "description": "Marketing homepage if separate from the documentation site or the repository.",
      "type": "string"
    },
    "support": {
      "description": "Where end users go when they have a problem with the plugin.",
      "type": "object",
      "properties": {
        "email": {
          "maxLength": 254,
          "description": "Contact email for end users.",
          "type": "string"
        },
        "issues_url": {
          "pattern": "^https?://.+",
          "description": "Issue tracker URL.",
          "type": "string"
        }
      }
    },
    "min_runtime_version": {
      "maxLength": 40,
      "description": "Minimum host runtime version (semver range or single version). The host refuses to load the plugin on older runtimes.",
      "type": "string"
    }
  }
}
