@clowder-ai/plugin-contract 0.1.0-beta.29 → 0.1.0-beta.37

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