Skip to content

Pinned Claude hooks.schema.json rejects documented hook fields (args/async/if/statusMessage/once/shell) and handler types (http/mcp_tool/prompt/agent) that claude plugin validate --strict accepts #477

Description

@ScriptedAlchemy

Problem

packages/agent-bundle/src/adapters/schemas/claude/hooks.schema.json (pinned at 2.1.250, PROVENANCE.json says it is a direct pin of https://code.claude.com/docs/en/hooks) accepts only:

  • handler: { type: "command", command, timeout } with additionalProperties: false
  • matcher group: { matcher, hooks } with additionalProperties: false

The current hooks reference documents considerably more for the same hooks/hooks.json document:

  • hooks-2.mdConfiguration › Hook handler fields › Common fields (L423–433): if, statusMessage, once on every handler type.
  • hooks-2.mdCommand hook fields (L453–462) and Exec form and shell form (L464–): args (exec form, recommended whenever the command references a path placeholder such as ${CLAUDE_PLUGIN_ROOT}), async, asyncRewake, shell.
  • hooks-2.mdHook handler fields (L407–413): five handler types — command, http, mcp_tool, prompt, agent — with their own field tables (HTTP hook fields L508, Prompt and agent hook fields L583).

Reproduced on this machine: a hooks/hooks.json using args, async, if, and statusMessage passes claude plugin validate .claude-plugin/plugin.json --strict on Claude Code 2.1.259 (✔ Validation passed), while validateClaudePluginFiles rejects it four times with AB6012 … must NOT have additional properties.

Why it matters

  • The compiler itself emits only shell-form command hooks with command/timeout, so today's emitted bundles are not affected. But the pinned schema is presented (docs/diagnostics.md AB6011/AB6012, capability plugin.devtools) as the Claude hooks contract, and doctor (AB7320) applies it to installed copies — including ones Claude itself accepted.
  • The reference explicitly recommends exec form (args) for path-placeholder commands, which is exactly how the emitted hooks reference ${CLAUDE_PLUGIN_ROOT}/hooks/*.mjs. Adopting exec form is blocked by the pin.
  • The hooks capability JSON (plugin.hooks.features) has no rows for args/async/if/once/statusMessage, http/mcp_tool/prompt/agent handler types, so the generated hosts/events pages cannot say whether the compiler supports them.

Proposed

At the next Claude CLI re-pin (the PROVENANCE.json notes already require a deliberate re-pin): widen hooks.schema.json to the documented handler union (or at least the command-hook field set) and add capability rows stating which of those fields the compiler emits versus passes through. Keep additionalProperties: false so genuinely unknown keys still fail (Claude only warns on them).

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthost-integrationAgent host capabilities, projection, discovery, and lifecycle

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions