Skip to content

antigravity-plugin-json-valid

plugin.json must parse as an Antigravity manifest with correctly typed fields

Severity error (auto)
Autofix -
Since v0.20.0
Repo Types antigravity, antigravity-plugin
Category Google Antigravity

Why

An Antigravity plugin conventionally lives under a customization root at .agents/plugins/<name>/, or the .agent/, _agents/, _agent/ equivalents. A plugins.json entry or inherited registry can also name a plugin elsewhere in the repository. Both require plugin.json. A standalone package at the lint root is also recognized when its manifest declares "$schema": "https://antigravity.google/schemas/v1/plugin.json". Use --type antigravity-plugin to check an existing root manifest without that declaration, including a malformed document. A collection with no root manifest does not acquire a missing-root-manifest finding.

Measured against agy 1.1.25: a directory whose manifest does not parse is not loaded as a plugin at all. Its skills, agents, commands, rules, hooks and MCP servers all go unread, and the only trace is one line in the debug log.

That is why a type error here is an error rather than a style note: the cost is the whole package, not the field.

The manifest is a protobuf JSON message with exactly four fields that carry meaning — name, description, disabled, logo. Every other key, $schema and version and author included, is discarded as unknown and the plugin still loads, so none of them is reported.

Severity

Errors — the directory is not a plugin:

  • plugin.json is missing, or is not a regular file.
  • Invalid JSON, including an unpaired Unicode surrogate escape in any string or key, even inside discarded metadata.
  • A repeated known root field (name, description, disabled, logo). Neither copy wins, including when one or both values are null.
  • A UTF-8 byte-order mark (BOM). Remove it; the loader does not strip it.
  • A root that is not a JSON object.
  • A type error on one of the four fields: name, description and logo must be strings, disabled a boolean.

Warnings — the plugin loads in place but cannot be installed:

  • A name outside [A-Za-z0-9_-], or one beginning with a dot. agy plugin install refuses Bad Name, a/b, ../esc and .hidden; discovery does not.

Info:

  • No canonical name. Runtime discovery falls back to the directory name. Add name for consistent behavior across consumers. The separate installer accepts capitalized Name, which the runtime ignores; this advisory does not claim every missing canonical name prevents installation.

What is not reported

  • Unknown keys and their duplicates. $schema, version, author, homepage, license, keywords, entrypoint and everything else are discarded by the parser and cost nothing. A package written to the portable Agent Plugins schema and dropped into .agents/plugins/ is claimed and loaded by Antigravity unchanged, and this rule says nothing about it.
  • A $schema value. The URL the vendor tells authors to write, https://antigravity.google/schemas/v1/plugin.json, is 404, so there is nothing to dereference. The schema itself is published inline under "Full JSON Schema" at https://antigravity.google/docs/cli/plugins/, and is narrower than what agy loads — it lists only name and description, while disabled and logo load fine — so this rule follows the loader rather than the schema.
  • Capitalized fields. Runtime fields match exactly: Description, Disabled and Logo are unknown metadata. This ProtoJSON behavior differs from Antigravity's hooks, MCP and registry readers.
  • disabled: true. It is the documented way to keep a plugin in the tree without loading it.
  • A null value, and an empty string in a string field. protojson decodes both as the field's default, so each reads as the key being absent: {"name": null}, {"name": ""} and no name at all give the same finding and the same directory-name fallback. disabled is the exception — it is a boolean, and "" there is invalid value for bool field disabled, so the directory is not a plugin.

Examples

Badname written as a number, so nothing in the directory loads:

{
  "name": 42,
  "description": "Berth allocation helpers"
}

Good:

{
  "name": "berth-tools",
  "description": "Berth allocation helpers: a status command, an allocation reviewer, and the simulator MCP server.",
  "logo": "assets/berth-tools.png"
}

How to fix

  • Give name a string of letters, digits, - and _, matching the directory name.
  • Give description a sentence saying when the plugin is worth loading — it is what a reader sees before the components.
  • Write disabled as a boolean, not "no" or 0.
  • Remove repeated known root fields. A repeated name, for example, fails with proto: duplicate field "name". Repeated unknown metadata is accepted.

Configuration

rules:
  antigravity-plugin-json-valid:
    enabled: auto  # true | false | auto
    severity: error

Run skillsaw explain antigravity-plugin-json-valid to see this documentation and the rule's effective configuration in your terminal.