{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "shep community dog index",
  "description": "Editor-time courtesy schema for web/public/dogs.json. web/src/data/dogs.ts's validate() (wrapped by unwrap()) is the actual gate this mirrors; if the two ever disagree, the validator wins. \"version\" pins this document to the wrapper shape shep understands -- see dog_index.rs's own module doc for why a bare array is refused now.",
  "type": "object",
  "additionalProperties": false,
  "required": ["version", "dogs"],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "version": {
      "const": 1,
      "description": "The wrapper's own format version, not an entry's. Bump only alongside a shep release that understands the new shape."
    },
    "dogs": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "package",
          "adopt_as",
          "description",
          "repo",
          "license",
          "category",
          "source"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The dog's own name, unique (case-insensitively) across the index. Displayed as \"package (Name)\"."
          },
          "package": {
            "type": "string",
            "minLength": 1,
            "description": "The crate or repository name; the real identity, also unique across the index."
          },
          "adopt_as": {
            "type": "string",
            "minLength": 1,
            "description": "The name this dog expects to be adopted under: shep adopt <path> --name <adopt_as>."
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "description": "One line describing what the dog does."
          },
          "repo": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "description": "HTTPS URL of the dog's repository, not just a domain or a profile page."
          },
          "license": {
            "type": "string",
            "minLength": 1,
            "description": "SPDX license string."
          },
          "category": {
            "type": "string",
            "enum": ["logs", "metrics", "alerts", "health", "deploy", "other"]
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["kind"],
                "properties": {
                  "kind": { "const": "cargo" },
                  "version": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The exact version to name, for a dog that needs one (a pre-release above all: cargo resolves * to the newest stable, and * never matches a pre-release). Omit for a normal release."
                  }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["kind", "url"],
                "properties": {
                  "kind": { "const": "cargo-git" },
                  "url": { "type": "string", "minLength": 1 }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["kind", "module"],
                "properties": {
                  "kind": { "const": "go-install" },
                  "module": { "type": "string", "minLength": 1 }
                }
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": ["kind", "instructions"],
                "properties": {
                  "kind": { "const": "manual" },
                  "instructions": { "type": "string", "minLength": 1 }
                }
              }
            ]
          }
        }
      }
    }
  }
}
