{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "#/definitions/HookManifest",
  "definitions": {
    "ExtensionVisibility": {
      "type": "string",
      "enum": ["public", "private"],
      "title": "Extension Visibility",
      "description": "Intended whole-Extension Registry visibility. Establishes new Extensions and must match established Extensions."
    },
    "PublishOptions": {
      "type": "object",
      "properties": {
        "visibility": {
          "anyOf": [{ "$ref": "#/definitions/ExtensionVisibility" }, { "type": "null" }]
        },
        "ignore": {
          "anyOf": [
            {
              "type": "array",
              "uniqueItems": true,
              "description": "Registry-only archive exclusions matched against package-relative POSIX paths. Matching files are omitted only from published archives; local, Git, workspace, import, fork, and agent projection behavior is unchanged. `*` is the only wildcard, is case-sensitive, and spans `/`. An explicit empty array records a reviewed publish-all decision.",
              "examples": [[], ["evals/*"]],
              "items": { "type": "string", "minLength": 1 }
            },
            { "type": "null" }
          ]
        }
      },
      "additionalProperties": false,
      "title": "Publish Options",
      "description": "Publication policy and archive options for this extension."
    },
    "Handle": {
      "type": "string",
      "pattern": "^@[a-z0-9_](?:[a-z0-9_-]*[a-z0-9_])?$",
      "title": "Handle",
      "description": "A unique username or organization name starting with @, like @my-org.",
      "examples": ["@my-org", "@username"]
    },
    "Version": {
      "type": "string",
      "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
      "title": "Version",
      "description": "A semver version like 1.0.0. Ranges are not allowed here.",
      "examples": ["1.0.0", "2.3.1", "0.1.0-beta.1"]
    },
    "Repository": {
      "anyOf": [
        {
          "type": "string",
          "examples": ["https://github.com/acme/code-review", "github:acme/code-review"],
          "format": "uri-reference"
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "description": "Version control system (e.g., `git`).",
                  "examples": ["git"]
                },
                { "type": "null" }
              ]
            },
            "url": {
              "type": "string",
              "allOf": [
                {
                  "minLength": 1,
                  "description": "Repository URL.",
                  "examples": ["https://github.com/acme/code-review"],
                  "format": "uri"
                }
              ]
            },
            "directory": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "description": "Subdirectory within the repository, for monorepo publishers.",
                  "examples": ["packages/code-review"]
                },
                { "type": "null" }
              ]
            }
          },
          "required": ["url"],
          "additionalProperties": false
        }
      ],
      "title": "Repository",
      "description": "Source repository for this extension. Accepts a URL string (or `host:owner/repo` shorthand) or an object with `type`, `url`, and optional `directory`."
    },
    "Bugs": {
      "anyOf": [
        {
          "type": "string",
          "examples": ["https://github.com/acme/code-review/issues"],
          "format": "uri"
        },
        {
          "type": "object",
          "properties": {
            "url": {
              "anyOf": [
                {
                  "type": "string",
                  "allOf": [
                    {
                      "minLength": 1,
                      "description": "Issue tracker URL.",
                      "examples": ["https://github.com/acme/code-review/issues"],
                      "format": "uri"
                    }
                  ]
                },
                { "type": "null" }
              ]
            },
            "email": {
              "anyOf": [
                {
                  "type": "string",
                  "allOf": [
                    {
                      "minLength": 1,
                      "description": "Contact email for bug reports.",
                      "examples": ["bugs@acme.dev"],
                      "format": "email"
                    }
                  ]
                },
                { "type": "null" }
              ]
            }
          },
          "additionalProperties": false
        }
      ],
      "title": "Bugs",
      "description": "Where to report bugs against this extension. Accepts a URL string or an object with optional `url` and `email`."
    },
    "Author": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
        "url": { "anyOf": [{ "type": "string" }, { "type": "null" }] }
      },
      "required": ["name"],
      "additionalProperties": false,
      "title": "Author",
      "description": "A person credited as a creator or maintainer of this extension."
    },
    "PackageIdentityPurl": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[Pp][Kk][Gg]:[a-zA-Z][a-zA-Z0-9.+-]*\\/.+$",
      "title": "Package Identity Purl",
      "description": "A Package URL (purl) identity for a companion package. Companion package purls are identities, not pins: omit the purl @version segment and put compatibility constraints in versionRange.",
      "examples": ["pkg:npm/react", "pkg:pypi/requests", "pkg:cargo/serde"]
    },
    "VersRangeEncoded": {
      "type": "string",
      "minLength": 1,
      "examples": ["vers:npm/>=18.0.0|<19.0.0", "vers:pypi/>=2.31.0", "vers:cargo/>=1.0.0"]
    },
    "CompanionPackage": {
      "type": "object",
      "properties": {
        "purl": { "$ref": "#/definitions/PackageIdentityPurl" },
        "versionRange": {
          "anyOf": [{ "$ref": "#/definitions/VersRangeEncoded" }, { "type": "null" }]
        }
      },
      "required": ["purl"],
      "additionalProperties": false,
      "title": "Companion Package",
      "description": "A companion package purl identity with an optional VERS compatibility range."
    },
    "PackSpec": {
      "type": "string",
      "minLength": 1,
      "pattern": "^(@[a-z0-9_](?:[a-z0-9_-]*[a-z0-9_])?)\\/packs\\/([a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?)(?:@.+)?$",
      "title": "Pack Spec",
      "description": "Pack reference with an optional version constraint suffix.",
      "examples": ["@acme/packs/typescript", "@acme/packs/typescript@^1.0.0"]
    },
    "ExtensionName": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
      "title": "Extension Name",
      "description": "The name of an extension — lowercase letters, numbers, and hyphens (e.g. my-skill).",
      "examples": ["my-skill", "code-review", "prettier"]
    },
    "ConfigurableAgentId": {
      "type": "string",
      "enum": [
        "adal",
        "fx",
        "muse-code",
        "mimo-code",
        "coder-agents",
        "aider-desk",
        "amp",
        "antigravity",
        "antigravity-cli",
        "augment",
        "claude-code",
        "cline",
        "codearts-agent",
        "codebuddy",
        "codemaker",
        "codestudio",
        "codex",
        "command-code",
        "continue",
        "cortex",
        "crush",
        "cursor",
        "deepagents",
        "devin",
        "dexto",
        "droid",
        "firebender",
        "forgecode",
        "gemini-cli",
        "github-copilot-cli",
        "goose",
        "grok-cli",
        "hermes",
        "ibm-bob",
        "iflow-cli",
        "junie",
        "lingma",
        "kilo",
        "kimi-cli",
        "kiro-cli",
        "kode",
        "mcpjam",
        "minimax-code",
        "mistral-vibe",
        "mux",
        "neovate",
        "openclaw",
        "opencode",
        "openhands",
        "ona",
        "pi",
        "vscode",
        "pochi",
        "qoder",
        "qoder-cn",
        "qwen-code",
        "replit",
        "roo",
        "rovodev",
        "tabnine-cli",
        "trae-cn",
        "trae",
        "warp",
        "windsurf",
        "zencoder",
        "zed",
        "zenflow"
      ],
      "title": "Configurable Agent ID",
      "description": "Supported coding agent identifier used in workspace settings `agents`.",
      "examples": ["claude-code", "codex", "cursor"]
    },
    "VersionRange": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[~^<>=*xXvV0-9A-Za-z+| .-]+$",
      "title": "Version Range",
      "description": "A semver version range like ^1.0.0, ~2.3.0, >=1.0.0 <3.0.0, or an exact version 1.2.3. Use \"*\" to always resolve to the latest available version.",
      "examples": ["^1.0.0", "~2.4", ">=1 <3", "1.2.3", "*"]
    },
    "HookEvent": {
      "type": "string",
      "minLength": 1,
      "pattern": "^[a-zA-Z][a-zA-Z0-9_.:-]*$",
      "description": "Exact event name in the implementation's native host protocol."
    },
    "HookRuntime": {
      "type": "string",
      "enum": ["bash", "node", "python"],
      "description": "Interpreter family used to execute this native command handler."
    },
    "HookPackagePath": {
      "type": "string",
      "minLength": 1,
      "pattern": "^(?!\\/)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*\\/\\/)(?!.*[\\\\:\\u0000-\\u001f])[^/]+(?:\\/[^/]+)*$",
      "description": "A safe, package-relative POSIX file path. Absolute paths and traversal are forbidden."
    },
    "HookValue": {
      "anyOf": [
        { "type": "string" },
        {
          "type": "object",
          "properties": {
            "config": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$",
              "maxLength": 64
            }
          },
          "required": ["config"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "env": { "type": "string", "minLength": 1, "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$" }
          },
          "required": ["env"],
          "additionalProperties": false
        }
      ]
    },
    "HookCommandHandler": {
      "type": "object",
      "properties": {
        "type": { "type": "string", "enum": ["command"] },
        "name": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
        "runtime": { "$ref": "#/definitions/HookRuntime" },
        "entrypoint": { "$ref": "#/definitions/HookPackagePath" },
        "args": {
          "anyOf": [
            { "type": "array", "items": { "$ref": "#/definitions/HookValue" } },
            { "type": "null" }
          ]
        },
        "env": {
          "anyOf": [
            {
              "type": "object",
              "propertyNames": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
              },
              "additionalProperties": { "$ref": "#/definitions/HookValue" }
            },
            { "type": "null" }
          ]
        },
        "timeoutMs": { "anyOf": [{ "type": "integer", "exclusiveMinimum": 0 }, { "type": "null" }] }
      },
      "required": ["type", "runtime", "entrypoint"],
      "additionalProperties": false
    },
    "HookBlockOutcome": {
      "type": "string",
      "enum": ["allow", "deny", "ask"],
      "title": "Hook Block Outcome",
      "description": "Decision outcome available to blocking hook systems."
    },
    "HookModifyOperation": {
      "type": "string",
      "enum": ["modify-input", "inject-context", "modify-output", "synthesize", "redact"],
      "title": "Hook Modify Operation",
      "description": "Transform operation available to modifying hook systems."
    },
    "HookBindingRequirements": {
      "type": "object",
      "properties": {
        "outcomes": {
          "anyOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": [{ "$ref": "#/definitions/HookBlockOutcome" }],
              "additionalItems": { "$ref": "#/definitions/HookBlockOutcome" }
            },
            { "type": "null" }
          ]
        },
        "operations": {
          "anyOf": [
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": [{ "$ref": "#/definitions/HookModifyOperation" }],
              "additionalItems": { "$ref": "#/definitions/HookModifyOperation" }
            },
            { "type": "null" }
          ]
        }
      },
      "additionalProperties": false,
      "description": "Every declared outcome and operation must be supported by this native event. Omit for observation only."
    },
    "HookBinding": {
      "type": "object",
      "properties": {
        "id": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9-]*$", "maxLength": 80 },
        "event": { "$ref": "#/definitions/HookEvent" },
        "matcher": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
        "handler": { "$ref": "#/definitions/HookCommandHandler" },
        "requires": {
          "anyOf": [{ "$ref": "#/definitions/HookBindingRequirements" }, { "type": "null" }]
        }
      },
      "required": ["id", "event", "handler"],
      "additionalProperties": false
    },
    "HookImplementation": {
      "type": "object",
      "properties": {
        "id": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9-]*$", "maxLength": 80 },
        "protocol": { "$ref": "#/definitions/ConfigurableAgentId" },
        "requires": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "hostVersion": {
                  "anyOf": [{ "$ref": "#/definitions/VersionRange" }, { "type": "null" }]
                },
                "profiles": {
                  "anyOf": [
                    {
                      "type": "array",
                      "minItems": 1,
                      "uniqueItems": true,
                      "items": [{ "type": "string", "minLength": 1 }],
                      "additionalItems": { "type": "string", "minLength": 1 }
                    },
                    { "type": "null" }
                  ]
                },
                "platforms": {
                  "anyOf": [
                    {
                      "type": "array",
                      "minItems": 1,
                      "uniqueItems": true,
                      "items": [{ "type": "string", "enum": ["darwin", "linux", "win32"] }],
                      "additionalItems": { "type": "string", "enum": ["darwin", "linux", "win32"] }
                    },
                    { "type": "null" }
                  ]
                },
                "scopes": {
                  "anyOf": [
                    {
                      "type": "array",
                      "minItems": 1,
                      "uniqueItems": true,
                      "items": [{ "type": "string", "enum": ["project", "user"] }],
                      "additionalItems": { "type": "string", "enum": ["project", "user"] }
                    },
                    { "type": "null" }
                  ]
                }
              },
              "additionalProperties": false
            },
            { "type": "null" }
          ]
        },
        "bindings": {
          "type": "array",
          "minItems": 1,
          "items": [{ "$ref": "#/definitions/HookBinding" }],
          "additionalItems": { "$ref": "#/definitions/HookBinding" }
        }
      },
      "required": ["id", "protocol", "bindings"],
      "additionalProperties": false
    },
    "HookConfigurationField": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "description": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
            "required": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "type": { "type": "string", "enum": ["string"] },
            "default": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
            "secret": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "allowEmpty": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "minLength": { "anyOf": [{ "type": "integer", "minimum": 0 }, { "type": "null" }] },
            "maxLength": { "anyOf": [{ "type": "integer", "minimum": 0 }, { "type": "null" }] }
          },
          "required": ["type"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "description": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
            "required": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "type": { "type": "string", "enum": ["number"] },
            "default": { "anyOf": [{ "type": "number" }, { "type": "null" }] },
            "minimum": { "anyOf": [{ "type": "number" }, { "type": "null" }] },
            "maximum": { "anyOf": [{ "type": "number" }, { "type": "null" }] }
          },
          "required": ["type"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "description": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
            "required": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "type": { "type": "string", "enum": ["boolean"] },
            "default": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] }
          },
          "required": ["type"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "description": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
            "required": { "anyOf": [{ "type": "boolean" }, { "type": "null" }] },
            "type": { "type": "string", "enum": ["enum"] },
            "values": {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": [{ "type": "string", "minLength": 1 }],
              "additionalItems": { "type": "string", "minLength": 1 }
            },
            "default": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }
          },
          "required": ["type", "values"],
          "additionalProperties": false
        }
      ]
    },
    "HookFixture": {
      "type": "object",
      "properties": {
        "id": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9-]*$", "maxLength": 80 },
        "implementation": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z][a-z0-9-]*$",
          "maxLength": 80
        },
        "binding": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z][a-z0-9-]*$",
          "maxLength": 80
        },
        "input": { "$ref": "#/definitions/HookPackagePath" },
        "expect": {
          "type": "object",
          "properties": {
            "exitCode": { "type": "integer", "minimum": 0, "maximum": 255 },
            "stdout": {
              "anyOf": [{ "$ref": "#/definitions/HookPackagePath" }, { "type": "null" }]
            },
            "stderr": { "anyOf": [{ "$ref": "#/definitions/HookPackagePath" }, { "type": "null" }] }
          },
          "required": ["exitCode"],
          "additionalProperties": false
        }
      },
      "required": ["id", "implementation", "binding", "input", "expect"],
      "additionalProperties": false,
      "description": "Native stdin and expected output files used only by explicitly requested fixture execution."
    },
    "HookManifest": {
      "type": "object",
      "properties": {
        "$schema": { "anyOf": [{ "type": "string" }, { "type": "null" }] },
        "publish": { "anyOf": [{ "$ref": "#/definitions/PublishOptions" }, { "type": "null" }] },
        "metadata": {
          "anyOf": [
            {
              "type": "object",
              "title": "Extension Metadata",
              "description": "Opaque consumer-defined JSON metadata. The compact UTF-8 JSON representation is limited to 65,536 bytes and container depth 16."
            },
            { "type": "null" }
          ]
        },
        "owner": { "$ref": "#/definitions/Handle" },
        "version": { "$ref": "#/definitions/Version" },
        "description": {
          "anyOf": [
            {
              "type": "string",
              "description": "Short, registry-facing summary of this extension shown in listings and search results."
            },
            { "type": "null" }
          ]
        },
        "keywords": {
          "anyOf": [
            {
              "type": "array",
              "examples": [["lint", "typescript", "review"]],
              "items": { "type": "string", "minLength": 1 }
            },
            { "type": "null" }
          ]
        },
        "repository": { "anyOf": [{ "$ref": "#/definitions/Repository" }, { "type": "null" }] },
        "homepage": {
          "anyOf": [
            { "type": "string", "examples": ["https://acme.dev/code-review"], "format": "uri" },
            { "type": "null" }
          ]
        },
        "license": {
          "anyOf": [
            {
              "type": "string",
              "title": "License",
              "description": "SPDX license expression, or `UNLICENSED` for proprietary code.",
              "examples": ["MIT", "Apache-2.0", "MIT OR Apache-2.0", "UNLICENSED"],
              "format": "spdx-expression"
            },
            { "type": "null" }
          ]
        },
        "bugs": { "anyOf": [{ "$ref": "#/definitions/Bugs" }, { "type": "null" }] },
        "authors": {
          "anyOf": [
            { "type": "array", "items": { "$ref": "#/definitions/Author" } },
            { "type": "null" }
          ]
        },
        "packages": {
          "anyOf": [
            {
              "type": "array",
              "description": "External ecosystem packages this extension is designed to work with, declared as identity Package URLs with optional VERS compatibility ranges.",
              "items": { "$ref": "#/definitions/CompanionPackage" }
            },
            { "type": "null" }
          ]
        },
        "enhances": {
          "anyOf": [
            {
              "type": "array",
              "uniqueItems": true,
              "description": "Soft capability enhancements used by the source. These never block installation.",
              "items": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?::[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)?$"
              }
            },
            { "type": "null" }
          ]
        },
        "requires": {
          "anyOf": [
            {
              "type": "array",
              "uniqueItems": true,
              "description": "Hard capabilities without which the extension cannot operate.",
              "items": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?::[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)?$"
              }
            },
            { "type": "null" }
          ]
        },
        "recommendedPacks": {
          "anyOf": [
            {
              "type": "array",
              "description": "Pack recommendations and same-pack composition metadata. Entries do not install or guarantee the pack or its members.",
              "items": { "$ref": "#/definitions/PackSpec" }
            },
            { "type": "null" }
          ]
        },
        "standalone": {
          "anyOf": [
            {
              "type": "boolean",
              "description": "False means the extension requires sibling extensions that are direct members of a pack named in recommendedPacks, resolved by extension identity rather than by path; it does not create dependencies.",
              "default": true
            },
            { "type": "null" }
          ]
        },
        "type": { "type": "string", "enum": ["hook"] },
        "name": { "$ref": "#/definitions/ExtensionName" },
        "title": { "anyOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
        "implementations": {
          "type": "array",
          "minItems": 1,
          "items": [{ "$ref": "#/definitions/HookImplementation" }],
          "additionalItems": { "$ref": "#/definitions/HookImplementation" }
        },
        "configuration": {
          "anyOf": [
            {
              "type": "object",
              "propertyNames": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$",
                "maxLength": 64
              },
              "additionalProperties": { "$ref": "#/definitions/HookConfigurationField" }
            },
            { "type": "null" }
          ]
        },
        "assets": {
          "anyOf": [
            {
              "type": "array",
              "uniqueItems": true,
              "items": { "$ref": "#/definitions/HookPackagePath" }
            },
            { "type": "null" }
          ]
        },
        "fixtures": {
          "anyOf": [
            { "type": "array", "items": { "$ref": "#/definitions/HookFixture" } },
            { "type": "null" }
          ]
        }
      },
      "required": ["owner", "version", "type", "name", "implementations"],
      "additionalProperties": false
    }
  }
}
