{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Havoptic Public API",
    "version": "1.0.0",
    "description": "Public data endpoints for the Havoptic AI coding tool release tracker. No authentication required. Release data is refreshed hourly by the havoptic-prod-pipeline Worker (R2-backed). Also available as a remote MCP server (streamable HTTP, no auth) at https://mcp.havoptic.com/mcp. JSON Schemas for every response object are served at /api/v1/schemas/{name}.json.",
    "contact": {
      "url": "https://www.havoptic.com/api-docs"
    },
    "license": {
      "name": "Data freely accessible",
      "url": "https://www.havoptic.com"
    }
  },
  "externalDocs": {
    "description": "Developer docs: quickstart, auth & rate limits, webhooks, MCP, errors",
    "url": "https://www.havoptic.com/docs"
  },
  "servers": [
    {
      "url": "https://api.havoptic.com",
      "description": "Production API host (primary)"
    },
    {
      "url": "https://www.havoptic.com",
      "description": "Production site (same API, additive-only alias)"
    }
  ],
  "paths": {
    "/api/v1/releases": {
      "get": {
        "summary": "Filterable, paginated release list",
        "description": "Stable versioned query endpoint over the release dataset. Returns release summaries (no fullNotes), newest first. Send cursor= for cursor pagination (object: list); offset= is deprecated (Deprecation + Sunset headers).",
        "operationId": "listReleasesV1",
        "parameters": [
          {
            "name": "tool",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            },
            "description": "Filter to one tool"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseType"
            },
            "description": "Release channel (stable vs prerelease)"
          },
          {
            "name": "bump",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Computed semver bump filter, comma-separated: major, minor, patch, unknown"
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseChannel"
            },
            "description": "Alias for type=release (stable) or type=prerelease"
          },
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated VendorId (see components.schemas.VendorId)"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ProductCategory (see components.schemas.ProductCategory)"
          },
          {
            "name": "breaking",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Enriched releases with (true) or without (false) breaking changes; legacy releases match neither"
          },
          {
            "name": "security",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Enriched releases with (true) or without (false) security changes; legacy releases match neither"
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Only releases on/after this date"
          },
          {
            "name": "until",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Only releases on/before this date"
          },
          {
            "name": "updated_since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Sync cursor: records updated (updated_at, else detected_at, else date) at/after this time"
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Substring match against version, summary, and full notes"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseSort",
              "default": "-published_at"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ReleaseExpand: notes (raw notes object), product (product reference), changes (already included on enriched rows)"
          },
          {
            "name": "fields",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated sparse fieldset"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor from next_cursor"
          },
          {
            "name": "offset",
            "in": "query",
            "deprecated": true,
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated release summaries",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Offset page (legacy, Deprecation header) or cursor list when ?cursor= is sent.",
                  "anyOf": [
                    {
                      "type": "object",
                      "required": [
                        "apiVersion",
                        "total",
                        "limit",
                        "offset",
                        "releases"
                      ],
                      "properties": {
                        "apiVersion": {
                          "const": "v1"
                        },
                        "lastUpdated": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "total": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "limit": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offset": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "releases": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ReleaseSummary"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/ResponseMeta"
                        }
                      }
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/List"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "data": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/ReleaseSummary"
                              }
                            },
                            "apiVersion": {
                              "const": "v1"
                            },
                            "lastUpdated": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/releases/{id}": {
      "get": {
        "summary": "One release with full notes",
        "operationId": "getReleaseV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "antigravity-cli-1.5.1",
            "description": "Release id ({tool}-{version}) or {tool}@{version}"
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated: notes, changes"
          }
        ],
        "responses": {
          "200": {
            "description": "The release, including fullNotes",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apiVersion",
                    "release"
                  ],
                  "properties": {
                    "apiVersion": {
                      "const": "v1"
                    },
                    "release": {
                      "$ref": "#/components/schemas/Release"
                    }
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools": {
      "get": {
        "summary": "Tracked tools with counts and latest release",
        "description": "Each item keeps its legacy fields (releaseCount, latest, firstTrackedDate) and adds vendor, category, status, latest_release, release_count and health (source-health status).",
        "operationId": "listToolsV1",
        "parameters": [
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/VendorId"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ProductCategory"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ProductStatusFilter",
              "default": "active"
            },
            "description": "Product lifecycle; all disables the filter"
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Substring match on id, name, alias, vendor"
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked tools",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Legacy envelope (apiVersion, lastUpdated, tools[]) with additive item fields.",
                  "required": [
                    "apiVersion",
                    "tools"
                  ],
                  "properties": {
                    "apiVersion": {
                      "const": "v1"
                    },
                    "lastUpdated": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "tools": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "releaseCount",
                          "latest_release",
                          "release_count",
                          "health"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "releaseCount": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Legacy alias of release_count"
                          },
                          "latest": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Legacy latest pointer (any channel)",
                            "additionalProperties": true
                          },
                          "firstTrackedDate": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "vendor_id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "vendor": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "enum": [
                                  "anthropic",
                                  "openai",
                                  "anysphere",
                                  "google",
                                  "amazon",
                                  "github",
                                  "cognition",
                                  "spacexai",
                                  "cline",
                                  "anomaly",
                                  "zed-industries",
                                  "factory",
                                  "lovable",
                                  "sourcegraph",
                                  "replit",
                                  "stackblitz",
                                  "vercel",
                                  "mistral",
                                  "deepseek",
                                  "modelcontextprotocol",
                                  "langchain",
                                  "llamaindex",
                                  "crewai",
                                  "mastra",
                                  "cloudflare",
                                  "ollama",
                                  "vllm",
                                  "element-labs",
                                  "huggingface"
                                ]
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active",
                              "deprecated",
                              "renamed"
                            ]
                          },
                          "aliases": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "latest_release": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "required": [
                              "id",
                              "version",
                              "published_at"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "version": {
                                "type": "string"
                              },
                              "published_at": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "release",
                                  "prerelease"
                                ]
                              },
                              "abstract": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Neutral summary (enriched releases only)"
                              }
                            },
                            "additionalProperties": true
                          },
                          "release_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "health": {
                            "type": "string",
                            "enum": [
                              "ok",
                              "stale",
                              "hard",
                              "excluded",
                              "no-history",
                              "unknown"
                            ]
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}": {
      "get": {
        "summary": "One tool: metadata, latest releases, cadence, health",
        "description": "Registry metadata, latest stable and prerelease, a cadence summary, and source health. Accepts registry aliases (devin-desktop → windsurf).",
        "operationId": "getToolV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "claude-code",
            "description": "ToolId or registry alias"
          }
        ],
        "responses": {
          "200": {
            "description": "Product",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Product"
                    },
                    {
                      "type": "object",
                      "required": [
                        "object",
                        "vendor",
                        "category",
                        "status",
                        "release_count",
                        "latest_release",
                        "latest_prerelease",
                        "cadence",
                        "health",
                        "sources",
                        "meta"
                      ],
                      "properties": {
                        "object": true,
                        "vendor": true,
                        "category": true,
                        "status": true,
                        "release_count": true,
                        "latest_release": true,
                        "latest_prerelease": true,
                        "cadence": true,
                        "health": true,
                        "sources": true,
                        "meta": true
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}/releases": {
      "get": {
        "summary": "Releases for one tool",
        "description": "Shortcut for /api/v1/releases?tool={id} (same envelope, filters and pagination; the path wins over ?tool=). Cursor pagination by default on api.havoptic.com.",
        "operationId": "listToolReleasesV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseType"
            },
            "description": "Release channel (stable vs prerelease)"
          },
          {
            "name": "bump",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Computed semver bump filter, comma-separated: major, minor, patch, unknown"
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseChannel"
            },
            "description": "Alias for type=release (stable) or type=prerelease"
          },
          {
            "name": "vendor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated VendorId (see components.schemas.VendorId)"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ProductCategory (see components.schemas.ProductCategory)"
          },
          {
            "name": "breaking",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Enriched releases with (true) or without (false) breaking changes; legacy releases match neither"
          },
          {
            "name": "security",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Enriched releases with (true) or without (false) security changes; legacy releases match neither"
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Only releases on/after this date"
          },
          {
            "name": "until",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Only releases on/before this date"
          },
          {
            "name": "updated_since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Sync cursor: records updated (updated_at, else detected_at, else date) at/after this time"
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Substring match against version, summary, and full notes"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseSort",
              "default": "-published_at"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ReleaseExpand: notes (raw notes object), product (product reference), changes (already included on enriched rows)"
          },
          {
            "name": "fields",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated sparse fieldset"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor from next_cursor"
          },
          {
            "name": "offset",
            "in": "query",
            "deprecated": true,
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated release summaries",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Offset page (legacy, Deprecation header) or cursor list when ?cursor= is sent.",
                  "anyOf": [
                    {
                      "type": "object",
                      "required": [
                        "apiVersion",
                        "total",
                        "limit",
                        "offset",
                        "releases"
                      ],
                      "properties": {
                        "apiVersion": {
                          "const": "v1"
                        },
                        "lastUpdated": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "total": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "limit": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offset": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "releases": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ReleaseSummary"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/ResponseMeta"
                        }
                      }
                    },
                    {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/List"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "data": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/ReleaseSummary"
                              }
                            },
                            "apiVersion": {
                              "const": "v1"
                            },
                            "lastUpdated": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}/versions/{version}": {
      "get": {
        "summary": "Resolve one version of a tool",
        "description": "latest → newest stable release. Matching is case-insensitive and tolerates a leading v and the codex rust-v prefix (0.142.4, v0.142.4 and rust-v0.142.4 are equivalent).",
        "operationId": "getToolVersionV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "latest"
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated: notes, changes"
          }
        ],
        "responses": {
          "200": {
            "description": "The release",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Release"
                    },
                    {
                      "type": "object",
                      "required": [
                        "object",
                        "meta"
                      ],
                      "properties": {
                        "object": {
                          "const": "release"
                        },
                        "meta": {
                          "$ref": "#/components/schemas/ResponseMeta"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}/cadence": {
      "get": {
        "summary": "Release cadence stats for one tool",
        "description": "Release counts over 7/30/90 days, average days between releases, and the latest release. With window=, cadence.window adds releases in that trailing window vs the one before it.",
        "operationId": "getToolCadenceV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "window",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/CadenceWindow"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cadence stats",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apiVersion",
                    "cadence"
                  ],
                  "properties": {
                    "apiVersion": {
                      "const": "v1"
                    },
                    "cadence": {
                      "$ref": "#/components/schemas/CadenceStats"
                    }
                  }
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}/latest": {
      "get": {
        "summary": "Latest release for one tool",
        "operationId": "getToolLatestV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReleaseChannel",
              "default": "stable"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Latest release",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Release"
                    },
                    {
                      "type": "object",
                      "required": [
                        "object",
                        "meta"
                      ],
                      "properties": {
                        "object": {
                          "const": "release"
                        },
                        "meta": {
                          "$ref": "#/components/schemas/ResponseMeta"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}/upgrade": {
      "get": {
        "summary": "Upgrade intelligence between two versions",
        "description": "Breaking changes, deprecations, and typed sections between from (exclusive) and to (inclusive, default latest). Typed sections come only from enriched releases; meta reports enriched vs legacy counts. Accept: text/markdown for a markdown report.",
        "operationId": "getToolUpgradeV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Start version (exclusive)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "End version (inclusive); defaults to latest"
          }
        ],
        "responses": {
          "200": {
            "description": "Upgrade report",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpgradeReport"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/compare": {
      "get": {
        "summary": "Compare 2–4 tools",
        "description": "Cadence, feature-matrix differences, recent typed changes, and the editorial verdict per pair, selected by aspects. For exactly two tools the legacy comparison object is also returned unchanged.",
        "operationId": "compareToolsV1",
        "parameters": [
          {
            "name": "tools",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "claude-code,cursor",
            "description": "2–4 comma-separated tool ids"
          },
          {
            "name": "aspects",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated CompareAspect; default cadence,features,verdict"
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "30d",
            "description": "Window for recent_changes: ISO date or relative Nd (default 30d)"
          }
        ],
        "responses": {
          "200": {
            "description": "Comparison",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comparison"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/features": {
      "get": {
        "summary": "Feature catalog with stable ids",
        "description": "Curated cross-tool features (first-to-ship adoption) joined with the feature matrix (per-tool support) by stable feature id.",
        "operationId": "listFeaturesV1",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Substring match on id, name, category, description"
          },
          {
            "name": "tool",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            },
            "description": "Features this tool ships or supports"
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/FeatureSource"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Features",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Feature"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/features/{id}": {
      "get": {
        "summary": "One feature",
        "operationId": "getFeatureV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "mcp-support"
          }
        ],
        "responses": {
          "200": {
            "description": "Feature",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Feature"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trends/cadence": {
      "get": {
        "summary": "Release velocity across tools",
        "description": "Releases per tool in a trailing window vs the window before it, average gap, and a 12-week series.",
        "operationId": "getCadenceTrendV1",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/CadenceWindow",
              "default": "30d"
            }
          },
          {
            "name": "tools",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated tool ids (default: all)"
          }
        ],
        "responses": {
          "200": {
            "description": "Cadence trend",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CadenceTrend"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trends/feature-adoption": {
      "get": {
        "summary": "Who copies whom",
        "description": "Copying-trend insights from the feature timeline (follower lag, fast-follow share, leaders) plus one row per feature.",
        "operationId": "getFeatureAdoptionTrendV1",
        "responses": {
          "200": {
            "description": "Feature adoption",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureAdoption"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          }
        }
      }
    },
    "/api/v1/trends/mechanics": {
      "get": {
        "summary": "Behaviors and mechanics trend",
        "description": "The mechanics taxonomy joined with first-ship dates (same data as /api/v1/mechanics, in the v1 envelope).",
        "operationId": "getMechanicsTrendV1",
        "parameters": [
          {
            "name": "behavior",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mechanic",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mechanics catalog",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MechanicsCatalog"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          }
        }
      }
    },
    "/api/v1/feature-timeline": {
      "get": {
        "summary": "First-to-ship feature timeline",
        "description": "Which tool shipped each notable cross-tool feature first, per-tool follower lag, and copying-trend insights.",
        "operationId": "getFeatureTimelineV1",
        "parameters": [
          {
            "name": "feature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional feature id/name filter, e.g. subagents"
          }
        ],
        "responses": {
          "200": {
            "description": "Feature timeline",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mechanics": {
      "get": {
        "summary": "Behaviors and mechanics catalog",
        "description": "Human-curated taxonomy of product behaviors and the machinery underneath named features, joined with first-ship dates from the feature timeline.",
        "operationId": "getMechanicsV1",
        "parameters": [
          {
            "name": "behavior",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional behavior id filter, e.g. delegate-with-trust"
          },
          {
            "name": "mechanic",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional mechanic id filter, e.g. propose-then-approve"
          }
        ],
        "responses": {
          "200": {
            "description": "Mechanics catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/changes": {
      "get": {
        "summary": "Typed change items",
        "description": "Item-level typed changes from enriched releases only (legacy releases have none).",
        "operationId": "listChangesV1",
        "parameters": [
          {
            "name": "tool",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated ChangeKind: feature, fix, breaking, deprecation, security, improvement, removal, performance, model, pricing, policy"
          },
          {
            "name": "breaking",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "security",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "until",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Change item list",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ChangeItem"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/digest": {
      "get": {
        "summary": "Change digest since a date",
        "description": "Rollup of typed changes since an ISO date or relative window (e.g. 7d). Accept: text/markdown for an agent-ready digest.",
        "operationId": "getDigestV1",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "7d"
          },
          {
            "name": "tools",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated tool ids"
          },
          {
            "name": "max_items",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 200,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Digest",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Digest"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "summary": "Search changes and notes",
        "operationId": "searchV1",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2
            }
          },
          {
            "name": "tool",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "all"
            },
            "description": "all (changes + legacy notes) or changes"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 50,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResults"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Dataset temporarily unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vendors": {
      "get": {
        "summary": "Vendor catalog",
        "operationId": "listVendorsV1",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Substring filter on id/name"
          }
        ],
        "responses": {
          "200": {
            "description": "Vendors",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Vendor"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          }
        }
      }
    },
    "/api/v1/vendors/{id}": {
      "get": {
        "summary": "One vendor with its products",
        "operationId": "getVendorV1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/VendorId"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Vendor",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Vendor"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/changelog": {
      "get": {
        "summary": "API changelog",
        "description": "Changes to this API, newest first, each with its Havoptic-Version and a breaking flag. Accept: text/markdown for markdown.",
        "operationId": "getChangelogV1",
        "responses": {
          "200": {
            "description": "API changelog",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiChangelog"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          }
        }
      }
    },
    "/api/v1/status": {
      "get": {
        "summary": "Dataset and source freshness",
        "description": "dataset_updated_at, intelligence_since, the last hourly ingest, and per-source health (last_success_at, last_error, last_release_at) from the pipeline source-health job. status is degraded when any source is failing or stale, unknown before the first snapshot.",
        "operationId": "getStatusV1",
        "responses": {
          "200": {
            "description": "Status",
            "headers": {
              "ETag": {
                "description": "Weak ETag; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiStatus"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          }
        }
      }
    },
    "/api/v1/schemas/{name}.json": {
      "get": {
        "summary": "JSON Schema export",
        "description": "JSON Schema 2020-12 document for one API object; the same definitions back components.schemas here and MCP outputSchema.",
        "operationId": "getSchemaV1",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/SchemaName"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON Schema 2020-12 document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/manifest.json": {
      "get": {
        "summary": "Bulk export manifest",
        "description": "Every bulk export file with its row count, size and sha256, the flat CSV/Parquet columns, the license (CC-BY-4.0: attribution to Havoptic), and the daily delta files. Rebuilt by the pipeline whenever the release dataset changes. Also served at /api/v1/export.",
        "operationId": "getExportManifestV1",
        "responses": {
          "200": {
            "description": "Export manifest",
            "headers": {
              "ETag": {
                "description": "Strong ETag of the stored file; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "description": "attachment; filename=\"havoptic-…\" (inline for the manifest)",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "description": "<https://creativecommons.org/licenses/by/4.0/>; rel=\"license\", plus the manifest as rel=\"describedby\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportManifest"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/releases.{format}": {
      "get": {
        "summary": "Download the full release snapshot",
        "description": "The whole release dataset as one file, streamed from storage with Content-Disposition: attachment. json is a list envelope ({object: \"list\", data: Release[], meta}); ndjson is one Release per line; csv (header row) and parquet use the flat columns listed in the manifest. Not paginated, not filterable: use /api/v1/releases for queries and deltas/{date}.ndjson for incremental sync.",
        "operationId": "exportReleasesV1",
        "parameters": [
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "ndjson",
                "csv",
                "parquet"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Release snapshot file",
            "headers": {
              "ETag": {
                "description": "Strong ETag of the stored file; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "description": "attachment; filename=\"havoptic-…\" (inline for the manifest)",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "description": "<https://creativecommons.org/licenses/by/4.0/>; rel=\"license\", plus the manifest as rel=\"describedby\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/List"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Release"
                          }
                        }
                      }
                    }
                  ]
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "One Release JSON object per line"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/vnd.apache.parquet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/changes.ndjson": {
      "get": {
        "summary": "Download every typed change item",
        "description": "All change items (the ChangeItem shape of /api/v1/changes), newest first, one per line. Legacy releases contribute none.",
        "operationId": "exportChangesV1",
        "responses": {
          "200": {
            "description": "Change items, NDJSON",
            "headers": {
              "ETag": {
                "description": "Strong ETag of the stored file; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "description": "attachment; filename=\"havoptic-…\" (inline for the manifest)",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "description": "<https://creativecommons.org/licenses/by/4.0/>; rel=\"license\", plus the manifest as rel=\"describedby\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "One ChangeItem JSON object per line"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/deltas/{date}.ndjson": {
      "get": {
        "summary": "Daily release delta",
        "description": "Releases whose public record changed on this UTC day, one line each (latest change of the day wins): {\"op\":\"upsert\",\"id\",\"changed_at\",\"record\": Release} or {\"op\":\"delete\",\"id\",\"changed_at\"}. Apply deltas in date order on top of a snapshot taken before them. 404 when nothing changed that day or the date predates the export baseline (manifest deltas.baseline_at).",
        "operationId": "exportDeltaV1",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "UTC day, YYYY-MM-DD"
          }
        ],
        "responses": {
          "200": {
            "description": "Delta lines, NDJSON (each line is an ExportDeltaLine)",
            "headers": {
              "ETag": {
                "description": "Strong ETag of the stored file; send as If-None-Match for a 304",
                "schema": {
                  "type": "string"
                }
              },
              "Content-Disposition": {
                "description": "attachment; filename=\"havoptic-…\" (inline for the manifest)",
                "schema": {
                  "type": "string"
                }
              },
              "Link": {
                "description": "<https://creativecommons.org/licenses/by/4.0/>; rel=\"license\", plus the manifest as rel=\"describedby\"",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (If-None-Match matched the ETag)"
          },
          "400": {
            "description": "Invalid parameter",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/data/releases.json": {
      "get": {
        "summary": "All tracked releases",
        "description": "Returns every release tracked across all AI coding tools. Refreshed hourly. Results are sorted newest-first within each tool.",
        "operationId": "getReleases",
        "responses": {
          "200": {
            "description": "Release dataset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReleasesResponse"
                },
                "example": {
                  "lastUpdated": "2026-11-05T07:32:58.000Z",
                  "releases": [
                    {
                      "id": "antigravity-cli-1.5.1",
                      "tool": "antigravity-cli",
                      "toolDisplayName": "Antigravity CLI",
                      "version": "1.5.1",
                      "date": "2026-11-05T07:32:58.000Z",
                      "summary": "Antigravity CLI 1.5.1 is here: every model on your account now works in any ACP client, faster command wrap-ups, clearer blocked subagents, and a batch of Windows and session fixes. Curious what else changed?",
                      "fullNotes": "- Changed agy acp to offer every model available to your account to every ACP client, where previously only a fixed list of editors were offered models other than Gemini. - Changed the tabs in /config during --remote-agent sessions from Local and Remote to TUI and Remote Agent, so it is clear that one configures the terminal UI and the other the remote agent; the settings on each tab are unchanged. - Improved how quickly the agent moves on after a terminal command exits while a background process it started still holds the command's output open, which now takes at most about 1 second instead of 5. - Improved subagent rows above the prompt so a subagent that is blocked waiting on you names the tool it is waiting on, such as Blocked · AskQuestion, instead of Blocked · Processing.... - Improved how plugin OAuth credentials are protected in the terminal sandbox: a plugin's real token now replaces its stand-in only in a request's Authorization header, so a command can no longer get a website to echo the real token back by sending the stand-in in another header or in the URL. - Fixed several agy acp session bugs: closing, reloading, or resuming a session while a prompt runs now ends that prompt as cancelled instead of leaving it hanging, cancelling a prompt no longer also stops the next prompt sent right after it, session/update notifications no longer arrive after the session/prompt reply for that prompt, and permission requests and question forms now close when they are answered elsewhere or their prompt ends, instead of blocking later prompts or receiving their answers. - Fixed file edits on Windows failing with target content not found in files that use CRLF line endings, so edits now match whichever line endings the file uses and the lines they insert keep the file's line endings. - Fixed agent-run commands on Windows failing or returning garbled text when their output contains non-ASCII characters, by running Python in UTF-8 mode (PYTHONUTF8=1, unless you have set PYTHONUTF8 yourself) and switching PowerShell's output encoding to UTF-8. - Fixed stdio MCP servers on Windows leaving their child processes running after the server stops, which could lock plugin folders and make plugin upgrades fail because the files were in use. - Fixed agy plugin commands being unavailable, with no plugin marketplaces listed, when you sign in with Application Default Credentials (AGYADCAUTH) or through an enterprise model gateway. - Fixed the built-in browser agent being listed among the agents you can start a conversation with, since it is meant to run only as a subagent, which it still does. - Fixed copy-on-select and /copy inside GNU screen, so copied text now reaches your clipboard and long selections no longer leave stray characters in the terminal.",
                      "url": "https://github.com/google-antigravity/antigravity-cli/releases/tag/1.5.1",
                      "type": "release",
                      "detected_at": "2026-11-05T08:10:53.978Z",
                      "changes_available": true,
                      "quality": {
                        "notes_available": true,
                        "extraction_status": "complete",
                        "review": "auto"
                      },
                      "abstract": "Antigravity CLI 1.5.1 lets agy acp offer all account models to every ACP client, renames /config tabs to TUI and Remote Agent, and fixes ACP session cancellation and Windows CRLF edits and encoding.",
                      "highlights": [
                        "Plugin OAuth tokens are now substituted only in the Authorization header inside the terminal sandbox",
                        "Multiple agy acp session fixes and all account models offered to every ACP client",
                        "Several Windows fixes for CRLF edits, UTF-8 output, and MCP child processes"
                      ],
                      "counts": {
                        "improvement": 3,
                        "performance": 1,
                        "security": 1,
                        "fix": 7
                      },
                      "has_breaking": false,
                      "has_security": true,
                      "changes": [
                        {
                          "id": "antigravity-cli@1.5.1#c1",
                          "kind": "improvement",
                          "title": "agy acp offers all account models to every ACP client",
                          "areas": [
                            "acp"
                          ],
                          "evidence": "Changed agy acp to offer every model available to your account to every ACP client, where previously only a fixed list of editors were offered models other than Gemini.",
                          "confidence": 0.85
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c2",
                          "kind": "improvement",
                          "title": "/config tabs renamed to TUI and Remote Agent in remote sessions",
                          "areas": [
                            "config",
                            "remote-agent"
                          ],
                          "evidence": "Changed the tabs in /config during --remote-agent sessions from Local and Remote to TUI and Remote Agent",
                          "confidence": 0.85
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c3",
                          "kind": "performance",
                          "title": "Agent moves on faster after command exits with background process holding output",
                          "areas": [
                            "terminal"
                          ],
                          "evidence": "Improved how quickly the agent moves on after a terminal command exits while a background process it started still holds the command's output open, which now takes at most about 1 second instead of 5.",
                          "confidence": 0.9
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c4",
                          "kind": "improvement",
                          "title": "Blocked subagent rows name the tool they are waiting on",
                          "areas": [
                            "subagents",
                            "tui"
                          ],
                          "evidence": "Improved subagent rows above the prompt so a subagent that is blocked waiting on you names the tool it is waiting on, such as Blocked · AskQuestion, instead of Blocked · Processing....",
                          "confidence": 0.9
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c5",
                          "kind": "security",
                          "title": "Plugin OAuth tokens only substituted in Authorization header in sandbox",
                          "areas": [
                            "sandbox",
                            "plugins",
                            "oauth"
                          ],
                          "evidence": "a plugin's real token now replaces its stand-in only in a request's Authorization header, so a command can no longer get a website to echo the real token back by sending the stand-in in another header or in the URL.",
                          "confidence": 0.92
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c6",
                          "kind": "fix",
                          "title": "Fixed several agy acp session bugs with prompts, cancellation, and notifications",
                          "areas": [
                            "acp"
                          ],
                          "evidence": "Fixed several agy acp session bugs: closing, reloading, or resuming a session while a prompt runs now ends that prompt as cancelled instead of leaving it hanging, cancelling a prompt no longer also stops the next prompt sent right after it, session/update notifications no longer arrive after the session/prompt reply for that prompt, and permission requests and question forms now close when they are answered elsewhere or their prompt ends, instead of blocking later prompts or receiving their answers.",
                          "confidence": 0.9
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c7",
                          "kind": "fix",
                          "title": "File edits on Windows now work with CRLF line endings",
                          "areas": [
                            "windows",
                            "editing"
                          ],
                          "evidence": "Fixed file edits on Windows failing with target content not found in files that use CRLF line endings, so edits now match whichever line endings the file uses and the lines they insert keep the file's line endings.",
                          "confidence": 0.92
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c8",
                          "kind": "fix",
                          "title": "Windows agent commands handle non-ASCII output correctly",
                          "areas": [
                            "windows",
                            "terminal"
                          ],
                          "evidence": "Fixed agent-run commands on Windows failing or returning garbled text when their output contains non-ASCII characters, by running Python in UTF-8 mode (PYTHONUTF8=1, unless you have set PYTHONUTF8 yourself) and switching PowerShell's output encoding to UTF-8.",
                          "confidence": 0.92
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c9",
                          "kind": "fix",
                          "title": "Stdio MCP servers on Windows no longer leave child processes running",
                          "areas": [
                            "windows",
                            "mcp",
                            "plugins"
                          ],
                          "evidence": "Fixed stdio MCP servers on Windows leaving their child processes running after the server stops, which could lock plugin folders and make plugin upgrades fail because the files were in use.",
                          "confidence": 0.92
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c10",
                          "kind": "fix",
                          "title": "agy plugin commands available with ADC or enterprise gateway sign-in",
                          "areas": [
                            "plugins",
                            "auth"
                          ],
                          "evidence": "Fixed agy plugin commands being unavailable, with no plugin marketplaces listed, when you sign in with Application Default Credentials (AGYADCAUTH) or through an enterprise model gateway.",
                          "confidence": 0.9
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c11",
                          "kind": "fix",
                          "title": "Built-in browser agent no longer listed as a conversation starter",
                          "areas": [
                            "subagents",
                            "browser"
                          ],
                          "evidence": "Fixed the built-in browser agent being listed among the agents you can start a conversation with, since it is meant to run only as a subagent, which it still does.",
                          "confidence": 0.9
                        },
                        {
                          "id": "antigravity-cli@1.5.1#c12",
                          "kind": "fix",
                          "title": "Copy-on-select and /copy fixed inside GNU screen",
                          "areas": [
                            "tui",
                            "clipboard"
                          ],
                          "evidence": "Fixed copy-on-select and /copy inside GNU screen, so copied text now reaches your clipboard and long selections no longer leave stray characters in the terminal.",
                          "confidence": 0.92
                        }
                      ],
                      "notes": {
                        "format": "markdown",
                        "raw": "- Changed agy acp to offer every model available to your account to every ACP client, where previously only a fixed list of editors were offered models other than Gemini. - Changed the tabs in /config during --remote-agent sessions from Local and Remote to TUI and Remote Agent, so it is clear that one configures the terminal UI and the other the remote agent; the settings on each tab are unchanged. - Improved how quickly the agent moves on after a terminal command exits while a background process it started still holds the command's output open, which now takes at most about 1 second instead of 5. - Improved subagent rows above the prompt so a subagent that is blocked waiting on you names the tool it is waiting on, such as Blocked · AskQuestion, instead of Blocked · Processing.... - Improved how plugin OAuth credentials are protected in the terminal sandbox: a plugin's real token now replaces its stand-in only in a request's Authorization header, so a command can no longer get a website to echo the real token back by sending the stand-in in another header or in the URL. - Fixed several agy acp session bugs: closing, reloading, or resuming a session while a prompt runs now ends that prompt as cancelled instead of leaving it hanging, cancelling a prompt no longer also stops the next prompt sent right after it, session/update notifications no longer arrive after the session/prompt reply for that prompt, and permission requests and question forms now close when they are answered elsewhere or their prompt ends, instead of blocking later prompts or receiving their answers. - Fixed file edits on Windows failing with target content not found in files that use CRLF line endings, so edits now match whichever line endings the file uses and the lines they insert keep the file's line endings. - Fixed agent-run commands on Windows failing or returning garbled text when their output contains non-ASCII characters, by running Python in UTF-8 mode (PYTHONUTF8=1, unless you have set PYTHONUTF8 yourself) and switching PowerShell's output encoding to UTF-8. - Fixed stdio MCP servers on Windows leaving their child processes running after the server stops, which could lock plugin folders and make plugin upgrades fail because the files were in use. - Fixed agy plugin commands being unavailable, with no plugin marketplaces listed, when you sign in with Application Default Credentials (AGYADCAUTH) or through an enterprise model gateway. - Fixed the built-in browser agent being listed among the agents you can start a conversation with, since it is meant to run only as a subagent, which it still does. - Fixed copy-on-select and /copy inside GNU screen, so copied text now reaches your clipboard and long selections no longer leave stray characters in the terminal.",
                        "raw_sha256": "e52edd3bab8ce9a57d255a9b90408546ca311c5aeb44c7fba7e8d7604d251651",
                        "truncated": false
                      },
                      "ai": {
                        "extraction_model": "claude-sonnet-5-5",
                        "prompt_version": "changes-v3",
                        "marketing_summary": "Antigravity CLI 1.5.1 is here: every model on your account now works in any ACP client, faster command wrap-ups, clearer blocked subagents, and a batch of Windows and session fixes. Curious what else changed?",
                        "abstract_model": "claude-haiku-5-5"
                      },
                      "provenance": {
                        "source": "pipeline",
                        "extracted_at": "2026-11-05T08:11:17.326Z"
                      },
                      "infographicUrl": "/images/infographics/antigravity-cli-1.5.1-2026-11-05-1x1.jpg",
                      "infographicUrlDisplay": "/images/infographics/antigravity-cli-1.5.1-2026-11-05-1x1-display.jpg",
                      "infographicText": {
                        "chars": 619,
                        "words": 97
                      },
                      "infographicSource": {
                        "origin": "whats-changed-api",
                        "change_ids": [
                          "antigravity-cli@1.5.1#c5",
                          "antigravity-cli@1.5.1#c4",
                          "antigravity-cli@1.5.1#c1",
                          "antigravity-cli@1.5.1#c2",
                          "antigravity-cli@1.5.1#c3",
                          "antigravity-cli@1.5.1#c7"
                        ],
                        "provider": "nano-banana",
                        "model": "gemini-3-pro-image-preview",
                        "generated_at": "2026-11-05T08:12:42.113Z"
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/data/feature-matrix.json": {
      "get": {
        "summary": "Feature comparison matrix",
        "description": "Feature-by-feature comparison across all tracked tools. Categories: Core Editing, Terminal Integration, MCP Support, IDE Integrations, Agentic Features.",
        "operationId": "getFeatureMatrix",
        "responses": {
          "200": {
            "description": "Feature matrix dataset",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureMatrixResponse"
                }
              }
            }
          }
        }
      }
    },
    "/data/mechanics.json": {
      "get": {
        "summary": "Behaviors and mechanics taxonomy",
        "description": "Human-curated map from product behaviors to the machinery underneath named features (why a capability copied, not just that it did).",
        "operationId": "getMechanicsTaxonomy",
        "responses": {
          "200": {
            "description": "Mechanics taxonomy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/data/blog/posts.json": {
      "get": {
        "summary": "Blog posts index",
        "description": "Index of all published blog posts including weekly digests, monthly comparisons, and quarterly deep dives.",
        "operationId": "getBlogPosts",
        "responses": {
          "200": {
            "description": "Blog posts list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlogPostsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/feeds/{tool}.xml": {
      "get": {
        "summary": "Per-tool RSS 2.0 feed",
        "description": "The 50 most recent releases for one tool in RSS 2.0 format. Use a tool ID (e.g. claude-code) or \"all\" for the combined feed. Also available as JSON Feed 1.1 at /feeds/{tool}.json.",
        "operationId": "getToolRssFeed",
        "parameters": [
          {
            "name": "tool",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolIdOrAll"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "RSS feed",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/badge/{tool}.json": {
      "get": {
        "summary": "Version badge (shields.io endpoint schema)",
        "description": "Latest tracked version of a tool as a shields.io endpoint badge. Embed via https://img.shields.io/endpoint?url=... — a self-rendered SVG is also available at /badge/{tool}.svg.",
        "operationId": "getVersionBadge",
        "parameters": [
          {
            "name": "tool",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/ToolId"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "shields.io endpoint badge JSON",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "schemaVersion": {
                      "type": "integer",
                      "examples": [
                        1
                      ]
                    },
                    "label": {
                      "type": "string",
                      "examples": [
                        "Claude Code"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "examples": [
                        "v2.1.73"
                      ]
                    },
                    "color": {
                      "type": "string",
                      "examples": [
                        "D97706"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/feed.xml": {
      "get": {
        "summary": "RSS 2.0 feed",
        "description": "The 50 most recent releases in RSS 2.0 format.",
        "operationId": "getRssFeed",
        "responses": {
          "200": {
            "description": "RSS feed",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/feed.json": {
      "get": {
        "summary": "JSON Feed 1.1",
        "description": "The 50 most recent releases in JSON Feed 1.1 format.",
        "operationId": "getJsonFeed",
        "responses": {
          "200": {
            "description": "JSON Feed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonFeedResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Release": {
        "title": "Release",
        "type": "object",
        "description": "A tracked release. Legacy (pre-intelligence_since) rows have changes_available: false, null has_breaking/has_security and no changes/counts; use summary when abstract is absent.",
        "required": [
          "id",
          "tool",
          "version",
          "date",
          "type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "examples": [
              "claude-code-2.1.183"
            ]
          },
          "tool": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "toolDisplayName": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "datePrecision": {
            "type": "string",
            "enum": [
              "second",
              "minute",
              "day",
              "unknown"
            ]
          },
          "detected_at": {
            "type": "string",
            "format": "date-time",
            "description": "When Havoptic first saw the release"
          },
          "type": {
            "type": "string",
            "enum": [
              "release",
              "prerelease"
            ]
          },
          "bump": {
            "type": "string",
            "enum": [
              "major",
              "minor",
              "patch",
              "unknown"
            ],
            "description": "Computed semver bump (API only)"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Upstream source (per-version when derivable)"
          },
          "summary": {
            "type": "string",
            "description": "Marketing-tone AI summary (legacy display copy)"
          },
          "fullNotes": {
            "type": "string",
            "description": "Raw release notes"
          },
          "abstract": {
            "type": "string",
            "description": "Neutral summary (enriched releases only)"
          },
          "highlights": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "changes_available": {
            "type": "boolean"
          },
          "has_breaking": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "has_security": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "counts": {
            "type": "object",
            "propertyNames": {
              "enum": [
                "feature",
                "fix",
                "breaking",
                "deprecation",
                "security",
                "improvement",
                "removal",
                "performance",
                "model",
                "pricing",
                "policy"
              ]
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": 0
            }
          },
          "changes": {
            "type": "array",
            "description": "Typed change items (only with ?expand=changes on enriched releases)",
            "items": {
              "type": "object",
              "required": [
                "id",
                "kind",
                "title",
                "evidence",
                "confidence"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "`{tool}@{version}#c{n}`"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "feature",
                    "fix",
                    "breaking",
                    "deprecation",
                    "security",
                    "improvement",
                    "removal",
                    "performance",
                    "model",
                    "pricing",
                    "policy"
                  ]
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "areas": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "evidence": {
                  "type": "string",
                  "description": "Exact quote from the raw release notes"
                },
                "confidence": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                },
                "review": {
                  "type": "string",
                  "enum": [
                    "auto",
                    "verified",
                    "disputed"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "notes": {
            "type": "object",
            "properties": {
              "format": {
                "type": "string",
                "enum": [
                  "markdown",
                  "plain"
                ]
              },
              "raw": {
                "type": "string"
              },
              "raw_sha256": {
                "type": "string"
              },
              "truncated": {
                "type": "boolean"
              }
            },
            "additionalProperties": true
          },
          "ai": {
            "type": "object",
            "properties": {
              "marketing_summary": {
                "type": "string"
              },
              "abstract_model": {
                "type": "string"
              },
              "extraction_model": {
                "type": "string"
              },
              "prompt_version": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "quality": {
            "type": "object",
            "properties": {
              "extraction_status": {
                "type": "string",
                "enum": [
                  "legacy",
                  "pending",
                  "complete",
                  "failed",
                  "skipped_no_notes",
                  "sample",
                  "backfill"
                ]
              },
              "notes_available": {
                "type": "boolean"
              },
              "review": {
                "type": "string",
                "enum": [
                  "auto",
                  "verified",
                  "disputed"
                ]
              }
            },
            "additionalProperties": true
          },
          "infographicUrl": {
            "type": "string",
            "format": "uri",
            "description": "1:1 original"
          },
          "infographicUrl16x9": {
            "type": "string",
            "format": "uri"
          },
          "infographicUrl4x5": {
            "type": "string",
            "format": "uri"
          },
          "infographicUrl9x16": {
            "type": "string",
            "format": "uri"
          },
          "infographicUrlDisplay": {
            "type": "string",
            "format": "uri",
            "description": "1:1 display variant (≤1200px)"
          },
          "infographicUrl16x9Display": {
            "type": "string",
            "format": "uri"
          },
          "infographicUrl4x5Display": {
            "type": "string",
            "format": "uri"
          },
          "infographicUrl9x16Display": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "ReleaseSummary": {
        "title": "ReleaseSummary",
        "description": "A release as returned in list endpoints (offset mode omits fullNotes). With ?fields=… the item is a sparse projection of these properties.",
        "$ref": "#/components/schemas/Release"
      },
      "ChangeItem": {
        "title": "ChangeItem",
        "type": "object",
        "description": "One typed change extracted from an enriched release (evidence-gated).",
        "required": [
          "id",
          "kind",
          "title",
          "evidence",
          "confidence",
          "release_id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "`{tool}@{version}#c{n}`"
          },
          "kind": {
            "type": "string",
            "enum": [
              "feature",
              "fix",
              "breaking",
              "deprecation",
              "security",
              "improvement",
              "removal",
              "performance",
              "model",
              "pricing",
              "policy"
            ]
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "areas": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidence": {
            "type": "string",
            "description": "Exact quote from the raw release notes"
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "review": {
            "type": "string",
            "enum": [
              "auto",
              "verified",
              "disputed"
            ]
          },
          "release_id": {
            "type": "string"
          },
          "version": {
            "type": "string",
            "description": "Release version (upgrade reports)"
          },
          "product": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "enum": [
                  "claude-code",
                  "openai-codex",
                  "cursor",
                  "gemini-cli",
                  "kiro",
                  "github-copilot",
                  "windsurf",
                  "antigravity-cli",
                  "grok-build",
                  "cline",
                  "opencode",
                  "zed",
                  "factory-droid",
                  "devin",
                  "lovable",
                  "amp",
                  "copilot-vscode",
                  "replit-agent",
                  "bolt",
                  "v0",
                  "openai-platform",
                  "anthropic-api",
                  "gemini-api",
                  "xai-api",
                  "mistral-api",
                  "deepseek-api",
                  "amazon-bedrock",
                  "gemini-agent-platform",
                  "mcp-spec",
                  "openai-agents-python",
                  "openai-agents-js",
                  "claude-agent-sdk-python",
                  "claude-agent-sdk-typescript",
                  "vercel-ai-sdk",
                  "langgraph-python",
                  "langgraph-js",
                  "llamaindex",
                  "crewai",
                  "mastra",
                  "cloudflare-agents-sdk",
                  "ollama",
                  "vllm",
                  "lm-studio",
                  "huggingface-transformers"
                ]
              },
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "tool": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "Product": {
        "title": "Product",
        "type": "object",
        "description": "A tracked product (tool) from packages/core/registry.json. GET /api/v1/tools/{id} adds latest_release, latest_prerelease, cadence, health and sources.",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "object": {
            "const": "product"
          },
          "id": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "name": {
            "type": "string"
          },
          "vendor_id": {
            "type": "string",
            "enum": [
              "anthropic",
              "openai",
              "anysphere",
              "google",
              "amazon",
              "github",
              "cognition",
              "spacexai",
              "cline",
              "anomaly",
              "zed-industries",
              "factory",
              "lovable",
              "sourcegraph",
              "replit",
              "stackblitz",
              "vercel",
              "mistral",
              "deepseek",
              "modelcontextprotocol",
              "langchain",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare",
              "ollama",
              "vllm",
              "element-labs",
              "huggingface"
            ]
          },
          "vendor": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "id",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "enum": [
                  "anthropic",
                  "openai",
                  "anysphere",
                  "google",
                  "amazon",
                  "github",
                  "cognition",
                  "spacexai",
                  "cline",
                  "anomaly",
                  "zed-industries",
                  "factory",
                  "lovable",
                  "sourcegraph",
                  "replit",
                  "stackblitz",
                  "vercel",
                  "mistral",
                  "deepseek",
                  "modelcontextprotocol",
                  "langchain",
                  "llamaindex",
                  "crewai",
                  "mastra",
                  "cloudflare",
                  "ollama",
                  "vllm",
                  "element-labs",
                  "huggingface"
                ]
              },
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "category": {
            "type": "string",
            "enum": [
              "coding-agent-cli",
              "ide",
              "ide-extension",
              "model-api",
              "agent-sdk",
              "framework",
              "infra",
              "hosted-agent",
              "protocol"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "deprecated",
              "renamed"
            ]
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "formerly": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "release_count": {
            "type": "integer",
            "minimum": 0
          },
          "first_tracked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "latest_release": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "id",
              "version",
              "published_at"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "published_at": {
                "type": "string",
                "format": "date-time"
              },
              "type": {
                "type": "string",
                "enum": [
                  "release",
                  "prerelease"
                ]
              },
              "abstract": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Neutral summary (enriched releases only)"
              }
            },
            "additionalProperties": true,
            "description": "Newest stable release"
          },
          "latest_prerelease": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "id",
              "version",
              "published_at"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "published_at": {
                "type": "string",
                "format": "date-time"
              },
              "type": {
                "type": "string",
                "enum": [
                  "release",
                  "prerelease"
                ]
              },
              "abstract": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Neutral summary (enriched releases only)"
              }
            },
            "additionalProperties": true,
            "description": "Newest prerelease"
          },
          "cadence": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "releases_last_7_days": {
                "type": "integer",
                "minimum": 0
              },
              "releases_last_30_days": {
                "type": "integer",
                "minimum": 0
              },
              "releases_last_90_days": {
                "type": "integer",
                "minimum": 0
              },
              "average_days_between_releases": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "last_release_at": {
                "type": "string",
                "format": "date-time"
              }
            },
            "additionalProperties": true
          },
          "health": {
            "type": "string",
            "enum": [
              "ok",
              "stale",
              "hard",
              "excluded",
              "no-history",
              "unknown"
            ],
            "description": "Source-health status (data/status.json)"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceStatus"
            }
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "Vendor": {
        "title": "Vendor",
        "type": "object",
        "required": [
          "object",
          "id",
          "name"
        ],
        "properties": {
          "object": {
            "const": "vendor"
          },
          "id": {
            "type": "string",
            "enum": [
              "anthropic",
              "openai",
              "anysphere",
              "google",
              "amazon",
              "github",
              "cognition",
              "spacexai",
              "cline",
              "anomaly",
              "zed-industries",
              "factory",
              "lovable",
              "sourcegraph",
              "replit",
              "stackblitz",
              "vercel",
              "mistral",
              "deepseek",
              "modelcontextprotocol",
              "langchain",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare",
              "ollama",
              "vllm",
              "element-labs",
              "huggingface"
            ]
          },
          "name": {
            "type": "string"
          },
          "product_count": {
            "type": "integer",
            "minimum": 0
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "UpgradeReport": {
        "title": "UpgradeReport",
        "type": "object",
        "required": [
          "object",
          "product_id",
          "from",
          "to",
          "release_count",
          "breaking",
          "deprecations",
          "sections",
          "meta"
        ],
        "properties": {
          "object": {
            "const": "upgrade_report"
          },
          "product_id": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "release_count": {
            "type": "integer",
            "minimum": 0
          },
          "breaking": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeItem"
            }
          },
          "deprecations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeItem"
            }
          },
          "sections": {
            "type": "object",
            "properties": {
              "features": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ChangeItem"
                }
              },
              "fixes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ChangeItem"
                }
              },
              "security": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ChangeItem"
                }
              }
            },
            "additionalProperties": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/ChangeItem"
              }
            }
          },
          "migration_summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta",
            "type": "object",
            "required": [
              "enriched_release_count",
              "legacy_release_count",
              "changes_available"
            ],
            "properties": {
              "enriched_release_count": {
                "type": "integer",
                "minimum": 0
              },
              "legacy_release_count": {
                "type": "integer",
                "minimum": 0
              },
              "changes_available": {
                "type": "boolean"
              }
            }
          }
        },
        "additionalProperties": true
      },
      "Digest": {
        "title": "Digest",
        "type": "object",
        "required": [
          "object",
          "since",
          "items",
          "meta"
        ],
        "properties": {
          "object": {
            "const": "digest"
          },
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeItem"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta",
            "type": "object",
            "required": [
              "total_items",
              "truncated",
              "legacy_release_count"
            ],
            "properties": {
              "total_items": {
                "type": "integer",
                "minimum": 0
              },
              "truncated": {
                "type": "boolean"
              },
              "legacy_release_count": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        },
        "additionalProperties": true
      },
      "SearchResults": {
        "title": "SearchResults",
        "type": "object",
        "required": [
          "object",
          "query",
          "releases",
          "changes",
          "snippets"
        ],
        "properties": {
          "object": {
            "const": "search_results"
          },
          "query": {
            "type": "string"
          },
          "releases": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "tool",
                "version",
                "date"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "tool": {
                  "type": "string",
                  "enum": [
                    "claude-code",
                    "openai-codex",
                    "cursor",
                    "gemini-cli",
                    "kiro",
                    "github-copilot",
                    "windsurf",
                    "antigravity-cli",
                    "grok-build",
                    "cline",
                    "opencode",
                    "zed",
                    "factory-droid",
                    "devin",
                    "lovable",
                    "amp",
                    "copilot-vscode",
                    "replit-agent",
                    "bolt",
                    "v0",
                    "openai-platform",
                    "anthropic-api",
                    "gemini-api",
                    "xai-api",
                    "mistral-api",
                    "deepseek-api",
                    "amazon-bedrock",
                    "gemini-agent-platform",
                    "mcp-spec",
                    "openai-agents-python",
                    "openai-agents-js",
                    "claude-agent-sdk-python",
                    "claude-agent-sdk-typescript",
                    "vercel-ai-sdk",
                    "langgraph-python",
                    "langgraph-js",
                    "llamaindex",
                    "crewai",
                    "mastra",
                    "cloudflare-agents-sdk",
                    "ollama",
                    "vllm",
                    "lm-studio",
                    "huggingface-transformers"
                  ]
                },
                "version": {
                  "type": "string"
                },
                "summary": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "format": "date-time"
                }
              },
              "additionalProperties": true
            }
          },
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeItem"
            }
          },
          "snippets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "List": {
        "title": "List",
        "type": "object",
        "description": "Generic list envelope. Cursor-paginated lists add has_more + next_cursor.",
        "required": [
          "object",
          "data"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "ProblemDetails": {
        "title": "ProblemDetails",
        "type": "object",
        "description": "RFC 9457 problem details (Content-Type: application/problem+json).",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "examples": [
              "https://www.havoptic.com/docs/errors/invalid_parameter"
            ]
          },
          "title": {
            "type": "string",
            "examples": [
              "Invalid parameter"
            ]
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string"
          },
          "param": {
            "type": "string",
            "description": "Offending query/path parameter"
          },
          "instance": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "ResponseMeta": {
        "title": "ResponseMeta",
        "type": "object",
        "description": "Response metadata carried on every v1 envelope.",
        "required": [
          "dataset_updated_at",
          "api_version"
        ],
        "properties": {
          "dataset_updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "api_version": {
            "type": "string",
            "description": "Date-stamped Havoptic-Version, e.g. 2026-11-01"
          }
        },
        "additionalProperties": true
      },
      "ApiChangelog": {
        "title": "ApiChangelog",
        "type": "object",
        "description": "The public API’s own changelog, newest first.",
        "required": [
          "object",
          "data",
          "meta"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangelogEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "ChangelogEntry": {
        "title": "ChangelogEntry",
        "type": "object",
        "required": [
          "id",
          "date",
          "havoptic_version",
          "title",
          "summary",
          "breaking"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "havoptic_version": {
            "type": "string",
            "description": "Havoptic-Version (date-stamped API version)"
          },
          "phase": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "breaking": {
            "type": "boolean"
          },
          "changes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "references": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "kind",
                "number",
                "url"
              ],
              "properties": {
                "kind": {
                  "enum": [
                    "pr",
                    "issue"
                  ]
                },
                "number": {
                  "type": "integer"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "ApiStatus": {
        "title": "ApiStatus",
        "type": "object",
        "description": "Dataset and per-source freshness so agents can judge staleness.",
        "required": [
          "object",
          "status",
          "dataset_updated_at",
          "intelligence_since",
          "last_ingest_at",
          "sources",
          "meta"
        ],
        "properties": {
          "object": {
            "const": "status"
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded",
              "unknown"
            ]
          },
          "dataset_updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "intelligence_since": {
            "type": "string",
            "format": "date-time",
            "description": "Typed-change cutover; older releases are legacy"
          },
          "last_ingest_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last hourly fetch observed by source-health"
          },
          "snapshot_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the source-health snapshot was written"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceStatus"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "SourceStatus": {
        "title": "SourceStatus",
        "type": "object",
        "required": [
          "product_id",
          "status",
          "last_success_at",
          "last_error",
          "last_release_at"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "stale",
              "hard",
              "excluded",
              "no-history",
              "unknown"
            ]
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last hourly run that parsed > 0 items"
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the source is failing/stale (null when ok)"
          },
          "last_release_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Newest release on file for this product"
          },
          "stale_threshold_days": {
            "type": [
              "integer",
              "null"
            ]
          },
          "consecutive_failures": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": true
      },
      "CadenceStats": {
        "title": "CadenceStats",
        "type": "object",
        "description": "Release cadence for one tool (GET /api/v1/tools/{id}/cadence). `window` only with ?window=.",
        "required": [
          "tool",
          "totalReleases",
          "releasesLast7Days",
          "releasesLast30Days",
          "releasesLast90Days",
          "lastReleaseAt"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "enum": [
              "claude-code",
              "openai-codex",
              "cursor",
              "gemini-cli",
              "kiro",
              "github-copilot",
              "windsurf",
              "antigravity-cli",
              "grok-build",
              "cline",
              "opencode",
              "zed",
              "factory-droid",
              "devin",
              "lovable",
              "amp",
              "copilot-vscode",
              "replit-agent",
              "bolt",
              "v0",
              "openai-platform",
              "anthropic-api",
              "gemini-api",
              "xai-api",
              "mistral-api",
              "deepseek-api",
              "amazon-bedrock",
              "gemini-agent-platform",
              "mcp-spec",
              "openai-agents-python",
              "openai-agents-js",
              "claude-agent-sdk-python",
              "claude-agent-sdk-typescript",
              "vercel-ai-sdk",
              "langgraph-python",
              "langgraph-js",
              "llamaindex",
              "crewai",
              "mastra",
              "cloudflare-agents-sdk",
              "ollama",
              "vllm",
              "lm-studio",
              "huggingface-transformers"
            ]
          },
          "toolDisplayName": {
            "type": "string"
          },
          "totalReleases": {
            "type": "integer",
            "minimum": 0
          },
          "releasesLast7Days": {
            "type": "integer",
            "minimum": 0
          },
          "releasesLast30Days": {
            "type": "integer",
            "minimum": 0
          },
          "releasesLast90Days": {
            "type": "integer",
            "minimum": 0
          },
          "averageDaysBetweenReleases": {
            "type": [
              "number",
              "null"
            ]
          },
          "lastReleaseAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastRelease": {
            "type": "object",
            "additionalProperties": true
          },
          "pipelineMetrics": {
            "type": "object",
            "additionalProperties": true
          },
          "window": {
            "type": "object",
            "required": [
              "window",
              "days",
              "since",
              "releases",
              "previous_releases",
              "delta"
            ],
            "properties": {
              "window": {
                "type": "string",
                "enum": [
                  "7d",
                  "30d",
                  "90d"
                ]
              },
              "days": {
                "type": "integer",
                "minimum": 1
              },
              "since": {
                "type": "string",
                "format": "date-time"
              },
              "releases": {
                "type": "integer",
                "minimum": 0
              },
              "previous_releases": {
                "type": "integer",
                "minimum": 0,
                "description": "Releases in the equal-length window before"
              },
              "delta": {
                "type": "integer"
              },
              "average_days_between_releases": {
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "Comparison": {
        "title": "Comparison",
        "type": "object",
        "description": "N-way tool comparison (2–4 tools), shared with the MCP compare_tools tool. Sections appear per `aspects`. For exactly two tools the legacy `comparison` object is also returned.",
        "required": [
          "object",
          "tools",
          "aspects",
          "names",
          "human_urls"
        ],
        "properties": {
          "object": {
            "const": "comparison"
          },
          "tools": {
            "type": "array",
            "minItems": 2,
            "maxItems": 4,
            "items": {
              "type": "string",
              "enum": [
                "claude-code",
                "openai-codex",
                "cursor",
                "gemini-cli",
                "kiro",
                "github-copilot",
                "windsurf",
                "antigravity-cli",
                "grok-build",
                "cline",
                "opencode",
                "zed",
                "factory-droid",
                "devin",
                "lovable",
                "amp",
                "copilot-vscode",
                "replit-agent",
                "bolt",
                "v0",
                "openai-platform",
                "anthropic-api",
                "gemini-api",
                "xai-api",
                "mistral-api",
                "deepseek-api",
                "amazon-bedrock",
                "gemini-agent-platform",
                "mcp-spec",
                "openai-agents-python",
                "openai-agents-js",
                "claude-agent-sdk-python",
                "claude-agent-sdk-typescript",
                "vercel-ai-sdk",
                "langgraph-python",
                "langgraph-js",
                "llamaindex",
                "crewai",
                "mastra",
                "cloudflare-agents-sdk",
                "ollama",
                "vllm",
                "lm-studio",
                "huggingface-transformers"
              ]
            }
          },
          "aspects": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "cadence",
                "features",
                "recent_changes",
                "verdict"
              ]
            }
          },
          "names": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "cadence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CadenceStats"
            }
          },
          "feature_differences": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "feature",
                "support"
              ],
              "properties": {
                "feature": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "support": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "boolean"
                  }
                }
              },
              "additionalProperties": true
            }
          },
          "feature_parity_count": {
            "type": "integer",
            "minimum": 0
          },
          "recent_changes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "tool",
                "since",
                "release_count",
                "change_counts"
              ],
              "properties": {
                "tool": {
                  "type": "string",
                  "enum": [
                    "claude-code",
                    "openai-codex",
                    "cursor",
                    "gemini-cli",
                    "kiro",
                    "github-copilot",
                    "windsurf",
                    "antigravity-cli",
                    "grok-build",
                    "cline",
                    "opencode",
                    "zed",
                    "factory-droid",
                    "devin",
                    "lovable",
                    "amp",
                    "copilot-vscode",
                    "replit-agent",
                    "bolt",
                    "v0",
                    "openai-platform",
                    "anthropic-api",
                    "gemini-api",
                    "xai-api",
                    "mistral-api",
                    "deepseek-api",
                    "amazon-bedrock",
                    "gemini-agent-platform",
                    "mcp-spec",
                    "openai-agents-python",
                    "openai-agents-js",
                    "claude-agent-sdk-python",
                    "claude-agent-sdk-typescript",
                    "vercel-ai-sdk",
                    "langgraph-python",
                    "langgraph-js",
                    "llamaindex",
                    "crewai",
                    "mastra",
                    "cloudflare-agents-sdk",
                    "ollama",
                    "vllm",
                    "lm-studio",
                    "huggingface-transformers"
                  ]
                },
                "since": {
                  "type": "string",
                  "format": "date-time"
                },
                "release_count": {
                  "type": "integer",
                  "minimum": 0
                },
                "change_counts": {
                  "type": "object",
                  "propertyNames": {
                    "enum": [
                      "feature",
                      "fix",
                      "breaking",
                      "deprecation",
                      "security",
                      "improvement",
                      "removal",
                      "performance",
                      "model",
                      "pricing",
                      "policy"
                    ]
                  },
                  "additionalProperties": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "latest": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true
                }
              },
              "additionalProperties": true
            }
          },
          "recent_change_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeItem"
            },
            "description": "Up to 40, breaking/security first"
          },
          "verdicts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "pair",
                "text"
              ],
              "properties": {
                "pair": {
                  "type": "array",
                  "minItems": 2,
                  "maxItems": 2,
                  "items": {
                    "type": "string",
                    "enum": [
                      "claude-code",
                      "openai-codex",
                      "cursor",
                      "gemini-cli",
                      "kiro",
                      "github-copilot",
                      "windsurf",
                      "antigravity-cli",
                      "grok-build",
                      "cline",
                      "opencode",
                      "zed",
                      "factory-droid",
                      "devin",
                      "lovable",
                      "amp",
                      "copilot-vscode",
                      "replit-agent",
                      "bolt",
                      "v0",
                      "openai-platform",
                      "anthropic-api",
                      "gemini-api",
                      "xai-api",
                      "mistral-api",
                      "deepseek-api",
                      "amazon-bedrock",
                      "gemini-agent-platform",
                      "mcp-spec",
                      "openai-agents-python",
                      "openai-agents-js",
                      "claude-agent-sdk-python",
                      "claude-agent-sdk-typescript",
                      "vercel-ai-sdk",
                      "langgraph-python",
                      "langgraph-js",
                      "llamaindex",
                      "crewai",
                      "mastra",
                      "cloudflare-agents-sdk",
                      "ollama",
                      "vllm",
                      "lm-studio",
                      "huggingface-transformers"
                    ]
                  }
                },
                "text": {
                  "type": "string"
                },
                "asOf": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "human_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "comparison": {
            "type": "object",
            "description": "Legacy two-tool comparison (unchanged shape)",
            "additionalProperties": true
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "Feature": {
        "title": "Feature",
        "type": "object",
        "description": "A tracked feature with a stable id (feature-timeline or feature-matrix featureId). `adoption` is the first-to-ship timeline (null for matrix-only features); `support` is per-tool matrix support (null for timeline-only features).",
        "required": [
          "object",
          "id",
          "name",
          "sources",
          "adoption",
          "support"
        ],
        "properties": {
          "object": {
            "const": "feature"
          },
          "id": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]*$"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "matrix_category_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "sources": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "timeline",
                "matrix"
              ]
            }
          },
          "adoption": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "leader",
              "shipped_by_count",
              "shipments"
            ],
            "properties": {
              "leader": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "shipped_by_count": {
                "type": "integer",
                "minimum": 0
              },
              "spread_days": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "shipments": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "tool",
                    "date",
                    "rank"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string"
                    },
                    "toolDisplayName": {
                      "type": "string"
                    },
                    "date": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "version": {
                      "type": "string"
                    },
                    "releaseId": {
                      "type": "string"
                    },
                    "rank": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "lagDaysFromLeader": {
                      "type": "integer",
                      "minimum": 0
                    }
                  },
                  "additionalProperties": true
                }
              }
            },
            "additionalProperties": true
          },
          "support": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "object",
              "required": [
                "supported"
              ],
              "properties": {
                "supported": {
                  "type": "boolean"
                },
                "notes": {
                  "type": "string"
                }
              },
              "additionalProperties": true
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "CadenceTrend": {
        "title": "CadenceTrend",
        "type": "object",
        "description": "Release velocity across tools for a trailing window, with a 12-week series per tool.",
        "required": [
          "object",
          "window",
          "since",
          "data"
        ],
        "properties": {
          "object": {
            "const": "cadence_trend"
          },
          "window": {
            "type": "string",
            "enum": [
              "7d",
              "30d",
              "90d"
            ]
          },
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "tool",
                "releases",
                "previous_releases",
                "delta",
                "weekly"
              ],
              "properties": {
                "tool": {
                  "type": "string",
                  "enum": [
                    "claude-code",
                    "openai-codex",
                    "cursor",
                    "gemini-cli",
                    "kiro",
                    "github-copilot",
                    "windsurf",
                    "antigravity-cli",
                    "grok-build",
                    "cline",
                    "opencode",
                    "zed",
                    "factory-droid",
                    "devin",
                    "lovable",
                    "amp",
                    "copilot-vscode",
                    "replit-agent",
                    "bolt",
                    "v0",
                    "openai-platform",
                    "anthropic-api",
                    "gemini-api",
                    "xai-api",
                    "mistral-api",
                    "deepseek-api",
                    "amazon-bedrock",
                    "gemini-agent-platform",
                    "mcp-spec",
                    "openai-agents-python",
                    "openai-agents-js",
                    "claude-agent-sdk-python",
                    "claude-agent-sdk-typescript",
                    "vercel-ai-sdk",
                    "langgraph-python",
                    "langgraph-js",
                    "llamaindex",
                    "crewai",
                    "mastra",
                    "cloudflare-agents-sdk",
                    "ollama",
                    "vllm",
                    "lm-studio",
                    "huggingface-transformers"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "releases": {
                  "type": "integer",
                  "minimum": 0
                },
                "previous_releases": {
                  "type": "integer",
                  "minimum": 0
                },
                "delta": {
                  "type": "integer"
                },
                "average_days_between_releases": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "last_release_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "weekly": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "week_start",
                      "releases"
                    ],
                    "properties": {
                      "week_start": {
                        "type": "string",
                        "format": "date"
                      },
                      "releases": {
                        "type": "integer",
                        "minimum": 0
                      }
                    },
                    "additionalProperties": true
                  }
                }
              },
              "additionalProperties": true
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "FeatureAdoption": {
        "title": "FeatureAdoption",
        "type": "object",
        "description": "Copying-trend insights from the feature timeline; available:false until it is published.",
        "required": [
          "object",
          "available",
          "data"
        ],
        "properties": {
          "object": {
            "const": "feature_adoption"
          },
          "available": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          },
          "last_updated": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "insights": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "shipped_by_count"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "category": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "leader": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "shipped_by_count": {
                  "type": "integer",
                  "minimum": 0
                },
                "spread_days": {
                  "type": [
                    "integer",
                    "null"
                  ]
                }
              },
              "additionalProperties": true
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "MechanicsCatalog": {
        "title": "MechanicsCatalog",
        "type": "object",
        "description": "Curated behaviors + mechanics taxonomy joined with feature-timeline first-ship dates.",
        "required": [
          "object",
          "available"
        ],
        "properties": {
          "object": {
            "const": "mechanics"
          },
          "available": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          },
          "lastUpdated": {
            "type": [
              "string",
              "null"
            ]
          },
          "timelineLastUpdated": {
            "type": [
              "string",
              "null"
            ]
          },
          "thesis": {
            "type": "string"
          },
          "behaviors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "additionalProperties": true
            }
          },
          "mechanics": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "behaviorIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "featureIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "features": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              },
              "additionalProperties": true
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "additionalProperties": true
      },
      "ExportManifest": {
        "title": "ExportManifest",
        "type": "object",
        "description": "GET /api/v1/export/manifest.json — the bulk export files (rows, bytes, sha256), the flat CSV/Parquet columns, the license, and the daily delta files. Rebuilt by the pipeline when the dataset changes.",
        "required": [
          "object",
          "schema_version",
          "generated_at",
          "dataset_updated_at",
          "license",
          "files",
          "columns",
          "deltas"
        ],
        "properties": {
          "object": {
            "const": "export_manifest"
          },
          "schema_version": {
            "type": "integer",
            "minimum": 1,
            "description": "Bumped on an incompatible row/column change"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "dataset_updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "api_version": {
            "type": "string"
          },
          "license": {
            "type": "object",
            "required": [
              "id",
              "url",
              "attribution"
            ],
            "properties": {
              "id": {
                "const": "CC-BY-4.0"
              },
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "attribution": {
                "type": "string"
              },
              "notice": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "citation": {
            "type": "string"
          },
          "source": {
            "type": "object",
            "properties": {
              "dataset": {
                "type": "string"
              },
              "sha256": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$"
              }
            },
            "additionalProperties": true
          },
          "files": {
            "type": "object",
            "description": "Keyed by file name (releases.json, releases.ndjson, releases.csv, releases.parquet, changes.ndjson)",
            "additionalProperties": {
              "type": "object",
              "required": [
                "path",
                "url",
                "content_type",
                "rows",
                "bytes",
                "sha256"
              ],
              "properties": {
                "path": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "content_type": {
                  "type": "string"
                },
                "row_type": {
                  "type": "string"
                },
                "rows": {
                  "type": "integer",
                  "minimum": 0
                },
                "bytes": {
                  "type": "integer",
                  "minimum": 0
                },
                "sha256": {
                  "type": "string",
                  "pattern": "^[0-9a-f]{64}$"
                }
              },
              "additionalProperties": true
            }
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "type"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "type": {
                  "enum": [
                    "STRING",
                    "BOOLEAN",
                    "INT32",
                    "TIMESTAMP"
                  ]
                },
                "description": {
                  "type": "string"
                }
              },
              "additionalProperties": true
            }
          },
          "deltas": {
            "type": "object",
            "required": [
              "baseline_at",
              "url_template",
              "files"
            ],
            "properties": {
              "description": {
                "type": "string"
              },
              "baseline_at": {
                "type": "string",
                "format": "date-time",
                "description": "Deltas exist only for changes after this time"
              },
              "url_template": {
                "type": "string"
              },
              "files": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "date",
                    "url",
                    "rows",
                    "bytes",
                    "sha256"
                  ],
                  "properties": {
                    "date": {
                      "type": "string",
                      "format": "date"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "rows": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "sha256": {
                      "type": "string",
                      "pattern": "^[0-9a-f]{64}$"
                    }
                  },
                  "additionalProperties": true
                }
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "ExportDeltaLine": {
        "title": "ExportDeltaLine",
        "type": "object",
        "description": "One line of /api/v1/export/deltas/{date}.ndjson: the latest change that UTC day to one release.",
        "required": [
          "op",
          "id",
          "changed_at"
        ],
        "properties": {
          "op": {
            "enum": [
              "upsert",
              "delete"
            ]
          },
          "id": {
            "type": "string"
          },
          "changed_at": {
            "type": "string",
            "format": "date-time"
          },
          "record": {
            "$ref": "#/components/schemas/Release"
          }
        },
        "additionalProperties": true
      },
      "ToolId": {
        "type": "string",
        "enum": [
          "claude-code",
          "openai-codex",
          "cursor",
          "gemini-cli",
          "kiro",
          "github-copilot",
          "windsurf",
          "antigravity-cli",
          "grok-build",
          "cline",
          "opencode",
          "zed",
          "factory-droid",
          "devin",
          "lovable",
          "amp",
          "copilot-vscode",
          "replit-agent",
          "bolt",
          "v0",
          "openai-platform",
          "anthropic-api",
          "gemini-api",
          "xai-api",
          "mistral-api",
          "deepseek-api",
          "amazon-bedrock",
          "gemini-agent-platform",
          "mcp-spec",
          "openai-agents-python",
          "openai-agents-js",
          "claude-agent-sdk-python",
          "claude-agent-sdk-typescript",
          "vercel-ai-sdk",
          "langgraph-python",
          "langgraph-js",
          "llamaindex",
          "crewai",
          "mastra",
          "cloudflare-agents-sdk",
          "ollama",
          "vllm",
          "lm-studio",
          "huggingface-transformers"
        ]
      },
      "ToolIdOrAll": {
        "type": "string",
        "enum": [
          "claude-code",
          "openai-codex",
          "cursor",
          "gemini-cli",
          "kiro",
          "github-copilot",
          "windsurf",
          "antigravity-cli",
          "grok-build",
          "cline",
          "opencode",
          "zed",
          "factory-droid",
          "devin",
          "lovable",
          "amp",
          "copilot-vscode",
          "replit-agent",
          "bolt",
          "v0",
          "openai-platform",
          "anthropic-api",
          "gemini-api",
          "xai-api",
          "mistral-api",
          "deepseek-api",
          "amazon-bedrock",
          "gemini-agent-platform",
          "mcp-spec",
          "openai-agents-python",
          "openai-agents-js",
          "claude-agent-sdk-python",
          "claude-agent-sdk-typescript",
          "vercel-ai-sdk",
          "langgraph-python",
          "langgraph-js",
          "llamaindex",
          "crewai",
          "mastra",
          "cloudflare-agents-sdk",
          "ollama",
          "vllm",
          "lm-studio",
          "huggingface-transformers",
          "all"
        ]
      },
      "VendorId": {
        "type": "string",
        "enum": [
          "anthropic",
          "openai",
          "anysphere",
          "google",
          "amazon",
          "github",
          "cognition",
          "spacexai",
          "cline",
          "anomaly",
          "zed-industries",
          "factory",
          "lovable",
          "sourcegraph",
          "replit",
          "stackblitz",
          "vercel",
          "mistral",
          "deepseek",
          "modelcontextprotocol",
          "langchain",
          "llamaindex",
          "crewai",
          "mastra",
          "cloudflare",
          "ollama",
          "vllm",
          "element-labs",
          "huggingface"
        ]
      },
      "ChangeKind": {
        "type": "string",
        "enum": [
          "feature",
          "fix",
          "breaking",
          "deprecation",
          "security",
          "improvement",
          "removal",
          "performance",
          "model",
          "pricing",
          "policy"
        ]
      },
      "ReleaseType": {
        "type": "string",
        "enum": [
          "release",
          "prerelease"
        ]
      },
      "ReleaseChannel": {
        "type": "string",
        "enum": [
          "stable",
          "prerelease"
        ]
      },
      "VersionBump": {
        "type": "string",
        "enum": [
          "major",
          "minor",
          "patch",
          "unknown"
        ]
      },
      "DatePrecision": {
        "type": "string",
        "enum": [
          "second",
          "minute",
          "day",
          "unknown"
        ]
      },
      "SchemaName": {
        "type": "string",
        "enum": [
          "release",
          "release_summary",
          "change",
          "product",
          "vendor",
          "upgrade_report",
          "digest",
          "search_results",
          "list",
          "problem",
          "meta",
          "changelog",
          "changelog_entry",
          "status",
          "source_status",
          "cadence",
          "comparison",
          "feature",
          "cadence_trend",
          "feature_adoption",
          "mechanics",
          "export_manifest",
          "export_delta"
        ]
      },
      "ProductCategory": {
        "type": "string",
        "enum": [
          "coding-agent-cli",
          "ide",
          "ide-extension",
          "model-api",
          "agent-sdk",
          "framework",
          "infra",
          "hosted-agent",
          "protocol"
        ]
      },
      "ProductStatusFilter": {
        "type": "string",
        "enum": [
          "active",
          "deprecated",
          "renamed",
          "all"
        ]
      },
      "CompareAspect": {
        "type": "string",
        "enum": [
          "cadence",
          "features",
          "recent_changes",
          "verdict"
        ]
      },
      "CadenceWindow": {
        "type": "string",
        "enum": [
          "7d",
          "30d",
          "90d"
        ]
      },
      "ReleaseSort": {
        "type": "string",
        "enum": [
          "-published_at",
          "published_at",
          "product"
        ]
      },
      "ReleaseExpand": {
        "type": "string",
        "enum": [
          "changes",
          "notes",
          "product"
        ]
      },
      "FeatureSource": {
        "type": "string",
        "enum": [
          "timeline",
          "matrix"
        ]
      },
      "ReleasesResponse": {
        "type": "object",
        "properties": {
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          },
          "releases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Release"
            }
          }
        }
      },
      "FeatureMatrixResponse": {
        "type": "object",
        "properties": {
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "features": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "categoryId": {
                  "type": "string"
                },
                "featureId": {
                  "type": "string"
                },
                "featureName": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "tools": {
                  "type": "object",
                  "description": "Per-tool support status keyed by tool ID",
                  "propertyNames": {
                    "enum": [
                      "claude-code",
                      "openai-codex",
                      "cursor",
                      "gemini-cli",
                      "kiro",
                      "github-copilot",
                      "windsurf",
                      "antigravity-cli",
                      "grok-build",
                      "cline",
                      "opencode",
                      "zed",
                      "factory-droid",
                      "devin",
                      "lovable",
                      "amp",
                      "copilot-vscode",
                      "replit-agent",
                      "bolt",
                      "v0",
                      "openai-platform",
                      "anthropic-api",
                      "gemini-api",
                      "xai-api",
                      "mistral-api",
                      "deepseek-api",
                      "amazon-bedrock",
                      "gemini-agent-platform",
                      "mcp-spec",
                      "openai-agents-python",
                      "openai-agents-js",
                      "claude-agent-sdk-python",
                      "claude-agent-sdk-typescript",
                      "vercel-ai-sdk",
                      "langgraph-python",
                      "langgraph-js",
                      "llamaindex",
                      "crewai",
                      "mastra",
                      "cloudflare-agents-sdk",
                      "ollama",
                      "vllm",
                      "lm-studio",
                      "huggingface-transformers"
                    ]
                  },
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "supported": {
                        "type": "boolean"
                      },
                      "notes": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "BlogPost": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "summary": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "weekly",
              "monthly",
              "quarterly",
              "deep-dive"
            ]
          }
        }
      },
      "BlogPostsResponse": {
        "type": "object",
        "properties": {
          "posts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlogPost"
            }
          }
        }
      },
      "JsonFeedResponse": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string",
            "examples": [
              "https://jsonfeed.org/version/1.1"
            ]
          },
          "title": {
            "type": "string"
          },
          "home_page_url": {
            "type": "string",
            "format": "uri"
          },
          "feed_url": {
            "type": "string",
            "format": "uri"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      }
    }
  }
}