{
  "title": "Monitor public community topics",
  "description": "Paste a public Discourse community base URL. The default returns three topic observations from Python Discussions. Reads one latest-topic JSON window per forum, with source counts and optional literal keyword evidence.",
  "type": "object",
  "schemaVersion": 1,
  "properties": {
    "communityUrls": {
      "title": "Community URLs",
      "type": "array",
      "editor": "stringList",
      "description": "Up to 10 public HTTPS community base URLs, such as https://discuss.python.org. Leave empty for that default. Paths, query strings, fragments, credentials, private networks and custom ports are rejected. No login-only forums.",
      "default": [],
      "prefill": [
        "https://discuss.python.org"
      ]
    },
    "keywords": {
      "title": "Keywords or phrases",
      "type": "array",
      "editor": "stringList",
      "description": "Optional: up to 20 literal terms (80 characters each). Matches title and tag text, ignoring case. Empty means all selected topics. This filters the returned latest-topic window; it is not whole-forum or post-text search.",
      "default": [],
      "sectionCaption": "Advanced options",
      "sectionDescription": "Keyword matching, source limits, saved comparisons and run budget."
    },
    "wholeWords": {
      "title": "Match whole words",
      "type": "boolean",
      "description": "Use Unicode letter/number boundaries. Disable for intentional substring matches. No sentiment or intent classification.",
      "default": true
    },
    "maxTopicsPerCommunity": {
      "title": "Topics inspected per community",
      "type": "integer",
      "description": "Inspect at most this many topics from the single latest.json response, in source order. The forum may return fewer, with pinned or older active topics. There is no pagination.",
      "default": 30,
      "minimum": 1,
      "maximum": 100
    },
    "comparePrevious": {
      "title": "Compare with saved observations",
      "type": "boolean",
      "description": "First run establishes a baseline. Later runs compare matching forum/topic IDs and produce changedFields and numeric deltas. Only confirmed saved rows advance history. Missing topics never establish deletion.",
      "default": false
    },
    "onlyChanges": {
      "title": "Save only new or changed topics",
      "type": "boolean",
      "description": "Also enables comparison. An unchanged run may save zero rows. Topics not saved in an earlier capped run can appear as new later.",
      "default": false
    },
    "snapshotName": {
      "title": "Comparison name",
      "type": "string",
      "editor": "textfield",
      "description": "1-80 letters, digits, underscores or hyphens. Use one sequential writer per comparison scope. Changing forums, keywords or topic-window size selects a separate baseline.",
      "default": "default"
    },
    "maxResults": {
      "title": "Maximum saved topics",
      "type": "integer",
      "description": "Global output cap across communities. The default is three. Fulfilling this cap is a bounded successful selection; later unreached communities are reported as partial coverage.",
      "default": 3,
      "minimum": 1,
      "maximum": 1000
    },
    "maxRunSeconds": {
      "title": "Run budget in seconds",
      "type": "integer",
      "description": "30-900 seconds, also bounded by platform timeout minus 25 seconds. Source requests reserve five seconds for output and have a 15-second ceiling within the remaining budget.",
      "default": 60,
      "minimum": 30,
      "maximum": 900
    }
  }
}
