@clowder-ai/plugin-contract 0.1.0-beta.3 → 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 (159) hide show
  1. package/dist/codegen/generate-contract.d.ts +10 -0
  2. package/dist/codegen/generate-contract.d.ts.map +1 -1
  3. package/dist/codegen/generate-contract.js +362 -21
  4. package/dist/codegen/generate-contract.js.map +1 -1
  5. package/dist/conformance/fixtures.d.ts +11 -0
  6. package/dist/conformance/fixtures.d.ts.map +1 -0
  7. package/dist/conformance/fixtures.js +9 -0
  8. package/dist/conformance/fixtures.js.map +1 -0
  9. package/dist/conformance/index.d.ts +4 -1
  10. package/dist/conformance/index.d.ts.map +1 -1
  11. package/dist/conformance/index.js +3 -1
  12. package/dist/conformance/index.js.map +1 -1
  13. package/dist/conformance/messaging-behavior-fixture.d.ts +12 -0
  14. package/dist/conformance/messaging-behavior-fixture.d.ts.map +1 -0
  15. package/dist/conformance/messaging-behavior-fixture.js +30 -0
  16. package/dist/conformance/messaging-behavior-fixture.js.map +1 -0
  17. package/dist/conformance/runner.d.ts.map +1 -1
  18. package/dist/conformance/runner.js +23 -3
  19. package/dist/conformance/runner.js.map +1 -1
  20. package/dist/conformance/stdio-harness/child-process-harness.d.ts +6 -0
  21. package/dist/conformance/stdio-harness/child-process-harness.d.ts.map +1 -1
  22. package/dist/conformance/stdio-harness/child-process-harness.js +26 -9
  23. package/dist/conformance/stdio-harness/child-process-harness.js.map +1 -1
  24. package/dist/conformance/stdio-harness/index.d.ts +1 -1
  25. package/dist/conformance/stdio-harness/index.d.ts.map +1 -1
  26. package/dist/conformance/stdio-harness/index.js +1 -1
  27. package/dist/conformance/stdio-harness/index.js.map +1 -1
  28. package/dist/conformance/stdio-harness/ndjson-frame.d.ts +6 -1
  29. package/dist/conformance/stdio-harness/ndjson-frame.d.ts.map +1 -1
  30. package/dist/conformance/stdio-harness/ndjson-frame.js +7 -1
  31. package/dist/conformance/stdio-harness/ndjson-frame.js.map +1 -1
  32. package/dist/conformance/stdio-harness/wire-shape.d.ts +1 -1
  33. package/dist/docx-materialization.d.ts +8 -0
  34. package/dist/docx-materialization.d.ts.map +1 -0
  35. package/dist/docx-materialization.js +19 -0
  36. package/dist/docx-materialization.js.map +1 -0
  37. package/dist/generated/contract.generated.d.ts +1793 -32
  38. package/dist/generated/contract.generated.d.ts.map +1 -1
  39. package/dist/generated/contract.generated.js +72 -3
  40. package/dist/generated/contract.generated.js.map +1 -1
  41. package/dist/index.d.ts +2 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/validation/catalog.d.ts +21 -0
  46. package/dist/validation/catalog.d.ts.map +1 -0
  47. package/dist/validation/catalog.js +140 -0
  48. package/dist/validation/catalog.js.map +1 -0
  49. package/dist/validation/cloud-conversation-host.d.ts +18 -0
  50. package/dist/validation/cloud-conversation-host.d.ts.map +1 -0
  51. package/dist/validation/cloud-conversation-host.js +83 -0
  52. package/dist/validation/cloud-conversation-host.js.map +1 -0
  53. package/dist/validation/companion-bridge.d.ts +6 -0
  54. package/dist/validation/companion-bridge.d.ts.map +1 -0
  55. package/dist/validation/companion-bridge.js +198 -0
  56. package/dist/validation/companion-bridge.js.map +1 -0
  57. package/dist/validation/docx-materialization.d.ts +6 -0
  58. package/dist/validation/docx-materialization.d.ts.map +1 -0
  59. package/dist/validation/docx-materialization.js +36 -0
  60. package/dist/validation/docx-materialization.js.map +1 -0
  61. package/dist/validation/index.d.ts +10 -0
  62. package/dist/validation/index.d.ts.map +1 -1
  63. package/dist/validation/index.js +10 -0
  64. package/dist/validation/index.js.map +1 -1
  65. package/dist/validation/manifest.d.ts +23 -0
  66. package/dist/validation/manifest.d.ts.map +1 -0
  67. package/dist/validation/manifest.js +273 -0
  68. package/dist/validation/manifest.js.map +1 -0
  69. package/dist/validation/members.d.ts +4 -0
  70. package/dist/validation/members.d.ts.map +1 -0
  71. package/dist/validation/members.js +11 -0
  72. package/dist/validation/members.js.map +1 -0
  73. package/dist/validation/messaging-semantic.d.ts.map +1 -1
  74. package/dist/validation/messaging-semantic.js +98 -0
  75. package/dist/validation/messaging-semantic.js.map +1 -1
  76. package/dist/validation/messaging-wire.d.ts +42 -0
  77. package/dist/validation/messaging-wire.d.ts.map +1 -0
  78. package/dist/validation/messaging-wire.js +184 -0
  79. package/dist/validation/messaging-wire.js.map +1 -0
  80. package/dist/validation/operation-rows.d.ts +25 -0
  81. package/dist/validation/operation-rows.d.ts.map +1 -0
  82. package/dist/validation/operation-rows.js +135 -0
  83. package/dist/validation/operation-rows.js.map +1 -0
  84. package/dist/validation/signals.d.ts +17 -0
  85. package/dist/validation/signals.d.ts.map +1 -0
  86. package/dist/validation/signals.js +32 -0
  87. package/dist/validation/signals.js.map +1 -0
  88. package/dist/wire/constants.d.ts +2 -1
  89. package/dist/wire/constants.d.ts.map +1 -1
  90. package/dist/wire/constants.js +2 -1
  91. package/dist/wire/constants.js.map +1 -1
  92. package/dist/wire/dispatch.d.ts +49 -0
  93. package/dist/wire/dispatch.d.ts.map +1 -0
  94. package/dist/wire/dispatch.js +880 -0
  95. package/dist/wire/dispatch.js.map +1 -0
  96. package/dist/wire/disposition-fixtures.d.ts +19 -2
  97. package/dist/wire/disposition-fixtures.d.ts.map +1 -1
  98. package/dist/wire/disposition-fixtures.js +1110 -77
  99. package/dist/wire/disposition-fixtures.js.map +1 -1
  100. package/dist/wire/disposition.d.ts +10 -8
  101. package/dist/wire/disposition.d.ts.map +1 -1
  102. package/dist/wire/disposition.js +20 -8
  103. package/dist/wire/disposition.js.map +1 -1
  104. package/dist/wire/envelope.d.ts +31 -0
  105. package/dist/wire/envelope.d.ts.map +1 -1
  106. package/dist/wire/envelope.js +48 -1
  107. package/dist/wire/envelope.js.map +1 -1
  108. package/dist/wire/errors.d.ts +31 -1
  109. package/dist/wire/errors.d.ts.map +1 -1
  110. package/dist/wire/errors.js +36 -0
  111. package/dist/wire/errors.js.map +1 -1
  112. package/dist/wire/grants.d.ts +4 -4
  113. package/dist/wire/grants.js +3 -3
  114. package/dist/wire/handshake-byte-bounds.d.ts +69 -0
  115. package/dist/wire/handshake-byte-bounds.d.ts.map +1 -0
  116. package/dist/wire/handshake-byte-bounds.js +176 -0
  117. package/dist/wire/handshake-byte-bounds.js.map +1 -0
  118. package/dist/wire/handshake.d.ts +59 -7
  119. package/dist/wire/handshake.d.ts.map +1 -1
  120. package/dist/wire/handshake.js +132 -10
  121. package/dist/wire/handshake.js.map +1 -1
  122. package/dist/wire/index.d.ts +18 -7
  123. package/dist/wire/index.d.ts.map +1 -1
  124. package/dist/wire/index.js +35 -6
  125. package/dist/wire/index.js.map +1 -1
  126. package/dist/wire/lifecycle-byte-bounds.d.ts +40 -0
  127. package/dist/wire/lifecycle-byte-bounds.d.ts.map +1 -0
  128. package/dist/wire/lifecycle-byte-bounds.js +149 -0
  129. package/dist/wire/lifecycle-byte-bounds.js.map +1 -0
  130. package/dist/wire/messaging-byte-bounds.d.ts +62 -0
  131. package/dist/wire/messaging-byte-bounds.d.ts.map +1 -0
  132. package/dist/wire/messaging-byte-bounds.js +581 -0
  133. package/dist/wire/messaging-byte-bounds.js.map +1 -0
  134. package/dist/wire/registry.d.ts +192 -35
  135. package/dist/wire/registry.d.ts.map +1 -1
  136. package/dist/wire/registry.js +57 -79
  137. package/dist/wire/registry.js.map +1 -1
  138. package/dist/wire/row-shapes.d.ts +98 -81
  139. package/dist/wire/row-shapes.d.ts.map +1 -1
  140. package/dist/wire/row-shapes.js +31 -4
  141. package/dist/wire/row-shapes.js.map +1 -1
  142. package/fixtures/behavior/messaging/adversarial-invariants.json +92 -2
  143. package/fixtures/manifest/invalid/duplicate-signal-type.json +35 -0
  144. package/fixtures/manifest/invalid/icon-package-escape.json +22 -0
  145. package/fixtures/manifest/valid/localized-product-metadata.json +27 -0
  146. package/fixtures/messaging/valid/subscription-delivery.json +1 -1
  147. package/fixtures/signals/invalid/dynamic-schema-url.json +10 -0
  148. package/fixtures/signals/invalid/forbidden-raw-privacy.json +10 -0
  149. package/fixtures/signals/valid/remote-service-declaration.json +10 -0
  150. package/package.json +18 -5
  151. package/src/schemas/behavior-fixture.schema.json +903 -116
  152. package/src/schemas/catalog.schema.json +91 -0
  153. package/src/schemas/companion-bridge.schema.json +2256 -0
  154. package/src/schemas/docx-materialization.schema.json +302 -0
  155. package/src/schemas/manifest.schema.json +2223 -89
  156. package/src/schemas/messaging.schema.json +692 -40
  157. package/src/schemas/physical-limb.schema.json +319 -0
  158. package/src/schemas/plugin-metadata.schema.json +62 -0
  159. package/src/schemas/signal.schema.json +119 -0
@@ -0,0 +1,184 @@
1
+ import { createRequire } from 'node:module';
2
+ import { validateMessagingSemantics } from './messaging-semantic.js';
3
+ const require = createRequire(import.meta.url);
4
+ const Ajv2020 = require('ajv/dist/2020');
5
+ const addFormats = require('ajv-formats');
6
+ const messagingSchema = require('@clowder-ai/plugin-contract/schemas/messaging');
7
+ export const MESSAGING_ROW_METHODS = [
8
+ 'messaging.send',
9
+ 'messaging.appendElements',
10
+ 'messaging.subscribe',
11
+ 'messaging.read',
12
+ 'messaging.ack',
13
+ 'messaging.snapshot',
14
+ 'streams.read',
15
+ 'host.messaging.deliver',
16
+ ];
17
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
18
+ addFormats(ajv);
19
+ ajv.addSchema(messagingSchema, messagingSchema['$id']);
20
+ function validator(definition) {
21
+ const validate = ajv.getSchema(`${String(messagingSchema['$id'])}#/$defs/${definition}`);
22
+ if (!validate)
23
+ throw new Error(`missing messaging schema definition: ${definition}`);
24
+ return { definition, validate };
25
+ }
26
+ const INPUT_VALIDATORS = {
27
+ 'messaging.send': validator('MessageDraft'),
28
+ 'messaging.appendElements': validator('AppendElementsRequest'),
29
+ 'messaging.subscribe': validator('M0CSubscribeInput'),
30
+ 'messaging.read': validator('M0CReadInput'),
31
+ 'messaging.ack': validator('M0CAckInput'),
32
+ 'messaging.snapshot': validator('M0CSnapshotInput'),
33
+ 'streams.read': validator('MediaReadInput'),
34
+ 'host.messaging.deliver': validator('PluginDeliveryInput'),
35
+ };
36
+ const RESULT_VALIDATORS = {
37
+ 'messaging.send': validator('SendReceipt'),
38
+ 'messaging.appendElements': validator('AppendReceipt'),
39
+ 'messaging.subscribe': validator('M0CSubscribeResult'),
40
+ 'messaging.read': validator('M0CReadResult'),
41
+ 'messaging.ack': validator('M0CAckResult'),
42
+ 'messaging.snapshot': validator('M0CSnapshotResult'),
43
+ 'streams.read': validator('MediaReadResult'),
44
+ 'host.messaging.deliver': validator('PluginDeliveryReceipt'),
45
+ };
46
+ function hasOnlyUnicodeScalars(value) {
47
+ for (let index = 0; index < value.length; index += 1) {
48
+ const unit = value.charCodeAt(index);
49
+ if (unit >= 0xd800 && unit <= 0xdbff) {
50
+ const next = value.charCodeAt(index + 1);
51
+ if (!(next >= 0xdc00 && next <= 0xdfff))
52
+ return false;
53
+ index += 1;
54
+ }
55
+ else if (unit >= 0xdc00 && unit <= 0xdfff) {
56
+ return false;
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ function isJsonScalarTree(value, ancestors = new Set()) {
62
+ if (value === null || typeof value === 'boolean')
63
+ return true;
64
+ if (typeof value === 'string')
65
+ return hasOnlyUnicodeScalars(value);
66
+ if (typeof value === 'number')
67
+ return Number.isFinite(value);
68
+ if (typeof value !== 'object')
69
+ return false;
70
+ if (ancestors.has(value))
71
+ return false;
72
+ const prototype = Object.getPrototypeOf(value);
73
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
74
+ return false;
75
+ }
76
+ if (Object.getOwnPropertySymbols(value).length > 0)
77
+ return false;
78
+ ancestors.add(value);
79
+ let valid = true;
80
+ if (Array.isArray(value)) {
81
+ for (let index = 0; index < value.length; index += 1) {
82
+ if (!Object.hasOwn(value, index) || !isJsonScalarTree(value[index], ancestors)) {
83
+ valid = false;
84
+ break;
85
+ }
86
+ }
87
+ if (valid) {
88
+ valid = Object.keys(value).every((key) => /^(0|[1-9][0-9]*)$/.test(key));
89
+ }
90
+ }
91
+ else {
92
+ for (const [key, child] of Object.entries(value)) {
93
+ if (!hasOnlyUnicodeScalars(key) || !isJsonScalarTree(child, ancestors)) {
94
+ valid = false;
95
+ break;
96
+ }
97
+ }
98
+ }
99
+ ancestors.delete(value);
100
+ return valid;
101
+ }
102
+ function errorsOf(validate) {
103
+ return (validate.errors ?? []).map((error) => ({
104
+ instancePath: error.instancePath,
105
+ schemaPath: error.schemaPath,
106
+ keyword: error.keyword,
107
+ message: error.message ?? 'messaging row validation failed',
108
+ }));
109
+ }
110
+ function invalid(instancePath, schemaPath, keyword, message) {
111
+ return {
112
+ valid: false,
113
+ errors: [{ instancePath, schemaPath, keyword, message }],
114
+ };
115
+ }
116
+ function validateWith(entry, value) {
117
+ let jsonSafe = false;
118
+ try {
119
+ jsonSafe = isJsonScalarTree(value);
120
+ }
121
+ catch {
122
+ jsonSafe = false;
123
+ }
124
+ if (!jsonSafe) {
125
+ return invalid('', `#/$defs/${entry.definition}`, 'jsonScalarTree', 'value must contain only finite JSON values and Unicode scalar strings without cycles');
126
+ }
127
+ let structurallyValid = false;
128
+ try {
129
+ structurallyValid = entry.validate(value);
130
+ }
131
+ catch {
132
+ structurallyValid = false;
133
+ }
134
+ if (!structurallyValid) {
135
+ const errors = errorsOf(entry.validate);
136
+ return errors.length > 0
137
+ ? { valid: false, errors }
138
+ : invalid('', `#/$defs/${entry.definition}`, 'schema', 'schema validation failed');
139
+ }
140
+ if (entry.definition === 'PluginDeliveryInput') {
141
+ const delivery = value;
142
+ if (delivery.kind === 'message' && delivery.threadId !== delivery.envelope.threadId) {
143
+ return invalid('/threadId', '#/$defs/PluginDeliveryInput', 'threadIdentity', 'delivery thread must match the envelope');
144
+ }
145
+ }
146
+ const semantic = validateMessagingSemantics(entry.definition, value);
147
+ if (!semantic.valid) {
148
+ return {
149
+ valid: false,
150
+ errors: semantic.errors.map((error) => ({
151
+ instancePath: error.path,
152
+ schemaPath: `#/$defs/${entry.definition}`,
153
+ keyword: 'maxEncodedBytes',
154
+ message: error.message,
155
+ })),
156
+ };
157
+ }
158
+ return { valid: true, value: value, errors: [] };
159
+ }
160
+ export function validateMessagingRowInput(method, value) {
161
+ return validateWith(INPUT_VALIDATORS[method], value);
162
+ }
163
+ export function validateMessagingRowResult(method, value) {
164
+ const structural = validateWith(RESULT_VALIDATORS[method], value);
165
+ if (!structural.valid || method !== 'messaging.send')
166
+ return structural;
167
+ const receipt = structural.value;
168
+ if (receipt.messageHandle.token === receipt.messageId) {
169
+ return invalid('/messageHandle/token', '#/$defs/SendReceipt', 'messageHandleIdentity', 'messageHandle.token must not equal messageId');
170
+ }
171
+ return structural;
172
+ }
173
+ const PLUGIN_DELIVERY = validator('PluginDeliveryInput');
174
+ const PLUGIN_RECEIPT = validator('PluginDeliveryReceipt');
175
+ export function isPluginDeliveryInput(value) {
176
+ if (!validateWith(PLUGIN_DELIVERY, value).valid)
177
+ return false;
178
+ const input = value;
179
+ return input.kind !== 'message' || input.envelope.threadId === input.threadId;
180
+ }
181
+ export function isPluginDeliveryReceipt(value) {
182
+ return PLUGIN_RECEIPT.validate(value);
183
+ }
184
+ //# sourceMappingURL=messaging-wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-wire.js","sourceRoot":"","sources":["../../src/validation/messaging-wire.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ActionDef, OperationRows } from '../generated/contract.generated.js';
2
+ export interface OperationRowsValidationError {
3
+ readonly instancePath: string;
4
+ readonly schemaPath: string;
5
+ readonly keyword: string;
6
+ readonly message: string;
7
+ }
8
+ export type OperationRowsValidationResult = {
9
+ readonly valid: true;
10
+ readonly value: OperationRows;
11
+ readonly errors: readonly [];
12
+ } | {
13
+ readonly valid: false;
14
+ readonly errors: readonly OperationRowsValidationError[];
15
+ };
16
+ /**
17
+ * Validates an `OperationActionResult` with `render: 'rows'` against the manifest's
18
+ * row declarations of the same operation. Host fail-closed: an undeclared or
19
+ * non-row action reference, a duplicate row key, or any schema violation makes the
20
+ * whole result invalid.
21
+ */
22
+ export declare function validateOperationRowsResult(operation: {
23
+ readonly actions: readonly ActionDef[];
24
+ }, value: unknown): OperationRowsValidationResult;
25
+ //# sourceMappingURL=operation-rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-rows.d.ts","sourceRoot":"","sources":["../../src/validation/operation-rows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAgCnF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,6BAA6B,GACrC;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GACrF;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,4BAA4B,EAAE,CAAA;CAAE,CAAC;AA6ExF;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,EACrD,KAAK,EAAE,OAAO,GACb,6BAA6B,CAmE/B"}
@@ -0,0 +1,135 @@
1
+ import { createRequire } from 'node:module';
2
+ const require = createRequire(import.meta.url);
3
+ const Ajv2020 = require('ajv/dist/2020');
4
+ const addFormats = require('ajv-formats');
5
+ const manifestSchema = require('@clowder-ai/plugin-contract/schemas/manifest');
6
+ const messagingSchema = require('@clowder-ai/plugin-contract/schemas/messaging');
7
+ const pluginMetadataSchema = require('@clowder-ai/plugin-contract/schemas/plugin-metadata');
8
+ const signalSchema = require('@clowder-ai/plugin-contract/schemas/signals');
9
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
10
+ addFormats(ajv);
11
+ const schemaId = manifestSchema['$id'];
12
+ ajv.addSchema(pluginMetadataSchema, pluginMetadataSchema['$id']);
13
+ ajv.addSchema(signalSchema, signalSchema['$id']);
14
+ ajv.addSchema(messagingSchema, messagingSchema['$id']);
15
+ ajv.addSchema(manifestSchema, schemaId);
16
+ const validateRowsShape = ajv.compile({
17
+ $ref: `${schemaId}#/$defs/OperationRows`,
18
+ });
19
+ function hasOnlyUnicodeScalars(value) {
20
+ for (let index = 0; index < value.length; index += 1) {
21
+ const unit = value.charCodeAt(index);
22
+ if (unit >= 0xd800 && unit <= 0xdbff) {
23
+ const next = value.charCodeAt(index + 1);
24
+ if (!(next >= 0xdc00 && next <= 0xdfff))
25
+ return false;
26
+ index += 1;
27
+ }
28
+ else if (unit >= 0xdc00 && unit <= 0xdfff) {
29
+ return false;
30
+ }
31
+ }
32
+ return true;
33
+ }
34
+ function isJsonScalarTree(value, ancestors = new Set()) {
35
+ if (value === null || typeof value === 'boolean')
36
+ return true;
37
+ if (typeof value === 'string')
38
+ return hasOnlyUnicodeScalars(value);
39
+ if (typeof value === 'number')
40
+ return Number.isFinite(value);
41
+ if (typeof value !== 'object')
42
+ return false;
43
+ if (ancestors.has(value))
44
+ return false;
45
+ const prototype = Object.getPrototypeOf(value);
46
+ if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
47
+ return false;
48
+ }
49
+ if (Object.getOwnPropertySymbols(value).length > 0)
50
+ return false;
51
+ ancestors.add(value);
52
+ let valid = true;
53
+ if (Array.isArray(value)) {
54
+ for (let index = 0; index < value.length; index += 1) {
55
+ if (!Object.hasOwn(value, index) || !isJsonScalarTree(value[index], ancestors)) {
56
+ valid = false;
57
+ break;
58
+ }
59
+ }
60
+ if (valid) {
61
+ valid = Object.keys(value).every((key) => /^(0|[1-9][0-9]*)$/.test(key));
62
+ }
63
+ }
64
+ else {
65
+ for (const [key, child] of Object.entries(value)) {
66
+ if (!hasOnlyUnicodeScalars(key) || !isJsonScalarTree(child, ancestors)) {
67
+ valid = false;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ ancestors.delete(value);
73
+ return valid;
74
+ }
75
+ function invalid(instancePath, schemaPath, keyword, message) {
76
+ return {
77
+ valid: false,
78
+ errors: [{ instancePath, schemaPath, keyword, message }],
79
+ };
80
+ }
81
+ /**
82
+ * Validates an `OperationActionResult` with `render: 'rows'` against the manifest's
83
+ * row declarations of the same operation. Host fail-closed: an undeclared or
84
+ * non-row action reference, a duplicate row key, or any schema violation makes the
85
+ * whole result invalid.
86
+ */
87
+ export function validateOperationRowsResult(operation, value) {
88
+ let jsonSafe = false;
89
+ try {
90
+ jsonSafe = isJsonScalarTree(value);
91
+ }
92
+ catch {
93
+ jsonSafe = false;
94
+ }
95
+ if (!jsonSafe) {
96
+ return invalid('', '#/$defs/OperationRows', 'jsonScalarTree', 'value must contain only finite JSON values and Unicode scalar strings without cycles');
97
+ }
98
+ let structurallyValid = false;
99
+ try {
100
+ structurallyValid = validateRowsShape(value);
101
+ }
102
+ catch {
103
+ structurallyValid = false;
104
+ }
105
+ if (!structurallyValid) {
106
+ const errors = (validateRowsShape.errors ?? []).map((error) => ({
107
+ instancePath: error.instancePath,
108
+ schemaPath: error.schemaPath,
109
+ keyword: error.keyword,
110
+ message: error.message ?? 'operation rows validation failed',
111
+ }));
112
+ return errors.length > 0
113
+ ? { valid: false, errors }
114
+ : invalid('', '#/$defs/OperationRows', 'schema', 'schema validation failed');
115
+ }
116
+ const rows = value;
117
+ const rowActionIds = new Set(operation.actions.filter((action) => action.render === 'row').map((action) => action.id));
118
+ const seenKeys = new Set();
119
+ for (let rowIndex = 0; rowIndex < rows.rows.length; rowIndex += 1) {
120
+ const row = rows.rows[rowIndex];
121
+ if (seenKeys.has(row.key)) {
122
+ return invalid(`/rows/${rowIndex}/key`, '#/$defs/OperationRow', 'uniqueKeys', `row key must be unique within the result: ${row.key}`);
123
+ }
124
+ seenKeys.add(row.key);
125
+ const actions = row.actions ?? [];
126
+ for (let actionIndex = 0; actionIndex < actions.length; actionIndex += 1) {
127
+ const reference = actions[actionIndex].action;
128
+ if (!rowActionIds.has(reference)) {
129
+ return invalid(`/rows/${rowIndex}/actions/${actionIndex}/action`, '#/$defs/OperationRowAction', 'rowActionReference', `row action must reference an ActionDef with render 'row' declared in the same operation: ${reference}`);
130
+ }
131
+ }
132
+ }
133
+ return { valid: true, value: rows, errors: [] };
134
+ }
135
+ //# sourceMappingURL=operation-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-rows.js","sourceRoot":"","sources":["../../src/validation/operation-rows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { SignalDeclaration } from '../generated/contract.generated.js';
2
+ export interface SignalValidationError {
3
+ readonly instancePath: string;
4
+ readonly schemaPath: string;
5
+ readonly keyword: string;
6
+ readonly message: string;
7
+ }
8
+ export type SignalValidationResult<Value> = {
9
+ readonly valid: true;
10
+ readonly value: Value;
11
+ readonly errors: readonly [];
12
+ } | {
13
+ readonly valid: false;
14
+ readonly errors: readonly SignalValidationError[];
15
+ };
16
+ export declare function validateSignalDeclaration(value: unknown): SignalValidationResult<SignalDeclaration>;
17
+ //# sourceMappingURL=signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/validation/signals.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AA+B5C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,sBAAsB,CAAC,KAAK,IACpC;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAAE,CAAC;AAiCjF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,sBAAsB,CAAC,iBAAiB,CAAC,CAE3C"}
@@ -0,0 +1,32 @@
1
+ import { createRequire } from 'node:module';
2
+ const require = createRequire(import.meta.url);
3
+ const Ajv2020 = require('ajv/dist/2020');
4
+ const addFormats = require('ajv-formats');
5
+ const signalSchema = require('@clowder-ai/plugin-contract/schemas/signals');
6
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
7
+ addFormats(ajv);
8
+ ajv.addSchema(signalSchema, signalSchema['$id']);
9
+ function validator(definition) {
10
+ const validate = ajv.getSchema(`${String(signalSchema['$id'])}#/$defs/${definition}`);
11
+ if (!validate)
12
+ throw new Error(`missing signal schema definition: ${definition}`);
13
+ return validate;
14
+ }
15
+ const validateDeclarationSchema = validator('SignalDeclaration');
16
+ function errorsOf(validate) {
17
+ return (validate.errors ?? []).map((error) => ({
18
+ instancePath: error.instancePath,
19
+ schemaPath: error.schemaPath,
20
+ keyword: error.keyword,
21
+ message: error.message ?? 'signal validation failed',
22
+ }));
23
+ }
24
+ function validateWith(validate, value) {
25
+ if (!validate(value))
26
+ return { valid: false, errors: errorsOf(validate) };
27
+ return { valid: true, value: value, errors: [] };
28
+ }
29
+ export function validateSignalDeclaration(value) {
30
+ return validateWith(validateDeclarationSchema, value);
31
+ }
32
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/validation/signals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAM5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,OAAO,GAGO,OAAO,CAAC,eAAe,CAAC,CAAC;AAC7C,MAAM,UAAU,GAA+B,OAAO,CAAC,aAAa,CAAC,CAAC;AACtE,MAAM,YAAY,GAAG,OAAO,CAAC,6CAA6C,CAGzE,CAAC;AA+BF,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,UAAU,CAAC,GAAG,CAAC,CAAC;AAChB,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,KAAK,CAAW,CAAC,CAAC;AAE3D,SAAS,SAAS,CAAC,UAAkB;IACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAC5B,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,UAAU,EAAE,CACtD,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,EAAE,CAAC,CAAC;IAClF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,yBAAyB,GAAG,SAAS,CAAC,mBAAmB,CAAC,CAAC;AAEjE,SAAS,QAAQ,CAAC,QAA6B;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7C,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,0BAA0B;KACrD,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,YAAY,CACnB,QAA6B,EAC7B,KAAc;IAEd,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC1E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAc,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAc;IAEd,OAAO,YAAY,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC"}
@@ -14,7 +14,8 @@ export declare const JSONRPC_VERSION: "2.0";
14
14
  /**
15
15
  * Maximum payload bytes per element payload (frozen x-clowder-bounds).
16
16
  * Open-membered payloads (MediaRefElementPayload, RichBlockElementPayload)
17
- * are bounded by this ceiling alone — no structural narrowing.
17
+ * use their contract schemas for structural narrowing. Unknown extension payloads remain
18
+ * open and are bounded by this ceiling.
18
19
  */
19
20
  export declare const MAX_ELEMENT_PAYLOAD_BYTES: 65536;
20
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/wire/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAG,OAAkB,CAAC;AAElD,oCAAoC;AACpC,eAAO,MAAM,YAAY,EAAG,OAAgB,CAAC;AAE7C,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,gDAAgD;AAChD,eAAO,MAAM,eAAe,EAAG,KAAc,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAG,KAAe,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAG,MAAgB,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,0BAA0B,EAAG,EAAW,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAG,GAAY,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAG,EAAW,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/wire/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAG,OAAkB,CAAC;AAElD,oCAAoC;AACpC,eAAO,MAAM,YAAY,EAAG,OAAgB,CAAC;AAE7C,uDAAuD;AACvD,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,gDAAgD;AAChD,eAAO,MAAM,eAAe,EAAG,KAAc,CAAC;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAG,KAAe,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAG,MAAgB,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,0BAA0B,EAAG,EAAW,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAG,GAAY,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAG,EAAW,CAAC"}
@@ -14,7 +14,8 @@ export const JSONRPC_VERSION = '2.0';
14
14
  /**
15
15
  * Maximum payload bytes per element payload (frozen x-clowder-bounds).
16
16
  * Open-membered payloads (MediaRefElementPayload, RichBlockElementPayload)
17
- * are bounded by this ceiling alone — no structural narrowing.
17
+ * use their contract schemas for structural narrowing. Unknown extension payloads remain
18
+ * open and are bounded by this ceiling.
18
19
  */
19
20
  export const MAX_ELEMENT_PAYLOAD_BYTES = 65_536;
20
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/wire/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,SAAkB,CAAC;AAElD,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,OAAgB,CAAC;AAE7C,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAgB,CAAC;AAEjD,gDAAgD;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAc,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAe,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAgB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAW,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAY,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAW,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/wire/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,SAAkB,CAAC;AAElD,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAG,OAAgB,CAAC;AAE7C,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAgB,CAAC;AAEjD,gDAAgD;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAc,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAe,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAgB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAW,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAY,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAW,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Wire dispatch classifier — pre-dispatch frame classification per the
3
+ * disposition table (T-A through T-M, §3.8-1 plus beta.8 closure).
4
+ *
5
+ * This module classifies decoded NDJSON frames into one of the 13
6
+ * disposition classes. T-A (transport failure) and T-B (JSON parse error)
7
+ * are handled by the NDJSON frame decoder layer — this classifier covers
8
+ * T-C through T-M.
9
+ *
10
+ * A frame that passes all rejection checks returns disposition=null with
11
+ * outcome='accept', indicating a valid request that should be dispatched
12
+ * to a method handler.
13
+ *
14
+ * This module lives in @clowder-ai/plugin-contract (F202 C1: the wire
15
+ * frame classifier was moved here from @clowder-ai/plugin-sdk so the
16
+ * dependency arrow is 插件 → SDK → contract ← Host). It defines nothing
17
+ * new — every classification rule traces to the frozen disposition table
18
+ * in this package, and every key set it uses is co-located with or
19
+ * generated from the contract types it mirrors.
20
+ */
21
+ import type { DecodedNdjsonFrame, JsonObject } from '../conformance/stdio-harness/ndjson-frame.js';
22
+ import type { DispositionClass } from './disposition.js';
23
+ import type { RequestSnapshot } from './disposition-fixtures.js';
24
+ import { type WireMethodName } from './registry.js';
25
+ export type { RequestSnapshot } from './disposition-fixtures.js';
26
+ export interface InFlightEntry {
27
+ readonly method: WireMethodName;
28
+ readonly requestSnapshot?: RequestSnapshot;
29
+ }
30
+ export interface DispatchResult {
31
+ /** T-class from the disposition table, or null for valid requests. */
32
+ readonly disposition: DispositionClass | null;
33
+ /** Required transport action: close, respond (with error), or accept. */
34
+ readonly outcome: 'close' | 'respond' | 'accept';
35
+ /** For 'respond': the error envelope to write back as NDJSON. */
36
+ readonly response?: JsonObject;
37
+ }
38
+ /**
39
+ * Classify a decoded NDJSON frame into a disposition class.
40
+ *
41
+ * Covers T-C through T-M of the disposition table. T-A and T-B
42
+ * are handled by the NDJSON frame decoder layer.
43
+ *
44
+ * @param frame Decoded frame with raw bytes and parsed value.
45
+ * @param inFlight Map of in-flight request IDs to their entry metadata.
46
+ * @returns The disposition result with class, outcome, and optional error response.
47
+ */
48
+ export declare function classifyFrame(frame: DecodedNdjsonFrame, inFlight: ReadonlyMap<string, InFlightEntry>): DispatchResult;
49
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/wire/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAEnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAwDjE,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAiBvB,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC9C,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;CAChC;AAwzBD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,cAAc,CAuEhB"}