@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.
- package/dist/atlassian.d.ts +278 -0
- package/dist/atlassian.js +55 -0
- package/dist/atlassian.js.map +1 -0
- package/dist/chunk-52SGB2QO.js +688 -0
- package/dist/chunk-52SGB2QO.js.map +1 -0
- package/dist/{chunk-7JZMI22I.js → chunk-5UDNP7AO.js} +34 -2
- package/dist/chunk-5UDNP7AO.js.map +1 -0
- package/dist/chunk-BVGIYW7D.js +11 -0
- package/dist/chunk-BVGIYW7D.js.map +1 -0
- package/dist/chunk-CADSX6UN.js +1145 -0
- package/dist/chunk-CADSX6UN.js.map +1 -0
- package/dist/chunk-D2HKF2EF.js +1460 -0
- package/dist/chunk-D2HKF2EF.js.map +1 -0
- package/dist/chunk-FJBG5E4O.js +194 -0
- package/dist/chunk-FJBG5E4O.js.map +1 -0
- package/dist/chunk-H5BVCZKF.js +382 -0
- package/dist/chunk-H5BVCZKF.js.map +1 -0
- package/dist/chunk-LSB7GRLG.js +779 -0
- package/dist/chunk-LSB7GRLG.js.map +1 -0
- package/dist/chunk-MYBZRDTY.js +340 -0
- package/dist/chunk-MYBZRDTY.js.map +1 -0
- package/dist/chunk-RIY7GYQS.js +1204 -0
- package/dist/chunk-RIY7GYQS.js.map +1 -0
- package/dist/chunk-TZ6YEYN4.js +386 -0
- package/dist/chunk-TZ6YEYN4.js.map +1 -0
- package/dist/chunk-VA22KRHS.js +15177 -0
- package/dist/chunk-VA22KRHS.js.map +1 -0
- package/dist/chunk-Y3MLSLB4.js +392 -0
- package/dist/chunk-Y3MLSLB4.js.map +1 -0
- package/dist/chunk-YRKRZ6OF.js +134 -0
- package/dist/chunk-YRKRZ6OF.js.map +1 -0
- package/dist/company-profile.d.ts +629 -0
- package/dist/document-artifact-commands.d.ts +282 -0
- package/dist/document-artifact-commands.js +54 -0
- package/dist/document-artifact-commands.js.map +1 -0
- package/dist/document-artifact-query.d.ts +2 -0
- package/dist/document-artifact-query.js +54 -0
- package/dist/document-artifact-query.js.map +1 -0
- package/dist/editable-artifact-binary.d.ts +56 -0
- package/dist/editable-artifact-causal-frontier.d.ts +12 -0
- package/dist/editable-artifact-causal-frontier.js +18 -0
- package/dist/editable-artifact-causal-frontier.js.map +1 -0
- package/dist/editable-artifact-codec-registry.d.ts +48 -0
- package/dist/editable-artifact-codec-registry.js +20 -0
- package/dist/editable-artifact-codec-registry.js.map +1 -0
- package/dist/editable-artifact-committed-transaction.d.ts +35 -0
- package/dist/editable-artifact-committed-transaction.js +19 -0
- package/dist/editable-artifact-committed-transaction.js.map +1 -0
- package/dist/editable-artifact-live.d.ts +276 -0
- package/dist/editable-artifact-live.js +907 -0
- package/dist/editable-artifact-live.js.map +1 -0
- package/dist/editable-artifact-serialized-commit.d.ts +53 -0
- package/dist/editable-artifact-serialized-commit.js +26 -0
- package/dist/editable-artifact-serialized-commit.js.map +1 -0
- package/dist/editable-artifact-versions.d.ts +6 -0
- package/dist/editable-artifact-versions.js +11 -0
- package/dist/editable-artifact-versions.js.map +1 -0
- package/dist/editable-artifacts.d.ts +46 -0
- package/dist/editable-artifacts.js +236 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/event-preview.d.ts +7 -7
- package/dist/google-drive.d.ts +114 -2
- package/dist/google-drive.js +70 -14
- package/dist/google-drive.js.map +1 -1
- package/dist/image-generation.d.ts +70 -0
- package/dist/index.d.ts +5180 -329
- package/dist/index.js +1173 -40
- package/dist/interaction.d.ts +6895 -0
- package/dist/mcp-receipts.d.ts +96 -0
- package/dist/memory-slack-delivery.d.ts +397 -0
- package/dist/presentation-artifact-commands.d.ts +349 -0
- package/dist/presentation-artifact-commands.js +66 -0
- package/dist/presentation-artifact-commands.js.map +1 -0
- package/dist/presentation-artifact-query.d.ts +2 -0
- package/dist/presentation-artifact-query.js +66 -0
- package/dist/presentation-artifact-query.js.map +1 -0
- package/dist/retained-output.d.ts +83 -6
- package/dist/sandbox-snapshots.d.ts +9 -0
- package/dist/scoped-knowledge.d.ts +14 -13
- package/dist/slack-bot-scopes.d.ts +4 -0
- package/dist/slack-bot-scopes.js +3 -1
- package/dist/spreadsheet-artifact-commands.d.ts +101 -0
- package/dist/spreadsheet-artifact-commands.js +27 -0
- package/dist/spreadsheet-artifact-commands.js.map +1 -0
- package/dist/spreadsheet-artifact-date.d.ts +4 -0
- package/dist/spreadsheet-artifact-query.d.ts +120 -0
- package/dist/spreadsheet-artifact-query.js +48 -0
- package/dist/spreadsheet-artifact-query.js.map +1 -0
- package/dist/tool-catalog.d.ts +576 -0
- package/dist/video-generation.d.ts +532 -0
- package/dist/video-generation.js +51 -0
- package/dist/video-generation.js.map +1 -0
- package/dist/workspace-learning-policy.d.ts +208 -0
- package/package.json +61 -1
- package/src/atlassian.ts +160 -0
- package/src/company-profile.ts +306 -0
- package/src/document-artifact-commands.ts +1709 -0
- package/src/document-artifact-query.ts +2 -0
- package/src/editable-artifact-binary.ts +396 -0
- package/src/editable-artifact-causal-frontier.ts +154 -0
- package/src/editable-artifact-codec-registry.ts +261 -0
- package/src/editable-artifact-committed-transaction.ts +478 -0
- package/src/editable-artifact-live.ts +1379 -0
- package/src/editable-artifact-serialized-commit.ts +494 -0
- package/src/editable-artifact-versions.ts +8 -0
- package/src/editable-artifacts.ts +473 -0
- package/src/event-preview.ts +6 -6
- package/src/google-drive.ts +68 -15
- package/src/image-generation.ts +106 -0
- package/src/index.ts +2535 -282
- package/src/interaction.ts +2292 -0
- package/src/mcp-receipts.ts +281 -0
- package/src/memory-slack-delivery.ts +183 -0
- package/src/presentation-artifact-commands.ts +2035 -0
- package/src/presentation-artifact-query.ts +2 -0
- package/src/retained-output.ts +248 -8
- package/src/sandbox-snapshots.ts +28 -1
- package/src/scoped-knowledge.ts +18 -4
- package/src/slack-bot-scopes.ts +34 -1
- package/src/spreadsheet-artifact-commands.ts +999 -0
- package/src/spreadsheet-artifact-date.ts +21 -0
- package/src/spreadsheet-artifact-query.ts +1411 -0
- package/src/tool-catalog.ts +334 -0
- package/src/video-generation.ts +394 -0
- package/src/workspace-learning-policy.ts +233 -0
- package/dist/chunk-7JZMI22I.js.map +0 -1
- package/dist/chunk-PCTCJEAF.js +0 -10799
- package/dist/chunk-PCTCJEAF.js.map +0 -1
- package/dist/secret-redaction.d.ts +0 -40
- 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
|
+
}
|
package/src/event-preview.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Canonical bounded representation for
|
|
2
|
+
* Canonical bounded representation for explicit session-event previews.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
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.
|
package/src/google-drive.ts
CHANGED
|
@@ -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
|
|
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.
|
|
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:
|
|
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
|
+
>;
|