{
  "openapi": "3.1.1",
  "info": {
    "title": "Wikinest Page Diff API",
    "version": "1.0.0",
    "summary": "Compare two versions of a page: added, removed and changed lines plus a unified diff.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://wikinestpagediff.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Compare two versions of a page: added, removed and changed lines plus a unified diff.",
        "description": "Compares two versions of a wiki page (or any text) line by line with the Myers algorithm, pairs replaced lines and marks the changed words inside them, counts added and removed words and writes a unified diff you can save as a patch. It is the comparison Wikinest shows in a page’s version history.\n\nMethodology:\n- Both versions are split into lines (Windows and old Mac line ends become \\n). With “ignore spaces”, runs of white space inside a line become one space and lines are trimmed before comparing.\n- The shortest edit script between the two line lists comes from Myers’ O(ND) algorithm after removing the common start and end. Deletions directly followed by insertions are paired as changed lines.\n- Inside each changed pair a second Myers diff over words, spaces and punctuation marks the changed words; added and removed words are counted from those marks and from whole added or removed lines.\n- Similarity = unchanged lines ÷ all rows of the side-by-side view. The unified diff uses the usual @@ -a,b +c,d @@ hunk headers with the chosen number of context lines.\n- Wikinest merges concurrent edits with the same line diff (a diff3-style three-way merge against the version both people started from).",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "wikinest_page_diff",
        "x-owner-app": "wikinest",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WikinestPageDiffInput"
              },
              "examples": {
                "example1": {
                  "summary": "Release checklist: status, tasks and commands changed",
                  "value": {
                    "before": "# Release checklist\n\nStatus: {status:yellow|In progress}\n\n- [x] Freeze the release branch\n- [ ] Run the smoke tests\n- [ ] Write the release notes\n\n## Commands\n```sh\ngit tag -a v2.4.0\n```\n\nAsk @[Ada] before tagging.\n",
                    "after": "# Release checklist\n\nStatus: {status:green|Done}\n\n- [x] Freeze the release branch\n- [x] Run the smoke tests\n- [x] Write the release notes\n- [x] Announce the release in #general\n\n## Commands\n```sh\ngit tag -a v2.4.0 -m \"Release 2.4.0\"\ngit push origin v2.4.0\n```\n\nAsk @[Grace] before tagging.\n"
                  }
                },
                "example2": {
                  "summary": "Same pages, one line of context, spaces ignored",
                  "value": {
                    "before": "# Release checklist\n\nStatus: {status:yellow|In progress}\n\n- [x] Freeze the release branch\n- [ ] Run the smoke tests\n- [ ] Write the release notes\n\n## Commands\n```sh\ngit tag -a v2.4.0\n```\n\nAsk @[Ada] before tagging.\n",
                    "after": "# Release checklist\n\nStatus: {status:green|Done}\n\n- [x] Freeze the release branch\n- [x] Run the smoke tests\n- [x] Write the release notes\n- [x] Announce the release in #general\n\n## Commands\n```sh\ngit tag -a v2.4.0 -m \"Release 2.4.0\"\n  git   push origin v2.4.0\n```\n\nAsk @[Grace] before tagging.\n",
                    "context": 1,
                    "ignoreWhitespace": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WikinestPageDiffResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "WikinestPageDiffInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "before": {
            "title": "Older version",
            "type": "string",
            "maxLength": 400000,
            "default": ""
          },
          "after": {
            "title": "Newer version",
            "type": "string",
            "maxLength": 400000,
            "default": ""
          },
          "context": {
            "title": "Unchanged lines around each change",
            "type": "integer",
            "minimum": 0,
            "maximum": 20,
            "default": 3
          },
          "ignoreWhitespace": {
            "title": "Ignore spaces and indentation",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "WikinestPageDiffResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}