@relayflows/sdk 2.0.29 → 2.0.30
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/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +10 -1
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/bundle-extensions.d.ts.map +1 -1
- package/dist/bundle-extensions.js +4 -7
- package/dist/bundle-extensions.js.map +1 -1
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +41 -7
- package/dist/bundle.js.map +1 -1
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +18 -6
- package/dist/canonical.js.map +1 -1
- package/dist/flow-extension-compat.d.ts.map +1 -1
- package/dist/flow-extension-compat.js +26 -8
- package/dist/flow-extension-compat.js.map +1 -1
- package/dist/flow-extension-loader.d.ts +7 -0
- package/dist/flow-extension-loader.d.ts.map +1 -1
- package/dist/flow-extension-loader.js +48 -22
- package/dist/flow-extension-loader.js.map +1 -1
- package/dist/fs-descriptor.d.ts +17 -0
- package/dist/fs-descriptor.d.ts.map +1 -0
- package/dist/fs-descriptor.js +96 -0
- package/dist/fs-descriptor.js.map +1 -0
- package/dist/hosted-base-snapshot.d.ts +25 -0
- package/dist/hosted-base-snapshot.d.ts.map +1 -0
- package/dist/hosted-base-snapshot.js +278 -0
- package/dist/hosted-base-snapshot.js.map +1 -0
- package/dist/hosted-extension-declarations.d.ts +10 -0
- package/dist/hosted-extension-declarations.d.ts.map +1 -0
- package/dist/hosted-extension-declarations.js +272 -0
- package/dist/hosted-extension-declarations.js.map +1 -0
- package/dist/hosted-extension-isolation.d.ts +82 -0
- package/dist/hosted-extension-isolation.d.ts.map +1 -0
- package/dist/hosted-extension-isolation.js +322 -0
- package/dist/hosted-extension-isolation.js.map +1 -0
- package/dist/hosted-extension-manifest.d.ts +9 -0
- package/dist/hosted-extension-manifest.d.ts.map +1 -0
- package/dist/hosted-extension-manifest.js +235 -0
- package/dist/hosted-extension-manifest.js.map +1 -0
- package/dist/hosted-extension-protocol.d.ts +16 -0
- package/dist/hosted-extension-protocol.d.ts.map +1 -0
- package/dist/hosted-extension-protocol.js +224 -0
- package/dist/hosted-extension-protocol.js.map +1 -0
- package/dist/hosted-extension-runtime.d.ts +30 -0
- package/dist/hosted-extension-runtime.d.ts.map +1 -0
- package/dist/hosted-extension-runtime.js +167 -0
- package/dist/hosted-extension-runtime.js.map +1 -0
- package/dist/hosted-extension-sandbox-source.d.ts +9 -0
- package/dist/hosted-extension-sandbox-source.d.ts.map +1 -0
- package/dist/hosted-extension-sandbox-source.js +95 -0
- package/dist/hosted-extension-sandbox-source.js.map +1 -0
- package/dist/hosted-extension-sandbox.d.ts +39 -0
- package/dist/hosted-extension-sandbox.d.ts.map +1 -0
- package/dist/hosted-extension-sandbox.js +418 -0
- package/dist/hosted-extension-sandbox.js.map +1 -0
- package/dist/hosted-project.d.ts +3 -0
- package/dist/hosted-project.d.ts.map +1 -0
- package/dist/hosted-project.js +19 -0
- package/dist/hosted-project.js.map +1 -0
- package/dist/hosted-promise-safety.d.ts +12 -0
- package/dist/hosted-promise-safety.d.ts.map +1 -0
- package/dist/hosted-promise-safety.js +63 -0
- package/dist/hosted-promise-safety.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/intrinsic-array.d.ts +3 -0
- package/dist/intrinsic-array.d.ts.map +1 -0
- package/dist/intrinsic-array.js +14 -0
- package/dist/intrinsic-array.js.map +1 -0
- package/dist/json-value.d.ts +6 -1
- package/dist/json-value.d.ts.map +1 -1
- package/dist/json-value.js +155 -36
- package/dist/json-value.js.map +1 -1
- package/dist/llm-worker.d.ts +9 -0
- package/dist/llm-worker.d.ts.map +1 -1
- package/dist/llm-worker.js +15 -1
- package/dist/llm-worker.js.map +1 -1
- package/dist/plugin-store.d.ts +8 -2
- package/dist/plugin-store.d.ts.map +1 -1
- package/dist/plugin-store.js +233 -56
- package/dist/plugin-store.js.map +1 -1
- package/dist/semver-range.d.ts.map +1 -1
- package/dist/semver-range.js +27 -15
- package/dist/semver-range.js.map +1 -1
- package/package.json +2 -2
- package/src/authored-flow-executor.ts +10 -1
- package/src/bundle-extensions.ts +6 -5
- package/src/bundle.ts +52 -7
- package/src/canonical.ts +20 -6
- package/src/flow-extension-compat.ts +32 -7
- package/src/flow-extension-loader.ts +56 -21
- package/src/fs-descriptor.ts +127 -0
- package/src/hosted-base-snapshot.ts +351 -0
- package/src/hosted-extension-declarations.ts +387 -0
- package/src/hosted-extension-isolation.ts +457 -0
- package/src/hosted-extension-manifest.ts +249 -0
- package/src/hosted-extension-protocol.ts +262 -0
- package/src/hosted-extension-runtime.ts +266 -0
- package/src/hosted-extension-sandbox-source.ts +94 -0
- package/src/hosted-extension-sandbox.ts +489 -0
- package/src/hosted-project.ts +18 -0
- package/src/hosted-promise-safety.ts +68 -0
- package/src/index.ts +18 -0
- package/src/intrinsic-array.ts +14 -0
- package/src/json-value.ts +184 -32
- package/src/llm-worker.ts +15 -1
- package/src/plugin-store.ts +323 -56
- package/src/semver-range.ts +39 -14
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { ChildProcess } from 'node:child_process';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { Readable, Writable } from 'node:stream';
|
|
4
|
+
import { clearTimeout as nodeClearTimeout, setTimeout as nodeSetTimeout } from 'node:timers';
|
|
5
|
+
import { snapshotJsonValue } from './json-value.js';
|
|
6
|
+
import { PluginError } from './plugin-manifest.js';
|
|
7
|
+
import { assertHostedPromiseSafety, frozenHostedPromiseValue, } from './hosted-promise-safety.js';
|
|
8
|
+
const HOSTED_WRITE = 'cloud:babysitter-turn';
|
|
9
|
+
const MAX_FRAME_BYTES = 256 * 1024;
|
|
10
|
+
const MAX_STDERR_BYTES = 16 * 1024;
|
|
11
|
+
const ARRAY_IS_ARRAY = Array.isArray;
|
|
12
|
+
const BUFFER_BYTE_LENGTH = Buffer.byteLength;
|
|
13
|
+
const CHILD_PROCESS_KILL = Function.prototype.call.bind(ChildProcess.prototype.kill);
|
|
14
|
+
const EVENT_ON = Function.prototype.call.bind(EventEmitter.prototype.on);
|
|
15
|
+
const ERROR_IS_INSTANCE = Function.prototype.call.bind(Function.prototype[Symbol.hasInstance], Error);
|
|
16
|
+
const JSON_PARSE = JSON.parse;
|
|
17
|
+
const JSON_STRINGIFY = JSON.stringify;
|
|
18
|
+
const OBJECT_CREATE = Object.create;
|
|
19
|
+
const OBJECT_HAS_OWN = Object.hasOwn;
|
|
20
|
+
const OBJECT_KEYS = Object.keys;
|
|
21
|
+
const OBJECT_FREEZE = Object.freeze;
|
|
22
|
+
const PROMISE = Promise;
|
|
23
|
+
const PROMISE_THEN = Function.prototype.call.bind(Promise.prototype.then);
|
|
24
|
+
const READABLE_SET_ENCODING = Function.prototype.call.bind(Readable.prototype.setEncoding);
|
|
25
|
+
const READABLE_RESUME = Function.prototype.call.bind(Readable.prototype.resume);
|
|
26
|
+
const CLEAR_TIMEOUT = nodeClearTimeout;
|
|
27
|
+
const SET_TIMEOUT = nodeSetTimeout;
|
|
28
|
+
const TIMER_SAMPLE = SET_TIMEOUT(() => undefined, 0);
|
|
29
|
+
const TIMER_UNREF = Function.prototype.call.bind(TIMER_SAMPLE.unref);
|
|
30
|
+
CLEAR_TIMEOUT(TIMER_SAMPLE);
|
|
31
|
+
const STRING = String;
|
|
32
|
+
const STRING_INDEX_OF = Function.prototype.call.bind(String.prototype.indexOf);
|
|
33
|
+
const STRING_SLICE = Function.prototype.call.bind(String.prototype.slice);
|
|
34
|
+
const WRITABLE_END = Function.prototype.call.bind(Writable.prototype.end);
|
|
35
|
+
const WRITABLE_WRITE = Function.prototype.call.bind(Writable.prototype.write);
|
|
36
|
+
const SNAPSHOT_LIMITS = Object.freeze({
|
|
37
|
+
maxDepth: 64,
|
|
38
|
+
maxNodes: 262_144,
|
|
39
|
+
maxBytes: MAX_FRAME_BYTES,
|
|
40
|
+
});
|
|
41
|
+
/** A bounded JSON copy, stripped of prototypes and behavior. */
|
|
42
|
+
export function boundedJsonSnapshot(value, what) {
|
|
43
|
+
let snapshot;
|
|
44
|
+
try {
|
|
45
|
+
snapshot = snapshotJsonValue(value, what, SNAPSHOT_LIMITS);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw new PluginError('plugin_unsupported', `${what} is not bounded JSON data.`);
|
|
49
|
+
}
|
|
50
|
+
const encoded = JSON_STRINGIFY(snapshot);
|
|
51
|
+
if (BUFFER_BYTE_LENGTH(encoded) > MAX_FRAME_BYTES) {
|
|
52
|
+
throw new PluginError('plugin_unsupported', `${what} is not bounded JSON data.`);
|
|
53
|
+
}
|
|
54
|
+
return snapshot;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Exchange hostile child frames for one parent-owned capability invocation.
|
|
58
|
+
* Descriptor 3 is transport, never authority: every frame and both boundary
|
|
59
|
+
* payloads are validated by the parent. A child writing descriptor 3 directly
|
|
60
|
+
* can request only the same exact, single capability its context exposes.
|
|
61
|
+
*/
|
|
62
|
+
export async function exchangeHostedExtension(child, protocol, stdin, stderr, timeoutMs, request, invoke) {
|
|
63
|
+
assertHostedPromiseSafety('plugin_unsupported');
|
|
64
|
+
const requestSnapshot = boundedJsonSnapshot(request, 'hosted extension request');
|
|
65
|
+
let buffer = '';
|
|
66
|
+
let stderrText = '';
|
|
67
|
+
let calls = 0;
|
|
68
|
+
READABLE_SET_ENCODING(stderr, 'utf8');
|
|
69
|
+
EVENT_ON(stderr, 'data', chunk => {
|
|
70
|
+
stderrText = STRING_SLICE(stderrText + STRING(chunk), -MAX_STDERR_BYTES);
|
|
71
|
+
});
|
|
72
|
+
READABLE_RESUME(stderr);
|
|
73
|
+
READABLE_SET_ENCODING(protocol, 'utf8');
|
|
74
|
+
return await new PROMISE((resolvePromise, rejectPromise) => {
|
|
75
|
+
let settled = false;
|
|
76
|
+
let capabilityState = 'none';
|
|
77
|
+
let capabilityError;
|
|
78
|
+
let deferredProtocolError;
|
|
79
|
+
const finish = (error, result) => {
|
|
80
|
+
if (settled)
|
|
81
|
+
return;
|
|
82
|
+
settled = true;
|
|
83
|
+
CLEAR_TIMEOUT(timeout);
|
|
84
|
+
WRITABLE_END(stdin);
|
|
85
|
+
if (child.exitCode === null && child.signalCode === null)
|
|
86
|
+
CHILD_PROCESS_KILL(child, 'SIGKILL');
|
|
87
|
+
if (error !== undefined)
|
|
88
|
+
rejectPromise(error);
|
|
89
|
+
else
|
|
90
|
+
resolvePromise(result);
|
|
91
|
+
};
|
|
92
|
+
const failure = (error) => ERROR_IS_INSTANCE(error)
|
|
93
|
+
? error
|
|
94
|
+
: new PluginError('plugin_unsupported', 'Hosted capability rejected with a non-error value.');
|
|
95
|
+
const refuse = (message) => {
|
|
96
|
+
const error = new PluginError('plugin_unsupported', message);
|
|
97
|
+
CHILD_PROCESS_KILL(child, 'SIGKILL');
|
|
98
|
+
if (capabilityState === 'pending') {
|
|
99
|
+
deferredProtocolError ??= error;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
finish(capabilityError ?? error);
|
|
103
|
+
};
|
|
104
|
+
const timeout = SET_TIMEOUT(() => {
|
|
105
|
+
CHILD_PROCESS_KILL(child, 'SIGKILL');
|
|
106
|
+
finish(new PluginError('plugin_unsupported', capabilityState === 'pending'
|
|
107
|
+
? 'Hosted capability outcome is in doubt after the sandbox timeout.'
|
|
108
|
+
: 'Hosted extension sandbox timed out.'));
|
|
109
|
+
}, timeoutMs);
|
|
110
|
+
TIMER_UNREF(timeout);
|
|
111
|
+
EVENT_ON(stdin, 'error', () => refuse('Hosted extension capability channel closed.'));
|
|
112
|
+
EVENT_ON(protocol, 'error', () => refuse('Hosted extension protocol channel failed.'));
|
|
113
|
+
EVENT_ON(protocol, 'data', chunk => {
|
|
114
|
+
buffer += STRING(chunk);
|
|
115
|
+
if (BUFFER_BYTE_LENGTH(buffer) > MAX_FRAME_BYTES)
|
|
116
|
+
return refuse('Hosted extension protocol exceeded its size limit.');
|
|
117
|
+
for (;;) {
|
|
118
|
+
const end = STRING_INDEX_OF(buffer, '\n');
|
|
119
|
+
if (end < 0)
|
|
120
|
+
break;
|
|
121
|
+
const line = STRING_SLICE(buffer, 0, end);
|
|
122
|
+
buffer = STRING_SLICE(buffer, end + 1);
|
|
123
|
+
let message;
|
|
124
|
+
try {
|
|
125
|
+
const parsed = JSON_PARSE(line);
|
|
126
|
+
if (typeof parsed !== 'object' || parsed === null || ARRAY_IS_ARRAY(parsed)) {
|
|
127
|
+
return refuse('Hosted extension emitted a non-object protocol frame.');
|
|
128
|
+
}
|
|
129
|
+
message = boundedJsonSnapshot(parsed, 'hosted extension protocol frame');
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return refuse('Hosted extension emitted malformed protocol data.');
|
|
133
|
+
}
|
|
134
|
+
if (message.type === 'capability') {
|
|
135
|
+
if (!hasExactKeys(message, ['type', 'id', 'name', 'request'])) {
|
|
136
|
+
return refuse('Hosted extension emitted a malformed capability frame.');
|
|
137
|
+
}
|
|
138
|
+
calls += 1;
|
|
139
|
+
if (calls !== 1 || capabilityState !== 'none' || message.name !== HOSTED_WRITE || message.id !== 1) {
|
|
140
|
+
return refuse('Hosted extension requested an undeclared or repeated capability.');
|
|
141
|
+
}
|
|
142
|
+
capabilityState = 'pending';
|
|
143
|
+
void PROMISE_THEN(invoke(message.request), value => {
|
|
144
|
+
if (settled)
|
|
145
|
+
return;
|
|
146
|
+
try {
|
|
147
|
+
const snapshot = boundedJsonSnapshot(value, 'hosted capability result');
|
|
148
|
+
capabilityState = 'completed';
|
|
149
|
+
if (deferredProtocolError !== undefined)
|
|
150
|
+
return finish(deferredProtocolError);
|
|
151
|
+
WRITABLE_WRITE(stdin, capabilityResultFrame(true, snapshot));
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
capabilityError = failure(error);
|
|
155
|
+
capabilityState = 'failed';
|
|
156
|
+
WRITABLE_WRITE(stdin, capabilityResultFrame(false));
|
|
157
|
+
finish(capabilityError);
|
|
158
|
+
}
|
|
159
|
+
}, error => {
|
|
160
|
+
if (settled)
|
|
161
|
+
return;
|
|
162
|
+
capabilityError = failure(error);
|
|
163
|
+
capabilityState = 'failed';
|
|
164
|
+
WRITABLE_WRITE(stdin, capabilityResultFrame(false));
|
|
165
|
+
finish(capabilityError);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else if (message.type === 'result') {
|
|
169
|
+
if (!hasExactKeys(message, ['type', 'completionReason', 'capabilityCalls'])
|
|
170
|
+
|| calls !== 1 || capabilityState !== 'completed'
|
|
171
|
+
|| message.completionReason !== 'success' || message.capabilityCalls !== 1) {
|
|
172
|
+
return refuse('Hosted extension reported a completion without exactly one capability call.');
|
|
173
|
+
}
|
|
174
|
+
finish(undefined, frozenHostedPromiseValue({ completionReason: 'success', capabilityCalls: 1 }));
|
|
175
|
+
}
|
|
176
|
+
else if (message.type === 'error') {
|
|
177
|
+
if (!hasExactKeys(message, ['type', 'message']) || typeof message.message !== 'string') {
|
|
178
|
+
return refuse('Hosted extension emitted a malformed error frame.');
|
|
179
|
+
}
|
|
180
|
+
const error = new PluginError('plugin_unsupported', `Hosted extension failed: ${STRING_SLICE(message.message, 0, 8192)}`);
|
|
181
|
+
if (capabilityState === 'pending') {
|
|
182
|
+
deferredProtocolError ??= error;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
finish(capabilityError ?? error);
|
|
186
|
+
}
|
|
187
|
+
else
|
|
188
|
+
return refuse('Hosted extension emitted an unknown protocol message.');
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
READABLE_RESUME(protocol);
|
|
192
|
+
EVENT_ON(child, 'error', () => refuse('Hosted extension sandbox could not start.'));
|
|
193
|
+
EVENT_ON(child, 'close', code => {
|
|
194
|
+
if (!settled)
|
|
195
|
+
refuse(`Hosted extension sandbox exited without a valid completion (exit ${code ?? 'signal'})`
|
|
196
|
+
+ (stderrText === '' ? '' : `: ${stderrText}`));
|
|
197
|
+
});
|
|
198
|
+
WRITABLE_WRITE(stdin, `${JSON_STRINGIFY(requestSnapshot)}\n`);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function capabilityResultFrame(ok, value) {
|
|
202
|
+
// JSON.stringify consults inherited `toJSON` before traversing an object.
|
|
203
|
+
// Protocol envelopes therefore never inherit from the ambient prototype;
|
|
204
|
+
// nested capability data is already a behavior-free bounded snapshot.
|
|
205
|
+
const envelope = OBJECT_CREATE(null);
|
|
206
|
+
envelope.type = 'capability-result';
|
|
207
|
+
envelope.id = 1;
|
|
208
|
+
envelope.ok = ok;
|
|
209
|
+
if (ok)
|
|
210
|
+
envelope.value = value;
|
|
211
|
+
else
|
|
212
|
+
envelope.error = 'hosted capability refused';
|
|
213
|
+
return `${JSON_STRINGIFY(envelope)}\n`;
|
|
214
|
+
}
|
|
215
|
+
function hasExactKeys(value, keys) {
|
|
216
|
+
if (OBJECT_KEYS(value).length !== keys.length)
|
|
217
|
+
return false;
|
|
218
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
219
|
+
if (!OBJECT_HAS_OWN(value, keys[index]))
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=hosted-extension-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-protocol.js","sourceRoot":"","sources":["../src/hosted-extension-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface HostedExtensionArtifact {
|
|
2
|
+
readonly ref: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly version: string;
|
|
5
|
+
readonly directory: string;
|
|
6
|
+
readonly digest: string;
|
|
7
|
+
readonly manifestSha256: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HostedExtensionInstallation {
|
|
10
|
+
readonly artifacts: readonly HostedExtensionArtifact[];
|
|
11
|
+
}
|
|
12
|
+
export interface HostedExtensionBase {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly version?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface HostedExtensionRuntime {
|
|
17
|
+
readonly installation: HostedExtensionInstallation;
|
|
18
|
+
readonly base: HostedExtensionBase;
|
|
19
|
+
}
|
|
20
|
+
/** Load one base/installation generation that cannot be paired across redeploys. */
|
|
21
|
+
export declare function loadHostedExtensionRuntime(flowPath: string): Promise<HostedExtensionRuntime>;
|
|
22
|
+
/** @internal Metadata-only test seam; public hosted callers use the combined loader. */
|
|
23
|
+
export declare function loadHostedExtensionArtifacts(flowPath: string): Promise<HostedExtensionInstallation>;
|
|
24
|
+
/** @internal Base-only test seam; public hosted callers use the combined loader. */
|
|
25
|
+
export declare function loadHostedExtensionBase(flowPath: string): Promise<HostedExtensionBase>;
|
|
26
|
+
/** Validate both opaque values and refuse a cached generation after redeploy. */
|
|
27
|
+
export declare function assertHostedRuntimeAuthority(installation: HostedExtensionInstallation, base: HostedExtensionBase): Promise<void>;
|
|
28
|
+
/** @internal Validate a metadata-only installation used by selection tests. */
|
|
29
|
+
export declare function assertHostedInstallationAuthority(value: unknown): asserts value is HostedExtensionInstallation;
|
|
30
|
+
//# sourceMappingURL=hosted-extension-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-runtime.d.ts","sourceRoot":"","sources":["../src/hosted-extension-runtime.ts"],"names":[],"mappings":"AA2DA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,uBAAuB,EAAE,CAAC;CACxD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,YAAY,EAAE,2BAA2B,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;CACpC;AAED,oFAAoF;AACpF,wBAAsB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAgBlG;AAED,wFAAwF;AACxF,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAOzG;AAED,oFAAoF;AACpF,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAM5F;AAED,iFAAiF;AACjF,wBAAsB,4BAA4B,CAChD,YAAY,EAAE,2BAA2B,EACzC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,+EAA+E;AAC/E,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,2BAA2B,CAS9G"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { realpath } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { canonicalize } from './canonical.js';
|
|
4
|
+
import { createHostedBaseSnapshot, hostedBaseSourceDigest, removeHostedBaseSnapshot, } from './hosted-base-snapshot.js';
|
|
5
|
+
import { appendIntrinsicArray } from './intrinsic-array.js';
|
|
6
|
+
import { declarationSignature, hostedDeclaredExtensions, } from './hosted-extension-declarations.js';
|
|
7
|
+
import { findHostedProject } from './hosted-project.js';
|
|
8
|
+
import { assertHostedPromiseSafety, frozenHostedPromiseValue, } from './hosted-promise-safety.js';
|
|
9
|
+
import { PluginError } from './plugin-manifest.js';
|
|
10
|
+
import { pluginStoreDirectory, verifyStoredPlugin } from './plugin-store.js';
|
|
11
|
+
const INSTALLATION_AUTHORITY = new WeakSet();
|
|
12
|
+
const BASE_AUTHORITY = new WeakSet();
|
|
13
|
+
const REALPATH = realpath;
|
|
14
|
+
const PATH_DIRNAME = dirname;
|
|
15
|
+
const PATH_JOIN = join;
|
|
16
|
+
const PATH_RESOLVE = resolve;
|
|
17
|
+
const SOFTWARE_FACTORY_SHA256 = '49c993220b9c34fab2d4b0e51911656f62b8b657f534d988691960d45bb9d9b6';
|
|
18
|
+
const ARRAY_IS_ARRAY = Array.isArray;
|
|
19
|
+
const OBJECT_FREEZE = Object.freeze;
|
|
20
|
+
const WEAK_MAP_GET = Function.prototype.call.bind(WeakMap.prototype.get);
|
|
21
|
+
const WEAK_MAP_SET = Function.prototype.call.bind(WeakMap.prototype.set);
|
|
22
|
+
const WEAK_SET_ADD = Function.prototype.call.bind(WeakSet.prototype.add);
|
|
23
|
+
const WEAK_SET_HAS = Function.prototype.call.bind(WeakSet.prototype.has);
|
|
24
|
+
const INSTALLATION_GENERATION = new WeakMap();
|
|
25
|
+
const BASE_GENERATION = new WeakMap();
|
|
26
|
+
/** Load one base/installation generation that cannot be paired across redeploys. */
|
|
27
|
+
export async function loadHostedExtensionRuntime(flowPath) {
|
|
28
|
+
assertHostedPromiseSafety('plugin_source_invalid');
|
|
29
|
+
const origin = await REALPATH(PATH_RESOLVE(flowPath));
|
|
30
|
+
const generation = newGeneration(origin);
|
|
31
|
+
const loaded = await installationAt(origin, generation);
|
|
32
|
+
generation.declarations = loaded.declarations;
|
|
33
|
+
const base = await baseAt(origin, generation);
|
|
34
|
+
if (loaded.declarations !== declaredExtensions(generation).signature) {
|
|
35
|
+
throw new PluginError('plugin_source_drift', 'Hosted extension declarations changed while their runtime generation was loaded.');
|
|
36
|
+
}
|
|
37
|
+
await assertCurrentGeneration(generation);
|
|
38
|
+
OBJECT_FREEZE(generation);
|
|
39
|
+
return frozenHostedPromiseValue({ installation: loaded.installation, base });
|
|
40
|
+
}
|
|
41
|
+
/** @internal Metadata-only test seam; public hosted callers use the combined loader. */
|
|
42
|
+
export async function loadHostedExtensionArtifacts(flowPath) {
|
|
43
|
+
assertHostedPromiseSafety('plugin_source_invalid');
|
|
44
|
+
const origin = await REALPATH(PATH_RESOLVE(flowPath));
|
|
45
|
+
const generation = newGeneration(origin);
|
|
46
|
+
const loaded = await installationAt(origin, generation);
|
|
47
|
+
generation.declarations = loaded.declarations;
|
|
48
|
+
return loaded.installation;
|
|
49
|
+
}
|
|
50
|
+
/** @internal Base-only test seam; public hosted callers use the combined loader. */
|
|
51
|
+
export async function loadHostedExtensionBase(flowPath) {
|
|
52
|
+
assertHostedPromiseSafety('plugin_source_invalid');
|
|
53
|
+
const origin = await REALPATH(PATH_RESOLVE(flowPath));
|
|
54
|
+
const generation = newGeneration(origin);
|
|
55
|
+
generation.declarations = declaredExtensions(generation).signature;
|
|
56
|
+
return await baseAt(origin, generation);
|
|
57
|
+
}
|
|
58
|
+
/** Validate both opaque values and refuse a cached generation after redeploy. */
|
|
59
|
+
export async function assertHostedRuntimeAuthority(installation, base) {
|
|
60
|
+
if (typeof base !== 'object' || base === null || !WEAK_SET_HAS(BASE_AUTHORITY, base)) {
|
|
61
|
+
throw new PluginError('plugin_incompatible', 'Hosted extension base authority is malformed; use loadHostedExtensionRuntime.');
|
|
62
|
+
}
|
|
63
|
+
if (typeof installation !== 'object' ||
|
|
64
|
+
installation === null ||
|
|
65
|
+
!WEAK_SET_HAS(INSTALLATION_AUTHORITY, installation)) {
|
|
66
|
+
throw new PluginError('plugin_source_invalid', 'Hosted extension installation authority is malformed; use loadHostedExtensionRuntime.');
|
|
67
|
+
}
|
|
68
|
+
const generation = WEAK_MAP_GET(BASE_GENERATION, base);
|
|
69
|
+
if (generation === undefined || generation !== WEAK_MAP_GET(INSTALLATION_GENERATION, installation)) {
|
|
70
|
+
throw new PluginError('plugin_source_invalid', 'Hosted extension base and installation must originate from the same runtime generation.');
|
|
71
|
+
}
|
|
72
|
+
await assertCurrentGeneration(generation);
|
|
73
|
+
}
|
|
74
|
+
/** @internal Validate a metadata-only installation used by selection tests. */
|
|
75
|
+
export function assertHostedInstallationAuthority(value) {
|
|
76
|
+
if (typeof value !== 'object' ||
|
|
77
|
+
value === null ||
|
|
78
|
+
!WEAK_SET_HAS(INSTALLATION_AUTHORITY, value) ||
|
|
79
|
+
!ARRAY_IS_ARRAY(value.artifacts)) {
|
|
80
|
+
throw new PluginError('plugin_source_invalid', 'Hosted extension installation authority is malformed.');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function installationAt(origin, generation) {
|
|
84
|
+
const root = generation.projectRoot;
|
|
85
|
+
if (root === undefined)
|
|
86
|
+
return frozenHostedPromiseValue({
|
|
87
|
+
installation: installation([], generation),
|
|
88
|
+
declarations: canonicalize([]),
|
|
89
|
+
});
|
|
90
|
+
const artifacts = [];
|
|
91
|
+
const declared = hostedDeclaredExtensions(root);
|
|
92
|
+
for (let index = 0; index < declared.length; index += 1) {
|
|
93
|
+
const { ref, entry } = declared[index];
|
|
94
|
+
const directory = pluginStoreDirectory(root, entry.name, entry.digest);
|
|
95
|
+
await verifyStoredPlugin(directory, entry.digest);
|
|
96
|
+
appendIntrinsicArray(artifacts, OBJECT_FREEZE({
|
|
97
|
+
ref,
|
|
98
|
+
name: entry.name,
|
|
99
|
+
version: entry.version,
|
|
100
|
+
directory,
|
|
101
|
+
digest: entry.digest,
|
|
102
|
+
manifestSha256: entry.manifestSha256,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
return frozenHostedPromiseValue({
|
|
106
|
+
installation: installation(artifacts, generation),
|
|
107
|
+
declarations: declarationSignature(declared),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function declaredExtensions(generation) {
|
|
111
|
+
const root = generation.projectRoot;
|
|
112
|
+
return {
|
|
113
|
+
signature: root === undefined ? canonicalize([]) : declarationSignature(hostedDeclaredExtensions(root)),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function newGeneration(origin) {
|
|
117
|
+
return {
|
|
118
|
+
origin,
|
|
119
|
+
projectRoot: findHostedProject(PATH_DIRNAME(origin)),
|
|
120
|
+
declarations: canonicalize([]),
|
|
121
|
+
sourceRoots: OBJECT_FREEZE([]),
|
|
122
|
+
sourceSha256: '',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function assertCurrentGeneration(generation) {
|
|
126
|
+
let currentSource;
|
|
127
|
+
try {
|
|
128
|
+
currentSource = await hostedBaseSourceDigest(generation.sourceRoots);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
throw new PluginError('plugin_source_invalid', 'Hosted extension runtime generation is no longer readable.');
|
|
132
|
+
}
|
|
133
|
+
if (declaredExtensions(generation).signature !== generation.declarations ||
|
|
134
|
+
currentSource !== generation.sourceSha256) {
|
|
135
|
+
throw new PluginError('plugin_source_invalid', 'Hosted extension runtime generation is stale; reload the base and installation together.');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function baseAt(origin, generation) {
|
|
139
|
+
const snapshot = await createHostedBaseSnapshot(origin, generation.projectRoot ?? PATH_DIRNAME(origin));
|
|
140
|
+
generation.sourceRoots = snapshot.liveSources;
|
|
141
|
+
generation.sourceSha256 = snapshot.liveDigest;
|
|
142
|
+
try {
|
|
143
|
+
if (snapshot.snapshotFlowSha256 !== SOFTWARE_FACTORY_SHA256) {
|
|
144
|
+
throw new PluginError('plugin_source_invalid', 'Hosted capability isolation accepts only the reviewed Software Factory base source.');
|
|
145
|
+
}
|
|
146
|
+
const value = frozenHostedPromiseValue({
|
|
147
|
+
name: 'software-factory',
|
|
148
|
+
version: '2.0.22',
|
|
149
|
+
});
|
|
150
|
+
WEAK_SET_ADD(BASE_AUTHORITY, value);
|
|
151
|
+
WEAK_MAP_SET(BASE_GENERATION, value, generation);
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
await removeHostedBaseSnapshot(snapshot);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function installation(artifacts, generation) {
|
|
159
|
+
const artifactCopy = [];
|
|
160
|
+
for (let index = 0; index < artifacts.length; index += 1)
|
|
161
|
+
appendIntrinsicArray(artifactCopy, artifacts[index]);
|
|
162
|
+
const value = frozenHostedPromiseValue({ artifacts: frozenHostedPromiseValue(artifactCopy) });
|
|
163
|
+
WEAK_SET_ADD(INSTALLATION_AUTHORITY, value);
|
|
164
|
+
WEAK_MAP_SET(INSTALLATION_GENERATION, value, generation);
|
|
165
|
+
return value;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=hosted-extension-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-runtime.js","sourceRoot":"","sources":["../src/hosted-extension-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source for the process that imports one hosted extension inside the Linux
|
|
3
|
+
* namespace assembled by hosted-extension-isolation.ts.
|
|
4
|
+
*
|
|
5
|
+
* Keep this dependency-free. The parent writes it to a private file and
|
|
6
|
+
* mounts that file read-only; the extension is not imported by the host.
|
|
7
|
+
*/
|
|
8
|
+
export declare const HOSTED_EXTENSION_SANDBOX_SOURCE: string;
|
|
9
|
+
//# sourceMappingURL=hosted-extension-sandbox-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-sandbox-source.d.ts","sourceRoot":"","sources":["../src/hosted-extension-sandbox-source.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,QAsF3C,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source for the process that imports one hosted extension inside the Linux
|
|
3
|
+
* namespace assembled by hosted-extension-isolation.ts.
|
|
4
|
+
*
|
|
5
|
+
* Keep this dependency-free. The parent writes it to a private file and
|
|
6
|
+
* mounts that file read-only; the extension is not imported by the host.
|
|
7
|
+
*/
|
|
8
|
+
export const HOSTED_EXTENSION_SANDBOX_SOURCE = String.raw `
|
|
9
|
+
import { createReadStream, writeSync } from 'node:fs';
|
|
10
|
+
import { createInterface } from 'node:readline';
|
|
11
|
+
import { pathToFileURL } from 'node:url';
|
|
12
|
+
|
|
13
|
+
const lines = createInterface({ input: createReadStream(null, { fd: 0 }), crlfDelay: Infinity });
|
|
14
|
+
const iterator = lines[Symbol.asyncIterator]();
|
|
15
|
+
const send = value => writeSync(3, JSON.stringify(value) + '\n');
|
|
16
|
+
const receive = async () => {
|
|
17
|
+
const next = await iterator.next();
|
|
18
|
+
if (next.done) throw new Error('hosted capability channel closed');
|
|
19
|
+
return JSON.parse(next.value);
|
|
20
|
+
};
|
|
21
|
+
const subscriptionOf = handler => {
|
|
22
|
+
const trigger = handler?.trigger;
|
|
23
|
+
const filter = trigger?.filter;
|
|
24
|
+
if (trigger?.kind !== 'webhook' || filter === undefined
|
|
25
|
+
|| typeof filter.provider !== 'string' || filter.provider !== trigger.name
|
|
26
|
+
|| typeof filter.type !== 'string') return undefined;
|
|
27
|
+
const action = typeof filter.payload === 'object' && filter.payload !== null && !Array.isArray(filter.payload)
|
|
28
|
+
? filter.payload.action : undefined;
|
|
29
|
+
if (action !== undefined && typeof action !== 'string') return undefined;
|
|
30
|
+
return action === undefined
|
|
31
|
+
? { provider: filter.provider, event: filter.type }
|
|
32
|
+
: { provider: filter.provider, event: filter.type, action };
|
|
33
|
+
};
|
|
34
|
+
const matches = (subscription, identity) => subscription !== undefined
|
|
35
|
+
&& subscription.provider === identity.provider
|
|
36
|
+
&& subscription.event === identity.event
|
|
37
|
+
&& (subscription.action === undefined || subscription.action === identity.action);
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const request = await receive();
|
|
41
|
+
if (request?.type !== 'execute' || typeof request.entry !== 'string'
|
|
42
|
+
|| typeof request.surfaceRuntime !== 'string' || typeof request.capability !== 'string') {
|
|
43
|
+
throw new Error('malformed hosted extension execution request');
|
|
44
|
+
}
|
|
45
|
+
const runtime = await import(pathToFileURL(request.surfaceRuntime).href);
|
|
46
|
+
const authored = await import(pathToFileURL(request.entry).href);
|
|
47
|
+
const definition = runtime.getFlowDefinition(authored.default);
|
|
48
|
+
const selected = definition.handlers.filter(handler => matches(subscriptionOf(handler), request.identity));
|
|
49
|
+
if (selected.length !== 1) throw new Error('hosted event must match exactly one isolated extension handler');
|
|
50
|
+
|
|
51
|
+
let nextCall = 1;
|
|
52
|
+
let capabilityCalls = 0;
|
|
53
|
+
let completion;
|
|
54
|
+
const invoke = async value => {
|
|
55
|
+
capabilityCalls += 1;
|
|
56
|
+
if (capabilityCalls !== 1) throw new Error('hosted extension may invoke its capability once');
|
|
57
|
+
const id = nextCall++;
|
|
58
|
+
send({ type: 'capability', id, name: request.capability, request: value });
|
|
59
|
+
const response = await receive();
|
|
60
|
+
if (response?.type !== 'capability-result' || response.id !== id || typeof response.ok !== 'boolean') {
|
|
61
|
+
throw new Error('malformed hosted capability response');
|
|
62
|
+
}
|
|
63
|
+
if (!response.ok) throw new Error(typeof response.error === 'string' ? response.error : 'hosted capability refused');
|
|
64
|
+
return response.value;
|
|
65
|
+
};
|
|
66
|
+
const capabilities = Object.freeze({
|
|
67
|
+
cloud: Object.freeze({ babysitterTurn: Object.freeze({ queue: invoke }) }),
|
|
68
|
+
});
|
|
69
|
+
const available = Object.freeze({
|
|
70
|
+
capabilities,
|
|
71
|
+
done(reason) {
|
|
72
|
+
if (completion !== undefined) throw new Error('hosted extension completed more than once');
|
|
73
|
+
completion = reason;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
const context = new Proxy(available, {
|
|
77
|
+
get(target, property, receiver) {
|
|
78
|
+
if (property !== 'capabilities' && property !== 'done') {
|
|
79
|
+
throw new Error('hosted extension context denies ' + String(property));
|
|
80
|
+
}
|
|
81
|
+
return Reflect.get(target, property, receiver);
|
|
82
|
+
},
|
|
83
|
+
has(_target, property) { return property === 'capabilities' || property === 'done'; },
|
|
84
|
+
ownKeys() { return ['capabilities', 'done']; },
|
|
85
|
+
});
|
|
86
|
+
await selected[0].body(context, request.input);
|
|
87
|
+
if (capabilityCalls !== 1) throw new Error('hosted extension did not invoke its capability exactly once');
|
|
88
|
+
if (completion !== 'success') throw new Error('hosted extension did not complete with success');
|
|
89
|
+
send({ type: 'result', completionReason: completion, capabilityCalls });
|
|
90
|
+
} catch (error) {
|
|
91
|
+
send({ type: 'error', message: error instanceof Error ? (error.stack ?? error.message) : String(error) });
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
//# sourceMappingURL=hosted-extension-sandbox-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-sandbox-source.js","sourceRoot":"","sources":["../src/hosted-extension-sandbox-source.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFxD,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type BigIntStats } from 'node:fs';
|
|
2
|
+
import { type HostedExtensionProtocolResult } from './hosted-extension-protocol.js';
|
|
3
|
+
export interface CapturedExecutable {
|
|
4
|
+
readonly descriptor: number;
|
|
5
|
+
readonly sha256: string;
|
|
6
|
+
readonly stat: BigIntStats;
|
|
7
|
+
}
|
|
8
|
+
export interface RunHostedExtensionSandboxOptions {
|
|
9
|
+
readonly artifactDirectory: string;
|
|
10
|
+
readonly artifactDigest: string;
|
|
11
|
+
readonly entry: string;
|
|
12
|
+
readonly surfaceVersion: string;
|
|
13
|
+
readonly identity: {
|
|
14
|
+
readonly provider: string;
|
|
15
|
+
readonly event: string;
|
|
16
|
+
readonly action?: string;
|
|
17
|
+
};
|
|
18
|
+
readonly input: unknown;
|
|
19
|
+
readonly invoke: (request: unknown) => Promise<unknown>;
|
|
20
|
+
readonly timeoutMs?: number;
|
|
21
|
+
readonly bubblewrapPath?: string;
|
|
22
|
+
readonly nodePath?: string;
|
|
23
|
+
readonly prlimitPath?: string;
|
|
24
|
+
/** @internal Test seam for a package root with the exact pinned runtime bytes. */
|
|
25
|
+
readonly surfaceRoot?: string;
|
|
26
|
+
/** @internal Last parent-side authority check after private snapshots exist. */
|
|
27
|
+
readonly beforeLaunch?: () => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export declare function runHostedExtensionSandbox(options: RunHostedExtensionSandboxOptions): Promise<HostedExtensionProtocolResult>;
|
|
30
|
+
/** @internal Pure construction seam for hostile-intrinsic regressions. */
|
|
31
|
+
export declare function sandboxArguments(input: {
|
|
32
|
+
dataDestinations: readonly string[];
|
|
33
|
+
}): string[];
|
|
34
|
+
/** @internal Descriptor-pinning seam for the executable replacement regression. */
|
|
35
|
+
export declare function captureExecutable(path: string, name: string): CapturedExecutable;
|
|
36
|
+
/** @internal Reads the inode captured before authored code could replace its path. */
|
|
37
|
+
export declare function readCapturedExecutable(capture: CapturedExecutable, name: string): Buffer;
|
|
38
|
+
export declare function supportsHostedSandboxFlags(version: string): boolean;
|
|
39
|
+
//# sourceMappingURL=hosted-extension-sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-extension-sandbox.d.ts","sourceRoot":"","sources":["../src/hosted-extension-sandbox.ts"],"names":[],"mappings":"AACA,OAAO,EASL,KAAK,WAAW,EACjB,MAAM,SAAS,CAAC;AAsBjB,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,gCAAgC,CAAC;AA0FxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC5B;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,6BAA6B,CAAC,CAgGxC;AAsGD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,GAAG,MAAM,EAAE,CAuDX;AAOD,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAuBhF;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CASxF;AA2BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAMnE"}
|