@clowder-ai/plugin-contract 0.1.0-beta.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/dist/codegen/generate-contract.d.ts +7 -0
  2. package/dist/codegen/generate-contract.d.ts.map +1 -1
  3. package/dist/codegen/generate-contract.js +350 -19
  4. package/dist/codegen/generate-contract.js.map +1 -1
  5. package/dist/conformance/fixtures.d.ts +3 -1
  6. package/dist/conformance/fixtures.d.ts.map +1 -1
  7. package/dist/conformance/fixtures.js +2 -1
  8. package/dist/conformance/fixtures.js.map +1 -1
  9. package/dist/conformance/index.d.ts +2 -1
  10. package/dist/conformance/index.d.ts.map +1 -1
  11. package/dist/conformance/index.js +2 -1
  12. package/dist/conformance/index.js.map +1 -1
  13. package/dist/conformance/messaging-behavior-fixture.d.ts +12 -0
  14. package/dist/conformance/messaging-behavior-fixture.d.ts.map +1 -0
  15. package/dist/conformance/messaging-behavior-fixture.js +30 -0
  16. package/dist/conformance/messaging-behavior-fixture.js.map +1 -0
  17. package/dist/conformance/runner.d.ts.map +1 -1
  18. package/dist/conformance/runner.js +23 -3
  19. package/dist/conformance/runner.js.map +1 -1
  20. package/dist/conformance/stdio-harness/wire-shape.d.ts +1 -1
  21. package/dist/docx-materialization.d.ts +8 -0
  22. package/dist/docx-materialization.d.ts.map +1 -0
  23. package/dist/docx-materialization.js +19 -0
  24. package/dist/docx-materialization.js.map +1 -0
  25. package/dist/generated/contract.generated.d.ts +1665 -33
  26. package/dist/generated/contract.generated.d.ts.map +1 -1
  27. package/dist/generated/contract.generated.js +72 -3
  28. package/dist/generated/contract.generated.js.map +1 -1
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/validation/catalog.d.ts +21 -0
  34. package/dist/validation/catalog.d.ts.map +1 -0
  35. package/dist/validation/catalog.js +140 -0
  36. package/dist/validation/catalog.js.map +1 -0
  37. package/dist/validation/cloud-conversation-host.d.ts +18 -0
  38. package/dist/validation/cloud-conversation-host.d.ts.map +1 -0
  39. package/dist/validation/cloud-conversation-host.js +83 -0
  40. package/dist/validation/cloud-conversation-host.js.map +1 -0
  41. package/dist/validation/companion-bridge.d.ts +6 -0
  42. package/dist/validation/companion-bridge.d.ts.map +1 -0
  43. package/dist/validation/companion-bridge.js +198 -0
  44. package/dist/validation/companion-bridge.js.map +1 -0
  45. package/dist/validation/docx-materialization.d.ts +6 -0
  46. package/dist/validation/docx-materialization.d.ts.map +1 -0
  47. package/dist/validation/docx-materialization.js +36 -0
  48. package/dist/validation/docx-materialization.js.map +1 -0
  49. package/dist/validation/index.d.ts +9 -0
  50. package/dist/validation/index.d.ts.map +1 -1
  51. package/dist/validation/index.js +9 -0
  52. package/dist/validation/index.js.map +1 -1
  53. package/dist/validation/manifest.d.ts.map +1 -1
  54. package/dist/validation/manifest.js +324 -1
  55. package/dist/validation/manifest.js.map +1 -1
  56. package/dist/validation/members.d.ts +4 -0
  57. package/dist/validation/members.d.ts.map +1 -0
  58. package/dist/validation/members.js +11 -0
  59. package/dist/validation/members.js.map +1 -0
  60. package/dist/validation/messaging-semantic.d.ts.map +1 -1
  61. package/dist/validation/messaging-semantic.js +98 -0
  62. package/dist/validation/messaging-semantic.js.map +1 -1
  63. package/dist/validation/messaging-wire.d.ts +42 -0
  64. package/dist/validation/messaging-wire.d.ts.map +1 -0
  65. package/dist/validation/messaging-wire.js +184 -0
  66. package/dist/validation/messaging-wire.js.map +1 -0
  67. package/dist/validation/operation-rows.d.ts +25 -0
  68. package/dist/validation/operation-rows.d.ts.map +1 -0
  69. package/dist/validation/operation-rows.js +135 -0
  70. package/dist/validation/operation-rows.js.map +1 -0
  71. package/dist/validation/signals.d.ts +17 -0
  72. package/dist/validation/signals.d.ts.map +1 -0
  73. package/dist/validation/signals.js +32 -0
  74. package/dist/validation/signals.js.map +1 -0
  75. package/dist/variant.d.ts +114 -0
  76. package/dist/variant.d.ts.map +1 -0
  77. package/dist/variant.js +305 -0
  78. package/dist/variant.js.map +1 -0
  79. package/dist/wire/constants.d.ts +2 -1
  80. package/dist/wire/constants.d.ts.map +1 -1
  81. package/dist/wire/constants.js +2 -1
  82. package/dist/wire/constants.js.map +1 -1
  83. package/dist/wire/dispatch.d.ts +49 -0
  84. package/dist/wire/dispatch.d.ts.map +1 -0
  85. package/dist/wire/dispatch.js +880 -0
  86. package/dist/wire/dispatch.js.map +1 -0
  87. package/dist/wire/disposition-fixtures.d.ts +10 -0
  88. package/dist/wire/disposition-fixtures.d.ts.map +1 -1
  89. package/dist/wire/disposition-fixtures.js +661 -75
  90. package/dist/wire/disposition-fixtures.js.map +1 -1
  91. package/dist/wire/envelope.d.ts +31 -0
  92. package/dist/wire/envelope.d.ts.map +1 -1
  93. package/dist/wire/envelope.js +48 -1
  94. package/dist/wire/envelope.js.map +1 -1
  95. package/dist/wire/errors.d.ts +31 -1
  96. package/dist/wire/errors.d.ts.map +1 -1
  97. package/dist/wire/errors.js +36 -0
  98. package/dist/wire/errors.js.map +1 -1
  99. package/dist/wire/grants.d.ts +4 -4
  100. package/dist/wire/grants.js +3 -3
  101. package/dist/wire/handshake-byte-bounds.d.ts.map +1 -1
  102. package/dist/wire/handshake-byte-bounds.js +5 -2
  103. package/dist/wire/handshake-byte-bounds.js.map +1 -1
  104. package/dist/wire/handshake.d.ts +6 -0
  105. package/dist/wire/handshake.d.ts.map +1 -1
  106. package/dist/wire/handshake.js +6 -3
  107. package/dist/wire/handshake.js.map +1 -1
  108. package/dist/wire/index.d.ts +13 -6
  109. package/dist/wire/index.d.ts.map +1 -1
  110. package/dist/wire/index.js +31 -6
  111. package/dist/wire/index.js.map +1 -1
  112. package/dist/wire/lifecycle-byte-bounds.d.ts +40 -0
  113. package/dist/wire/lifecycle-byte-bounds.d.ts.map +1 -0
  114. package/dist/wire/lifecycle-byte-bounds.js +149 -0
  115. package/dist/wire/lifecycle-byte-bounds.js.map +1 -0
  116. package/dist/wire/messaging-byte-bounds.d.ts +62 -0
  117. package/dist/wire/messaging-byte-bounds.d.ts.map +1 -0
  118. package/dist/wire/messaging-byte-bounds.js +581 -0
  119. package/dist/wire/messaging-byte-bounds.js.map +1 -0
  120. package/dist/wire/registry.d.ts +63 -77
  121. package/dist/wire/registry.d.ts.map +1 -1
  122. package/dist/wire/registry.js +47 -76
  123. package/dist/wire/registry.js.map +1 -1
  124. package/dist/wire/row-shapes.d.ts +87 -70
  125. package/dist/wire/row-shapes.d.ts.map +1 -1
  126. package/dist/wire/row-shapes.js +31 -4
  127. package/dist/wire/row-shapes.js.map +1 -1
  128. package/fixtures/behavior/messaging/adversarial-invariants.json +92 -2
  129. package/fixtures/manifest/invalid/duplicate-signal-type.json +35 -0
  130. package/fixtures/manifest/invalid/icon-package-escape.json +22 -0
  131. package/fixtures/manifest/valid/localized-product-metadata.json +27 -0
  132. package/fixtures/messaging/valid/subscription-delivery.json +1 -1
  133. package/fixtures/signals/invalid/dynamic-schema-url.json +10 -0
  134. package/fixtures/signals/invalid/forbidden-raw-privacy.json +10 -0
  135. package/fixtures/signals/valid/remote-service-declaration.json +10 -0
  136. package/package.json +17 -3
  137. package/src/schemas/behavior-fixture.schema.json +903 -116
  138. package/src/schemas/catalog.schema.json +91 -0
  139. package/src/schemas/companion-bridge.schema.json +2256 -0
  140. package/src/schemas/docx-materialization.schema.json +302 -0
  141. package/src/schemas/manifest.schema.json +2276 -88
  142. package/src/schemas/messaging.schema.json +692 -41
  143. package/src/schemas/plugin-metadata.schema.json +62 -0
  144. package/src/schemas/signal.schema.json +119 -0
@@ -2,39 +2,127 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://clowder-ai.dev/schemas/manifest/v0.1",
4
4
  "title": "Clowder AI Plugin Manifest (v0.1)",
5
- "description": "Machine-readable truth source for plugin manifest (§3.4/§3.5). v0.1 covers core manifest + features + data classification. Signals/events (C-2) and schedule/state (C-3) are schema deltas in future contract versions.",
5
+ "description": "Machine-readable truth source for the current static plugin.yaml access protocol: declarations, capabilities, operation row actions, runtime dataDirectory, and contribution schemas. Runtime data paths need no separate capability; attachment readers use streams.read.",
6
6
  "x-clowder-capability-layers": {
7
- "L0": ["plugin.config.read", "plugin.state.get", "plugin.state.set"],
8
- "L1": ["messaging.send", "schedule.register", "events.publish", "messaging.appendElements"],
9
- "L2": ["onMessage", "message.event.subscribe", "secret.read", "thread.listMetadata", "thread.readContent", "memory.query", "memory.append", "memory.retrieve", "windows.create", "whisper.extend"]
7
+ "L0": [
8
+ "plugin.config.read",
9
+ "plugin.state.get",
10
+ "plugin.state.set"
11
+ ],
12
+ "L1": [
13
+ "messaging.send",
14
+ "schedule.register",
15
+ "messaging.appendElements",
16
+ "streams.read"
17
+ ],
18
+ "L2": [
19
+ "onMessage",
20
+ "message.event.subscribe",
21
+ "secret.read",
22
+ "thread.listMetadata",
23
+ "thread.readContent",
24
+ "thread.write",
25
+ "task.read",
26
+ "task.write",
27
+ "task.admitEntrusted",
28
+ "memory.query",
29
+ "memory.append",
30
+ "memory.retrieve",
31
+ "windows.create",
32
+ "whisper.extend",
33
+ "cloud.conversation.host"
34
+ ]
10
35
  },
11
36
  "x-clowder-data-class-strategies": {
12
- "cache": ["lifecycle", "retained", "ask-on-uninstall"],
13
- "ephemeral": ["lifecycle", "retained", "ask-on-uninstall"],
14
- "user-authored": ["retained", "ask-on-uninstall"],
15
- "derived-user-visible": ["retained", "ask-on-uninstall"],
16
- "relationship": ["retained", "ask-on-uninstall"],
17
- "interaction-history": ["retained", "ask-on-uninstall"]
37
+ "cache": [
38
+ "lifecycle",
39
+ "retained",
40
+ "ask-on-uninstall"
41
+ ],
42
+ "ephemeral": [
43
+ "lifecycle",
44
+ "retained",
45
+ "ask-on-uninstall"
46
+ ],
47
+ "user-authored": [
48
+ "retained",
49
+ "ask-on-uninstall"
50
+ ],
51
+ "derived-user-visible": [
52
+ "retained",
53
+ "ask-on-uninstall"
54
+ ],
55
+ "relationship": [
56
+ "retained",
57
+ "ask-on-uninstall"
58
+ ],
59
+ "interaction-history": [
60
+ "retained",
61
+ "ask-on-uninstall"
62
+ ]
18
63
  },
19
-
20
64
  "$defs": {
65
+ "PluginMember": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "required": [
69
+ "catId",
70
+ "displayName",
71
+ "defaultModel",
72
+ "available"
73
+ ],
74
+ "properties": {
75
+ "catId": {
76
+ "type": "string"
77
+ },
78
+ "displayName": {
79
+ "type": "string"
80
+ },
81
+ "defaultModel": {
82
+ "type": "string"
83
+ },
84
+ "nickname": {
85
+ "type": "string"
86
+ },
87
+ "variantLabel": {
88
+ "type": "string"
89
+ },
90
+ "roleDescription": {
91
+ "type": "string"
92
+ },
93
+ "avatar": {
94
+ "type": "string"
95
+ },
96
+ "available": {
97
+ "type": "boolean"
98
+ }
99
+ }
100
+ },
21
101
  "SemVer": {
22
102
  "type": "string",
23
103
  "minLength": 1,
24
104
  "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$",
25
105
  "description": "SemVer 2.0.0 including optional prerelease and build metadata."
26
106
  },
27
-
28
107
  "DataClass": {
29
108
  "type": "string",
30
- "enum": ["cache", "ephemeral", "user-authored", "derived-user-visible", "relationship", "interaction-history"]
109
+ "enum": [
110
+ "cache",
111
+ "ephemeral",
112
+ "user-authored",
113
+ "derived-user-visible",
114
+ "relationship",
115
+ "interaction-history"
116
+ ]
31
117
  },
32
-
33
118
  "DataStrategy": {
34
119
  "type": "string",
35
- "enum": ["lifecycle", "retained", "ask-on-uninstall"]
120
+ "enum": [
121
+ "lifecycle",
122
+ "retained",
123
+ "ask-on-uninstall"
124
+ ]
36
125
  },
37
-
38
126
  "Capability": {
39
127
  "type": "string",
40
128
  "enum": [
@@ -43,144 +131,2244 @@
43
131
  "plugin.state.set",
44
132
  "messaging.send",
45
133
  "schedule.register",
46
- "events.publish",
47
134
  "messaging.appendElements",
135
+ "streams.read",
48
136
  "onMessage",
49
137
  "message.event.subscribe",
50
138
  "secret.read",
51
139
  "thread.listMetadata",
52
140
  "thread.readContent",
141
+ "thread.write",
142
+ "task.read",
143
+ "task.write",
144
+ "task.admitEntrusted",
53
145
  "memory.query",
54
146
  "memory.append",
55
147
  "memory.retrieve",
56
148
  "windows.create",
57
- "whisper.extend"
149
+ "whisper.extend",
150
+ "cloud.conversation.host"
58
151
  ]
59
152
  },
60
-
61
153
  "DataDeclaration": {
62
154
  "type": "object",
63
155
  "properties": {
64
- "name": { "type": "string", "minLength": 1 },
65
- "dataClass": { "$ref": "#/$defs/DataClass" },
66
- "strategy": { "$ref": "#/$defs/DataStrategy" },
67
- "schemaVersion": { "type": "string" }
156
+ "name": {
157
+ "type": "string",
158
+ "minLength": 1
159
+ },
160
+ "dataClass": {
161
+ "$ref": "#/$defs/DataClass"
162
+ },
163
+ "strategy": {
164
+ "$ref": "#/$defs/DataStrategy"
165
+ },
166
+ "schemaVersion": {
167
+ "type": "string"
168
+ }
68
169
  },
69
- "required": ["name", "dataClass", "strategy"],
170
+ "required": [
171
+ "name",
172
+ "dataClass",
173
+ "strategy"
174
+ ],
70
175
  "additionalProperties": false,
71
176
  "allOf": [
72
177
  {
73
178
  "if": {
74
179
  "properties": {
75
180
  "dataClass": {
76
- "enum": ["user-authored", "derived-user-visible", "relationship", "interaction-history"]
181
+ "enum": [
182
+ "user-authored",
183
+ "derived-user-visible",
184
+ "relationship",
185
+ "interaction-history"
186
+ ]
77
187
  }
78
188
  },
79
- "required": ["dataClass"]
189
+ "required": [
190
+ "dataClass"
191
+ ]
80
192
  },
81
193
  "then": {
82
194
  "properties": {
83
195
  "strategy": {
84
- "enum": ["retained", "ask-on-uninstall"],
85
- "description": "User-visible/relationship data MUST be retained or ask-on-uninstall. lifecycle is structurally forbidden (铁律 #5: user state defaults to persistent)."
196
+ "enum": [
197
+ "retained",
198
+ "ask-on-uninstall"
199
+ ],
200
+ "description": "User-visible/relationship data MUST be retained or ask-on-uninstall. lifecycle is structurally forbidden (\u94c1\u5f8b #5: user state defaults to persistent)."
86
201
  }
87
202
  }
88
203
  }
89
204
  }
90
205
  ]
91
206
  },
92
-
93
207
  "ResourceReference": {
94
208
  "type": "object",
95
209
  "properties": {
96
- "type": { "type": "string", "minLength": 1 },
97
- "id": { "type": "string", "minLength": 1 }
210
+ "type": {
211
+ "type": "string",
212
+ "minLength": 1
213
+ },
214
+ "id": {
215
+ "type": "string",
216
+ "minLength": 1
217
+ }
98
218
  },
99
- "required": ["type", "id"],
219
+ "required": [
220
+ "type",
221
+ "id"
222
+ ],
100
223
  "additionalProperties": false
101
224
  },
102
-
103
- "PluginFeature": {
225
+ "ContributionReference": {
104
226
  "type": "object",
105
227
  "properties": {
106
- "id": { "type": "string", "minLength": 1 },
107
- "name": { "type": "string", "minLength": 1 },
108
- "resources": {
109
- "type": "array",
110
- "items": { "$ref": "#/$defs/ResourceReference" }
228
+ "type": {
229
+ "type": "string",
230
+ "enum": [
231
+ "identity",
232
+ "schedule",
233
+ "tool",
234
+ "mcp",
235
+ "skill",
236
+ "limb",
237
+ "webhook",
238
+ "message-subscription",
239
+ "media-source",
240
+ "service",
241
+ "connector",
242
+ "cloud-conversation-host",
243
+ "ui",
244
+ "content-editor-provider",
245
+ "desktop-window"
246
+ ]
111
247
  },
112
- "capabilities": {
113
- "type": "array",
114
- "items": { "$ref": "#/$defs/Capability" },
115
- "description": "@signed(G-0 2026-07-15) — capability vocabulary is contract-versioned (P15). Adding a new capability = new contract version. Unknown strings are structurally rejected at schema level; authorization is a separate host runtime layer. Lifecycle callbacks are protocol-intrinsic baseline behavior, so they are not grantable or revocable capability IDs."
248
+ "id": {
249
+ "type": "string",
250
+ "minLength": 1
116
251
  }
117
252
  },
118
- "required": ["id", "name", "resources", "capabilities"],
253
+ "required": [
254
+ "type",
255
+ "id"
256
+ ],
119
257
  "additionalProperties": false
120
258
  },
121
-
122
- "RuntimeTransport": {
259
+ "PackageRelativePath": {
123
260
  "type": "string",
124
- "enum": ["stdio", "ipc", "builtin"]
261
+ "minLength": 1,
262
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*(/[A-Za-z0-9][A-Za-z0-9._-]*)*$"
125
263
  },
126
-
127
- "ExternalRuntimeTransport": {
128
- "type": "string",
129
- "enum": ["stdio", "ipc"]
264
+ "ConfigurationOption": {
265
+ "type": "object",
266
+ "properties": {
267
+ "value": {
268
+ "type": "string",
269
+ "minLength": 1
270
+ },
271
+ "label": {
272
+ "type": "string",
273
+ "minLength": 1
274
+ },
275
+ "hint": {
276
+ "type": "string"
277
+ },
278
+ "docsUrl": {
279
+ "type": "string",
280
+ "format": "uri"
281
+ }
282
+ },
283
+ "required": [
284
+ "value",
285
+ "label"
286
+ ],
287
+ "additionalProperties": false
130
288
  },
131
-
132
- "ExternalRuntimeDeclaration": {
289
+ "RequiredWhen": {
133
290
  "type": "object",
291
+ "description": "Makes the containing field conditionally required and overrides its required flag. The condition compares against the referenced field's effective value (stored value, otherwise default); an array matches when any listed value is strictly equal.",
134
292
  "properties": {
135
- "transport": { "$ref": "#/$defs/ExternalRuntimeTransport" },
136
- "entrypoint": { "type": "string", "minLength": 1 }
293
+ "key": {
294
+ "type": "string",
295
+ "minLength": 1,
296
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
297
+ },
298
+ "value": {
299
+ "oneOf": [
300
+ {
301
+ "type": [
302
+ "string",
303
+ "number",
304
+ "boolean"
305
+ ]
306
+ },
307
+ {
308
+ "type": "array",
309
+ "items": {
310
+ "type": [
311
+ "string",
312
+ "number",
313
+ "boolean"
314
+ ]
315
+ },
316
+ "minItems": 1
317
+ }
318
+ ]
319
+ }
137
320
  },
138
- "required": ["transport", "entrypoint"],
321
+ "required": [
322
+ "key",
323
+ "value"
324
+ ],
139
325
  "additionalProperties": false
140
326
  },
141
-
142
- "BuiltinRuntimeDeclaration": {
327
+ "ConfigurationVariantBranch": {
328
+ "type": "object",
329
+ "description": "One branch of a configurationVariants discriminator. `when` is a constrained JSON Schema fragment (only the discriminator key, const/enum over declared option values); `fields` references keys declared in the top-level configuration and decides applicability, never requiredness.",
330
+ "properties": {
331
+ "id": {
332
+ "type": "string",
333
+ "minLength": 1
334
+ },
335
+ "when": {
336
+ "type": "object"
337
+ },
338
+ "fields": {
339
+ "type": "array",
340
+ "items": {
341
+ "type": "string",
342
+ "minLength": 1,
343
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
344
+ },
345
+ "uniqueItems": true
346
+ }
347
+ },
348
+ "required": [
349
+ "id",
350
+ "when",
351
+ "fields"
352
+ ],
353
+ "additionalProperties": false
354
+ },
355
+ "ConfigurationVariants": {
143
356
  "type": "object",
357
+ "description": "Mode-branched configuration (contractVersion 0.2.0+). The discriminator is a plain non-operation select field; each declared option value must be matched by exactly one branch (completeness + exclusivity, checked semantically).",
144
358
  "properties": {
145
- "transport": { "const": "builtin" },
146
- "entrypoint": { "type": "string", "minLength": 1 }
359
+ "discriminator": {
360
+ "type": "string",
361
+ "minLength": 1,
362
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
363
+ },
364
+ "branches": {
365
+ "type": "array",
366
+ "items": {
367
+ "$ref": "#/$defs/ConfigurationVariantBranch"
368
+ },
369
+ "minItems": 1
370
+ }
147
371
  },
148
- "required": ["transport"],
372
+ "required": [
373
+ "discriminator",
374
+ "branches"
375
+ ],
149
376
  "additionalProperties": false
150
377
  },
151
-
152
- "RuntimeDeclaration": {
378
+ "ConfigurationField": {
379
+ "type": "object",
380
+ "properties": {
381
+ "key": {
382
+ "type": "string",
383
+ "minLength": 1,
384
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
385
+ },
386
+ "label": {
387
+ "type": "string",
388
+ "minLength": 1
389
+ },
390
+ "description": {
391
+ "type": "string"
392
+ },
393
+ "kind": {
394
+ "type": "string",
395
+ "enum": [
396
+ "string",
397
+ "secret",
398
+ "select",
399
+ "boolean",
400
+ "number",
401
+ "url",
402
+ "operation"
403
+ ]
404
+ },
405
+ "required": {
406
+ "type": "boolean",
407
+ "description": "Makes the field unconditionally required unless requiredWhen is present; requiredWhen overrides this flag."
408
+ },
409
+ "hidden": {
410
+ "type": "boolean",
411
+ "description": "Hide a value field from manual owner editing while retaining it as an operation target or runtime value."
412
+ },
413
+ "requiredWhen": {
414
+ "$ref": "#/$defs/RequiredWhen",
415
+ "description": "Overrides required and makes this field required only when the referenced field's effective value (stored value, otherwise default) strictly equals value, or any member when value is an array."
416
+ },
417
+ "default": {
418
+ "type": [
419
+ "string",
420
+ "number",
421
+ "boolean"
422
+ ]
423
+ },
424
+ "options": {
425
+ "type": "array",
426
+ "items": {
427
+ "$ref": "#/$defs/ConfigurationOption"
428
+ },
429
+ "minItems": 1
430
+ },
431
+ "target": {
432
+ "type": "array",
433
+ "description": "Configuration keys whose values are backfilled when the operation succeeds; operation fields use contract key rather than the legacy Host name property.",
434
+ "items": {
435
+ "type": "string",
436
+ "minLength": 1,
437
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
438
+ },
439
+ "uniqueItems": true
440
+ },
441
+ "actions": {
442
+ "type": "array",
443
+ "items": {
444
+ "$ref": "#/$defs/ActionDef"
445
+ },
446
+ "minItems": 1
447
+ }
448
+ },
449
+ "required": [
450
+ "key",
451
+ "label",
452
+ "kind",
453
+ "required"
454
+ ],
455
+ "additionalProperties": false,
456
+ "allOf": [
457
+ {
458
+ "if": {
459
+ "properties": {
460
+ "kind": {
461
+ "const": "select"
462
+ }
463
+ },
464
+ "required": [
465
+ "kind"
466
+ ]
467
+ },
468
+ "then": {
469
+ "required": [
470
+ "options"
471
+ ]
472
+ },
473
+ "else": {
474
+ "properties": {
475
+ "options": false
476
+ }
477
+ }
478
+ },
479
+ {
480
+ "if": {
481
+ "properties": {
482
+ "kind": {
483
+ "const": "secret"
484
+ }
485
+ },
486
+ "required": [
487
+ "kind"
488
+ ]
489
+ },
490
+ "then": {
491
+ "properties": {
492
+ "default": false
493
+ }
494
+ }
495
+ },
496
+ {
497
+ "if": {
498
+ "properties": {
499
+ "kind": {
500
+ "const": "boolean"
501
+ }
502
+ },
503
+ "required": [
504
+ "kind"
505
+ ]
506
+ },
507
+ "then": {
508
+ "properties": {
509
+ "default": {
510
+ "type": "boolean"
511
+ }
512
+ }
513
+ }
514
+ },
515
+ {
516
+ "if": {
517
+ "properties": {
518
+ "kind": {
519
+ "const": "number"
520
+ }
521
+ },
522
+ "required": [
523
+ "kind"
524
+ ]
525
+ },
526
+ "then": {
527
+ "properties": {
528
+ "default": {
529
+ "type": "number"
530
+ }
531
+ }
532
+ }
533
+ },
534
+ {
535
+ "if": {
536
+ "properties": {
537
+ "kind": {
538
+ "enum": [
539
+ "string",
540
+ "select"
541
+ ]
542
+ }
543
+ },
544
+ "required": [
545
+ "kind"
546
+ ]
547
+ },
548
+ "then": {
549
+ "properties": {
550
+ "default": {
551
+ "type": "string"
552
+ }
553
+ }
554
+ }
555
+ },
556
+ {
557
+ "if": {
558
+ "properties": {
559
+ "kind": {
560
+ "const": "url"
561
+ }
562
+ },
563
+ "required": [
564
+ "kind"
565
+ ]
566
+ },
567
+ "then": {
568
+ "properties": {
569
+ "default": {
570
+ "type": "string",
571
+ "format": "uri"
572
+ }
573
+ }
574
+ }
575
+ },
576
+ {
577
+ "if": {
578
+ "properties": {
579
+ "kind": {
580
+ "const": "operation"
581
+ }
582
+ },
583
+ "required": [
584
+ "kind"
585
+ ]
586
+ },
587
+ "then": {
588
+ "required": [
589
+ "actions"
590
+ ],
591
+ "properties": {
592
+ "default": false,
593
+ "hidden": false,
594
+ "requiredWhen": false
595
+ }
596
+ },
597
+ "else": {
598
+ "properties": {
599
+ "target": false,
600
+ "actions": false
601
+ }
602
+ }
603
+ }
604
+ ]
605
+ },
606
+ "EnvironmentBinding": {
153
607
  "oneOf": [
154
- { "$ref": "#/$defs/ExternalRuntimeDeclaration" },
155
- { "$ref": "#/$defs/BuiltinRuntimeDeclaration" }
608
+ {
609
+ "type": "object",
610
+ "properties": {
611
+ "source": {
612
+ "const": "config"
613
+ },
614
+ "key": {
615
+ "type": "string",
616
+ "minLength": 1
617
+ }
618
+ },
619
+ "required": [
620
+ "source",
621
+ "key"
622
+ ],
623
+ "additionalProperties": false
624
+ },
625
+ {
626
+ "type": "object",
627
+ "properties": {
628
+ "source": {
629
+ "const": "secret"
630
+ },
631
+ "key": {
632
+ "type": "string",
633
+ "minLength": 1
634
+ }
635
+ },
636
+ "required": [
637
+ "source",
638
+ "key"
639
+ ],
640
+ "additionalProperties": false
641
+ }
156
642
  ]
157
- }
158
- },
159
-
160
- "type": "object",
161
- "properties": {
162
- "pluginId": { "type": "string", "minLength": 1 },
163
- "version": {
164
- "$ref": "#/$defs/SemVer",
165
- "description": "Plugin version — must be valid semver (§9: numeric prerelease identifiers MUST NOT have leading zeroes)."
166
643
  },
167
- "contractVersion": {
168
- "$ref": "#/$defs/SemVer",
169
- "description": "Must be an exact published semver version — no ranges, wildcards, or operator prefixes (five-step freeze: pin exact version). §9: numeric prerelease identifiers MUST NOT have leading zeroes."
644
+ "ContributionRuntime": {
645
+ "type": "object",
646
+ "properties": {
647
+ "transport": {
648
+ "type": "string",
649
+ "enum": [
650
+ "stdio",
651
+ "ipc"
652
+ ]
653
+ },
654
+ "entrypoint": {
655
+ "$ref": "#/$defs/PackageRelativePath"
656
+ },
657
+ "args": {
658
+ "type": "array",
659
+ "items": {
660
+ "type": "string"
661
+ }
662
+ }
663
+ },
664
+ "required": [
665
+ "transport",
666
+ "entrypoint"
667
+ ],
668
+ "additionalProperties": false
170
669
  },
171
- "name": { "type": "string", "minLength": 1 },
172
- "description": { "type": "string" },
173
- "features": {
174
- "type": "array",
175
- "items": { "$ref": "#/$defs/PluginFeature" },
176
- "minItems": 1
670
+ "CallbackAction": {
671
+ "type": "object",
672
+ "properties": {
673
+ "method": {
674
+ "type": "string",
675
+ "minLength": 1
676
+ },
677
+ "params": {
678
+ "type": "object",
679
+ "additionalProperties": true
680
+ }
681
+ },
682
+ "required": [
683
+ "method"
684
+ ],
685
+ "additionalProperties": false
177
686
  },
178
- "data": {
179
- "type": "array",
180
- "items": { "$ref": "#/$defs/DataDeclaration" }
687
+ "ActionDef": {
688
+ "type": "object",
689
+ "description": "One Host-rendered operation action. render is closed to the renderers the frontend implements: 'row' actions are not rendered standalone and can only be invoked from a row of a 'rows' result in the same operation.",
690
+ "properties": {
691
+ "id": {
692
+ "type": "string",
693
+ "minLength": 1,
694
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
695
+ },
696
+ "label": {
697
+ "type": "string",
698
+ "minLength": 1
699
+ },
700
+ "render": {
701
+ "type": "string",
702
+ "enum": [
703
+ "button",
704
+ "polling",
705
+ "status",
706
+ "row"
707
+ ]
708
+ },
709
+ "confirm": {
710
+ "type": "string",
711
+ "minLength": 1,
712
+ "maxLength": 200,
713
+ "description": "Plain text (1..200 chars). Applies to button and row actions: the Host must ask the owner to confirm before every invocation when the manifest declares it; a row-level confirm can only replace the wording, never skip the confirmation step."
714
+ },
715
+ "action": {
716
+ "$ref": "#/$defs/CallbackAction"
717
+ },
718
+ "resultRender": {
719
+ "type": "string"
720
+ },
721
+ "next": {
722
+ "type": "string",
723
+ "minLength": 1
724
+ },
725
+ "rollback": {
726
+ "type": "string",
727
+ "minLength": 1
728
+ },
729
+ "timeout": {
730
+ "type": "integer",
731
+ "minimum": 1
732
+ }
733
+ },
734
+ "required": [
735
+ "id",
736
+ "label",
737
+ "render",
738
+ "action"
739
+ ],
740
+ "additionalProperties": false
741
+ },
742
+ "OperationRows": {
743
+ "type": "object",
744
+ "description": "Typed payload of an operation result whose render is 'rows': a bounded, Host-rendered row list. Runtime data is validated by the contract-exported rows validator against the declaring operation, fail-closed.",
745
+ "properties": {
746
+ "rows": {
747
+ "type": "array",
748
+ "items": {
749
+ "$ref": "#/$defs/OperationRow"
750
+ },
751
+ "minItems": 0,
752
+ "maxItems": 200
753
+ },
754
+ "empty": {
755
+ "type": "string",
756
+ "minLength": 1,
757
+ "maxLength": 200
758
+ }
759
+ },
760
+ "required": [
761
+ "rows"
762
+ ],
763
+ "additionalProperties": false
764
+ },
765
+ "OperationRow": {
766
+ "type": "object",
767
+ "description": "One row of a 'rows' result. The hard storage ceiling behind a row list is 32 authorizations; stay well below the 200-row schema bound.",
768
+ "properties": {
769
+ "key": {
770
+ "type": "string",
771
+ "minLength": 1,
772
+ "maxLength": 200
773
+ },
774
+ "label": {
775
+ "type": "string",
776
+ "minLength": 1,
777
+ "maxLength": 200
778
+ },
779
+ "detail": {
780
+ "type": "string",
781
+ "maxLength": 500
782
+ },
783
+ "actions": {
784
+ "type": "array",
785
+ "items": {
786
+ "$ref": "#/$defs/OperationRowAction"
787
+ },
788
+ "minItems": 0,
789
+ "maxItems": 4
790
+ }
791
+ },
792
+ "required": [
793
+ "key",
794
+ "label"
795
+ ],
796
+ "additionalProperties": false
181
797
  },
182
- "runtime": { "$ref": "#/$defs/RuntimeDeclaration" }
798
+ "OperationRowAction": {
799
+ "type": "object",
800
+ "description": "Invocation of one render-'row' ActionDef of the same operation, carrying this row's input. Host validates the reference fail-closed: undeclared, or referencing a non-row action, invalidates the whole result.",
801
+ "properties": {
802
+ "action": {
803
+ "type": "string",
804
+ "minLength": 1
805
+ },
806
+ "label": {
807
+ "type": "string",
808
+ "maxLength": 60,
809
+ "description": "Defaults to the referenced ActionDef label."
810
+ },
811
+ "input": {
812
+ "type": "object",
813
+ "minProperties": 1,
814
+ "maxProperties": 16,
815
+ "propertyNames": {
816
+ "pattern": "^[A-Za-z][A-Za-z0-9._-]*$"
817
+ },
818
+ "additionalProperties": {
819
+ "type": [
820
+ "string",
821
+ "number",
822
+ "boolean"
823
+ ],
824
+ "maxLength": 1000
825
+ }
826
+ },
827
+ "confirm": {
828
+ "type": "string",
829
+ "minLength": 1,
830
+ "maxLength": 200,
831
+ "description": "Replaces the referenced ActionDef confirm wording; it can never remove the confirmation step the manifest declared."
832
+ }
833
+ },
834
+ "required": [
835
+ "action",
836
+ "input"
837
+ ],
838
+ "additionalProperties": false
839
+ },
840
+ "OperationActionResult": {
841
+ "type": "object",
842
+ "properties": {
843
+ "render": {
844
+ "type": "string"
845
+ },
846
+ "data": {},
847
+ "label": {
848
+ "type": "string"
849
+ },
850
+ "targetValues": {
851
+ "type": "object",
852
+ "additionalProperties": {
853
+ "type": "string"
854
+ }
855
+ },
856
+ "advance": {
857
+ "type": "boolean"
858
+ },
859
+ "activate": {
860
+ "type": "boolean"
861
+ }
862
+ },
863
+ "required": [
864
+ "render",
865
+ "data"
866
+ ],
867
+ "additionalProperties": false,
868
+ "allOf": [
869
+ {
870
+ "if": {
871
+ "properties": {
872
+ "render": {
873
+ "const": "rows"
874
+ }
875
+ },
876
+ "required": [
877
+ "render"
878
+ ]
879
+ },
880
+ "then": {
881
+ "properties": {
882
+ "data": {
883
+ "$ref": "#/$defs/OperationRows"
884
+ }
885
+ }
886
+ }
887
+ }
888
+ ]
889
+ },
890
+ "PluginTestDeclaration": {
891
+ "type": "object",
892
+ "properties": {
893
+ "action": {
894
+ "$ref": "#/$defs/CallbackAction"
895
+ }
896
+ },
897
+ "required": [
898
+ "action"
899
+ ],
900
+ "additionalProperties": false
901
+ },
902
+ "PluginTestResult": {
903
+ "type": "object",
904
+ "properties": {
905
+ "ok": {
906
+ "type": "boolean"
907
+ },
908
+ "message": {
909
+ "type": "string"
910
+ },
911
+ "details": {
912
+ "type": "object",
913
+ "additionalProperties": true
914
+ }
915
+ },
916
+ "required": [
917
+ "ok"
918
+ ],
919
+ "additionalProperties": false
920
+ },
921
+ "SetupStep": {
922
+ "type": "object",
923
+ "properties": {
924
+ "text": {
925
+ "type": "string",
926
+ "minLength": 1
927
+ },
928
+ "mode": {
929
+ "type": "string",
930
+ "description": "Original connector setup visibility: show this step when the connectionMode configuration value matches."
931
+ }
932
+ },
933
+ "required": [
934
+ "text"
935
+ ],
936
+ "additionalProperties": false
937
+ },
938
+ "ConnectorPermissions": {
939
+ "type": "object",
940
+ "description": "Original connector group settings declaration. The label names the owner UI; this does not grant Host capabilities or contain permission state.",
941
+ "properties": {
942
+ "label": {
943
+ "type": "string"
944
+ }
945
+ },
946
+ "required": [
947
+ "label"
948
+ ],
949
+ "additionalProperties": false
950
+ },
951
+ "IdentityContribution": {
952
+ "type": "object",
953
+ "properties": {
954
+ "type": {
955
+ "const": "identity"
956
+ },
957
+ "id": {
958
+ "type": "string",
959
+ "minLength": 1
960
+ },
961
+ "displayName": {
962
+ "type": "string",
963
+ "minLength": 1
964
+ },
965
+ "icon": {
966
+ "type": "string"
967
+ },
968
+ "color": {
969
+ "type": "string"
970
+ }
971
+ },
972
+ "required": [
973
+ "type",
974
+ "id",
975
+ "displayName"
976
+ ],
977
+ "additionalProperties": false
978
+ },
979
+ "ScheduleContribution": {
980
+ "type": "object",
981
+ "properties": {
982
+ "type": {
983
+ "const": "schedule"
984
+ },
985
+ "id": {
986
+ "type": "string",
987
+ "minLength": 1
988
+ },
989
+ "schedule": {
990
+ "oneOf": [
991
+ {
992
+ "type": "object",
993
+ "properties": {
994
+ "kind": {
995
+ "const": "interval"
996
+ },
997
+ "everyMs": {
998
+ "type": "integer",
999
+ "minimum": 1000
1000
+ }
1001
+ },
1002
+ "required": [
1003
+ "kind",
1004
+ "everyMs"
1005
+ ],
1006
+ "additionalProperties": false
1007
+ },
1008
+ {
1009
+ "type": "object",
1010
+ "properties": {
1011
+ "kind": {
1012
+ "const": "cron"
1013
+ },
1014
+ "expression": {
1015
+ "type": "string",
1016
+ "minLength": 1
1017
+ }
1018
+ },
1019
+ "required": [
1020
+ "kind",
1021
+ "expression"
1022
+ ],
1023
+ "additionalProperties": false
1024
+ }
1025
+ ]
1026
+ },
1027
+ "action": {
1028
+ "$ref": "#/$defs/CallbackAction"
1029
+ },
1030
+ "policy": {
1031
+ "type": "object",
1032
+ "properties": {
1033
+ "overlap": {
1034
+ "const": "skip"
1035
+ },
1036
+ "timeoutMs": {
1037
+ "type": "integer",
1038
+ "minimum": 1000,
1039
+ "maximum": 86400000
1040
+ }
1041
+ },
1042
+ "required": [
1043
+ "overlap",
1044
+ "timeoutMs"
1045
+ ],
1046
+ "additionalProperties": false
1047
+ }
1048
+ },
1049
+ "required": [
1050
+ "type",
1051
+ "id",
1052
+ "schedule",
1053
+ "action",
1054
+ "policy"
1055
+ ],
1056
+ "additionalProperties": false
1057
+ },
1058
+ "DirectToolContribution": {
1059
+ "type": "object",
1060
+ "properties": {
1061
+ "type": {
1062
+ "const": "tool"
1063
+ },
1064
+ "id": {
1065
+ "type": "string",
1066
+ "minLength": 1
1067
+ },
1068
+ "name": {
1069
+ "type": "string",
1070
+ "minLength": 1
1071
+ },
1072
+ "description": {
1073
+ "type": "string"
1074
+ },
1075
+ "inputSchema": {
1076
+ "type": "object",
1077
+ "additionalProperties": true
1078
+ },
1079
+ "action": {
1080
+ "$ref": "#/$defs/CallbackAction"
1081
+ }
1082
+ },
1083
+ "required": [
1084
+ "type",
1085
+ "id",
1086
+ "name",
1087
+ "inputSchema",
1088
+ "action"
1089
+ ],
1090
+ "additionalProperties": false
1091
+ },
1092
+ "McpActionMethod": {
1093
+ "description": "A native MCP method allowlist entry, without fixed business parameters.",
1094
+ "type": "object",
1095
+ "properties": {
1096
+ "method": {
1097
+ "type": "string",
1098
+ "minLength": 1
1099
+ }
1100
+ },
1101
+ "required": [
1102
+ "method"
1103
+ ],
1104
+ "additionalProperties": false
1105
+ },
1106
+ "McpContribution": {
1107
+ "type": "object",
1108
+ "properties": {
1109
+ "type": {
1110
+ "const": "mcp"
1111
+ },
1112
+ "id": {
1113
+ "type": "string",
1114
+ "minLength": 1
1115
+ },
1116
+ "runtime": {
1117
+ "$ref": "#/$defs/ContributionRuntime"
1118
+ },
1119
+ "actions": {
1120
+ "description": "Module methods callable by this native MCP server; these do not publish direct tools.",
1121
+ "type": "array",
1122
+ "minItems": 1,
1123
+ "uniqueItems": true,
1124
+ "items": {
1125
+ "$ref": "#/$defs/McpActionMethod"
1126
+ }
1127
+ },
1128
+ "environment": {
1129
+ "type": "object",
1130
+ "additionalProperties": {
1131
+ "$ref": "#/$defs/EnvironmentBinding"
1132
+ }
1133
+ }
1134
+ },
1135
+ "required": [
1136
+ "type",
1137
+ "id",
1138
+ "runtime"
1139
+ ],
1140
+ "additionalProperties": false
1141
+ },
1142
+ "SkillContribution": {
1143
+ "type": "object",
1144
+ "properties": {
1145
+ "type": {
1146
+ "const": "skill"
1147
+ },
1148
+ "id": {
1149
+ "type": "string",
1150
+ "minLength": 1
1151
+ },
1152
+ "path": {
1153
+ "$ref": "#/$defs/PackageRelativePath"
1154
+ }
1155
+ },
1156
+ "required": [
1157
+ "type",
1158
+ "id",
1159
+ "path"
1160
+ ],
1161
+ "additionalProperties": false
1162
+ },
1163
+ "LimbContribution": {
1164
+ "type": "object",
1165
+ "properties": {
1166
+ "type": {
1167
+ "const": "limb"
1168
+ },
1169
+ "id": {
1170
+ "type": "string",
1171
+ "minLength": 1
1172
+ },
1173
+ "manifestPath": {
1174
+ "$ref": "#/$defs/PackageRelativePath"
1175
+ }
1176
+ },
1177
+ "required": [
1178
+ "type",
1179
+ "id",
1180
+ "manifestPath"
1181
+ ],
1182
+ "additionalProperties": false
1183
+ },
1184
+ "WebhookContribution": {
1185
+ "type": "object",
1186
+ "properties": {
1187
+ "type": {
1188
+ "const": "webhook"
1189
+ },
1190
+ "id": {
1191
+ "type": "string",
1192
+ "minLength": 1
1193
+ },
1194
+ "path": {
1195
+ "type": "string",
1196
+ "pattern": "^(?!(?:config|test|enable|disable|actions|operations)(?:/|$))[A-Za-z0-9][A-Za-z0-9_-]*(/(?:[A-Za-z0-9][A-Za-z0-9_-]*|:[A-Za-z_][A-Za-z0-9_]*))*$"
1197
+ },
1198
+ "methods": {
1199
+ "type": "array",
1200
+ "items": {
1201
+ "type": "string",
1202
+ "enum": [
1203
+ "GET",
1204
+ "POST",
1205
+ "PUT",
1206
+ "PATCH",
1207
+ "DELETE"
1208
+ ]
1209
+ },
1210
+ "minItems": 1,
1211
+ "uniqueItems": true
1212
+ },
1213
+ "action": {
1214
+ "$ref": "#/$defs/CallbackAction"
1215
+ },
1216
+ "verificationSecretRef": {
1217
+ "type": "string",
1218
+ "minLength": 1
1219
+ }
1220
+ },
1221
+ "required": [
1222
+ "type",
1223
+ "id",
1224
+ "path",
1225
+ "methods",
1226
+ "action"
1227
+ ],
1228
+ "additionalProperties": false
1229
+ },
1230
+ "MessageSubscriptionContribution": {
1231
+ "type": "object",
1232
+ "properties": {
1233
+ "type": {
1234
+ "const": "message-subscription"
1235
+ },
1236
+ "id": {
1237
+ "type": "string",
1238
+ "minLength": 1
1239
+ },
1240
+ "binding": {
1241
+ "type": "string",
1242
+ "minLength": 1
1243
+ },
1244
+ "filter": {
1245
+ "type": "object",
1246
+ "additionalProperties": true
1247
+ },
1248
+ "action": {
1249
+ "$ref": "#/$defs/CallbackAction"
1250
+ },
1251
+ "presentation": {
1252
+ "enum": [
1253
+ "v1",
1254
+ "v2"
1255
+ ]
1256
+ }
1257
+ },
1258
+ "required": [
1259
+ "type",
1260
+ "id",
1261
+ "binding",
1262
+ "action"
1263
+ ],
1264
+ "additionalProperties": false
1265
+ },
1266
+ "MediaSourceContribution": {
1267
+ "type": "object",
1268
+ "properties": {
1269
+ "type": {
1270
+ "const": "media-source"
1271
+ },
1272
+ "id": {
1273
+ "type": "string",
1274
+ "minLength": 1,
1275
+ "maxLength": 256
1276
+ },
1277
+ "binding": {
1278
+ "type": "string",
1279
+ "minLength": 1
1280
+ }
1281
+ },
1282
+ "required": [
1283
+ "type",
1284
+ "id",
1285
+ "binding"
1286
+ ],
1287
+ "additionalProperties": false
1288
+ },
1289
+ "ServiceContribution": {
1290
+ "type": "object",
1291
+ "properties": {
1292
+ "type": {
1293
+ "const": "service"
1294
+ },
1295
+ "id": {
1296
+ "type": "string",
1297
+ "minLength": 1
1298
+ },
1299
+ "runtime": {
1300
+ "$ref": "#/$defs/ContributionRuntime"
1301
+ },
1302
+ "healthMethod": {
1303
+ "type": "string",
1304
+ "minLength": 1
1305
+ },
1306
+ "environment": {
1307
+ "type": "object",
1308
+ "additionalProperties": {
1309
+ "$ref": "#/$defs/EnvironmentBinding"
1310
+ }
1311
+ }
1312
+ },
1313
+ "required": [
1314
+ "type",
1315
+ "id",
1316
+ "runtime",
1317
+ "healthMethod"
1318
+ ],
1319
+ "additionalProperties": false
1320
+ },
1321
+ "ConnectorContribution": {
1322
+ "type": "object",
1323
+ "properties": {
1324
+ "type": {
1325
+ "const": "connector"
1326
+ },
1327
+ "id": {
1328
+ "type": "string",
1329
+ "minLength": 1
1330
+ },
1331
+ "identityRef": {
1332
+ "type": "string",
1333
+ "minLength": 1
1334
+ },
1335
+ "inboundMethod": {
1336
+ "type": "string",
1337
+ "minLength": 1
1338
+ },
1339
+ "outboundMethod": {
1340
+ "type": "string",
1341
+ "minLength": 1
1342
+ }
1343
+ },
1344
+ "required": [
1345
+ "type",
1346
+ "id",
1347
+ "identityRef",
1348
+ "inboundMethod",
1349
+ "outboundMethod"
1350
+ ],
1351
+ "additionalProperties": false
1352
+ },
1353
+ "CloudConversationHostMethod": {
1354
+ "type": "object",
1355
+ "properties": {
1356
+ "method": {
1357
+ "type": "string",
1358
+ "minLength": 1
1359
+ }
1360
+ },
1361
+ "required": [
1362
+ "method"
1363
+ ],
1364
+ "additionalProperties": false
1365
+ },
1366
+ "CloudConversationHostContribution": {
1367
+ "type": "object",
1368
+ "description": "Declares that this package hosts one cloud conversation provider: the Host sends owner cloud-cat messages through appendMessage and pulls assistant returns through assistantReturns.list / ack. Method semantics come from the manifest only; runtime data can never introduce new methods. Error codes are data (external-process transports flatten thrown errors): NEEDS_BINDING / BOUND_CONVERSATION_MISMATCH -> needs-binding (incl. h4); HOST_UNAVAILABLE -> treated as no adapter (null); every other code (the STALE_* revisions, AMBIGUOUS_EFFECT, IDEMPOTENCY_CONFLICT, NEEDS_AUTHORIZATION, HOST_STOPPED, PAIRING_REJECTED, ...) and any unknown code -> host-append-failed. HOST_UNAVAILABLE must only describe failures before a request could have had any effect (no pairing record, missing socket, connection refused); any error after the request was written is AMBIGUOUS_EFFECT. The owning feature must be granted cloud.conversation.host; one provider accepts at most one enabled package.",
1369
+ "properties": {
1370
+ "type": {
1371
+ "const": "cloud-conversation-host"
1372
+ },
1373
+ "id": {
1374
+ "type": "string",
1375
+ "minLength": 1
1376
+ },
1377
+ "provider": {
1378
+ "const": "chatgpt"
1379
+ },
1380
+ "appendMessage": {
1381
+ "$ref": "#/$defs/CloudConversationHostMethod"
1382
+ },
1383
+ "assistantReturns": {
1384
+ "type": "object",
1385
+ "properties": {
1386
+ "list": {
1387
+ "$ref": "#/$defs/CloudConversationHostMethod"
1388
+ },
1389
+ "ack": {
1390
+ "$ref": "#/$defs/CloudConversationHostMethod"
1391
+ }
1392
+ },
1393
+ "required": [
1394
+ "list",
1395
+ "ack"
1396
+ ],
1397
+ "additionalProperties": false
1398
+ }
1399
+ },
1400
+ "required": [
1401
+ "type",
1402
+ "id",
1403
+ "provider",
1404
+ "appendMessage",
1405
+ "assistantReturns"
1406
+ ],
1407
+ "additionalProperties": false
1408
+ },
1409
+ "CloudBridgeDomFingerprintNodeV1": {
1410
+ "type": "object",
1411
+ "properties": {
1412
+ "path": {
1413
+ "type": "string",
1414
+ "minLength": 1,
1415
+ "maxLength": 512,
1416
+ "pattern": "^composer(?:/(?:[a-z][a-z0-9-]{0,31}|#text|#node-(?:0|[1-9]\\d{0,3}))\\[(?:0|[1-9]\\d{0,9})\\])*$"
1417
+ },
1418
+ "kind": {
1419
+ "enum": [
1420
+ "text",
1421
+ "element",
1422
+ "other"
1423
+ ]
1424
+ },
1425
+ "empty": {
1426
+ "type": "boolean"
1427
+ },
1428
+ "tag": {
1429
+ "type": "string",
1430
+ "pattern": "^[A-Z][A-Z0-9-]{0,31}$"
1431
+ },
1432
+ "nodeType": {
1433
+ "type": "integer",
1434
+ "minimum": 0,
1435
+ "maximum": 1000
1436
+ },
1437
+ "childCount": {
1438
+ "type": "integer",
1439
+ "minimum": 0,
1440
+ "maximum": 4294967295
1441
+ },
1442
+ "contentEditable": {
1443
+ "type": "boolean"
1444
+ },
1445
+ "proseMirror": {
1446
+ "type": "boolean"
1447
+ },
1448
+ "placeholder": {
1449
+ "type": "boolean"
1450
+ },
1451
+ "virtualKeyboard": {
1452
+ "type": "boolean"
1453
+ },
1454
+ "trailingBreak": {
1455
+ "type": "boolean"
1456
+ }
1457
+ },
1458
+ "required": [
1459
+ "path",
1460
+ "kind"
1461
+ ],
1462
+ "additionalProperties": false
1463
+ },
1464
+ "CloudBridgeDomFingerprintV1": {
1465
+ "type": "object",
1466
+ "properties": {
1467
+ "v": {
1468
+ "const": 1
1469
+ },
1470
+ "phase": {
1471
+ "type": "string",
1472
+ "minLength": 1,
1473
+ "maxLength": 32,
1474
+ "pattern": "^[A-Za-z0-9._:-]+$"
1475
+ },
1476
+ "adapterRevision": {
1477
+ "type": "string",
1478
+ "minLength": 1,
1479
+ "maxLength": 32,
1480
+ "pattern": "^[A-Za-z0-9._:-]+$"
1481
+ },
1482
+ "artifactRevision": {
1483
+ "type": "string",
1484
+ "minLength": 1,
1485
+ "maxLength": 32,
1486
+ "pattern": "^[A-Za-z0-9._:-]+$"
1487
+ },
1488
+ "firstUnsupportedPath": {
1489
+ "type": "string",
1490
+ "minLength": 1,
1491
+ "maxLength": 512,
1492
+ "pattern": "^composer(?:/(?:[a-z][a-z0-9-]{0,31}|#text|#node-(?:0|[1-9]\\d{0,3}))\\[(?:0|[1-9]\\d{0,9})\\])*$"
1493
+ },
1494
+ "nodes": {
1495
+ "type": "array",
1496
+ "items": {
1497
+ "$ref": "#/$defs/CloudBridgeDomFingerprintNodeV1"
1498
+ },
1499
+ "maxItems": 12
1500
+ },
1501
+ "truncated": {
1502
+ "type": "boolean"
1503
+ }
1504
+ },
1505
+ "required": [
1506
+ "v",
1507
+ "phase",
1508
+ "adapterRevision",
1509
+ "artifactRevision",
1510
+ "nodes",
1511
+ "truncated"
1512
+ ],
1513
+ "additionalProperties": false
1514
+ },
1515
+ "CloudBridgeFailureDiagnosticV1": {
1516
+ "type": "object",
1517
+ "properties": {
1518
+ "v": {
1519
+ "const": 1
1520
+ },
1521
+ "errorCode": {
1522
+ "type": "string",
1523
+ "pattern": "^[A-Z][A-Z0-9_]{2,63}$"
1524
+ },
1525
+ "nextAction": {
1526
+ "const": "inspect_bound_tab"
1527
+ },
1528
+ "fingerprint": {
1529
+ "$ref": "#/$defs/CloudBridgeDomFingerprintV1"
1530
+ }
1531
+ },
1532
+ "required": [
1533
+ "v",
1534
+ "errorCode",
1535
+ "nextAction",
1536
+ "fingerprint"
1537
+ ],
1538
+ "additionalProperties": false
1539
+ },
1540
+ "CloudConversationAppendMessageInput": {
1541
+ "type": "object",
1542
+ "description": "Host -> package input of the appendMessage method. idempotencyKey references the shared MessageId (1..512) and is the Clowder source message id; the package answers failed + INVALID_REQUEST when the key does not match its own token format. text is additionally checked in code: UTF-8 <= 128 KiB and non-empty after trim (isCloudConversationTextBudget).",
1543
+ "properties": {
1544
+ "conversationId": {
1545
+ "type": "string",
1546
+ "minLength": 1,
1547
+ "maxLength": 200,
1548
+ "pattern": "^[A-Za-z0-9._:-]+$"
1549
+ },
1550
+ "text": {
1551
+ "type": "string",
1552
+ "minLength": 1,
1553
+ "maxLength": 131072
1554
+ },
1555
+ "idempotencyKey": {
1556
+ "$ref": "https://clowder-ai.dev/schemas/messaging/v0.1#/$defs/MessageId"
1557
+ }
1558
+ },
1559
+ "required": [
1560
+ "conversationId",
1561
+ "text",
1562
+ "idempotencyKey"
1563
+ ],
1564
+ "additionalProperties": false
1565
+ },
1566
+ "CloudConversationAppendMessageAppendedResult": {
1567
+ "type": "object",
1568
+ "description": "Successful append. providerMessageId is the provider-side (ChatGPT) message id; the Host's generic adapter maps it back to its internal hostMessageId.",
1569
+ "properties": {
1570
+ "status": {
1571
+ "const": "appended"
1572
+ },
1573
+ "providerMessageId": {
1574
+ "type": "string",
1575
+ "minLength": 1,
1576
+ "maxLength": 512
1577
+ },
1578
+ "idempotentReplay": {
1579
+ "type": "boolean"
1580
+ }
1581
+ },
1582
+ "required": [
1583
+ "status",
1584
+ "providerMessageId"
1585
+ ],
1586
+ "additionalProperties": false
1587
+ },
1588
+ "CloudConversationAppendMessageFailedResult": {
1589
+ "type": "object",
1590
+ "description": "Failed append. errorCode is a safe string; diagnostic is the contract copy of CloudBridgeFailureDiagnosticV1 and is re-validated by the contract-exported isCloudBridgeFailureDiagnosticV1. A Host that preserves errorCode while dropping an invalid diagnostic validates in two stages: validate the envelope without diagnostic, then validate diagnostic separately.",
1591
+ "properties": {
1592
+ "status": {
1593
+ "const": "failed"
1594
+ },
1595
+ "errorCode": {
1596
+ "type": "string",
1597
+ "pattern": "^[A-Z][A-Z0-9_]{2,63}$"
1598
+ },
1599
+ "diagnostic": {
1600
+ "$ref": "#/$defs/CloudBridgeFailureDiagnosticV1"
1601
+ },
1602
+ "idempotentReplay": {
1603
+ "type": "boolean"
1604
+ }
1605
+ },
1606
+ "required": [
1607
+ "status",
1608
+ "errorCode"
1609
+ ],
1610
+ "additionalProperties": false
1611
+ },
1612
+ "CloudConversationAppendMessageResult": {
1613
+ "oneOf": [
1614
+ {
1615
+ "$ref": "#/$defs/CloudConversationAppendMessageAppendedResult"
1616
+ },
1617
+ {
1618
+ "$ref": "#/$defs/CloudConversationAppendMessageFailedResult"
1619
+ }
1620
+ ]
1621
+ },
1622
+ "CloudConversationReturnCursor": {
1623
+ "type": "object",
1624
+ "description": "Assistant-return cursor: the after? triplet is either fully present or fully absent.",
1625
+ "properties": {
1626
+ "conversationId": {
1627
+ "type": "string",
1628
+ "minLength": 1,
1629
+ "maxLength": 200,
1630
+ "pattern": "^[A-Za-z0-9._:-]+$"
1631
+ },
1632
+ "sourceMessageId": {
1633
+ "$ref": "https://clowder-ai.dev/schemas/messaging/v0.1#/$defs/MessageId"
1634
+ },
1635
+ "assistantMessageId": {
1636
+ "type": "string",
1637
+ "minLength": 1,
1638
+ "maxLength": 512
1639
+ }
1640
+ },
1641
+ "required": [
1642
+ "conversationId",
1643
+ "sourceMessageId",
1644
+ "assistantMessageId"
1645
+ ],
1646
+ "additionalProperties": false
1647
+ },
1648
+ "CloudConversationAssistantReturn": {
1649
+ "type": "object",
1650
+ "description": "One candidate assistant return. sourceMessageId echoes the appendMessage idempotencyKey (the Clowder source message id). content is additionally checked in code: UTF-8 <= 128 KiB and non-empty after trim.",
1651
+ "properties": {
1652
+ "conversationId": {
1653
+ "type": "string",
1654
+ "minLength": 1,
1655
+ "maxLength": 200,
1656
+ "pattern": "^[A-Za-z0-9._:-]+$"
1657
+ },
1658
+ "sourceMessageId": {
1659
+ "$ref": "https://clowder-ai.dev/schemas/messaging/v0.1#/$defs/MessageId"
1660
+ },
1661
+ "assistantMessageId": {
1662
+ "type": "string",
1663
+ "minLength": 1,
1664
+ "maxLength": 512
1665
+ },
1666
+ "content": {
1667
+ "type": "string",
1668
+ "minLength": 1,
1669
+ "maxLength": 131072
1670
+ }
1671
+ },
1672
+ "required": [
1673
+ "conversationId",
1674
+ "sourceMessageId",
1675
+ "assistantMessageId",
1676
+ "content"
1677
+ ],
1678
+ "additionalProperties": false
1679
+ },
1680
+ "CloudConversationListInput": {
1681
+ "type": "object",
1682
+ "description": "Host -> package input of the assistantReturns.list method. Returns at most one return per call (the native inbox delivers one per poll; a single content can reach ~768 KiB after JSON escaping, so two would risk the 1 MiB frame bound).",
1683
+ "properties": {
1684
+ "after": {
1685
+ "$ref": "#/$defs/CloudConversationReturnCursor"
1686
+ }
1687
+ },
1688
+ "additionalProperties": false
1689
+ },
1690
+ "CloudConversationListResult": {
1691
+ "type": "object",
1692
+ "properties": {
1693
+ "returns": {
1694
+ "type": "array",
1695
+ "items": {
1696
+ "$ref": "#/$defs/CloudConversationAssistantReturn"
1697
+ },
1698
+ "minItems": 0,
1699
+ "maxItems": 1
1700
+ }
1701
+ },
1702
+ "required": [
1703
+ "returns"
1704
+ ],
1705
+ "additionalProperties": false
1706
+ },
1707
+ "CloudConversationAckInput": {
1708
+ "type": "object",
1709
+ "description": "Host -> package input of the assistantReturns.ack method.",
1710
+ "properties": {
1711
+ "conversationId": {
1712
+ "type": "string",
1713
+ "minLength": 1,
1714
+ "maxLength": 200,
1715
+ "pattern": "^[A-Za-z0-9._:-]+$"
1716
+ },
1717
+ "sourceMessageId": {
1718
+ "$ref": "https://clowder-ai.dev/schemas/messaging/v0.1#/$defs/MessageId"
1719
+ },
1720
+ "assistantMessageId": {
1721
+ "type": "string",
1722
+ "minLength": 1,
1723
+ "maxLength": 512
1724
+ }
1725
+ },
1726
+ "required": [
1727
+ "conversationId",
1728
+ "sourceMessageId",
1729
+ "assistantMessageId"
1730
+ ],
1731
+ "additionalProperties": false
1732
+ },
1733
+ "CloudConversationAcknowledgedResult": {
1734
+ "type": "object",
1735
+ "properties": {
1736
+ "status": {
1737
+ "const": "acknowledged"
1738
+ }
1739
+ },
1740
+ "required": [
1741
+ "status"
1742
+ ],
1743
+ "additionalProperties": false
1744
+ },
1745
+ "CloudConversationAckFailedResult": {
1746
+ "type": "object",
1747
+ "description": "Failed ack. ASSISTANT_RETURN_NOT_FOUND means the return is already settled and must not be retried. A Host that preserves errorCode while dropping an invalid diagnostic validates in two stages: validate the envelope without diagnostic, then validate diagnostic separately.",
1748
+ "properties": {
1749
+ "status": {
1750
+ "const": "failed"
1751
+ },
1752
+ "errorCode": {
1753
+ "type": "string",
1754
+ "pattern": "^[A-Z][A-Z0-9_]{2,63}$"
1755
+ },
1756
+ "diagnostic": {
1757
+ "$ref": "#/$defs/CloudBridgeFailureDiagnosticV1"
1758
+ }
1759
+ },
1760
+ "required": [
1761
+ "status",
1762
+ "errorCode"
1763
+ ],
1764
+ "additionalProperties": false
1765
+ },
1766
+ "CloudConversationAckResult": {
1767
+ "oneOf": [
1768
+ {
1769
+ "$ref": "#/$defs/CloudConversationAcknowledgedResult"
1770
+ },
1771
+ {
1772
+ "$ref": "#/$defs/CloudConversationAckFailedResult"
1773
+ }
1774
+ ]
1775
+ },
1776
+ "UiWhenClause": {
1777
+ "type": "object",
1778
+ "properties": {
1779
+ "featureEnabled": {
1780
+ "type": "boolean"
1781
+ },
1782
+ "requiresCapabilities": {
1783
+ "type": "array",
1784
+ "items": {
1785
+ "$ref": "#/$defs/Capability"
1786
+ },
1787
+ "minItems": 1,
1788
+ "uniqueItems": true
1789
+ }
1790
+ },
1791
+ "minProperties": 1,
1792
+ "additionalProperties": false
1793
+ },
1794
+ "UiAnchor": {
1795
+ "type": "object",
1796
+ "properties": {
1797
+ "position": {
1798
+ "type": "string",
1799
+ "enum": [
1800
+ "before",
1801
+ "after"
1802
+ ]
1803
+ },
1804
+ "target": {
1805
+ "type": "string",
1806
+ "minLength": 1
1807
+ }
1808
+ },
1809
+ "required": [
1810
+ "position",
1811
+ "target"
1812
+ ],
1813
+ "additionalProperties": false
1814
+ },
1815
+ "UiCommandContribution": {
1816
+ "type": "object",
1817
+ "properties": {
1818
+ "type": {
1819
+ "const": "ui"
1820
+ },
1821
+ "id": {
1822
+ "type": "string",
1823
+ "minLength": 1
1824
+ },
1825
+ "kind": {
1826
+ "const": "command"
1827
+ },
1828
+ "label": {
1829
+ "type": "string",
1830
+ "minLength": 1
1831
+ },
1832
+ "action": {
1833
+ "$ref": "#/$defs/CallbackAction"
1834
+ },
1835
+ "when": {
1836
+ "$ref": "#/$defs/UiWhenClause"
1837
+ }
1838
+ },
1839
+ "required": [
1840
+ "type",
1841
+ "id",
1842
+ "kind",
1843
+ "label",
1844
+ "action"
1845
+ ],
1846
+ "additionalProperties": false
1847
+ },
1848
+ "UiSlotItemContribution": {
1849
+ "type": "object",
1850
+ "properties": {
1851
+ "type": {
1852
+ "const": "ui"
1853
+ },
1854
+ "id": {
1855
+ "type": "string",
1856
+ "minLength": 1
1857
+ },
1858
+ "kind": {
1859
+ "const": "slot-item"
1860
+ },
1861
+ "label": {
1862
+ "type": "string",
1863
+ "minLength": 1
1864
+ },
1865
+ "command": {
1866
+ "type": "string",
1867
+ "minLength": 1
1868
+ },
1869
+ "group": {
1870
+ "type": "string",
1871
+ "minLength": 1
1872
+ },
1873
+ "anchor": {
1874
+ "$ref": "#/$defs/UiAnchor"
1875
+ },
1876
+ "order": {
1877
+ "type": "integer",
1878
+ "minimum": -10000,
1879
+ "maximum": 10000
1880
+ },
1881
+ "when": {
1882
+ "$ref": "#/$defs/UiWhenClause"
1883
+ }
1884
+ },
1885
+ "required": [
1886
+ "type",
1887
+ "id",
1888
+ "kind",
1889
+ "label",
1890
+ "command",
1891
+ "group"
1892
+ ],
1893
+ "additionalProperties": false
1894
+ },
1895
+ "UiMessageElementContribution": {
1896
+ "type": "object",
1897
+ "properties": {
1898
+ "type": {
1899
+ "const": "ui"
1900
+ },
1901
+ "id": {
1902
+ "type": "string",
1903
+ "minLength": 1
1904
+ },
1905
+ "kind": {
1906
+ "const": "message-element"
1907
+ },
1908
+ "label": {
1909
+ "type": "string",
1910
+ "minLength": 1
1911
+ },
1912
+ "elementKind": {
1913
+ "type": "string",
1914
+ "minLength": 1
1915
+ },
1916
+ "renderer": {
1917
+ "type": "string",
1918
+ "minLength": 1
1919
+ },
1920
+ "when": {
1921
+ "$ref": "#/$defs/UiWhenClause"
1922
+ }
1923
+ },
1924
+ "required": [
1925
+ "type",
1926
+ "id",
1927
+ "kind",
1928
+ "label",
1929
+ "elementKind",
1930
+ "renderer"
1931
+ ],
1932
+ "additionalProperties": false
1933
+ },
1934
+ "UiContribution": {
1935
+ "oneOf": [
1936
+ {
1937
+ "$ref": "#/$defs/UiCommandContribution"
1938
+ },
1939
+ {
1940
+ "$ref": "#/$defs/UiSlotItemContribution"
1941
+ },
1942
+ {
1943
+ "$ref": "#/$defs/UiMessageElementContribution"
1944
+ }
1945
+ ]
1946
+ },
1947
+ "SemanticMaterializerDeclaration": {
1948
+ "type": "object",
1949
+ "description": "Optional independent DOCX computation. The Host admits one closed worker bundle under the installed package and live feature authority, in a fresh sandboxed private browser process with no ambient effects. This is not permission to execute package code in the Host or renderer.",
1950
+ "properties": {
1951
+ "executionClass": {
1952
+ "const": "dedicated-browser-worker"
1953
+ },
1954
+ "entrypoint": {
1955
+ "$ref": "#/$defs/PackageRelativePath",
1956
+ "pattern": "\\.js$"
1957
+ },
1958
+ "integrity": {
1959
+ "type": "string",
1960
+ "pattern": "^sha256-[A-Za-z0-9+/]{43}=$"
1961
+ },
1962
+ "protocolVersion": {
1963
+ "const": "1.0.0"
1964
+ }
1965
+ },
1966
+ "required": [
1967
+ "executionClass",
1968
+ "entrypoint",
1969
+ "integrity",
1970
+ "protocolVersion"
1971
+ ],
1972
+ "additionalProperties": false
1973
+ },
1974
+ "DesktopWindowContribution": {
1975
+ "type": "object",
1976
+ "description": "Host-created desktop surface under its owning feature's windows.create grant. surface.integrity verifies only the entry HTML bytes. The Host must separately verify the complete installed package and serve a verified snapshot of all referenced assets. This declares no executable, Host origin, identity, or capture permission. The Host owns window execution, media/session admission and the isolated receive-only provider channel.",
1977
+ "properties": {
1978
+ "type": {
1979
+ "const": "desktop-window"
1980
+ },
1981
+ "id": {
1982
+ "type": "string",
1983
+ "minLength": 1,
1984
+ "maxLength": 128
1985
+ },
1986
+ "role": {
1987
+ "const": "companion"
1988
+ },
1989
+ "surface": {
1990
+ "type": "object",
1991
+ "properties": {
1992
+ "entrypoint": {
1993
+ "$ref": "#/$defs/PackageRelativePath",
1994
+ "pattern": "\\.html$"
1995
+ },
1996
+ "integrity": {
1997
+ "type": "string",
1998
+ "pattern": "^sha256-[A-Za-z0-9+/]{43}=$"
1999
+ }
2000
+ },
2001
+ "required": [
2002
+ "entrypoint",
2003
+ "integrity"
2004
+ ],
2005
+ "additionalProperties": false
2006
+ },
2007
+ "bridgeVersion": {
2008
+ "enum": [
2009
+ "1.0.0",
2010
+ "1.1.0",
2011
+ "1.2.0",
2012
+ "1.3.0",
2013
+ "1.4.0",
2014
+ "1.5.0",
2015
+ "1.6.0"
2016
+ ]
2017
+ },
2018
+ "presentation": {
2019
+ "type": "object",
2020
+ "properties": {
2021
+ "width": {
2022
+ "type": "integer",
2023
+ "minimum": 160,
2024
+ "maximum": 600
2025
+ },
2026
+ "height": {
2027
+ "type": "integer",
2028
+ "minimum": 160,
2029
+ "maximum": 1000
2030
+ },
2031
+ "transparent": {
2032
+ "const": true
2033
+ },
2034
+ "frame": {
2035
+ "const": false
2036
+ },
2037
+ "alwaysOnTop": {
2038
+ "type": "boolean"
2039
+ },
2040
+ "skipTaskbar": {
2041
+ "type": "boolean"
2042
+ }
2043
+ },
2044
+ "required": [
2045
+ "width",
2046
+ "height",
2047
+ "transparent",
2048
+ "frame",
2049
+ "alwaysOnTop",
2050
+ "skipTaskbar"
2051
+ ],
2052
+ "additionalProperties": false
2053
+ }
2054
+ },
2055
+ "required": [
2056
+ "type",
2057
+ "id",
2058
+ "role",
2059
+ "surface",
2060
+ "bridgeVersion",
2061
+ "presentation"
2062
+ ],
2063
+ "additionalProperties": false
2064
+ },
2065
+ "ContentEditorProviderContribution": {
2066
+ "type": "object",
2067
+ "properties": {
2068
+ "type": {
2069
+ "const": "content-editor-provider"
2070
+ },
2071
+ "id": {
2072
+ "type": "string",
2073
+ "minLength": 1
2074
+ },
2075
+ "mediaTypes": {
2076
+ "type": "array",
2077
+ "items": {
2078
+ "const": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
2079
+ },
2080
+ "minItems": 1,
2081
+ "maxItems": 1,
2082
+ "uniqueItems": true
2083
+ },
2084
+ "surface": {
2085
+ "type": "object",
2086
+ "properties": {
2087
+ "entrypoint": {
2088
+ "$ref": "#/$defs/PackageRelativePath"
2089
+ },
2090
+ "integrity": {
2091
+ "type": "string",
2092
+ "pattern": "^sha256-[A-Za-z0-9+/]{43}=$"
2093
+ },
2094
+ "sandbox": {
2095
+ "const": "dedicated-origin-iframe",
2096
+ "description": "Host serves the renderer from an origin that has no Host cookies or Host APIs, applies sandbox=allow-scripts allow-same-origin, and sends a frame-ancestors response header restricted to the exact Host origin."
2097
+ },
2098
+ "navigationPolicy": {
2099
+ "const": "navigation-api-deny",
2100
+ "description": "The renderer must install a fail-closed Navigation API listener before upstream code and prevent every self-navigation before its request starts."
2101
+ }
2102
+ },
2103
+ "required": [
2104
+ "entrypoint",
2105
+ "integrity",
2106
+ "sandbox",
2107
+ "navigationPolicy"
2108
+ ],
2109
+ "additionalProperties": false
2110
+ },
2111
+ "bridgeVersion": {
2112
+ "const": "1.0.0"
2113
+ },
2114
+ "semanticMaterializer": {
2115
+ "$ref": "#/$defs/SemanticMaterializerDeclaration"
2116
+ },
2117
+ "operations": {
2118
+ "type": "array",
2119
+ "items": {
2120
+ "type": "string",
2121
+ "enum": [
2122
+ "load",
2123
+ "settle",
2124
+ "comment",
2125
+ "tracked-change"
2126
+ ]
2127
+ },
2128
+ "minItems": 4,
2129
+ "maxItems": 4,
2130
+ "uniqueItems": true
2131
+ }
2132
+ },
2133
+ "required": [
2134
+ "type",
2135
+ "id",
2136
+ "mediaTypes",
2137
+ "surface",
2138
+ "bridgeVersion",
2139
+ "operations"
2140
+ ],
2141
+ "additionalProperties": false
2142
+ },
2143
+ "StaticContribution": {
2144
+ "oneOf": [
2145
+ {
2146
+ "$ref": "#/$defs/IdentityContribution"
2147
+ },
2148
+ {
2149
+ "$ref": "#/$defs/ScheduleContribution"
2150
+ },
2151
+ {
2152
+ "$ref": "#/$defs/DirectToolContribution"
2153
+ },
2154
+ {
2155
+ "$ref": "#/$defs/McpContribution"
2156
+ },
2157
+ {
2158
+ "$ref": "#/$defs/SkillContribution"
2159
+ },
2160
+ {
2161
+ "$ref": "#/$defs/LimbContribution"
2162
+ },
2163
+ {
2164
+ "$ref": "#/$defs/WebhookContribution"
2165
+ },
2166
+ {
2167
+ "$ref": "#/$defs/MessageSubscriptionContribution"
2168
+ },
2169
+ {
2170
+ "$ref": "#/$defs/MediaSourceContribution"
2171
+ },
2172
+ {
2173
+ "$ref": "#/$defs/ServiceContribution"
2174
+ },
2175
+ {
2176
+ "$ref": "#/$defs/ConnectorContribution"
2177
+ },
2178
+ {
2179
+ "$ref": "#/$defs/CloudConversationHostContribution"
2180
+ },
2181
+ {
2182
+ "$ref": "#/$defs/UiContribution"
2183
+ },
2184
+ {
2185
+ "$ref": "#/$defs/ContentEditorProviderContribution"
2186
+ },
2187
+ {
2188
+ "$ref": "#/$defs/DesktopWindowContribution"
2189
+ }
2190
+ ]
2191
+ },
2192
+ "PluginFeature": {
2193
+ "type": "object",
2194
+ "properties": {
2195
+ "id": {
2196
+ "type": "string",
2197
+ "minLength": 1
2198
+ },
2199
+ "name": {
2200
+ "type": "string",
2201
+ "minLength": 1
2202
+ },
2203
+ "resources": {
2204
+ "type": "array",
2205
+ "items": {
2206
+ "$ref": "#/$defs/ResourceReference"
2207
+ }
2208
+ },
2209
+ "contributions": {
2210
+ "type": "array",
2211
+ "items": {
2212
+ "$ref": "#/$defs/ContributionReference"
2213
+ }
2214
+ },
2215
+ "capabilities": {
2216
+ "type": "array",
2217
+ "items": {
2218
+ "$ref": "#/$defs/Capability"
2219
+ },
2220
+ "description": "@signed(G-0 2026-07-15) \u2014 capability vocabulary is contract-versioned (P15). Adding a new capability = new contract version. Unknown strings are structurally rejected at schema level; authorization is a separate host runtime layer. Lifecycle callbacks are protocol-intrinsic baseline behavior, so they are not grantable or revocable capability IDs."
2221
+ }
2222
+ },
2223
+ "required": [
2224
+ "id",
2225
+ "name",
2226
+ "resources",
2227
+ "capabilities"
2228
+ ],
2229
+ "additionalProperties": false
2230
+ },
2231
+ "RuntimeTransport": {
2232
+ "type": "string",
2233
+ "enum": [
2234
+ "stdio",
2235
+ "ipc",
2236
+ "builtin"
2237
+ ]
2238
+ },
2239
+ "ExternalRuntimeTransport": {
2240
+ "type": "string",
2241
+ "enum": [
2242
+ "stdio",
2243
+ "ipc"
2244
+ ]
2245
+ },
2246
+ "ExternalRuntimeDeclaration": {
2247
+ "type": "object",
2248
+ "properties": {
2249
+ "transport": {
2250
+ "$ref": "#/$defs/ExternalRuntimeTransport"
2251
+ },
2252
+ "entrypoint": {
2253
+ "$ref": "#/$defs/PackageRelativePath"
2254
+ }
2255
+ },
2256
+ "required": [
2257
+ "transport",
2258
+ "entrypoint"
2259
+ ],
2260
+ "additionalProperties": false
2261
+ },
2262
+ "BuiltinRuntimeDeclaration": {
2263
+ "type": "object",
2264
+ "properties": {
2265
+ "transport": {
2266
+ "const": "builtin"
2267
+ },
2268
+ "entrypoint": {
2269
+ "type": "string",
2270
+ "minLength": 1
2271
+ },
2272
+ "dataDirectory": {
2273
+ "type": "string",
2274
+ "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$",
2275
+ "description": "Single-segment module data directory name ('.' and '..' are excluded by the pattern). The Host creates <projectRoot>/.cat-cafe/plugin-host/<name> (0700) before start and each installed instance receives it as dataPath without a separate grant; omit to derive the name from the plugin id. Uninstall retains the directory (owner data)."
2276
+ }
2277
+ },
2278
+ "required": [
2279
+ "transport"
2280
+ ],
2281
+ "additionalProperties": false
2282
+ },
2283
+ "RuntimeDeclaration": {
2284
+ "oneOf": [
2285
+ {
2286
+ "$ref": "#/$defs/ExternalRuntimeDeclaration"
2287
+ },
2288
+ {
2289
+ "$ref": "#/$defs/BuiltinRuntimeDeclaration"
2290
+ }
2291
+ ]
2292
+ }
2293
+ },
2294
+ "type": "object",
2295
+ "properties": {
2296
+ "pluginId": {
2297
+ "type": "string",
2298
+ "minLength": 1
2299
+ },
2300
+ "version": {
2301
+ "$ref": "#/$defs/SemVer",
2302
+ "description": "Plugin version \u2014 must be valid semver (\u00a79: numeric prerelease identifiers MUST NOT have leading zeroes)."
2303
+ },
2304
+ "contractVersion": {
2305
+ "$ref": "#/$defs/SemVer",
2306
+ "description": "Must be an exact published semver version \u2014 no ranges, wildcards, or operator prefixes (five-step freeze: pin exact version). \u00a79: numeric prerelease identifiers MUST NOT have leading zeroes."
2307
+ },
2308
+ "name": {
2309
+ "type": "string",
2310
+ "minLength": 1
2311
+ },
2312
+ "description": {
2313
+ "$ref": "https://clowder-ai.dev/schemas/plugin-metadata/v1#/$defs/LocalizedDescription"
2314
+ },
2315
+ "icon": {
2316
+ "$ref": "https://clowder-ai.dev/schemas/plugin-metadata/v1#/$defs/PluginIcon"
2317
+ },
2318
+ "configuration": {
2319
+ "type": "array",
2320
+ "items": {
2321
+ "$ref": "#/$defs/ConfigurationField"
2322
+ }
2323
+ },
2324
+ "configurationVariants": {
2325
+ "$ref": "#/$defs/ConfigurationVariants"
2326
+ },
2327
+ "contributions": {
2328
+ "type": "array",
2329
+ "items": {
2330
+ "$ref": "#/$defs/StaticContribution"
2331
+ }
2332
+ },
2333
+ "features": {
2334
+ "type": "array",
2335
+ "items": {
2336
+ "$ref": "#/$defs/PluginFeature"
2337
+ },
2338
+ "minItems": 1
2339
+ },
2340
+ "data": {
2341
+ "type": "array",
2342
+ "items": {
2343
+ "$ref": "#/$defs/DataDeclaration"
2344
+ }
2345
+ },
2346
+ "runtime": {
2347
+ "$ref": "#/$defs/RuntimeDeclaration"
2348
+ },
2349
+ "test": {
2350
+ "$ref": "#/$defs/PluginTestDeclaration"
2351
+ },
2352
+ "permissions": {
2353
+ "$ref": "#/$defs/ConnectorPermissions"
2354
+ },
2355
+ "steps": {
2356
+ "type": "array",
2357
+ "items": {
2358
+ "$ref": "#/$defs/SetupStep"
2359
+ },
2360
+ "minItems": 1
2361
+ },
2362
+ "signals": {
2363
+ "$ref": "https://clowder-ai.dev/schemas/signals/v0.2#/$defs/SignalContribution"
2364
+ }
183
2365
  },
184
- "required": ["pluginId", "version", "contractVersion", "name", "features", "runtime"],
2366
+ "required": [
2367
+ "pluginId",
2368
+ "version",
2369
+ "contractVersion",
2370
+ "name",
2371
+ "features"
2372
+ ],
185
2373
  "additionalProperties": false
186
2374
  }