@pella-labs/pinakes 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -0
- package/dist/cli/audit.d.ts +30 -0
- package/dist/cli/audit.d.ts.map +1 -0
- package/dist/cli/audit.js +49 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/export.d.ts +32 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +73 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/import.d.ts +24 -0
- package/dist/cli/import.d.ts.map +1 -0
- package/dist/cli/import.js +96 -0
- package/dist/cli/import.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +172 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/purge.d.ts +23 -0
- package/dist/cli/purge.d.ts.map +1 -0
- package/dist/cli/purge.js +57 -0
- package/dist/cli/purge.js.map +1 -0
- package/dist/cli/rebuild.d.ts +54 -0
- package/dist/cli/rebuild.d.ts.map +1 -0
- package/dist/cli/rebuild.js +113 -0
- package/dist/cli/rebuild.js.map +1 -0
- package/dist/cli/serve.d.ts +49 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +296 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/status.d.ts +39 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +108 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/db/client.d.ts +109 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +175 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/repository.d.ts +82 -0
- package/dist/db/repository.d.ts.map +1 -0
- package/dist/db/repository.js +173 -0
- package/dist/db/repository.js.map +1 -0
- package/dist/db/schema.d.ts +990 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +259 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/types.d.ts +28 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +11 -0
- package/dist/db/types.js.map +1 -0
- package/dist/gaps/detector.d.ts +67 -0
- package/dist/gaps/detector.d.ts.map +1 -0
- package/dist/gaps/detector.js +160 -0
- package/dist/gaps/detector.js.map +1 -0
- package/dist/gate/budget.d.ts +90 -0
- package/dist/gate/budget.d.ts.map +1 -0
- package/dist/gate/budget.js +145 -0
- package/dist/gate/budget.js.map +1 -0
- package/dist/ingest/chokidar.d.ts +33 -0
- package/dist/ingest/chokidar.d.ts.map +1 -0
- package/dist/ingest/chokidar.js +152 -0
- package/dist/ingest/chokidar.js.map +1 -0
- package/dist/ingest/ingester.d.ts +117 -0
- package/dist/ingest/ingester.d.ts.map +1 -0
- package/dist/ingest/ingester.js +312 -0
- package/dist/ingest/ingester.js.map +1 -0
- package/dist/ingest/manifest.d.ts +87 -0
- package/dist/ingest/manifest.d.ts.map +1 -0
- package/dist/ingest/manifest.js +223 -0
- package/dist/ingest/manifest.js.map +1 -0
- package/dist/ingest/memory-store.d.ts +55 -0
- package/dist/ingest/memory-store.d.ts.map +1 -0
- package/dist/ingest/memory-store.js +94 -0
- package/dist/ingest/memory-store.js.map +1 -0
- package/dist/ingest/parse/chunk.d.ts +15 -0
- package/dist/ingest/parse/chunk.d.ts.map +1 -0
- package/dist/ingest/parse/chunk.js +88 -0
- package/dist/ingest/parse/chunk.js.map +1 -0
- package/dist/ingest/parse/markdown.d.ts +64 -0
- package/dist/ingest/parse/markdown.d.ts.map +1 -0
- package/dist/ingest/parse/markdown.js +152 -0
- package/dist/ingest/parse/markdown.js.map +1 -0
- package/dist/ingest/queue.d.ts +21 -0
- package/dist/ingest/queue.d.ts.map +1 -0
- package/dist/ingest/queue.js +24 -0
- package/dist/ingest/queue.js.map +1 -0
- package/dist/ingest/source.d.ts +42 -0
- package/dist/ingest/source.d.ts.map +1 -0
- package/dist/ingest/source.js +19 -0
- package/dist/ingest/source.js.map +1 -0
- package/dist/mcp/envelope.d.ts +73 -0
- package/dist/mcp/envelope.d.ts.map +1 -0
- package/dist/mcp/envelope.js +46 -0
- package/dist/mcp/envelope.js.map +1 -0
- package/dist/mcp/tools/execute.d.ts +55 -0
- package/dist/mcp/tools/execute.d.ts.map +1 -0
- package/dist/mcp/tools/execute.js +232 -0
- package/dist/mcp/tools/execute.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +53 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +114 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/observability/audit.d.ts +25 -0
- package/dist/observability/audit.d.ts.map +1 -0
- package/dist/observability/audit.js +38 -0
- package/dist/observability/audit.js.map +1 -0
- package/dist/observability/logger.d.ts +4 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +56 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +38 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +64 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/retrieval/embedder.d.ts +130 -0
- package/dist/retrieval/embedder.d.ts.map +1 -0
- package/dist/retrieval/embedder.js +278 -0
- package/dist/retrieval/embedder.js.map +1 -0
- package/dist/retrieval/fts.d.ts +42 -0
- package/dist/retrieval/fts.d.ts.map +1 -0
- package/dist/retrieval/fts.js +46 -0
- package/dist/retrieval/fts.js.map +1 -0
- package/dist/retrieval/hybrid.d.ts +43 -0
- package/dist/retrieval/hybrid.d.ts.map +1 -0
- package/dist/retrieval/hybrid.js +120 -0
- package/dist/retrieval/hybrid.js.map +1 -0
- package/dist/retrieval/vec.d.ts +39 -0
- package/dist/retrieval/vec.d.ts.map +1 -0
- package/dist/retrieval/vec.js +50 -0
- package/dist/retrieval/vec.js.map +1 -0
- package/dist/sandbox/bindings/budget.d.ts +10 -0
- package/dist/sandbox/bindings/budget.d.ts.map +1 -0
- package/dist/sandbox/bindings/budget.js +44 -0
- package/dist/sandbox/bindings/budget.js.map +1 -0
- package/dist/sandbox/bindings/install.d.ts +23 -0
- package/dist/sandbox/bindings/install.d.ts.map +1 -0
- package/dist/sandbox/bindings/install.js +15 -0
- package/dist/sandbox/bindings/install.js.map +1 -0
- package/dist/sandbox/bindings/kg.d.ts +29 -0
- package/dist/sandbox/bindings/kg.d.ts.map +1 -0
- package/dist/sandbox/bindings/kg.js +323 -0
- package/dist/sandbox/bindings/kg.js.map +1 -0
- package/dist/sandbox/bindings/logger.d.ts +11 -0
- package/dist/sandbox/bindings/logger.d.ts.map +1 -0
- package/dist/sandbox/bindings/logger.js +33 -0
- package/dist/sandbox/bindings/logger.js.map +1 -0
- package/dist/sandbox/bindings/write.d.ts +34 -0
- package/dist/sandbox/bindings/write.d.ts.map +1 -0
- package/dist/sandbox/bindings/write.js +195 -0
- package/dist/sandbox/bindings/write.js.map +1 -0
- package/dist/sandbox/executor.d.ts +68 -0
- package/dist/sandbox/executor.d.ts.map +1 -0
- package/dist/sandbox/executor.js +280 -0
- package/dist/sandbox/executor.js.map +1 -0
- package/dist/sandbox/helpers.d.ts +26 -0
- package/dist/sandbox/helpers.d.ts.map +1 -0
- package/dist/sandbox/helpers.js +131 -0
- package/dist/sandbox/helpers.js.map +1 -0
- package/dist/sandbox/pool.d.ts +63 -0
- package/dist/sandbox/pool.d.ts.map +1 -0
- package/dist/sandbox/pool.js +98 -0
- package/dist/sandbox/pool.js.map +1 -0
- package/dist/sandbox/vendored-codemode.d.ts +99 -0
- package/dist/sandbox/vendored-codemode.d.ts.map +1 -0
- package/dist/sandbox/vendored-codemode.js +471 -0
- package/dist/sandbox/vendored-codemode.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/spike.d.ts +15 -0
- package/dist/spike.d.ts.map +1 -0
- package/dist/spike.js +90 -0
- package/dist/spike.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type ExecuteResult, type Executor, type ResolvedProvider } from './vendored-codemode.js';
|
|
2
|
+
import { type PoolStats } from './pool.js';
|
|
3
|
+
import { type BindingDeps } from './bindings/install.js';
|
|
4
|
+
/**
|
|
5
|
+
* QuickJS-backed Executor.
|
|
6
|
+
*
|
|
7
|
+
* Phase 3 upgrade: warm pool N=2 + `executeWithBindings()` for the full
|
|
8
|
+
* `kg.project.*` binding surface. The legacy `execute()` path (flat
|
|
9
|
+
* providers) remains for backward compatibility with Phase 1/2 tests.
|
|
10
|
+
*
|
|
11
|
+
* **Pool path** (`executeWithBindings`):
|
|
12
|
+
* 1. Acquire a runtime from the warm pool (or cold-spawn on overflow)
|
|
13
|
+
* 2. Create a fresh context on the pooled runtime
|
|
14
|
+
* 3. Bootstrap disabled globals + install full bindings
|
|
15
|
+
* 4. Evaluate normalized code
|
|
16
|
+
* 5. Dispose context, release runtime back to pool
|
|
17
|
+
*
|
|
18
|
+
* **Legacy path** (`execute`):
|
|
19
|
+
* Fresh runtime + context per call, flat provider injection.
|
|
20
|
+
* Kept for Phase 1/2 spike tests that use `kg.search`/`kg.get` directly.
|
|
21
|
+
*
|
|
22
|
+
* Error handling is always in-payload (CLAUDE.md §API Rules #8).
|
|
23
|
+
*/
|
|
24
|
+
export interface QuickJSExecutorOptions {
|
|
25
|
+
/** Memory limit in bytes. Defaults to 64 MB per `KG_MAX_MEMORY_MB`. */
|
|
26
|
+
memoryLimitBytes?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Execution deadline in ms. The interrupt handler fires after this much
|
|
29
|
+
* wall-clock time. Defaults to 2000; clamped to `maxTimeoutMs`.
|
|
30
|
+
*/
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Hard ceiling on `timeoutMs` from tool-call params. Defaults to 10_000
|
|
34
|
+
* per `KG_MAX_TIMEOUT_MS`. Callers cannot set `timeoutMs` above this.
|
|
35
|
+
*/
|
|
36
|
+
maxTimeoutMs?: number;
|
|
37
|
+
/** Warm pool size. Defaults to 2. */
|
|
38
|
+
poolSize?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare class QuickJSExecutor implements Executor {
|
|
41
|
+
private wasmModule;
|
|
42
|
+
private pool;
|
|
43
|
+
private readonly memoryLimitBytes;
|
|
44
|
+
private readonly defaultTimeoutMs;
|
|
45
|
+
private readonly maxTimeoutMs;
|
|
46
|
+
private readonly poolSize;
|
|
47
|
+
constructor(options?: QuickJSExecutorOptions);
|
|
48
|
+
/**
|
|
49
|
+
* Warm the cached WASM module and initialize the pool. Safe to call
|
|
50
|
+
* multiple times.
|
|
51
|
+
*/
|
|
52
|
+
warmup(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Phase 3 primary path: execute code with the full `kg.project.*`
|
|
55
|
+
* bindings, `budget.fit()`, and `logger.log()` installed via the pool.
|
|
56
|
+
*/
|
|
57
|
+
executeWithBindings(code: string, deps: BindingDeps, timeoutMs?: number): Promise<ExecuteResult>;
|
|
58
|
+
/** Pool stats for instrumentation / tests. */
|
|
59
|
+
getPoolStats(): PoolStats | null;
|
|
60
|
+
/** Dispose the pool and release all runtimes. */
|
|
61
|
+
dispose(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Execute LLM-generated JS with flat provider injection (Phase 1/2 path).
|
|
64
|
+
* Creates a fresh runtime + context per call. Kept for backward compat.
|
|
65
|
+
*/
|
|
66
|
+
execute(code: string, providersOrFns: ResolvedProvider[] | Record<string, (...args: unknown[]) => Promise<unknown>>): Promise<ExecuteResult>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/sandbox/executor.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAWhC,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,GAAE,sBAA2B;IAOhD;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B;;;OAGG;IACG,mBAAmB,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAqFzB,8CAA8C;IAC9C,YAAY,IAAI,SAAS,GAAG,IAAI;IAIhC,iDAAiD;IACjD,OAAO,IAAI,IAAI;IASf;;;OAGG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,cAAc,EACV,gBAAgB,EAAE,GAClB,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAC3D,OAAO,CAAC,aAAa,CAAC;CA+E1B"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { getQuickJS, Scope, } from 'quickjs-emscripten';
|
|
2
|
+
import { normalizeCode, } from './vendored-codemode.js';
|
|
3
|
+
import { DISABLE_GLOBALS_BOOTSTRAP, drainPendingJobs, errorMessage, formatGuestError, isPromise, marshalJsValue, } from './helpers.js';
|
|
4
|
+
import { SandboxPool } from './pool.js';
|
|
5
|
+
import { installBindings } from './bindings/install.js';
|
|
6
|
+
const DEFAULT_MEMORY_LIMIT = 64 * 1024 * 1024;
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 2000;
|
|
8
|
+
const DEFAULT_MAX_TIMEOUT_MS = 10_000;
|
|
9
|
+
/** Error patterns that indicate the QuickJS runtime is compromised. */
|
|
10
|
+
const CRASH_PATTERNS = ['out of memory', 'allocation failed', 'stack overflow'];
|
|
11
|
+
export class QuickJSExecutor {
|
|
12
|
+
wasmModule = null;
|
|
13
|
+
pool = null;
|
|
14
|
+
memoryLimitBytes;
|
|
15
|
+
defaultTimeoutMs;
|
|
16
|
+
maxTimeoutMs;
|
|
17
|
+
poolSize;
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.memoryLimitBytes = options.memoryLimitBytes ?? DEFAULT_MEMORY_LIMIT;
|
|
20
|
+
this.defaultTimeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
21
|
+
this.maxTimeoutMs = options.maxTimeoutMs ?? DEFAULT_MAX_TIMEOUT_MS;
|
|
22
|
+
this.poolSize = options.poolSize ?? 2;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Warm the cached WASM module and initialize the pool. Safe to call
|
|
26
|
+
* multiple times.
|
|
27
|
+
*/
|
|
28
|
+
async warmup() {
|
|
29
|
+
if (!this.wasmModule) {
|
|
30
|
+
this.wasmModule = await getQuickJS();
|
|
31
|
+
}
|
|
32
|
+
if (!this.pool) {
|
|
33
|
+
this.pool = new SandboxPool(this.wasmModule, {
|
|
34
|
+
poolSize: this.poolSize,
|
|
35
|
+
memoryLimitBytes: this.memoryLimitBytes,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Phase 3 primary path: execute code with the full `kg.project.*`
|
|
41
|
+
* bindings, `budget.fit()`, and `logger.log()` installed via the pool.
|
|
42
|
+
*/
|
|
43
|
+
async executeWithBindings(code, deps, timeoutMs) {
|
|
44
|
+
await this.warmup();
|
|
45
|
+
const pool = this.pool;
|
|
46
|
+
let wrapped;
|
|
47
|
+
try {
|
|
48
|
+
wrapped = normalizeCode(code);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return { result: null, error: `normalizeCode failed: ${errorMessage(e)}` };
|
|
52
|
+
}
|
|
53
|
+
const effectiveTimeout = Math.min(timeoutMs ?? this.defaultTimeoutMs, this.maxTimeoutMs);
|
|
54
|
+
const pr = pool.acquire();
|
|
55
|
+
let context = null;
|
|
56
|
+
let crashed = false;
|
|
57
|
+
try {
|
|
58
|
+
const deadline = Date.now() + effectiveTimeout;
|
|
59
|
+
pr.runtime.setInterruptHandler(() => Date.now() > deadline);
|
|
60
|
+
context = pr.runtime.newContext();
|
|
61
|
+
// Bootstrap disabled globals
|
|
62
|
+
const disableResult = context.evalCode(DISABLE_GLOBALS_BOOTSTRAP);
|
|
63
|
+
if (disableResult.error) {
|
|
64
|
+
const err = context.dump(disableResult.error);
|
|
65
|
+
disableResult.error.dispose();
|
|
66
|
+
return { result: null, error: `bootstrap failed: ${JSON.stringify(err)}`, logs: deps.logs };
|
|
67
|
+
}
|
|
68
|
+
disableResult.value.dispose();
|
|
69
|
+
// Install all bindings (logger, kg.project.*, budget.fit)
|
|
70
|
+
installBindings(context, deps);
|
|
71
|
+
// Evaluate the wrapped code
|
|
72
|
+
const callSource = `(${wrapped})()`;
|
|
73
|
+
const evalResult = context.evalCode(callSource, 'kg_execute.js');
|
|
74
|
+
if (evalResult.error) {
|
|
75
|
+
const err = context.dump(evalResult.error);
|
|
76
|
+
evalResult.error.dispose();
|
|
77
|
+
return { result: null, error: formatGuestError(err), logs: deps.logs };
|
|
78
|
+
}
|
|
79
|
+
const promiseHandle = evalResult.value;
|
|
80
|
+
try {
|
|
81
|
+
drainPendingJobs(pr.runtime);
|
|
82
|
+
const state = context.getPromiseState(promiseHandle);
|
|
83
|
+
if (state.type === 'pending') {
|
|
84
|
+
return {
|
|
85
|
+
result: null,
|
|
86
|
+
error: 'kg_execute Promise never settled — all host bindings are synchronous',
|
|
87
|
+
logs: deps.logs,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (state.type === 'rejected') {
|
|
91
|
+
try {
|
|
92
|
+
const err = context.dump(state.error);
|
|
93
|
+
return { result: null, error: formatGuestError(err), logs: deps.logs };
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
state.error.dispose();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const value = context.dump(state.value);
|
|
101
|
+
return { result: value, logs: deps.logs };
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
state.value.dispose();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
promiseHandle.dispose();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
const msg = errorMessage(e);
|
|
113
|
+
crashed = isCrash(msg);
|
|
114
|
+
return { result: null, error: msg, logs: deps.logs };
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
context?.dispose();
|
|
118
|
+
pool.release(pr, crashed);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Pool stats for instrumentation / tests. */
|
|
122
|
+
getPoolStats() {
|
|
123
|
+
return this.pool?.getStats() ?? null;
|
|
124
|
+
}
|
|
125
|
+
/** Dispose the pool and release all runtimes. */
|
|
126
|
+
dispose() {
|
|
127
|
+
this.pool?.dispose();
|
|
128
|
+
this.pool = null;
|
|
129
|
+
}
|
|
130
|
+
// ==========================================================================
|
|
131
|
+
// Legacy path — backward compat for Phase 1/2 spike tests
|
|
132
|
+
// ==========================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Execute LLM-generated JS with flat provider injection (Phase 1/2 path).
|
|
135
|
+
* Creates a fresh runtime + context per call. Kept for backward compat.
|
|
136
|
+
*/
|
|
137
|
+
async execute(code, providersOrFns) {
|
|
138
|
+
await this.warmup();
|
|
139
|
+
const wasmModule = this.wasmModule;
|
|
140
|
+
let wrapped;
|
|
141
|
+
try {
|
|
142
|
+
wrapped = normalizeCode(code);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
return { result: null, error: `normalizeCode failed: ${errorMessage(e)}` };
|
|
146
|
+
}
|
|
147
|
+
const logs = [];
|
|
148
|
+
const timeoutMs = Math.min(this.defaultTimeoutMs, this.maxTimeoutMs);
|
|
149
|
+
let runtime = null;
|
|
150
|
+
let context = null;
|
|
151
|
+
try {
|
|
152
|
+
runtime = wasmModule.newRuntime();
|
|
153
|
+
runtime.setMemoryLimit(this.memoryLimitBytes);
|
|
154
|
+
const deadline = Date.now() + timeoutMs;
|
|
155
|
+
runtime.setInterruptHandler(() => Date.now() > deadline);
|
|
156
|
+
context = runtime.newContext();
|
|
157
|
+
const disableResult = context.evalCode(DISABLE_GLOBALS_BOOTSTRAP);
|
|
158
|
+
if (disableResult.error) {
|
|
159
|
+
const err = context.dump(disableResult.error);
|
|
160
|
+
disableResult.error.dispose();
|
|
161
|
+
return { result: null, error: `bootstrap failed: ${JSON.stringify(err)}`, logs };
|
|
162
|
+
}
|
|
163
|
+
disableResult.value.dispose();
|
|
164
|
+
installLegacyLogger(context, logs);
|
|
165
|
+
installProviders(context, providersOrFns);
|
|
166
|
+
const callSource = `(${wrapped})()`;
|
|
167
|
+
const evalResult = context.evalCode(callSource, 'kg_execute.js');
|
|
168
|
+
if (evalResult.error) {
|
|
169
|
+
const err = context.dump(evalResult.error);
|
|
170
|
+
evalResult.error.dispose();
|
|
171
|
+
return { result: null, error: formatGuestError(err), logs };
|
|
172
|
+
}
|
|
173
|
+
const promiseHandle = evalResult.value;
|
|
174
|
+
try {
|
|
175
|
+
drainPendingJobs(runtime);
|
|
176
|
+
const state = context.getPromiseState(promiseHandle);
|
|
177
|
+
if (state.type === 'pending') {
|
|
178
|
+
return {
|
|
179
|
+
result: null,
|
|
180
|
+
error: 'kg_execute Promise never settled — async host bindings are not supported',
|
|
181
|
+
logs,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
if (state.type === 'rejected') {
|
|
185
|
+
try {
|
|
186
|
+
const err = context.dump(state.error);
|
|
187
|
+
return { result: null, error: formatGuestError(err), logs };
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
state.error.dispose();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
const value = context.dump(state.value);
|
|
195
|
+
return { result: value, logs };
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
state.value.dispose();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
promiseHandle.dispose();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
return { result: null, error: errorMessage(e), logs };
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
context?.dispose();
|
|
210
|
+
runtime?.dispose();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Crash detection
|
|
216
|
+
// ============================================================================
|
|
217
|
+
function isCrash(errorMsg) {
|
|
218
|
+
const lower = errorMsg.toLowerCase();
|
|
219
|
+
return CRASH_PATTERNS.some((p) => lower.includes(p));
|
|
220
|
+
}
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Legacy logger (for execute() backward compat)
|
|
223
|
+
// ============================================================================
|
|
224
|
+
function installLegacyLogger(context, logs) {
|
|
225
|
+
Scope.withScope((scope) => {
|
|
226
|
+
const loggerObj = scope.manage(context.newObject());
|
|
227
|
+
const logFn = context.newFunction('log', (...argsHandles) => {
|
|
228
|
+
try {
|
|
229
|
+
const parts = [];
|
|
230
|
+
for (const h of argsHandles) {
|
|
231
|
+
const dumped = context.dump(h);
|
|
232
|
+
parts.push(typeof dumped === 'string' ? dumped : JSON.stringify(dumped));
|
|
233
|
+
}
|
|
234
|
+
logs.push(parts.join(' '));
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
logs.push(`<logger.log serialization error: ${errorMessage(e)}>`);
|
|
238
|
+
}
|
|
239
|
+
return context.undefined;
|
|
240
|
+
});
|
|
241
|
+
context.setProp(loggerObj, 'log', logFn);
|
|
242
|
+
logFn.dispose();
|
|
243
|
+
context.setProp(context.global, 'logger', loggerObj);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// ============================================================================
|
|
247
|
+
// Legacy provider injection (for execute() backward compat)
|
|
248
|
+
// ============================================================================
|
|
249
|
+
function installProviders(context, providersOrFns) {
|
|
250
|
+
const providers = Array.isArray(providersOrFns)
|
|
251
|
+
? providersOrFns
|
|
252
|
+
: [{ name: 'codemode', fns: providersOrFns }];
|
|
253
|
+
for (const provider of providers) {
|
|
254
|
+
Scope.withScope((scope) => {
|
|
255
|
+
const nsObj = scope.manage(context.newObject());
|
|
256
|
+
for (const [fnName, hostFn] of Object.entries(provider.fns)) {
|
|
257
|
+
const wrapped = context.newFunction(fnName, (...argsHandles) => {
|
|
258
|
+
try {
|
|
259
|
+
const nativeArgs = argsHandles.map((h) => context.dump(h));
|
|
260
|
+
const rawResult = provider.positionalArgs
|
|
261
|
+
? hostFn(...nativeArgs)
|
|
262
|
+
: hostFn(nativeArgs[0]);
|
|
263
|
+
if (isPromise(rawResult)) {
|
|
264
|
+
throw new Error(`host function ${provider.name}.${fnName} returned a Promise; ` +
|
|
265
|
+
'only synchronous host bindings are supported');
|
|
266
|
+
}
|
|
267
|
+
return marshalJsValue(context, rawResult);
|
|
268
|
+
}
|
|
269
|
+
catch (e) {
|
|
270
|
+
return context.newError(errorMessage(e));
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
context.setProp(nsObj, fnName, wrapped);
|
|
274
|
+
wrapped.dispose();
|
|
275
|
+
}
|
|
276
|
+
context.setProp(context.global, provider.name, nsObj);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/sandbox/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { QuickJSContext, QuickJSHandle, QuickJSRuntime } from 'quickjs-emscripten';
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for the QuickJS sandbox. Extracted from executor.ts in
|
|
4
|
+
* Phase 3 so both the legacy flat-binding path and the new nested-binding
|
|
5
|
+
* path can reuse them.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DISABLE_GLOBALS_BOOTSTRAP = "\n(() => {\n const ban = (name) => {\n try { delete globalThis[name]; } catch (_) {}\n try {\n Object.defineProperty(globalThis, name, {\n get() { throw new Error(name + ' is not available in the kg sandbox'); },\n configurable: false,\n });\n } catch (_) {}\n };\n ban('eval');\n ban('Function');\n ban('fetch');\n ban('require');\n ban('process');\n ban('WebAssembly');\n try {\n Object.defineProperty(globalThis, 'constructor', {\n get() { throw new Error('constructor is not available in the kg sandbox'); },\n configurable: false,\n });\n } catch (_) {}\n})();\n";
|
|
8
|
+
/**
|
|
9
|
+
* Pump the pending-jobs queue until it's drained or the runtime rejects
|
|
10
|
+
* further work. Our async IIFE's microtasks all live in this queue, so a
|
|
11
|
+
* single pass is usually enough — but nested `Promise.then` chains can
|
|
12
|
+
* require multiple passes. Bounded at 32 iterations to avoid spinning
|
|
13
|
+
* forever on runaway code (the interrupt handler is the real safety net).
|
|
14
|
+
*/
|
|
15
|
+
export declare function drainPendingJobs(runtime: QuickJSRuntime): void;
|
|
16
|
+
/**
|
|
17
|
+
* Convert a plain JS value into a QuickJSHandle that the guest can see.
|
|
18
|
+
* Handles primitives, arrays, and plain objects recursively. The caller is
|
|
19
|
+
* NOT responsible for disposing the returned handle — QuickJS's function
|
|
20
|
+
* return mechanism transfers ownership into the guest VM.
|
|
21
|
+
*/
|
|
22
|
+
export declare function marshalJsValue(context: QuickJSContext, value: unknown): QuickJSHandle;
|
|
23
|
+
export declare function errorMessage(e: unknown): string;
|
|
24
|
+
export declare function formatGuestError(dumped: unknown): string;
|
|
25
|
+
export declare function isPromise(value: unknown): value is Promise<unknown>;
|
|
26
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/sandbox/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AAMH,eAAO,MAAM,yBAAyB,unBAwBrC,CAAC;AAMF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAS9D;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,aAAa,CA2BrF;AAMD,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAQ/C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CASxD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAMnE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the QuickJS sandbox. Extracted from executor.ts in
|
|
3
|
+
* Phase 3 so both the legacy flat-binding path and the new nested-binding
|
|
4
|
+
* path can reuse them.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Bootstrap: disabled globals
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export const DISABLE_GLOBALS_BOOTSTRAP = `
|
|
10
|
+
(() => {
|
|
11
|
+
const ban = (name) => {
|
|
12
|
+
try { delete globalThis[name]; } catch (_) {}
|
|
13
|
+
try {
|
|
14
|
+
Object.defineProperty(globalThis, name, {
|
|
15
|
+
get() { throw new Error(name + ' is not available in the kg sandbox'); },
|
|
16
|
+
configurable: false,
|
|
17
|
+
});
|
|
18
|
+
} catch (_) {}
|
|
19
|
+
};
|
|
20
|
+
ban('eval');
|
|
21
|
+
ban('Function');
|
|
22
|
+
ban('fetch');
|
|
23
|
+
ban('require');
|
|
24
|
+
ban('process');
|
|
25
|
+
ban('WebAssembly');
|
|
26
|
+
try {
|
|
27
|
+
Object.defineProperty(globalThis, 'constructor', {
|
|
28
|
+
get() { throw new Error('constructor is not available in the kg sandbox'); },
|
|
29
|
+
configurable: false,
|
|
30
|
+
});
|
|
31
|
+
} catch (_) {}
|
|
32
|
+
})();
|
|
33
|
+
`;
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Pending-jobs drain
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Pump the pending-jobs queue until it's drained or the runtime rejects
|
|
39
|
+
* further work. Our async IIFE's microtasks all live in this queue, so a
|
|
40
|
+
* single pass is usually enough — but nested `Promise.then` chains can
|
|
41
|
+
* require multiple passes. Bounded at 32 iterations to avoid spinning
|
|
42
|
+
* forever on runaway code (the interrupt handler is the real safety net).
|
|
43
|
+
*/
|
|
44
|
+
export function drainPendingJobs(runtime) {
|
|
45
|
+
for (let i = 0; i < 32; i++) {
|
|
46
|
+
const result = runtime.executePendingJobs();
|
|
47
|
+
if (result.error) {
|
|
48
|
+
result.error.dispose();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (result.value <= 0)
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Host-value marshaling
|
|
57
|
+
// ============================================================================
|
|
58
|
+
/**
|
|
59
|
+
* Convert a plain JS value into a QuickJSHandle that the guest can see.
|
|
60
|
+
* Handles primitives, arrays, and plain objects recursively. The caller is
|
|
61
|
+
* NOT responsible for disposing the returned handle — QuickJS's function
|
|
62
|
+
* return mechanism transfers ownership into the guest VM.
|
|
63
|
+
*/
|
|
64
|
+
export function marshalJsValue(context, value) {
|
|
65
|
+
if (value === undefined)
|
|
66
|
+
return context.undefined;
|
|
67
|
+
if (value === null)
|
|
68
|
+
return context.null;
|
|
69
|
+
if (typeof value === 'string')
|
|
70
|
+
return context.newString(value);
|
|
71
|
+
if (typeof value === 'number')
|
|
72
|
+
return context.newNumber(value);
|
|
73
|
+
if (typeof value === 'boolean')
|
|
74
|
+
return value ? context.true : context.false;
|
|
75
|
+
if (typeof value === 'bigint')
|
|
76
|
+
return context.newNumber(Number(value));
|
|
77
|
+
if (Array.isArray(value)) {
|
|
78
|
+
const arr = context.newArray();
|
|
79
|
+
for (let i = 0; i < value.length; i++) {
|
|
80
|
+
const elem = marshalJsValue(context, value[i]);
|
|
81
|
+
context.setProp(arr, i, elem);
|
|
82
|
+
elem.dispose();
|
|
83
|
+
}
|
|
84
|
+
return arr;
|
|
85
|
+
}
|
|
86
|
+
if (typeof value === 'object') {
|
|
87
|
+
const obj = context.newObject();
|
|
88
|
+
for (const [k, v] of Object.entries(value)) {
|
|
89
|
+
const elem = marshalJsValue(context, v);
|
|
90
|
+
context.setProp(obj, k, elem);
|
|
91
|
+
elem.dispose();
|
|
92
|
+
}
|
|
93
|
+
return obj;
|
|
94
|
+
}
|
|
95
|
+
// Fallback: stringify unknowns. Covers symbols, functions, etc.
|
|
96
|
+
return context.newString(String(value));
|
|
97
|
+
}
|
|
98
|
+
// ============================================================================
|
|
99
|
+
// Error helpers
|
|
100
|
+
// ============================================================================
|
|
101
|
+
export function errorMessage(e) {
|
|
102
|
+
if (e instanceof Error)
|
|
103
|
+
return e.message;
|
|
104
|
+
if (typeof e === 'string')
|
|
105
|
+
return e;
|
|
106
|
+
try {
|
|
107
|
+
return JSON.stringify(e);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return String(e);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function formatGuestError(dumped) {
|
|
114
|
+
if (dumped && typeof dumped === 'object') {
|
|
115
|
+
const obj = dumped;
|
|
116
|
+
const parts = [];
|
|
117
|
+
if (obj.name)
|
|
118
|
+
parts.push(String(obj.name));
|
|
119
|
+
if (obj.message)
|
|
120
|
+
parts.push(String(obj.message));
|
|
121
|
+
if (parts.length > 0)
|
|
122
|
+
return parts.join(': ');
|
|
123
|
+
}
|
|
124
|
+
return typeof dumped === 'string' ? dumped : JSON.stringify(dumped);
|
|
125
|
+
}
|
|
126
|
+
export function isPromise(value) {
|
|
127
|
+
return (value !== null &&
|
|
128
|
+
(typeof value === 'object' || typeof value === 'function') &&
|
|
129
|
+
typeof value.then === 'function');
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/sandbox/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { QuickJSRuntime, QuickJSWASMModule } from 'quickjs-emscripten';
|
|
2
|
+
/**
|
|
3
|
+
* Warm sandbox pool (presearch D12, CLAUDE.md §Architecture #1).
|
|
4
|
+
*
|
|
5
|
+
* Manages a pool of N pre-created QuickJS runtimes with synchronous
|
|
6
|
+
* acquire/release semantics. Each runtime has its memory limit pre-set;
|
|
7
|
+
* callers create fresh contexts on the acquired runtime, run code, dispose
|
|
8
|
+
* the context, then release the runtime back.
|
|
9
|
+
*
|
|
10
|
+
* **Overflow**: when all N runtimes are checked out, `acquire()` spawns a
|
|
11
|
+
* cold runtime on the spot — it never blocks. Cold overflow runtimes are
|
|
12
|
+
* disposed on release (the pool never grows beyond `maxSize`).
|
|
13
|
+
*
|
|
14
|
+
* **Crash recovery**: if the caller signals `crashed=true` on release, the
|
|
15
|
+
* runtime is disposed and a fresh replacement is created so the pool stays
|
|
16
|
+
* at its target size. This handles QuickJS OOM or WASM-level failures that
|
|
17
|
+
* leave the runtime in an inconsistent state.
|
|
18
|
+
*
|
|
19
|
+
* **Instrumentation**: `getStats()` reports warm hits, cold hits, and crash
|
|
20
|
+
* counts for the Phase 3 test suite.
|
|
21
|
+
*/
|
|
22
|
+
export interface PoolStats {
|
|
23
|
+
warmHits: number;
|
|
24
|
+
coldHits: number;
|
|
25
|
+
crashes: number;
|
|
26
|
+
currentSize: number;
|
|
27
|
+
}
|
|
28
|
+
export interface PooledRuntime {
|
|
29
|
+
runtime: QuickJSRuntime;
|
|
30
|
+
/** Monotonic id for instrumentation / test assertions. */
|
|
31
|
+
id: number;
|
|
32
|
+
/** True if this runtime came from the warm pool, false if overflow-spawned. */
|
|
33
|
+
isWarm: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare class SandboxPool {
|
|
36
|
+
private readonly wasmModule;
|
|
37
|
+
private readonly available;
|
|
38
|
+
private readonly maxSize;
|
|
39
|
+
private readonly memoryLimitBytes;
|
|
40
|
+
private readonly stats;
|
|
41
|
+
private nextId;
|
|
42
|
+
private disposed;
|
|
43
|
+
constructor(wasmModule: QuickJSWASMModule, opts?: {
|
|
44
|
+
poolSize?: number;
|
|
45
|
+
memoryLimitBytes?: number;
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Acquire a runtime from the pool. If the pool has warm runtimes available,
|
|
49
|
+
* returns one immediately. Otherwise spawns a cold overflow runtime.
|
|
50
|
+
* Never blocks.
|
|
51
|
+
*/
|
|
52
|
+
acquire(): PooledRuntime;
|
|
53
|
+
/**
|
|
54
|
+
* Release a runtime back to the pool. If `crashed` is true, the runtime
|
|
55
|
+
* is disposed and replaced with a fresh one. Overflow runtimes (not from
|
|
56
|
+
* the warm pool) are always disposed on release.
|
|
57
|
+
*/
|
|
58
|
+
release(pr: PooledRuntime, crashed: boolean): void;
|
|
59
|
+
getStats(): Readonly<PoolStats>;
|
|
60
|
+
dispose(): void;
|
|
61
|
+
private spawnRuntime;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/sandbox/pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,CAAC;IACxB,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,WAAW;IAcpB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAb7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAKpB;IACF,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAS;gBAGN,UAAU,EAAE,iBAAiB,EAC9C,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE;IAYzD;;;;OAIG;IACH,OAAO,IAAI,aAAa;IAcxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAyBlD,QAAQ,IAAI,QAAQ,CAAC,SAAS,CAAC;IAI/B,OAAO,IAAI,IAAI;IAUf,OAAO,CAAC,YAAY;CAKrB"}
|