{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://raw.githubusercontent.com/clay-good/OpenLore/main/schemas/openspec-plugin-manifest-v1.json",
  "title": "OpenSpec Plugin Manifest",
  "description": "The declarative contract a package publishes (as an \"openspec\" key in package.json, or a sibling openspec.plugin.json) so OpenSpec can discover, surface, gate, and install it without importing its code. Vendored from the OpenSpec add-plugin-marketplace plugin-manifest spec. Top-level unknown fields are intentionally allowed (forward-compatible passthrough); the executable requirement (bin OR binArgs) is enforced programmatically, not by this schema.",
  "type": "object",
  "required": [
    "manifestVersion",
    "id",
    "namespace",
    "openspecCompat"
  ],
  "properties": {
    "manifestVersion": { "const": 1 },
    "id": {
      "type": "string",
      "description": "Stable plugin id. Conventionally the npm package name."
    },
    "namespace": {
      "type": "string",
      "description": "The single reserved top-level command namespace (e.g. \"lore\"). Must not collide with a reserved OpenSpec core command."
    },
    "bin": {
      "type": "string",
      "description": "Package executable OpenSpec spawns (no shell). Resolved from the package's bin map."
    },
    "binArgs": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Fallback invocation for environments where the plugin is not a resolvable dependency, e.g. [\"npx\", \"--yes\", \"openlore\"]."
    },
    "openspecCompat": {
      "type": "string",
      "description": "Semver range of OpenSpec versions this plugin supports. Incompatible host versions are gated by OpenSpec, not the plugin."
    },
    "displayName": { "type": "string" },
    "summary": { "type": "string" },
    "commands": {
      "type": "array",
      "description": "Help/completion only — does NOT route execution. OpenSpec passes everything after the namespace verbatim to the bin.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "summary"],
        "properties": {
          "name": { "type": "string" },
          "summary": { "type": "string" }
        }
      }
    },
    "skills": {
      "type": "array",
      "description": "Skills the plugin contributes for OpenSpec to install into AI tool directories.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["dir", "source"],
        "properties": {
          "dir": {
            "type": "string",
            "description": "Single path segment used as the installed skill directory name (no separators or \"..\")."
          },
          "source": {
            "type": "string",
            "description": "Package-relative path to the skill source directory (must stay inside the package)."
          }
        }
      }
    },
    "workflows": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Plugin-contributed, namespaced workflow ids."
    },
    "ownsConfigKeys": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Top-level openspec/config.yaml keys this plugin owns and may write. OpenSpec preserves all other keys."
    }
  }
}
