online.timtinkers.bot.command

bot.timtinkers.online

Schema Diff

+43 -88

From

CID
bafyreifeewksgh3...
Indexed At
2026-04-16 21:00 UTC
View this version

To

CID
bafyreib3oa2zwsq...
Indexed At
2026-05-05 14:40 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

31 breaking changes, 28 non-breaking changes.

Breaking Changes (31)
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#commandType" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.description" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.name" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.required" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.type" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameterizedCommand" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#rngCommand" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command#simpleCommand" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.commandType" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.parameters" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.parameters:items" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.responseTemplate" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngMax" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngMin" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngParameter" }
  • RemovedVertex RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngTemplate" }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.description", kind: "prop", name: Some("description") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.name", kind: "prop", name: Some("name") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.required", kind: "prop", name: Some("required") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.type", kind: "prop", name: Some("type") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.commandType", kind: "prop", name: Some("commandType") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.parameters", kind: "prop", name: Some("parameters") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.responseTemplate", kind: "prop", name: Some("responseTemplate") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngMax", kind: "prop", name: Some("rngMax") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngMin", kind: "prop", name: Some("rngMin") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngParameter", kind: "prop", name: Some("rngParameter") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngTemplate", kind: "prop", name: Some("rngTemplate") }
  • RemovedEdge RemovedEdge { src: "online.timtinkers.bot.command:body.parameters", tgt: "online.timtinkers.bot.command:body.parameters:items", kind: "items", name: None }
  • ConstraintAdded ConstraintAdded { vertex_id: "online.timtinkers.bot.command:body.globalCooldown", sort: "minimum", value: "0" }
  • ConstraintAdded ConstraintAdded { vertex_id: "online.timtinkers.bot.command:body.userCooldown", sort: "minimum", value: "0" }
Non-Breaking Changes (28)
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command#default" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command#moderator" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command#permissionLevel" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command#streamer" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command#vip" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.globalCooldown" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.hidden" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.isReply" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.permissions" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.permissions:items" }
  • AddedVertex AddedVertex { vertex_id: "online.timtinkers.bot.command:body.userCooldown" }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.globalCooldown", kind: "prop", name: Some("globalCooldown") }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.hidden", kind: "prop", name: Some("hidden") }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.isReply", kind: "prop", name: Some("isReply") }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.permissions", kind: "prop", name: Some("permissions") }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.userCooldown", kind: "prop", name: Some("userCooldown") }
  • AddedEdge AddedEdge { src: "online.timtinkers.bot.command:body.permissions", tgt: "online.timtinkers.bot.command:body.permissions:items", kind: "items", name: None }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.description", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.name", sort: "minLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.name", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.rngTemplate", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.rngTemplate", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.response", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.response", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.required", sort: "default" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.type", sort: "enum" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.responseTemplate", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.responseTemplate", sort: "maxLength" }

Migration Guidance

Removed Elements

  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#commandType" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.description" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.name" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.required" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameter.type" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#parameterizedCommand" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#rngCommand" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command#simpleCommand" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.commandType" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.parameters" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.parameters:items" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.responseTemplate" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngMax" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngMin" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngParameter" }
  • RemovedVertex { vertex_id: "online.timtinkers.bot.command:body.rngTemplate" }

Added Elements

  • AddedVertex { vertex_id: "online.timtinkers.bot.command#default" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command#moderator" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command#permissionLevel" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command#streamer" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command#vip" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.globalCooldown" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.hidden" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.isReply" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.permissions" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.permissions:items" }
  • AddedVertex { vertex_id: "online.timtinkers.bot.command:body.userCooldown" }

Constraint Changes

  • ConstraintAdded ConstraintAdded { vertex_id: "online.timtinkers.bot.command:body.globalCooldown", sort: "minimum", value: "0" }
  • ConstraintAdded ConstraintAdded { vertex_id: "online.timtinkers.bot.command:body.userCooldown", sort: "minimum", value: "0" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.response", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.response", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.type", sort: "enum" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.rngTemplate", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.rngTemplate", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.description", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.required", sort: "default" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.name", sort: "minLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command#parameter.name", sort: "maxLength" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.responseTemplate", sort: "maxGraphemes" }
  • ConstraintRemoved ConstraintRemoved { vertex_id: "online.timtinkers.bot.command:body.responseTemplate", sort: "maxLength" }

Additional Notes

  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.description", kind: "prop", name: Some("description") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.name", kind: "prop", name: Some("name") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.required", kind: "prop", name: Some("required") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command#parameter", tgt: "online.timtinkers.bot.command#parameter.type", kind: "prop", name: Some("type") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.commandType", kind: "prop", name: Some("commandType") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.parameters", kind: "prop", name: Some("parameters") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.responseTemplate", kind: "prop", name: Some("responseTemplate") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngMax", kind: "prop", name: Some("rngMax") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngMin", kind: "prop", name: Some("rngMin") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngParameter", kind: "prop", name: Some("rngParameter") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.rngTemplate", kind: "prop", name: Some("rngTemplate") }
  • Breaking: RemovedEdge { src: "online.timtinkers.bot.command:body.parameters", tgt: "online.timtinkers.bot.command:body.parameters:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.globalCooldown", kind: "prop", name: Some("globalCooldown") }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.hidden", kind: "prop", name: Some("hidden") }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.isReply", kind: "prop", name: Some("isReply") }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.permissions", kind: "prop", name: Some("permissions") }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body", tgt: "online.timtinkers.bot.command:body.userCooldown", kind: "prop", name: Some("userCooldown") }
  • Non-breaking: AddedEdge { src: "online.timtinkers.bot.command:body.permissions", tgt: "online.timtinkers.bot.command:body.permissions:items", kind: "items", name: None }
1 1
{
2 2
  "id": "online.timtinkers.bot.command",
3 3
  "defs": {
4 +
    "vip": {
5 +
      "type": "token",
6 +
      "description": "A VIP viewer"
7 +
    },
4 8
    "main": {
5 9
      "key": "tid",
6 10
      "type": "record",
7 11
      "record": {
8 12
        "type": "object",
9 13
        "required": [
10 14
          "trigger",
11 -
          "commandType",
15 +
          "response",
12 16
          "createdAt"
13 17
        ],
14 18
        "properties": {
15 -
          "rngMax": {
16 -
            "type": "integer",
17 -
            "description": "Maximum value for RNG (inclusive, required for rngCommand type)"
19 +
          "hidden": {
20 +
            "type": "boolean",
21 +
            "description": "Whether the command is hidden from the !commands list"
18 22
          },
19 -
          "rngMin": {
20 -
            "type": "integer",
21 -
            "description": "Minimum value for RNG (inclusive, required for rngCommand type)"
23 +
          "isReply": {
24 +
            "type": "boolean",
25 +
            "description": "Whether the bot should reply to the triggering message rather than posting standalone"
22 26
          },
23 27
          "trigger": {
24 28
            "type": "string",
25 29
            "maxLength": 50,
26 30
            "minLength": 1,
27 31
            "description": "The command trigger without prefix (e.g., 'socials', 'hug', 'd6')"
28 32
          },
29 33
          "response": {
30 34
            "type": "string",
31 -
            "maxLength": 3000,
32 -
            "description": "Static response text (required for simpleCommand type)",
33 -
            "maxGraphemes": 300
35 +
            "description": "Response text supporting variable substitution ($user, $target, $arg[n], $randomNumber[min,max], etc.). Length is validated at runtime after substitution."
34 36
          },
35 37
          "createdAt": {
36 38
            "type": "string",
37 39
            "format": "datetime"
38 40
          },
39 -
          "parameters": {
41 +
          "description": {
42 +
            "type": "string",
43 +
            "maxLength": 300,
44 +
            "description": "Optional help text describing what the command does"
45 +
          },
46 +
          "permissions": {
40 47
            "type": "array",
41 48
            "items": {
42 -
              "ref": "#parameter",
49 +
              "ref": "#permissionLevel",
43 50
              "type": "ref"
44 51
            },
45 52
            "maxLength": 10,
46 -
            "minLength": 1,
47 -
            "description": "Parameter definitions (required for parameterizedCommand type)"
48 -
          },
49 -
          "commandType": {
50 -
            "ref": "#commandType",
51 -
            "type": "ref",
52 -
            "description": "The type of command (simple, parameterized, or rng)"
53 -
          },
54 -
          "description": {
55 -
            "type": "string",
56 -
            "maxLength": 300,
57 -
            "description": "Optional help text describing what the command does"
58 -
          },
59 -
          "rngTemplate": {
60 -
            "type": "string",
61 -
            "maxLength": 3000,
62 -
            "description": "Template with {result} placeholder for RNG result and optional {paramName} for input (required for rngCommand type)",
63 -
            "maxGraphemes": 300
53 +
            "description": "Roles that are allowed to use this command. If omitted, the command is available to everyone."
64 54
          },
65 -
          "rngParameter": {
66 -
            "ref": "#parameter",
67 -
            "type": "ref",
68 -
            "description": "Optional parameter definition for rngCommand type (e.g., target user for 'stinky' command)"
55 +
          "userCooldown": {
56 +
            "type": "integer",
57 +
            "minimum": 0,
58 +
            "description": "Per-user cooldown in seconds. 0 means no cooldown."
69 59
          },
70 -
          "responseTemplate": {
71 -
            "type": "string",
72 -
            "maxLength": 3000,
73 -
            "description": "Template with {paramName} placeholders (required for parameterizedCommand type)",
74 -
            "maxGraphemes": 300
60 +
          "globalCooldown": {
61 +
            "type": "integer",
62 +
            "minimum": 0,
63 +
            "description": "Global cooldown in seconds shared across all users. 0 means no cooldown."
75 64
          }
76 65
        }
77 66
      },
78 -
      "description": "Record representing a chat bot command. Commands can be simple (static response), parameterized (template-based with arguments), or RNG-based (random number generation)."
67 +
      "description": "Record representing a chat bot command. The response field supports variable substitution (e.g. $user, $target, $randomNumber[min,max]) which is resolved at runtime."
68 +
    },
69 +
    "default": {
70 +
      "type": "token",
71 +
      "description": "Any viewer (default permission level)"
79 72
    },
80 -
    "parameter": {
81 -
      "type": "object",
82 -
      "required": [
83 -
        "name",
84 -
        "type"
85 -
      ],
86 -
      "properties": {
87 -
        "name": {
88 -
          "type": "string",
89 -
          "maxLength": 30,
90 -
          "minLength": 1,
91 -
          "description": "Parameter name used in template (e.g., 'target' for {target})"
92 -
        },
93 -
        "type": {
94 -
          "enum": [
95 -
            "string",
96 -
            "handle",
97 -
            "number"
98 -
          ],
99 -
          "type": "string",
100 -
          "description": "Expected parameter type for validation"
101 -
        },
102 -
        "required": {
103 -
          "type": "boolean",
104 -
          "default": false,
105 -
          "description": "Whether this parameter must be provided"
106 -
        },
107 -
        "description": {
108 -
          "type": "string",
109 -
          "maxLength": 200,
110 -
          "description": "Help text for this parameter"
111 -
        }
112 -
      },
113 -
      "description": "Definition of a command parameter"
73 +
    "streamer": {
74 +
      "type": "token",
75 +
      "description": "The channel owner / streamer"
114 76
    },
115 -
    "rngCommand": {
77 +
    "moderator": {
116 78
      "type": "token",
117 -
      "description": "A command that generates a random number within a specified range and formats it using a template"
79 +
      "description": "A channel moderator"
118 80
    },
119 -
    "commandType": {
81 +
    "permissionLevel": {
120 82
      "type": "string",
121 83
      "knownValues": [
122 -
        "online.timtinkers.bot.command#simpleCommand",
123 -
        "online.timtinkers.bot.command#parameterizedCommand",
124 -
        "online.timtinkers.bot.command#rngCommand"
84 +
        "online.timtinkers.bot.command#streamer",
85 +
        "online.timtinkers.bot.command#moderator",
86 +
        "online.timtinkers.bot.command#vip",
87 +
        "online.timtinkers.bot.command#default"
125 88
      ]
126 -
    },
127 -
    "simpleCommand": {
128 -
      "type": "token",
129 -
      "description": "A command that returns a static response with no parameters"
130 -
    },
131 -
    "parameterizedCommand": {
132 -
      "type": "token",
133 -
      "description": "A command that accepts one or more parameters and uses a response template"
134 89
    }
135 90
  },
136 91
  "$type": "com.atproto.lexicon.schema",
137 92
  "lexicon": 1
138 93
}

Compare Other Versions

Lexicon Garden

@