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