{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "/schemas/chroma-plugins/chroma.plugin.schema.json",
  "title": "Chroma Plugin Manifest",
  "description": "Machine-readable contract for browser-side Chroma plugins vendored under plugins/<id>/chroma.plugin.json. Consumed by plugins/loader.js in Chroma CLI examples, Targ-Apps-Finance, and Chroma-Server. Canonical sources: Chroma-Style/, Chroma-Fs/, Chroma-Router/, Chroma-t2t/.",
  "type": "object",
  "additionalProperties": false,
  "required": ["name", "package", "version", "description", "entry", "loadAs", "hooks"],
  "properties": {
    "name": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*$",
      "description": "Plugin folder id referenced in chroma.json plugins array (e.g. chroma-style, chroma-fs).",
      "examples": ["chroma-style", "chroma-fs", "chroma-router", "chroma-t2t"]
    },
    "package": {
      "type": "string",
      "pattern": "^@chroma/",
      "description": "npm-style package id for the plugin.",
      "examples": ["@chroma/style", "@chroma/fs", "@chroma/router", "@chroma/t2t"]
    },
    "version": {
      "type": "string",
      "description": "Semver version of the vendored plugin package.",
      "examples": ["0.1.2", "0.1.0"]
    },
    "description": {
      "type": "string",
      "description": "Human-readable summary of plugin purpose."
    },
    "entry": {
      "type": "string",
      "default": "index.js",
      "description": "Main ESM module relative to the plugin root. Loader imports plugins/<name>/<entry>.",
      "examples": ["index.js"]
    },
    "loadAs": {
      "type": "string",
      "description": "Key on the object returned by loadPlugins(). Defaults to name with chroma- prefix stripped when omitted.",
      "examples": ["style", "fs", "router", "t2t"]
    },
    "capabilities": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "enum": [
          "styling",
          "design-tokens",
          "storage",
          "routing",
          "fetch-intercept",
          "testing",
          "dev-tools"
        ]
      },
      "description": "Tags for docs and generic loaders; not enforced at runtime."
    },
    "hooks": {
      "type": "object",
      "description": "Hook point name to exported function name in entry module. Loader calls styles before bootstrap.",
      "additionalProperties": false,
      "properties": {
        "styles": {
          "type": "string",
          "description": "CSS injection hook (chroma-style: injectStyles). Invoked synchronously before bootstrap.",
          "examples": ["injectStyles"]
        },
        "bootstrap": {
          "type": "string",
          "description": "Async startup hook. Return value is assigned to loaded[loadAs]. Router receives { manifestUrl } from loader options.",
          "examples": ["bootstrapFs", "bootstrapRouter", "bootstrapT2t"]
        }
      },
      "anyOf": [
        { "required": ["styles"] },
        { "required": ["bootstrap"] }
      ]
    },
    "assets": {
      "type": "object",
      "description": "Static files shipped with the plugin (chroma-style).",
      "additionalProperties": false,
      "properties": {
        "stylesheets": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "\\.css$"
          },
          "description": "CSS files relative to plugin root, injected by the styles hook.",
          "examples": [["tokens.css", "utilities.css"]]
        }
      },
      "required": ["stylesheets"]
    },
    "routing": {
      "type": "object",
      "description": "Router-specific metadata (chroma-router). Documents path conventions; bootstrapRouter reads manifestUrl from loader options.",
      "additionalProperties": false,
      "properties": {
        "reservedMethods": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "type": "string",
            "enum": ["GET", "POST", "PUT", "DELETE", "CUSTOM"]
          },
          "description": "HTTP-like handler method names supported by file-based routes.",
          "examples": [["GET", "POST", "PUT", "DELETE", "CUSTOM"]]
        },
        "manifestPath": {
          "type": "string",
          "description": "Default routes-manifest.json path relative to app root.",
          "examples": ["./api/routes-manifest.json"]
        },
        "pathConvention": {
          "type": "string",
          "description": "Directory prefix for file-based route handlers.",
          "examples": ["api/"]
        }
      },
      "required": ["reservedMethods", "manifestPath", "pathConvention"]
    }
  }
}
