@opengeni/contracts 0.39.0 → 0.44.1

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 (130) hide show
  1. package/dist/atlassian.d.ts +278 -0
  2. package/dist/atlassian.js +55 -0
  3. package/dist/atlassian.js.map +1 -0
  4. package/dist/chunk-52SGB2QO.js +688 -0
  5. package/dist/chunk-52SGB2QO.js.map +1 -0
  6. package/dist/{chunk-7JZMI22I.js → chunk-5UDNP7AO.js} +34 -2
  7. package/dist/chunk-5UDNP7AO.js.map +1 -0
  8. package/dist/chunk-BVGIYW7D.js +11 -0
  9. package/dist/chunk-BVGIYW7D.js.map +1 -0
  10. package/dist/chunk-CADSX6UN.js +1145 -0
  11. package/dist/chunk-CADSX6UN.js.map +1 -0
  12. package/dist/chunk-D2HKF2EF.js +1460 -0
  13. package/dist/chunk-D2HKF2EF.js.map +1 -0
  14. package/dist/chunk-FJBG5E4O.js +194 -0
  15. package/dist/chunk-FJBG5E4O.js.map +1 -0
  16. package/dist/chunk-H5BVCZKF.js +382 -0
  17. package/dist/chunk-H5BVCZKF.js.map +1 -0
  18. package/dist/chunk-LSB7GRLG.js +779 -0
  19. package/dist/chunk-LSB7GRLG.js.map +1 -0
  20. package/dist/chunk-MYBZRDTY.js +340 -0
  21. package/dist/chunk-MYBZRDTY.js.map +1 -0
  22. package/dist/chunk-RIY7GYQS.js +1204 -0
  23. package/dist/chunk-RIY7GYQS.js.map +1 -0
  24. package/dist/chunk-TZ6YEYN4.js +386 -0
  25. package/dist/chunk-TZ6YEYN4.js.map +1 -0
  26. package/dist/chunk-VA22KRHS.js +15177 -0
  27. package/dist/chunk-VA22KRHS.js.map +1 -0
  28. package/dist/chunk-Y3MLSLB4.js +392 -0
  29. package/dist/chunk-Y3MLSLB4.js.map +1 -0
  30. package/dist/chunk-YRKRZ6OF.js +134 -0
  31. package/dist/chunk-YRKRZ6OF.js.map +1 -0
  32. package/dist/company-profile.d.ts +629 -0
  33. package/dist/document-artifact-commands.d.ts +282 -0
  34. package/dist/document-artifact-commands.js +54 -0
  35. package/dist/document-artifact-commands.js.map +1 -0
  36. package/dist/document-artifact-query.d.ts +2 -0
  37. package/dist/document-artifact-query.js +54 -0
  38. package/dist/document-artifact-query.js.map +1 -0
  39. package/dist/editable-artifact-binary.d.ts +56 -0
  40. package/dist/editable-artifact-causal-frontier.d.ts +12 -0
  41. package/dist/editable-artifact-causal-frontier.js +18 -0
  42. package/dist/editable-artifact-causal-frontier.js.map +1 -0
  43. package/dist/editable-artifact-codec-registry.d.ts +48 -0
  44. package/dist/editable-artifact-codec-registry.js +20 -0
  45. package/dist/editable-artifact-codec-registry.js.map +1 -0
  46. package/dist/editable-artifact-committed-transaction.d.ts +35 -0
  47. package/dist/editable-artifact-committed-transaction.js +19 -0
  48. package/dist/editable-artifact-committed-transaction.js.map +1 -0
  49. package/dist/editable-artifact-live.d.ts +276 -0
  50. package/dist/editable-artifact-live.js +907 -0
  51. package/dist/editable-artifact-live.js.map +1 -0
  52. package/dist/editable-artifact-serialized-commit.d.ts +53 -0
  53. package/dist/editable-artifact-serialized-commit.js +26 -0
  54. package/dist/editable-artifact-serialized-commit.js.map +1 -0
  55. package/dist/editable-artifact-versions.d.ts +6 -0
  56. package/dist/editable-artifact-versions.js +11 -0
  57. package/dist/editable-artifact-versions.js.map +1 -0
  58. package/dist/editable-artifacts.d.ts +46 -0
  59. package/dist/editable-artifacts.js +236 -0
  60. package/dist/editable-artifacts.js.map +1 -0
  61. package/dist/event-preview.d.ts +7 -7
  62. package/dist/google-drive.d.ts +114 -2
  63. package/dist/google-drive.js +70 -14
  64. package/dist/google-drive.js.map +1 -1
  65. package/dist/image-generation.d.ts +70 -0
  66. package/dist/index.d.ts +5180 -329
  67. package/dist/index.js +1173 -40
  68. package/dist/interaction.d.ts +6895 -0
  69. package/dist/mcp-receipts.d.ts +96 -0
  70. package/dist/memory-slack-delivery.d.ts +397 -0
  71. package/dist/presentation-artifact-commands.d.ts +349 -0
  72. package/dist/presentation-artifact-commands.js +66 -0
  73. package/dist/presentation-artifact-commands.js.map +1 -0
  74. package/dist/presentation-artifact-query.d.ts +2 -0
  75. package/dist/presentation-artifact-query.js +66 -0
  76. package/dist/presentation-artifact-query.js.map +1 -0
  77. package/dist/retained-output.d.ts +83 -6
  78. package/dist/sandbox-snapshots.d.ts +9 -0
  79. package/dist/scoped-knowledge.d.ts +14 -13
  80. package/dist/slack-bot-scopes.d.ts +4 -0
  81. package/dist/slack-bot-scopes.js +3 -1
  82. package/dist/spreadsheet-artifact-commands.d.ts +101 -0
  83. package/dist/spreadsheet-artifact-commands.js +27 -0
  84. package/dist/spreadsheet-artifact-commands.js.map +1 -0
  85. package/dist/spreadsheet-artifact-date.d.ts +4 -0
  86. package/dist/spreadsheet-artifact-query.d.ts +120 -0
  87. package/dist/spreadsheet-artifact-query.js +48 -0
  88. package/dist/spreadsheet-artifact-query.js.map +1 -0
  89. package/dist/tool-catalog.d.ts +576 -0
  90. package/dist/video-generation.d.ts +532 -0
  91. package/dist/video-generation.js +51 -0
  92. package/dist/video-generation.js.map +1 -0
  93. package/dist/workspace-learning-policy.d.ts +208 -0
  94. package/package.json +61 -1
  95. package/src/atlassian.ts +160 -0
  96. package/src/company-profile.ts +306 -0
  97. package/src/document-artifact-commands.ts +1709 -0
  98. package/src/document-artifact-query.ts +2 -0
  99. package/src/editable-artifact-binary.ts +396 -0
  100. package/src/editable-artifact-causal-frontier.ts +154 -0
  101. package/src/editable-artifact-codec-registry.ts +261 -0
  102. package/src/editable-artifact-committed-transaction.ts +478 -0
  103. package/src/editable-artifact-live.ts +1379 -0
  104. package/src/editable-artifact-serialized-commit.ts +494 -0
  105. package/src/editable-artifact-versions.ts +8 -0
  106. package/src/editable-artifacts.ts +473 -0
  107. package/src/event-preview.ts +6 -6
  108. package/src/google-drive.ts +68 -15
  109. package/src/image-generation.ts +106 -0
  110. package/src/index.ts +2535 -282
  111. package/src/interaction.ts +2292 -0
  112. package/src/mcp-receipts.ts +281 -0
  113. package/src/memory-slack-delivery.ts +183 -0
  114. package/src/presentation-artifact-commands.ts +2035 -0
  115. package/src/presentation-artifact-query.ts +2 -0
  116. package/src/retained-output.ts +248 -8
  117. package/src/sandbox-snapshots.ts +28 -1
  118. package/src/scoped-knowledge.ts +18 -4
  119. package/src/slack-bot-scopes.ts +34 -1
  120. package/src/spreadsheet-artifact-commands.ts +999 -0
  121. package/src/spreadsheet-artifact-date.ts +21 -0
  122. package/src/spreadsheet-artifact-query.ts +1411 -0
  123. package/src/tool-catalog.ts +334 -0
  124. package/src/video-generation.ts +394 -0
  125. package/src/workspace-learning-policy.ts +233 -0
  126. package/dist/chunk-7JZMI22I.js.map +0 -1
  127. package/dist/chunk-PCTCJEAF.js +0 -10799
  128. package/dist/chunk-PCTCJEAF.js.map +0 -1
  129. package/dist/secret-redaction.d.ts +0 -40
  130. package/src/secret-redaction.ts +0 -364
@@ -0,0 +1,473 @@
1
+ import { sha256 } from "@noble/hashes/sha256";
2
+ import { bytesToHex } from "@noble/hashes/utils";
3
+
4
+ export * from "./spreadsheet-artifact-commands";
5
+ export * from "./spreadsheet-artifact-query";
6
+ export * from "./editable-artifact-causal-frontier";
7
+ export * from "./document-artifact-commands";
8
+ export * from "./presentation-artifact-commands";
9
+ export * from "./editable-artifact-codec-registry";
10
+
11
+ export const EDITABLE_ARTIFACT_INTENT_VERSION = 1 as const;
12
+ export const EDITABLE_ARTIFACT_INTENT_MAX_BYTES = 5 * 1024 * 1024;
13
+ export const EDITABLE_ARTIFACT_COMMAND_MAX_BYTES = 4 * 1024 * 1024;
14
+ export const EDITABLE_ARTIFACT_KERNEL_VERSION_MAX_BYTES = 512;
15
+ /** Largest durable snapshot every supported browser/WASM client can open. */
16
+ export const EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES = 64 * 1024 * 1024;
17
+ export const EDITABLE_ARTIFACT_INTENT_MAX_CAUSAL_ACTORS = 1_024;
18
+ export const EDITABLE_ARTIFACT_INTENT_MAX_UNDO_TARGETS = 10_000;
19
+
20
+ const MAGIC = new TextEncoder().encode("OGATX001");
21
+ const textEncoder = new TextEncoder();
22
+ const textDecoder = new TextDecoder("utf-8", { fatal: true });
23
+ const STABLE_ID = /^[0-9a-f]{32}$/u;
24
+ const REPLICA_ID = /^[0-9a-f]{16}$/u;
25
+ const CLIENT_TRANSACTION_ID = /^[A-Za-z0-9._:-]{1,200}$/u;
26
+ const REQUEST_HASH = /^sha256:[0-9a-f]{64}$/u;
27
+
28
+ export type EditableArtifactCausalEntry = Readonly<{
29
+ replicaId: string;
30
+ counter: number;
31
+ }>;
32
+
33
+ /**
34
+ * Exact client-authored mutation identity. Scope and actor authority are
35
+ * deliberately absent: the server derives them and binds them in the
36
+ * idempotency lookup tuple instead of trusting client bytes.
37
+ */
38
+ export type EditableArtifactMutationIntent = Readonly<{
39
+ envelopeVersion: typeof EDITABLE_ARTIFACT_INTENT_VERSION;
40
+ protocolVersion: number;
41
+ modelSchemaVersion: number;
42
+ commandProtocolVersion: number;
43
+ artifactId: string;
44
+ clientTransactionId: string;
45
+ replicaId: string;
46
+ replicaCounter: number;
47
+ previousLocalTransactionId: string | null;
48
+ observedHeadSequence: number;
49
+ causalBase: readonly EditableArtifactCausalEntry[];
50
+ selectiveUndoOperationIds: readonly string[];
51
+ commandBytes: Uint8Array;
52
+ }>;
53
+
54
+ export function encodeEditableArtifactMutationIntent(
55
+ input: EditableArtifactMutationIntent,
56
+ ): Uint8Array {
57
+ // The writer owns the emitted bytes, so a second eager copy of a potentially
58
+ // multi-megabyte command block would add no safety.
59
+ const intent = normalizeIntent(input, false);
60
+ const writer = new BinaryWriter(EDITABLE_ARTIFACT_INTENT_MAX_BYTES);
61
+ writer.bytes(MAGIC);
62
+ writer.u16(intent.envelopeVersion);
63
+ writer.u16(intent.protocolVersion);
64
+ writer.u16(intent.modelSchemaVersion);
65
+ writer.u16(intent.commandProtocolVersion);
66
+ writer.string(intent.artifactId);
67
+ writer.string(intent.clientTransactionId);
68
+ writer.string(intent.replicaId);
69
+ writer.u64(intent.replicaCounter);
70
+ writer.u8(intent.previousLocalTransactionId === null ? 0 : 1);
71
+ if (intent.previousLocalTransactionId !== null) {
72
+ writer.string(intent.previousLocalTransactionId);
73
+ }
74
+ writer.u64(intent.observedHeadSequence);
75
+ writer.u16(intent.causalBase.length);
76
+ for (const entry of intent.causalBase) {
77
+ writer.string(entry.replicaId);
78
+ writer.u64(entry.counter);
79
+ }
80
+ writer.u16(intent.selectiveUndoOperationIds.length);
81
+ for (const operationId of intent.selectiveUndoOperationIds) writer.string(operationId);
82
+ writer.byteBlock(intent.commandBytes);
83
+ return writer.finish();
84
+ }
85
+
86
+ export function decodeEditableArtifactMutationIntent(
87
+ bytes: Uint8Array,
88
+ ): EditableArtifactMutationIntent {
89
+ return parseEditableArtifactMutationIntent(bytes, true);
90
+ }
91
+
92
+ function parseEditableArtifactMutationIntent(
93
+ bytes: Uint8Array,
94
+ copyCommandBytes: boolean,
95
+ ): EditableArtifactMutationIntent {
96
+ if (!(bytes instanceof Uint8Array)) throw new TypeError("intent bytes must be a Uint8Array");
97
+ if (bytes.byteLength > EDITABLE_ARTIFACT_INTENT_MAX_BYTES) {
98
+ throw new RangeError("editable artifact intent exceeds its byte limit");
99
+ }
100
+ const reader = new BinaryReader(bytes);
101
+ const magic = reader.bytes(MAGIC.byteLength);
102
+ if (!equalBytes(magic, MAGIC)) throw new TypeError("invalid editable artifact intent magic");
103
+ const envelopeVersion = reader.u16();
104
+ if (envelopeVersion !== EDITABLE_ARTIFACT_INTENT_VERSION) {
105
+ throw new TypeError(`unsupported editable artifact intent version: ${envelopeVersion}`);
106
+ }
107
+ const protocolVersion = reader.u16();
108
+ const modelSchemaVersion = reader.u16();
109
+ const commandProtocolVersion = reader.u16();
110
+ const artifactId = reader.string();
111
+ const clientTransactionId = reader.string();
112
+ const replicaId = reader.string();
113
+ const replicaCounter = reader.u64();
114
+ const predecessorFlag = reader.u8();
115
+ if (predecessorFlag > 1) throw new TypeError("invalid predecessor presence flag");
116
+ const previousLocalTransactionId = predecessorFlag === 1 ? reader.string() : null;
117
+ const observedHeadSequence = reader.u64();
118
+ const causalCount = reader.u16();
119
+ if (causalCount > EDITABLE_ARTIFACT_INTENT_MAX_CAUSAL_ACTORS) {
120
+ throw new RangeError("editable artifact causal base exceeds its actor limit");
121
+ }
122
+ const causalBase: EditableArtifactCausalEntry[] = [];
123
+ let previousReplicaId = "";
124
+ for (let index = 0; index < causalCount; index += 1) {
125
+ const causalReplicaId = reader.string();
126
+ if (causalReplicaId <= previousReplicaId) {
127
+ throw new TypeError("causal base replica ids must be unique and canonically sorted");
128
+ }
129
+ previousReplicaId = causalReplicaId;
130
+ causalBase.push(Object.freeze({ replicaId: causalReplicaId, counter: reader.u64() }));
131
+ }
132
+ const undoCount = reader.u16();
133
+ if (undoCount > EDITABLE_ARTIFACT_INTENT_MAX_UNDO_TARGETS) {
134
+ throw new RangeError("editable artifact undo targets exceed their limit");
135
+ }
136
+ const selectiveUndoOperationIds: string[] = [];
137
+ let previousOperationId = "";
138
+ for (let index = 0; index < undoCount; index += 1) {
139
+ const operationId = reader.string();
140
+ if (operationId <= previousOperationId) {
141
+ throw new TypeError("undo operation ids must be unique and canonically sorted");
142
+ }
143
+ previousOperationId = operationId;
144
+ selectiveUndoOperationIds.push(operationId);
145
+ }
146
+ const commandBytes = reader.byteBlock(EDITABLE_ARTIFACT_COMMAND_MAX_BYTES);
147
+ reader.done();
148
+ return normalizeIntent(
149
+ {
150
+ envelopeVersion: EDITABLE_ARTIFACT_INTENT_VERSION,
151
+ protocolVersion,
152
+ modelSchemaVersion,
153
+ commandProtocolVersion,
154
+ artifactId,
155
+ clientTransactionId,
156
+ replicaId,
157
+ replicaCounter,
158
+ previousLocalTransactionId,
159
+ observedHeadSequence,
160
+ causalBase,
161
+ selectiveUndoOperationIds,
162
+ commandBytes,
163
+ },
164
+ copyCommandBytes,
165
+ );
166
+ }
167
+
168
+ export function hashEditableArtifactMutationIntentBytes(bytes: Uint8Array): string {
169
+ // Decode first so noncanonical or malformed bytes can never acquire a valid
170
+ // application-level request hash merely because SHA-256 accepts any bytes.
171
+ parseEditableArtifactMutationIntent(bytes, false);
172
+ return `sha256:${bytesToHex(sha256(bytes))}`;
173
+ }
174
+
175
+ export function hashEditableArtifactMutationIntent(intent: EditableArtifactMutationIntent): {
176
+ bytes: Uint8Array;
177
+ requestHash: string;
178
+ } {
179
+ const bytes = encodeEditableArtifactMutationIntent(intent);
180
+ return { bytes, requestHash: `sha256:${bytesToHex(sha256(bytes))}` };
181
+ }
182
+
183
+ export function assertEditableArtifactRequestHash(value: string): string {
184
+ if (!REQUEST_HASH.test(value)) {
185
+ throw new TypeError("editable artifact request hash must be canonical sha256 text");
186
+ }
187
+ return value;
188
+ }
189
+
190
+ function normalizeIntent(
191
+ input: EditableArtifactMutationIntent,
192
+ copyCommandBytes = true,
193
+ ): EditableArtifactMutationIntent {
194
+ if (!isPlainRecord(input)) throw new TypeError("editable artifact intent must be a plain record");
195
+ if (input.envelopeVersion !== EDITABLE_ARTIFACT_INTENT_VERSION) {
196
+ throw new TypeError("editable artifact intent envelope version must be 1");
197
+ }
198
+ const protocolVersion = positiveU16(input.protocolVersion, "protocolVersion");
199
+ const modelSchemaVersion = positiveU16(input.modelSchemaVersion, "modelSchemaVersion");
200
+ const commandProtocolVersion = positiveU16(
201
+ input.commandProtocolVersion,
202
+ "commandProtocolVersion",
203
+ );
204
+ const artifactId = stableId(input.artifactId, "artifactId");
205
+ const clientTransactionId = portableTransactionId(
206
+ input.clientTransactionId,
207
+ "clientTransactionId",
208
+ );
209
+ const replicaId = replicaIdentity(input.replicaId, "replicaId");
210
+ const replicaCounter = positiveSafeInteger(input.replicaCounter, "replicaCounter");
211
+ const previousLocalTransactionId =
212
+ input.previousLocalTransactionId === null
213
+ ? null
214
+ : portableTransactionId(input.previousLocalTransactionId, "previousLocalTransactionId");
215
+ const observedHeadSequence = nonnegativeSafeInteger(
216
+ input.observedHeadSequence,
217
+ "observedHeadSequence",
218
+ );
219
+ if (!Array.isArray(input.causalBase)) throw new TypeError("causalBase must be an array");
220
+ if (input.causalBase.length > EDITABLE_ARTIFACT_INTENT_MAX_CAUSAL_ACTORS) {
221
+ throw new RangeError("editable artifact causal base exceeds its actor limit");
222
+ }
223
+ const causalByReplica = new Map<string, number>();
224
+ for (const entry of input.causalBase) {
225
+ if (!isPlainRecord(entry)) throw new TypeError("causal entries must be plain records");
226
+ const causalReplicaId = replicaIdentity(entry.replicaId, "causal replicaId");
227
+ if (causalByReplica.has(causalReplicaId)) throw new TypeError("duplicate causal replicaId");
228
+ causalByReplica.set(
229
+ causalReplicaId,
230
+ positiveSafeInteger(entry.counter, `causal counter for ${causalReplicaId}`),
231
+ );
232
+ }
233
+ const causalBase = [...causalByReplica]
234
+ .sort(([left], [right]) => compareCodeUnits(left, right))
235
+ .map(([causalReplicaId, counter]) => Object.freeze({ replicaId: causalReplicaId, counter }));
236
+ if (!Array.isArray(input.selectiveUndoOperationIds)) {
237
+ throw new TypeError("selectiveUndoOperationIds must be an array");
238
+ }
239
+ if (input.selectiveUndoOperationIds.length > EDITABLE_ARTIFACT_INTENT_MAX_UNDO_TARGETS) {
240
+ throw new RangeError("editable artifact undo targets exceed their limit");
241
+ }
242
+ const undoSet = new Set<string>();
243
+ for (const value of input.selectiveUndoOperationIds) {
244
+ const operationId = stableId(value, "selective undo operation id");
245
+ if (undoSet.has(operationId)) throw new TypeError("duplicate selective undo operation id");
246
+ undoSet.add(operationId);
247
+ }
248
+ const selectiveUndoOperationIds = [...undoSet].sort(compareCodeUnits);
249
+ if (!(input.commandBytes instanceof Uint8Array)) {
250
+ throw new TypeError("commandBytes must be a Uint8Array");
251
+ }
252
+ if (input.commandBytes.byteLength < 1) throw new TypeError("commandBytes must not be empty");
253
+ if (input.commandBytes.byteLength > EDITABLE_ARTIFACT_COMMAND_MAX_BYTES) {
254
+ throw new RangeError("commandBytes exceeds its byte limit");
255
+ }
256
+ return Object.freeze({
257
+ envelopeVersion: EDITABLE_ARTIFACT_INTENT_VERSION,
258
+ protocolVersion,
259
+ modelSchemaVersion,
260
+ commandProtocolVersion,
261
+ artifactId,
262
+ clientTransactionId,
263
+ replicaId,
264
+ replicaCounter,
265
+ previousLocalTransactionId,
266
+ observedHeadSequence,
267
+ causalBase: Object.freeze(causalBase),
268
+ selectiveUndoOperationIds: Object.freeze(selectiveUndoOperationIds),
269
+ commandBytes: copyCommandBytes ? input.commandBytes.slice() : input.commandBytes,
270
+ });
271
+ }
272
+
273
+ function isPlainRecord(value: unknown): value is Record<string, unknown> {
274
+ return (
275
+ typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype
276
+ );
277
+ }
278
+
279
+ function stableId(value: unknown, label: string): string {
280
+ if (typeof value !== "string" || !STABLE_ID.test(value) || /^0+$/u.test(value)) {
281
+ throw new TypeError(`${label} must be nonzero fixed-width lowercase hexadecimal text`);
282
+ }
283
+ return value;
284
+ }
285
+
286
+ function replicaIdentity(value: unknown, label: string): string {
287
+ if (typeof value !== "string" || !REPLICA_ID.test(value) || /^0+$/u.test(value)) {
288
+ throw new TypeError(`${label} must be nonzero 64-bit lowercase hexadecimal text`);
289
+ }
290
+ return value;
291
+ }
292
+
293
+ function portableTransactionId(value: unknown, label: string): string {
294
+ if (typeof value !== "string" || !CLIENT_TRANSACTION_ID.test(value)) {
295
+ throw new TypeError(`${label} must contain 1-200 portable identifier characters`);
296
+ }
297
+ return value;
298
+ }
299
+
300
+ function positiveU16(value: unknown, label: string): number {
301
+ if (!Number.isInteger(value) || (value as number) < 1 || (value as number) > 0xffff) {
302
+ throw new TypeError(`${label} must be a positive 16-bit integer`);
303
+ }
304
+ return value as number;
305
+ }
306
+
307
+ function positiveSafeInteger(value: unknown, label: string): number {
308
+ if (!Number.isSafeInteger(value) || (value as number) < 1) {
309
+ throw new TypeError(`${label} must be a positive safe integer`);
310
+ }
311
+ return value as number;
312
+ }
313
+
314
+ function nonnegativeSafeInteger(value: unknown, label: string): number {
315
+ if (!Number.isSafeInteger(value) || (value as number) < 0) {
316
+ throw new TypeError(`${label} must be a nonnegative safe integer`);
317
+ }
318
+ return value as number;
319
+ }
320
+
321
+ function compareCodeUnits(left: string, right: string): number {
322
+ return left < right ? -1 : left > right ? 1 : 0;
323
+ }
324
+
325
+ function equalBytes(left: Uint8Array, right: Uint8Array): boolean {
326
+ return (
327
+ left.byteLength === right.byteLength && left.every((value, index) => value === right[index])
328
+ );
329
+ }
330
+
331
+ class BinaryWriter {
332
+ private buffer = new Uint8Array(1_024);
333
+ private length = 0;
334
+
335
+ constructor(private readonly maximum: number) {}
336
+
337
+ u8(value: number): void {
338
+ this.ensure(1);
339
+ this.buffer[this.length++] = value;
340
+ }
341
+
342
+ u16(value: number): void {
343
+ this.ensure(2);
344
+ this.buffer[this.length++] = value & 0xff;
345
+ this.buffer[this.length++] = (value >>> 8) & 0xff;
346
+ }
347
+
348
+ u32(value: number): void {
349
+ this.ensure(4);
350
+ for (let offset = 0; offset < 4; offset += 1) {
351
+ this.buffer[this.length++] = Math.floor(value / 2 ** (offset * 8)) & 0xff;
352
+ }
353
+ }
354
+
355
+ u64(value: number): void {
356
+ if (!Number.isSafeInteger(value) || value < 0) throw new TypeError("u64 must be safe");
357
+ this.ensure(8);
358
+ let remaining = BigInt(value);
359
+ for (let offset = 0; offset < 8; offset += 1) {
360
+ this.buffer[this.length++] = Number(remaining & 0xffn);
361
+ remaining >>= 8n;
362
+ }
363
+ }
364
+
365
+ string(value: string): void {
366
+ const bytes = textEncoder.encode(value);
367
+ if (bytes.byteLength > 0xffff) throw new RangeError("intent string exceeds 65535 bytes");
368
+ this.u16(bytes.byteLength);
369
+ this.bytes(bytes);
370
+ }
371
+
372
+ byteBlock(value: Uint8Array): void {
373
+ this.u32(value.byteLength);
374
+ this.bytes(value);
375
+ }
376
+
377
+ bytes(value: Uint8Array): void {
378
+ this.ensure(value.byteLength);
379
+ this.buffer.set(value, this.length);
380
+ this.length += value.byteLength;
381
+ }
382
+
383
+ finish(): Uint8Array {
384
+ return this.buffer.slice(0, this.length);
385
+ }
386
+
387
+ private ensure(additional: number): void {
388
+ const needed = this.length + additional;
389
+ if (!Number.isSafeInteger(needed) || needed > this.maximum) {
390
+ throw new RangeError("editable artifact intent exceeds its byte limit");
391
+ }
392
+ if (needed <= this.buffer.byteLength) return;
393
+ let size = this.buffer.byteLength;
394
+ while (size < needed) size = Math.min(this.maximum, size * 2);
395
+ const next = new Uint8Array(size);
396
+ next.set(this.buffer.subarray(0, this.length));
397
+ this.buffer = next;
398
+ }
399
+ }
400
+
401
+ class BinaryReader {
402
+ private offset = 0;
403
+
404
+ constructor(private readonly input: Uint8Array) {}
405
+
406
+ u8(): number {
407
+ this.require(1);
408
+ return this.input[this.offset++]!;
409
+ }
410
+
411
+ u16(): number {
412
+ this.require(2);
413
+ const value = this.input[this.offset]! | (this.input[this.offset + 1]! << 8);
414
+ this.offset += 2;
415
+ return value;
416
+ }
417
+
418
+ u32(): number {
419
+ this.require(4);
420
+ const value =
421
+ this.input[this.offset]! +
422
+ this.input[this.offset + 1]! * 2 ** 8 +
423
+ this.input[this.offset + 2]! * 2 ** 16 +
424
+ this.input[this.offset + 3]! * 2 ** 24;
425
+ this.offset += 4;
426
+ return value;
427
+ }
428
+
429
+ u64(): number {
430
+ this.require(8);
431
+ let value = 0n;
432
+ for (let offset = 0; offset < 8; offset += 1) {
433
+ value |= BigInt(this.input[this.offset + offset]!) << BigInt(offset * 8);
434
+ }
435
+ this.offset += 8;
436
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) throw new RangeError("u64 exceeds safe integer");
437
+ return Number(value);
438
+ }
439
+
440
+ string(): string {
441
+ return textDecoder.decode(this.bytes(this.u16()));
442
+ }
443
+
444
+ byteBlock(maximum: number): Uint8Array {
445
+ const length = this.u32();
446
+ if (length < 1) throw new TypeError("commandBytes must not be empty");
447
+ if (length > maximum) throw new RangeError("commandBytes exceeds its byte limit");
448
+ return this.bytes(length);
449
+ }
450
+
451
+ bytes(length: number): Uint8Array {
452
+ this.require(length);
453
+ const output = this.input.subarray(this.offset, this.offset + length);
454
+ this.offset += length;
455
+ return output;
456
+ }
457
+
458
+ done(): void {
459
+ if (this.offset !== this.input.byteLength) {
460
+ throw new TypeError("editable artifact intent contains trailing bytes");
461
+ }
462
+ }
463
+
464
+ private require(length: number): void {
465
+ if (
466
+ !Number.isSafeInteger(length) ||
467
+ length < 0 ||
468
+ this.offset + length > this.input.byteLength
469
+ ) {
470
+ throw new TypeError("truncated editable artifact intent");
471
+ }
472
+ }
473
+ }
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Canonical bounded representation for `session_events.payload`.
2
+ * Canonical bounded representation for explicit session-event previews.
3
3
  *
4
- * Session events are the lossy human/audit projection, not model memory and not
5
- * an evidence blob store. This helper keeps that projection useful while making
6
- * the loss explicit. It deliberately has no server-only dependency so the DB,
7
- * realtime transports, SDK/React, and tests can share one wire contract.
4
+ * Canonical session-event payloads are stored in full. This helper derives a
5
+ * bounded monitoring/public projection without writing that projection back
6
+ * over canonical data. It deliberately has no server-only dependency so the
7
+ * DB, realtime transports, SDK/React, and tests can share one wire contract.
8
8
  */
9
9
 
10
10
  import {
@@ -184,7 +184,7 @@ export function sessionEventPayloadTruncation(
184
184
  }
185
185
 
186
186
  /**
187
- * Return a byte-bounded audit payload. Unchanged ordinary payloads retain their
187
+ * Return a byte-bounded preview payload. Unchanged ordinary payloads retain their
188
188
  * reference. Oversized strings/containers get deterministic head+tail previews;
189
189
  * inline images/binary values become metadata because `session_events` does not
190
190
  * durably retain their source bytes as independently retrievable evidence.
@@ -13,8 +13,10 @@ export const GOOGLE_DRIVE_METADATA_READONLY_SCOPE =
13
13
  "https://www.googleapis.com/auth/drive.metadata.readonly" as const;
14
14
  export const GOOGLE_DRIVE_READONLY_SCOPE =
15
15
  "https://www.googleapis.com/auth/drive.readonly" as const;
16
+ /** Stable serialized role retained for existing connection rows; not product-facing copy. */
16
17
  export const GOOGLE_DRIVE_CREDENTIAL_ROLE = "google_drive_metadata" as const;
17
- export const GOOGLE_DRIVE_CREDENTIAL_LABEL = "Google Drive metadata browser" as const;
18
+ export const GOOGLE_DRIVE_CREDENTIAL_LABEL = "Google Drive read-only source sync" as const;
19
+ export const GOOGLE_DRIVE_LEGACY_CREDENTIAL_LABEL = "Google Drive metadata browser" as const;
18
20
 
19
21
  export const GoogleDriveOAuthCapability = z.enum([
20
22
  "picker_file_read",
@@ -139,6 +141,8 @@ export const GoogleDriveSelectedSource = z.object({
139
141
  /** @deprecated Missing destinations resolve to the current workspace boundary. */
140
142
  targetScope: GoogleDriveTargetScope.optional(),
141
143
  syncCadence: GoogleDriveSyncCadence.default("hourly"),
144
+ syncEnabled: z.boolean().default(false),
145
+ configGeneration: z.number().int().positive().default(1),
142
146
  readPolicy: GoogleDriveReadPolicy.default("allow"),
143
147
  selectedAt: z.string().datetime({ offset: true }),
144
148
  });
@@ -147,7 +151,10 @@ export type GoogleDriveSelectedSource = z.infer<typeof GoogleDriveSelectedSource
147
151
  export const GoogleDriveConnectionMetadata = z
148
152
  .object({
149
153
  credentialRole: z.literal(GOOGLE_DRIVE_CREDENTIAL_ROLE),
150
- credentialLabel: z.literal(GOOGLE_DRIVE_CREDENTIAL_LABEL),
154
+ credentialLabel: z.union([
155
+ z.literal(GOOGLE_DRIVE_CREDENTIAL_LABEL),
156
+ z.literal(GOOGLE_DRIVE_LEGACY_CREDENTIAL_LABEL),
157
+ ]),
151
158
  googlePermissionId: z.string().min(1).max(256),
152
159
  googleEmail: z.string().email().max(320),
153
160
  googleDisplayName: z.string().min(1).max(512).nullable(),
@@ -207,28 +214,74 @@ export const GoogleDriveBrowseResponse = z.object({
207
214
  });
208
215
  export type GoogleDriveBrowseResponse = z.infer<typeof GoogleDriveBrowseResponse>;
209
216
 
217
+ const GoogleDriveSourceSelection = z
218
+ .array(
219
+ GoogleDriveBrowseItem.pick({
220
+ id: true,
221
+ name: true,
222
+ mimeType: true,
223
+ driveId: true,
224
+ }),
225
+ )
226
+ .max(100)
227
+ .refine((sources) => new Set(sources.map((source) => source.id)).size === sources.length, {
228
+ message: "Google Drive sources must be unique",
229
+ });
230
+
210
231
  export const SaveGoogleDriveSourceRequest = z
211
232
  .object({
212
- sources: z
213
- .array(
214
- GoogleDriveBrowseItem.pick({
215
- id: true,
216
- name: true,
217
- mimeType: true,
218
- driveId: true,
219
- }),
220
- )
221
- .max(100)
222
- .refine((sources) => new Set(sources.map((source) => source.id)).size === sources.length, {
223
- message: "Google Drive sources must be unique",
224
- }),
233
+ sources: GoogleDriveSourceSelection,
225
234
  destination: ConnectorDocumentDestinationSelection.optional(),
226
235
  /** @deprecated Legacy requests are accepted but resolve to workspace authority. */
227
236
  targetScope: GoogleDriveTargetScope.optional(),
228
237
  syncCadence: GoogleDriveSyncCadence.default("hourly"),
238
+ syncEnabled: z.boolean().default(false),
229
239
  readPolicy: GoogleDriveReadPolicy.default("allow"),
230
240
  })
231
241
  .refine((request) => request.destination !== undefined || request.targetScope !== undefined, {
232
242
  message: "Google Drive document destination is required",
233
243
  });
234
244
  export type SaveGoogleDriveSourceRequest = z.infer<typeof SaveGoogleDriveSourceRequest>;
245
+
246
+ export const GoogleDriveKnowledgeSourceItem = z.object({
247
+ id: z.string().min(1).max(512),
248
+ name: z.string().min(1).max(1024),
249
+ mimeType: z.string().min(1).max(256),
250
+ driveId: z.string().min(1).max(512).optional(),
251
+ sourceKind: z.enum(["my_drive", "shared_drive", "folder"]),
252
+ includeDescendants: z.boolean(),
253
+ });
254
+ export type GoogleDriveKnowledgeSourceItem = z.infer<typeof GoogleDriveKnowledgeSourceItem>;
255
+
256
+ export const GoogleDriveKnowledgeSourceDestination = z.object({
257
+ authorityKind: z.enum(["organization", "workspace", "personal"]),
258
+ authorityAccountId: z.string().min(1).max(128),
259
+ authorityWorkspaceId: z.string().min(1).max(128).optional(),
260
+ authoritySubjectId: z.string().min(1).max(512).optional(),
261
+ collectionId: z.string().min(1).max(512).optional(),
262
+ });
263
+ export type GoogleDriveKnowledgeSourceDestination = z.infer<
264
+ typeof GoogleDriveKnowledgeSourceDestination
265
+ >;
266
+
267
+ export const GoogleDriveKnowledgeSourceConfig = z.object({
268
+ sources: z.array(GoogleDriveKnowledgeSourceItem).min(1).max(100),
269
+ destination: GoogleDriveKnowledgeSourceDestination,
270
+ syncCadence: GoogleDriveSyncCadence,
271
+ readPolicy: GoogleDriveReadPolicy,
272
+ });
273
+ export type GoogleDriveKnowledgeSourceConfig = z.infer<typeof GoogleDriveKnowledgeSourceConfig>;
274
+
275
+ export const SaveGoogleDriveIntegrationSourceRequest = z.intersection(
276
+ SaveGoogleDriveSourceRequest,
277
+ z.object({
278
+ sources: GoogleDriveSourceSelection.refine((sources) => sources.length > 0, {
279
+ message: "At least one Google Drive source is required",
280
+ }),
281
+ expectedVersion: z.number().int().positive().optional(),
282
+ idempotencyKey: z.string().uuid(),
283
+ }),
284
+ );
285
+ export type SaveGoogleDriveIntegrationSourceRequest = z.infer<
286
+ typeof SaveGoogleDriveIntegrationSourceRequest
287
+ >;