brepjs-verify 0.4.0 → 0.8.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.
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ let node_url = require("node:url");
3
+ let node_fs = require("node:fs");
4
+ let node_path = require("node:path");
5
+ let node_os = require("node:os");
6
+ let node_child_process = require("node:child_process");
7
+ let node_fs_promises = require("node:fs/promises");
8
+ let _modelcontextprotocol_sdk_server_index_js = require("@modelcontextprotocol/sdk/server/index.js");
9
+ let _modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
10
+ let _modelcontextprotocol_sdk_types_js = require("@modelcontextprotocol/sdk/types.js");
11
+ let node_util = require("node:util");
12
+ let node_crypto = require("node:crypto");
13
+ //#region src/sandbox/runProgram.ts
14
+ /**
15
+ * Sandbox executor — run agent-authored brepjs TypeScript in an isolated child process.
16
+ *
17
+ * The program is written to a temp ESM directory and executed by the verify CLI in a separate
18
+ * process, with a wall-clock timeout and a memory cap. Out-of-process execution is what makes the
19
+ * loop *unattended-safe*: a runaway (CPU-bound infinite loop) or memory-hungry part is killed
20
+ * rather than hanging or crashing the host. Results cross the boundary as serialized JSON (never
21
+ * live WASM handles), and the temp program directory is always cleaned up.
22
+ */
23
+ var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
24
+ var DEFAULT_TIMEOUT_MS = 3e4;
25
+ var DEFAULT_MAX_MEMORY_MB = 2048;
26
+ var MAX_OUTPUT_BYTES = 8 * 1024 * 1024;
27
+ /**
28
+ * Clamp a caller-supplied limit to a positive, finite value, falling back to the default otherwise.
29
+ * Critical for the timeout: Node's `execFile` treats `timeout: 0` (and it ignores negatives) as
30
+ * "no timeout", which would silently disable the sandbox's only runaway protection.
31
+ */
32
+ function positiveOrDefault(value, fallback) {
33
+ return value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
34
+ }
35
+ function defaultCliEntry() {
36
+ const builtJs = (0, node_url.fileURLToPath)(new URL("data:video/mp2t;base64,IyEvdXNyL2Jpbi9lbnYgbm9kZQppbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJzsKaW1wb3J0IHsgd3JpdGVGaWxlU3luYywgd2F0Y2ggYXMgZnNXYXRjaCwgcmVhbHBhdGhTeW5jIH0gZnJvbSAnbm9kZTpmcyc7CmltcG9ydCB7IHJlc29sdmUsIGpvaW4sIGJhc2VuYW1lLCBkaXJuYW1lIH0gZnJvbSAnbm9kZTpwYXRoJzsKaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSAnbm9kZTpvcyc7CmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICdub2RlOnVybCc7CmltcG9ydCB7IHJ1blBhcnQgfSBmcm9tICcuLi92ZXJpZnkvcnVuUGFydC5qcyc7CmltcG9ydCB7IHB1c2hFcnJvciwgcmVwb3J0T2ssIHNlcmlhbGl6ZVJlcG9ydCB9IGZyb20gJy4uL3ZlcmlmeS9yZXBvcnQuanMnOwppbXBvcnQgeyBydW5NZWFzdXJlIH0gZnJvbSAnLi4vdmVyaWZ5L21lYXN1cmUuanMnOwppbXBvcnQgeyBydW5EaWZmIH0gZnJvbSAnLi4vdmVyaWZ5L2RpZmYuanMnOwppbXBvcnQgeyBzY2FmZm9sZFBhcnQgfSBmcm9tICcuL3NjYWZmb2xkLmpzJzsKaW1wb3J0IHsgZGVib3VuY2UsIERFRkFVTFRfREVCT1VOQ0VfTVMgfSBmcm9tICcuL3dhdGNoLmpzJzsKaW1wb3J0IHsgZXhwb3J0UGFydCB9IGZyb20gJy4vZXhwb3J0UGFydC5qcyc7CmltcG9ydCB7IG9wZW5Ccm93c2VyLCBzaG91bGRBdXRvT3BlbiB9IGZyb20gJy4vb3BlbkJyb3dzZXIuanMnOwppbXBvcnQgeyBkaXNwb3NlU2hhcGUgfSBmcm9tICcuLi9kaXNwb3NlU2hhcGUuanMnOwppbXBvcnQgdHlwZSB7IHNob290IGFzIFNob290Rm4gfSBmcm9tICcuLi9zbmFwc2hvdC9zaG9vdC5qcyc7CgovLyBPQ0NUJ3MgV0FTTSBTVEVQIHdyaXRlciBlbWl0cyBhICJTdGF0aXN0aWNzIG9uIFRyYW5zZmVyIiBiYW5uZXIgdmlhIGNvbnNvbGUubG9nCi8vIChFbXNjcmlwdGVuJ3MgZGVmYXVsdCBzdGRvdXQgc2luaykuIFRoZSBDTEkgb3ducyBzdGRvdXQgZm9yIG1hY2hpbmUtcmVhZGFibGUgSlNPTiwKLy8gc28gZGl2ZXJ0IHRoYXQga2VybmVsIGNoYXR0ZXIgdG8gc3RkZXJyIHRvIGtlZXAgc3Rkb3V0IGEgc2luZ2xlIGNsZWFuIEpTT04gZG9jdW1lbnQuCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlIC0tIHJlcm91dGUga2VybmVsIHN0ZG91dCBjaGF0dGVyIG9mZiB0aGUgSlNPTiBjaGFubmVsCmNvbnNvbGUubG9nID0gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gewogIHByb2Nlc3Muc3RkZXJyLndyaXRlKGFyZ3MubWFwKFN0cmluZykuam9pbignICcpICsgJ1xuJyk7Cn07CgpleHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFNuYXBzaG90U2hvb3QoKTogUHJvbWlzZTx0eXBlb2YgU2hvb3RGbiB8IHVuZGVmaW5lZD4gewogIHRyeSB7CiAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoJy4uL3NuYXBzaG90L3Nob290LmpzJyk7CiAgICByZXR1cm4gbW9kLnNob290OwogIH0gY2F0Y2ggewogICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoJ3NuYXBzaG90cyBuZWVkIHB1cHBldGVlci9DaHJvbWUg4oCUIHJ1bjogbnBtIGkgcHVwcGV0ZWVyXG4nKTsKICAgIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9Cn0KCmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpOwpwcm9ncmFtLm5hbWUoJ2JyZXBqcy12ZXJpZnknKTsKCnByb2dyYW0KICAuY29tbWFuZCgndmVyaWZ5JywgeyBpc0RlZmF1bHQ6IHRydWUgfSkKICAuYXJndW1lbnQoJzxmaWxlPicsICdwYXRoIHRvIGEgLmJyZXAudHMgbW9kdWxlIHdpdGggYSBkZWZhdWx0LWV4cG9ydGVkIHBhcnQgZnVuY3Rpb24nKQogIC5vcHRpb24oJy0tc3RlcCA8b3V0PicsICd3cml0ZSB0aGUgcHJpbWFyeSBTVEVQIGFydGlmYWN0IHRvIHRoaXMgcGF0aCcpCiAgLm9wdGlvbignLS1nbGIgPG91dD4nLCAnd3JpdGUgYSBkZXJpdmVkIEdMQiBwcmV2aWV3IHRvIHRoaXMgcGF0aCcpCiAgLm9wdGlvbignLS1qc29uIDxvdXQ+JywgJ3dyaXRlIHRoZSBKU09OIHJlcG9ydCB0byB0aGlzIHBhdGgnKQogIC5vcHRpb24oCiAgICAnLS1jaGVjaycsCiAgICAndHlwZS1jaGVjayB0aGUgcGFydCAoYWdhaW5zdCBicmVwanMgdHlwZXMpIGJlZm9yZSBydW5uaW5nOyBza2lwIGV4ZWN1dGlvbiBvbiB0eXBlIGVycm9ycycKICApCiAgLm9wdGlvbignLS1zbmFwc2hvdCA8ZGlyPicsICdyZW5kZXIgaXNvL2Zyb250L3RvcC9yaWdodCBQTkdzIHRvIHRoaXMgZGlyIChyZXF1aXJlcyBidWlsdCB2aWV3ZXIpJykKICAub3B0aW9uKAogICAgJy0tc2VydmUnLAogICAgJ2FmdGVyIHZlcmlmeWluZywgc3RhcnQgYSBwcmV2aWV3IHNlcnZlciBhbmQgcHJpbnQgYSA/ZGlyPSZmaWxlPSBkZWVwIGxpbmsgKHN0YXlzIHJ1bm5pbmcpJwogICkKICAub3B0aW9uKCctLW5vLW9wZW4nLCAnd2l0aCAtLXNlcnZlLCBkbyBub3QgYXV0by1vcGVuIHRoZSBicm93c2VyIChqdXN0IHByaW50IHRoZSB2aWV3ZXIgVVJMKScpCiAgLmFjdGlvbigKICAgIGFzeW5jICgKICAgICAgZmlsZTogc3RyaW5nLAogICAgICBvcHRzOiB7CiAgICAgICAgc3RlcD86IHN0cmluZzsKICAgICAgICBnbGI/OiBzdHJpbmc7CiAgICAgICAganNvbj86IHN0cmluZzsKICAgICAgICBjaGVjaz86IGJvb2xlYW47CiAgICAgICAgc25hcHNob3Q/OiBzdHJpbmc7CiAgICAgICAgc2VydmU/OiBib29sZWFuOwogICAgICAgIC8vIENvbW1hbmRlciBtYXRlcmlhbGl6ZXMgYSBuZWdhdGVkIGZsYWcgYXMgYSBjb25jcmV0ZSBib29sZWFuOiB0cnVlIGJ5CiAgICAgICAgLy8gZGVmYXVsdCwgZmFsc2Ugd2hlbiAtLW5vLW9wZW4gaXMgcGFzc2VkLgogICAgICAgIG9wZW46IGJvb2xlYW47CiAgICAgIH0KICAgICkgPT4gewogICAgICAvLyBUaGUgV0FTTSB2aWV3ZXIgbG9hZHMgYSBDQUQgZmlsZSAoaXQgY2FuJ3QgcnVuIGEgLmJyZXAudHMpLCBzbyAtLXNuYXBzaG90Ly0tc2VydmUKICAgICAgLy8gc3RhZ2UgdGhlIHByaW1hcnkgU1RFUCBhbmQgcG9pbnQgdGhlIHZpZXdlciBhdCBpdCB2aWEgP2Rpcj0mZmlsZT0uIC0tZ2xiIGlzIGl0cyBvd24gYXJ0aWZhY3QuCiAgICAgIGNvbnN0IHdhbnRTdGVwID0gQm9vbGVhbihvcHRzLnN0ZXApIHx8IEJvb2xlYW4ob3B0cy5zbmFwc2hvdCkgfHwgQm9vbGVhbihvcHRzLnNlcnZlKTsKICAgICAgY29uc3QgeyByZXBvcnQsIHN0ZXAsIGdsYiwgc2hhcGUgfSA9IGF3YWl0IHJ1blBhcnQocmVzb2x2ZShmaWxlKSwgewogICAgICAgIHN0ZXA6IHdhbnRTdGVwLAogICAgICAgIGdsYjogQm9vbGVhbihvcHRzLmdsYiksCiAgICAgICAgY2hlY2s6IEJvb2xlYW4ob3B0cy5jaGVjayksCiAgICAgIH0pOwogICAgICBsZXQgc3RlcFBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCA9IG9wdHMuc3RlcDsKICAgICAgdHJ5IHsKICAgICAgICBpZiAob3B0cy5nbGIgJiYgZ2xiKSB3cml0ZUZpbGVTeW5jKG9wdHMuZ2xiLCBCdWZmZXIuZnJvbShnbGIpKTsKCiAgICAgICAgaWYgKHdhbnRTdGVwICYmIHN0ZXApIHsKICAgICAgICAgIHN0ZXBQYXRoID0gb3B0cy5zdGVwID8/IGpvaW4odG1wZGlyKCksIGBicmVwanMtdmVyaWZ5LSR7YmFzZW5hbWUoZmlsZSl9LnN0ZXBgKTsKICAgICAgICAgIHdyaXRlRmlsZVN5bmMoc3RlcFBhdGgsIEJ1ZmZlci5mcm9tKHN0ZXApKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdHMuc25hcHNob3QgJiYgc3RlcFBhdGgpIHsKICAgICAgICAgIGNvbnN0IHNob290ID0gYXdhaXQgbG9hZFNuYXBzaG90U2hvb3QoKTsgLy8gbGF6eToga2VlcHMgcHVwcGV0ZWVyIG9mZiB0aGUgZGVmYXVsdCBwYXRoCiAgICAgICAgICBpZiAoc2hvb3QpIHsKICAgICAgICAgICAgY29uc3QgeyBwbmdzIH0gPSBhd2FpdCBzaG9vdCh7IGZpbGU6IHN0ZXBQYXRoLCBvdXREaXI6IG9wdHMuc25hcHNob3QgfSk7CiAgICAgICAgICAgIC8vIERpYWdub3N0aWMgcGF0aHMgZ28gdG8gc3RkZXJyIOKAlCBzdGRvdXQgc3RheXMgYSBzaW5nbGUgY2xlYW4gSlNPTiBkb2N1bWVudC4KICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIHBuZ3MpIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBzbmFwc2hvdDogJHtwfVxuYCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChvcHRzLnNuYXBzaG90KSB7CiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZSgnc25hcHNob3Qgc2tpcHBlZDogU1RFUCBleHBvcnQgcHJvZHVjZWQgbm8gYXJ0aWZhY3RcbicpOwogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHB1c2hFcnJvcihyZXBvcnQsIHsgbWVzc2FnZTogYGFydGlmYWN0IHdyaXRlIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gIH0pOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIC8vIFRoZSBzaGFwZSBpcyBhIGxpdmUgV0FTTSBoYW5kbGU7IHJlbGVhc2UgaXQgYmVmb3JlIHRoZSBzZXJ2ZXIgdGFrZXMgb3ZlciAodGhlCiAgICAgICAgLy8gLS1zZXJ2ZSBwYXRoIHN0YXlzIHJ1bm5pbmcsIHNvIGxlYWtpbmcgaGVyZSB3b3VsZCBwZXJzaXN0IGZvciB0aGUgc2VydmVyJ3MgbGlmZXRpbWUpLgogICAgICAgIGRpc3Bvc2VTaGFwZShzaGFwZSk7CiAgICAgIH0KICAgICAgLy8gU2VyaWFsaXplIG9uY2UgYWZ0ZXIgYWxsIGFydGlmYWN0IHdyaXRlcyBzbyB0aGUgLS1qc29uIGZpbGUgYW5kIHN0ZG91dAogICAgICAvLyByZWZsZWN0IHRoZSBzYW1lIHJlcG9ydCAoaW5jbC4gYW55ICJhcnRpZmFjdCB3cml0ZSBmYWlsZWQiIGVycm9yKS4KICAgICAgY29uc3QganNvbiA9IHNlcmlhbGl6ZVJlcG9ydChyZXBvcnQpOwogICAgICBpZiAob3B0cy5qc29uKSB3cml0ZUZpbGVTeW5jKG9wdHMuanNvbiwganNvbik7CiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGpzb24gKyAnXG4nKTsKICAgICAgaWYgKCFyZXBvcnRPayhyZXBvcnQpKSBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgICAgY29uc3Qgd2lsbFNlcnZlID0gQm9vbGVhbihvcHRzLnNlcnZlKSAmJiBzdGVwUGF0aCAhPT0gdW5kZWZpbmVkICYmIHJlcG9ydE9rKHJlcG9ydCk7CiAgICAgIGlmICh3aWxsU2VydmUgJiYgc3RlcFBhdGgpIHsKICAgICAgICBjb25zdCB7IHNlcnZlIH0gPSBhd2FpdCBpbXBvcnQoJy4uL3NuYXBzaG90L3NlcnZlLmpzJyk7IC8vIGxhenk6IG5vIHNlcnZlciBkZXBzIG9uIHRoZSBkZWZhdWx0IHBhdGgKICAgICAgICBjb25zdCB7IHVybCwgcmV1c2VkIH0gPSBhd2FpdCBzZXJ2ZSh7IGZpbGU6IHN0ZXBQYXRoIH0pOyAvLyBidWlsZHMgYSA/ZGlyPSZmaWxlPSBVUkw7IHNlcnZlciBydW5zIHVudGlsIEN0cmwtQwogICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGB2aWV3ZXI6ICR7dXJsfVxuYCk7CiAgICAgICAgLy8gQXV0by1vcGVuIG9ubHkgZm9yIGEgZnJlc2hseSBzdGFydGVkIHNlcnZlciAoYSByZXVzZWQgb25lIGFscmVhZHkgaGFzCiAgICAgICAgLy8gYSB0YWIpIGluIGFuIGludGVyYWN0aXZlIHNlc3Npb247IGAtLW5vLW9wZW5gIChvcHRzLm9wZW4gPT09IGZhbHNlKQogICAgICAgIC8vIGFsd2F5cyBzdXBwcmVzc2VzIGl0LgogICAgICAgIGlmICghcmV1c2VkICYmIG9wdHMub3BlbiAmJiBzaG91bGRBdXRvT3BlbigpKSB7CiAgICAgICAgICBvcGVuQnJvd3Nlcih1cmwpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICk7Cgpwcm9ncmFtCiAgLmNvbW1hbmQoJ21lYXN1cmUnKQogIC5hcmd1bWVudCgnPGE+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGUnKQogIC5hcmd1bWVudCgnW2JdJywgJ29wdGlvbmFsIHNlY29uZCBtb2R1bGU7IGlmIGdpdmVuLCBtZWFzdXJlcyBkaXN0YW5jZSBiZXR3ZWVuIHRoZSB0d28gcGFydHMnKQogIC5hY3Rpb24oYXN5bmMgKGE6IHN0cmluZywgYj86IHN0cmluZykgPT4gewogICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuTWVhc3VyZShyZXNvbHZlKGEpLCBiID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZXNvbHZlKGIpKTsKICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICBKU09OLnN0cmluZ2lmeSh7IG9rOiByZXN1bHQuZXJyb3JzLmxlbmd0aCA9PT0gMCwgLi4ucmVzdWx0IH0sIG51bGwsIDIpICsgJ1xuJwogICAgKTsKICAgIGlmIChyZXN1bHQuZXJyb3JzLmxlbmd0aCA+IDApIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdkaWZmJykKICAuYXJndW1lbnQoJzxhPicsICdwYXRoIHRvIHRoZSBiYXNlbGluZSAuYnJlcC50cyBtb2R1bGUnKQogIC5hcmd1bWVudCgnPGI+JywgJ3BhdGggdG8gdGhlIGNvbXBhcmlzb24gLmJyZXAudHMgbW9kdWxlJykKICAuYWN0aW9uKGFzeW5jIChhOiBzdHJpbmcsIGI6IHN0cmluZykgPT4gewogICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuRGlmZihyZXNvbHZlKGEpLCByZXNvbHZlKGIpKTsKICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICBKU09OLnN0cmluZ2lmeSh7IG9rOiByZXN1bHQuZXJyb3JzLmxlbmd0aCA9PT0gMCwgLi4ucmVzdWx0IH0sIG51bGwsIDIpICsgJ1xuJwogICAgKTsKICAgIGlmIChyZXN1bHQuZXJyb3JzLmxlbmd0aCA+IDApIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdpbml0JykKICAuYXJndW1lbnQoJzxuYW1lPicsICdwYXJ0IG5hbWU7IHNjYWZmb2xkcyA8bmFtZT4uYnJlcC50cyArIHRzY29uZmlnLmpzb24gKyBSRUFETUUubWQnKQogIC5vcHRpb24oJy0tb3V0IDxkaXI+JywgJ3RhcmdldCBkaXJlY3RvcnkgKGRlZmF1bHRzIHRvIC4vPG5hbWU+KScpCiAgLmFjdGlvbigobmFtZTogc3RyaW5nLCBvcHRzOiB7IG91dD86IHN0cmluZyB9KSA9PiB7CiAgICBjb25zdCBkaXIgPSByZXNvbHZlKG9wdHMub3V0ID8/IG5hbWUpOwogICAgY29uc3QgcmVzdWx0ID0gc2NhZmZvbGRQYXJ0KG5hbWUsIGRpcik7CiAgICBmb3IgKGNvbnN0IGYgb2YgcmVzdWx0LmZpbGVzKSB7CiAgICAgIGNvbnN0IHRhZyA9IGYuY3JlYXRlZCA/ICdjcmVhdGVkJyA6ICdleGlzdHMgKGtlcHQpJzsKICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYCR7dGFnfTogJHtmLnBhdGh9XG5gKTsKICAgIH0KICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMikgKyAnXG4nKTsKICB9KTsKCnByb2dyYW0KICAuY29tbWFuZCgnd2F0Y2gnKQogIC5hcmd1bWVudCgnPGZpbGU+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGU7IHJlLXZlcmlmaWVzIG9uIGVhY2ggc2F2ZSB1bnRpbCBDdHJsLUMnKQogIC5hY3Rpb24oKGZpbGU6IHN0cmluZykgPT4gewogICAgY29uc3QgcGF0aCA9IHJlc29sdmUoZmlsZSk7CiAgICBjb25zdCBydW4gPSBhc3luYyAoKSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgeyByZXBvcnQsIHNoYXBlIH0gPSBhd2FpdCBydW5QYXJ0KHBhdGgpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShzZXJpYWxpemVSZXBvcnQocmVwb3J0KSArICdcbicpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBkaXNwb3NlU2hhcGUoc2hhcGUpOyAvLyBsaXZlIFdBU00gaGFuZGxlOyB0aGUgbG9vcCBydW5zIGluZGVmaW5pdGVseQogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGB3YXRjaCBydW4gZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfVxuYCk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCB7IHRyaWdnZXIgfSA9IGRlYm91bmNlKHJ1biwgREVGQVVMVF9ERUJPVU5DRV9NUyk7CiAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgd2F0Y2hpbmcgJHtwYXRofSAoQ3RybC1DIHRvIHN0b3ApXG5gKTsKICAgIHZvaWQgcnVuKCk7IC8vIGluaXRpYWwgdmVyaWZ5CiAgICAvLyBXYXRjaCB0aGUgcGFyZW50IGRpcjogZWRpdG9ycyBvZnRlbiByZXBsYWNlIHRoZSBmaWxlIChyZW5hbWUpIG9uIHNhdmUsCiAgICAvLyB3aGljaCBkcm9wcyBhIHdhdGNoZXIgYm91bmQgdG8gdGhlIGZpbGUgaW5vZGUgaXRzZWxmLgogICAgY29uc3Qgd2F0Y2hlciA9IGZzV2F0Y2goZGlybmFtZShwYXRoKSwgKF9ldmVudCwgZmlsZW5hbWUpID0+IHsKICAgICAgaWYgKGZpbGVuYW1lID09PSB1bmRlZmluZWQgfHwgZmlsZW5hbWUgPT09IG51bGwpIHsKICAgICAgICB0cmlnZ2VyKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGlmIChiYXNlbmFtZShwYXRoKSA9PT0gZmlsZW5hbWUudG9TdHJpbmcoKSkgdHJpZ2dlcigpOwogICAgfSk7CiAgICBjb25zdCBzdG9wID0gKCkgPT4gewogICAgICB3YXRjaGVyLmNsb3NlKCk7CiAgICAgIHByb2Nlc3MuZXhpdCgwKTsKICAgIH07CiAgICBwcm9jZXNzLm9uKCdTSUdJTlQnLCBzdG9wKTsKICAgIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBzdG9wKTsgLy8gc3VwZXJ2aXNvcnMgKGRvY2tlciBzdG9wLCBzeXN0ZW1jdGwpIHNlbmQgU0lHVEVSTQogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdleHBvcnQnKQogIC5hcmd1bWVudCgnPGZpbGU+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGUnKQogIC5vcHRpb24oJy0tc3RlcCcsICd3cml0ZSBhIFNURVAgYXJ0aWZhY3QnKQogIC5vcHRpb24oJy0tZ2xiJywgJ3dyaXRlIGEgR0xCIGFydGlmYWN0JykKICAub3B0aW9uKCctLXN0bCcsICd3cml0ZSBhbiBTVEwgYXJ0aWZhY3QnKQogIC5vcHRpb24oJy0tYWxsJywgJ3dyaXRlIFNURVAgKyBHTEIgKyBTVEwnKQogIC5vcHRpb24oJy0tb3V0IDxkaXI+JywgJ291dHB1dCBkaXJlY3RvcnknLCAnLicpCiAgLmFjdGlvbigKICAgIGFzeW5jICgKICAgICAgZmlsZTogc3RyaW5nLAogICAgICBvcHRzOiB7IHN0ZXA/OiBib29sZWFuOyBnbGI/OiBib29sZWFuOyBzdGw/OiBib29sZWFuOyBhbGw/OiBib29sZWFuOyBvdXQ6IHN0cmluZyB9CiAgICApID0+IHsKICAgICAgY29uc3QgZm9ybWF0cyA9IG9wdHMuYWxsCiAgICAgICAgPyB7IHN0ZXA6IHRydWUsIGdsYjogdHJ1ZSwgc3RsOiB0cnVlIH0KICAgICAgICA6IHsgc3RlcDogQm9vbGVhbihvcHRzLnN0ZXApLCBnbGI6IEJvb2xlYW4ob3B0cy5nbGIpLCBzdGw6IEJvb2xlYW4ob3B0cy5zdGwpIH07CiAgICAgIGlmICghZm9ybWF0cy5zdGVwICYmICFmb3JtYXRzLmdsYiAmJiAhZm9ybWF0cy5zdGwpIHsKICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZSgnbm8gZm9ybWF0cyByZXF1ZXN0ZWQg4oCUIHBhc3MgLS1zdGVwLy0tZ2xiLy0tc3RsIG9yIC0tYWxsXG4nKTsKICAgICAgICBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhwb3J0UGFydChyZXNvbHZlKGZpbGUpLCBmb3JtYXRzLCByZXNvbHZlKG9wdHMub3V0KSk7CiAgICAgIGZvciAoY29uc3QgcCBvZiByZXN1bHQud3JpdHRlbikgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYHdyb3RlOiAke3B9XG5gKTsKICAgICAgZm9yIChjb25zdCBlIG9mIHJlc3VsdC5lcnJvcnMpIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBlcnJvcjogJHtlfVxuYCk7CiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICAgIEpTT04uc3RyaW5naWZ5KHsgb2s6IHJlc3VsdC5vaywgd3JpdHRlbjogcmVzdWx0LndyaXR0ZW4sIGVycm9yczogcmVzdWx0LmVycm9ycyB9LCBudWxsLCAyKSArCiAgICAgICAgICAnXG4nCiAgICAgICk7CiAgICAgIGlmICghcmVzdWx0Lm9rKSBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgIH0KICApOwoKLy8gT25seSBkcml2ZSB0aGUgQ0xJIHdoZW4gcnVuIGFzIHRoZSBlbnRyeSBzY3JpcHQsIHNvIHRlc3RzIGNhbiBpbXBvcnQgdGhlCi8vIGd1YXJkZWQgbG9hZGVycyB3aXRob3V0IGNvbW1hbmRlciBwYXJzaW5nIHRoZSB0ZXN0IHJ1bm5lcidzIGFyZ3YuCi8vIFJlc29sdmUgc3ltbGlua3Mgb24gYm90aCBzaWRlczogdGhlIG5wbS1pbnN0YWxsZWQgYmluIChub2RlX21vZHVsZXMvLmJpbi9icmVwanMpCi8vIGlzIGEgc3ltbGluaywgc28gcHJvY2Vzcy5hcmd2WzFdIHdvdWxkIG90aGVyd2lzZSBuZXZlciBlcXVhbCB0aGUgcmVhbCBtb2R1bGUgcGF0aC4KZXhwb3J0IGZ1bmN0aW9uIGlzRW50cnlwb2ludChhcmd2MTogc3RyaW5nIHwgdW5kZWZpbmVkLCBtb2R1bGVVcmw6IHN0cmluZyk6IGJvb2xlYW4gewogIGlmICghYXJndjEpIHJldHVybiBmYWxzZTsKICB0cnkgewogICAgcmV0dXJuIHJlYWxwYXRoU3luYyhhcmd2MSkgPT09IHJlYWxwYXRoU3luYyhmaWxlVVJMVG9QYXRoKG1vZHVsZVVybCkpOwogIH0gY2F0Y2ggewogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKaWYgKGlzRW50cnlwb2ludChwcm9jZXNzLmFyZ3ZbMV0sIGltcG9ydC5tZXRhLnVybCkpIHsKICB2b2lkIHByb2dyYW0ucGFyc2VBc3luYygpOwp9Cg==", "" + {}.url));
37
+ if ((0, node_fs.existsSync)(builtJs)) return builtJs;
38
+ return (0, node_url.fileURLToPath)(new URL("data:video/mp2t;base64,IyEvdXNyL2Jpbi9lbnYgbm9kZQppbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJzsKaW1wb3J0IHsgd3JpdGVGaWxlU3luYywgd2F0Y2ggYXMgZnNXYXRjaCwgcmVhbHBhdGhTeW5jIH0gZnJvbSAnbm9kZTpmcyc7CmltcG9ydCB7IHJlc29sdmUsIGpvaW4sIGJhc2VuYW1lLCBkaXJuYW1lIH0gZnJvbSAnbm9kZTpwYXRoJzsKaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSAnbm9kZTpvcyc7CmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICdub2RlOnVybCc7CmltcG9ydCB7IHJ1blBhcnQgfSBmcm9tICcuLi92ZXJpZnkvcnVuUGFydC5qcyc7CmltcG9ydCB7IHB1c2hFcnJvciwgcmVwb3J0T2ssIHNlcmlhbGl6ZVJlcG9ydCB9IGZyb20gJy4uL3ZlcmlmeS9yZXBvcnQuanMnOwppbXBvcnQgeyBydW5NZWFzdXJlIH0gZnJvbSAnLi4vdmVyaWZ5L21lYXN1cmUuanMnOwppbXBvcnQgeyBydW5EaWZmIH0gZnJvbSAnLi4vdmVyaWZ5L2RpZmYuanMnOwppbXBvcnQgeyBzY2FmZm9sZFBhcnQgfSBmcm9tICcuL3NjYWZmb2xkLmpzJzsKaW1wb3J0IHsgZGVib3VuY2UsIERFRkFVTFRfREVCT1VOQ0VfTVMgfSBmcm9tICcuL3dhdGNoLmpzJzsKaW1wb3J0IHsgZXhwb3J0UGFydCB9IGZyb20gJy4vZXhwb3J0UGFydC5qcyc7CmltcG9ydCB7IG9wZW5Ccm93c2VyLCBzaG91bGRBdXRvT3BlbiB9IGZyb20gJy4vb3BlbkJyb3dzZXIuanMnOwppbXBvcnQgeyBkaXNwb3NlU2hhcGUgfSBmcm9tICcuLi9kaXNwb3NlU2hhcGUuanMnOwppbXBvcnQgdHlwZSB7IHNob290IGFzIFNob290Rm4gfSBmcm9tICcuLi9zbmFwc2hvdC9zaG9vdC5qcyc7CgovLyBPQ0NUJ3MgV0FTTSBTVEVQIHdyaXRlciBlbWl0cyBhICJTdGF0aXN0aWNzIG9uIFRyYW5zZmVyIiBiYW5uZXIgdmlhIGNvbnNvbGUubG9nCi8vIChFbXNjcmlwdGVuJ3MgZGVmYXVsdCBzdGRvdXQgc2luaykuIFRoZSBDTEkgb3ducyBzdGRvdXQgZm9yIG1hY2hpbmUtcmVhZGFibGUgSlNPTiwKLy8gc28gZGl2ZXJ0IHRoYXQga2VybmVsIGNoYXR0ZXIgdG8gc3RkZXJyIHRvIGtlZXAgc3Rkb3V0IGEgc2luZ2xlIGNsZWFuIEpTT04gZG9jdW1lbnQuCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlIC0tIHJlcm91dGUga2VybmVsIHN0ZG91dCBjaGF0dGVyIG9mZiB0aGUgSlNPTiBjaGFubmVsCmNvbnNvbGUubG9nID0gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gewogIHByb2Nlc3Muc3RkZXJyLndyaXRlKGFyZ3MubWFwKFN0cmluZykuam9pbignICcpICsgJ1xuJyk7Cn07CgpleHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFNuYXBzaG90U2hvb3QoKTogUHJvbWlzZTx0eXBlb2YgU2hvb3RGbiB8IHVuZGVmaW5lZD4gewogIHRyeSB7CiAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoJy4uL3NuYXBzaG90L3Nob290LmpzJyk7CiAgICByZXR1cm4gbW9kLnNob290OwogIH0gY2F0Y2ggewogICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoJ3NuYXBzaG90cyBuZWVkIHB1cHBldGVlci9DaHJvbWUg4oCUIHJ1bjogbnBtIGkgcHVwcGV0ZWVyXG4nKTsKICAgIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9Cn0KCmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpOwpwcm9ncmFtLm5hbWUoJ2JyZXBqcy12ZXJpZnknKTsKCnByb2dyYW0KICAuY29tbWFuZCgndmVyaWZ5JywgeyBpc0RlZmF1bHQ6IHRydWUgfSkKICAuYXJndW1lbnQoJzxmaWxlPicsICdwYXRoIHRvIGEgLmJyZXAudHMgbW9kdWxlIHdpdGggYSBkZWZhdWx0LWV4cG9ydGVkIHBhcnQgZnVuY3Rpb24nKQogIC5vcHRpb24oJy0tc3RlcCA8b3V0PicsICd3cml0ZSB0aGUgcHJpbWFyeSBTVEVQIGFydGlmYWN0IHRvIHRoaXMgcGF0aCcpCiAgLm9wdGlvbignLS1nbGIgPG91dD4nLCAnd3JpdGUgYSBkZXJpdmVkIEdMQiBwcmV2aWV3IHRvIHRoaXMgcGF0aCcpCiAgLm9wdGlvbignLS1qc29uIDxvdXQ+JywgJ3dyaXRlIHRoZSBKU09OIHJlcG9ydCB0byB0aGlzIHBhdGgnKQogIC5vcHRpb24oCiAgICAnLS1jaGVjaycsCiAgICAndHlwZS1jaGVjayB0aGUgcGFydCAoYWdhaW5zdCBicmVwanMgdHlwZXMpIGJlZm9yZSBydW5uaW5nOyBza2lwIGV4ZWN1dGlvbiBvbiB0eXBlIGVycm9ycycKICApCiAgLm9wdGlvbignLS1zbmFwc2hvdCA8ZGlyPicsICdyZW5kZXIgaXNvL2Zyb250L3RvcC9yaWdodCBQTkdzIHRvIHRoaXMgZGlyIChyZXF1aXJlcyBidWlsdCB2aWV3ZXIpJykKICAub3B0aW9uKAogICAgJy0tc2VydmUnLAogICAgJ2FmdGVyIHZlcmlmeWluZywgc3RhcnQgYSBwcmV2aWV3IHNlcnZlciBhbmQgcHJpbnQgYSA/ZGlyPSZmaWxlPSBkZWVwIGxpbmsgKHN0YXlzIHJ1bm5pbmcpJwogICkKICAub3B0aW9uKCctLW5vLW9wZW4nLCAnd2l0aCAtLXNlcnZlLCBkbyBub3QgYXV0by1vcGVuIHRoZSBicm93c2VyIChqdXN0IHByaW50IHRoZSB2aWV3ZXIgVVJMKScpCiAgLmFjdGlvbigKICAgIGFzeW5jICgKICAgICAgZmlsZTogc3RyaW5nLAogICAgICBvcHRzOiB7CiAgICAgICAgc3RlcD86IHN0cmluZzsKICAgICAgICBnbGI/OiBzdHJpbmc7CiAgICAgICAganNvbj86IHN0cmluZzsKICAgICAgICBjaGVjaz86IGJvb2xlYW47CiAgICAgICAgc25hcHNob3Q/OiBzdHJpbmc7CiAgICAgICAgc2VydmU/OiBib29sZWFuOwogICAgICAgIC8vIENvbW1hbmRlciBtYXRlcmlhbGl6ZXMgYSBuZWdhdGVkIGZsYWcgYXMgYSBjb25jcmV0ZSBib29sZWFuOiB0cnVlIGJ5CiAgICAgICAgLy8gZGVmYXVsdCwgZmFsc2Ugd2hlbiAtLW5vLW9wZW4gaXMgcGFzc2VkLgogICAgICAgIG9wZW46IGJvb2xlYW47CiAgICAgIH0KICAgICkgPT4gewogICAgICAvLyBUaGUgV0FTTSB2aWV3ZXIgbG9hZHMgYSBDQUQgZmlsZSAoaXQgY2FuJ3QgcnVuIGEgLmJyZXAudHMpLCBzbyAtLXNuYXBzaG90Ly0tc2VydmUKICAgICAgLy8gc3RhZ2UgdGhlIHByaW1hcnkgU1RFUCBhbmQgcG9pbnQgdGhlIHZpZXdlciBhdCBpdCB2aWEgP2Rpcj0mZmlsZT0uIC0tZ2xiIGlzIGl0cyBvd24gYXJ0aWZhY3QuCiAgICAgIGNvbnN0IHdhbnRTdGVwID0gQm9vbGVhbihvcHRzLnN0ZXApIHx8IEJvb2xlYW4ob3B0cy5zbmFwc2hvdCkgfHwgQm9vbGVhbihvcHRzLnNlcnZlKTsKICAgICAgY29uc3QgeyByZXBvcnQsIHN0ZXAsIGdsYiwgc2hhcGUgfSA9IGF3YWl0IHJ1blBhcnQocmVzb2x2ZShmaWxlKSwgewogICAgICAgIHN0ZXA6IHdhbnRTdGVwLAogICAgICAgIGdsYjogQm9vbGVhbihvcHRzLmdsYiksCiAgICAgICAgY2hlY2s6IEJvb2xlYW4ob3B0cy5jaGVjayksCiAgICAgIH0pOwogICAgICBsZXQgc3RlcFBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCA9IG9wdHMuc3RlcDsKICAgICAgdHJ5IHsKICAgICAgICBpZiAob3B0cy5nbGIgJiYgZ2xiKSB3cml0ZUZpbGVTeW5jKG9wdHMuZ2xiLCBCdWZmZXIuZnJvbShnbGIpKTsKCiAgICAgICAgaWYgKHdhbnRTdGVwICYmIHN0ZXApIHsKICAgICAgICAgIHN0ZXBQYXRoID0gb3B0cy5zdGVwID8/IGpvaW4odG1wZGlyKCksIGBicmVwanMtdmVyaWZ5LSR7YmFzZW5hbWUoZmlsZSl9LnN0ZXBgKTsKICAgICAgICAgIHdyaXRlRmlsZVN5bmMoc3RlcFBhdGgsIEJ1ZmZlci5mcm9tKHN0ZXApKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdHMuc25hcHNob3QgJiYgc3RlcFBhdGgpIHsKICAgICAgICAgIGNvbnN0IHNob290ID0gYXdhaXQgbG9hZFNuYXBzaG90U2hvb3QoKTsgLy8gbGF6eToga2VlcHMgcHVwcGV0ZWVyIG9mZiB0aGUgZGVmYXVsdCBwYXRoCiAgICAgICAgICBpZiAoc2hvb3QpIHsKICAgICAgICAgICAgY29uc3QgeyBwbmdzIH0gPSBhd2FpdCBzaG9vdCh7IGZpbGU6IHN0ZXBQYXRoLCBvdXREaXI6IG9wdHMuc25hcHNob3QgfSk7CiAgICAgICAgICAgIC8vIERpYWdub3N0aWMgcGF0aHMgZ28gdG8gc3RkZXJyIOKAlCBzdGRvdXQgc3RheXMgYSBzaW5nbGUgY2xlYW4gSlNPTiBkb2N1bWVudC4KICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIHBuZ3MpIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBzbmFwc2hvdDogJHtwfVxuYCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChvcHRzLnNuYXBzaG90KSB7CiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZSgnc25hcHNob3Qgc2tpcHBlZDogU1RFUCBleHBvcnQgcHJvZHVjZWQgbm8gYXJ0aWZhY3RcbicpOwogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHB1c2hFcnJvcihyZXBvcnQsIHsgbWVzc2FnZTogYGFydGlmYWN0IHdyaXRlIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gIH0pOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIC8vIFRoZSBzaGFwZSBpcyBhIGxpdmUgV0FTTSBoYW5kbGU7IHJlbGVhc2UgaXQgYmVmb3JlIHRoZSBzZXJ2ZXIgdGFrZXMgb3ZlciAodGhlCiAgICAgICAgLy8gLS1zZXJ2ZSBwYXRoIHN0YXlzIHJ1bm5pbmcsIHNvIGxlYWtpbmcgaGVyZSB3b3VsZCBwZXJzaXN0IGZvciB0aGUgc2VydmVyJ3MgbGlmZXRpbWUpLgogICAgICAgIGRpc3Bvc2VTaGFwZShzaGFwZSk7CiAgICAgIH0KICAgICAgLy8gU2VyaWFsaXplIG9uY2UgYWZ0ZXIgYWxsIGFydGlmYWN0IHdyaXRlcyBzbyB0aGUgLS1qc29uIGZpbGUgYW5kIHN0ZG91dAogICAgICAvLyByZWZsZWN0IHRoZSBzYW1lIHJlcG9ydCAoaW5jbC4gYW55ICJhcnRpZmFjdCB3cml0ZSBmYWlsZWQiIGVycm9yKS4KICAgICAgY29uc3QganNvbiA9IHNlcmlhbGl6ZVJlcG9ydChyZXBvcnQpOwogICAgICBpZiAob3B0cy5qc29uKSB3cml0ZUZpbGVTeW5jKG9wdHMuanNvbiwganNvbik7CiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGpzb24gKyAnXG4nKTsKICAgICAgaWYgKCFyZXBvcnRPayhyZXBvcnQpKSBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgICAgY29uc3Qgd2lsbFNlcnZlID0gQm9vbGVhbihvcHRzLnNlcnZlKSAmJiBzdGVwUGF0aCAhPT0gdW5kZWZpbmVkICYmIHJlcG9ydE9rKHJlcG9ydCk7CiAgICAgIGlmICh3aWxsU2VydmUgJiYgc3RlcFBhdGgpIHsKICAgICAgICBjb25zdCB7IHNlcnZlIH0gPSBhd2FpdCBpbXBvcnQoJy4uL3NuYXBzaG90L3NlcnZlLmpzJyk7IC8vIGxhenk6IG5vIHNlcnZlciBkZXBzIG9uIHRoZSBkZWZhdWx0IHBhdGgKICAgICAgICBjb25zdCB7IHVybCwgcmV1c2VkIH0gPSBhd2FpdCBzZXJ2ZSh7IGZpbGU6IHN0ZXBQYXRoIH0pOyAvLyBidWlsZHMgYSA/ZGlyPSZmaWxlPSBVUkw7IHNlcnZlciBydW5zIHVudGlsIEN0cmwtQwogICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGB2aWV3ZXI6ICR7dXJsfVxuYCk7CiAgICAgICAgLy8gQXV0by1vcGVuIG9ubHkgZm9yIGEgZnJlc2hseSBzdGFydGVkIHNlcnZlciAoYSByZXVzZWQgb25lIGFscmVhZHkgaGFzCiAgICAgICAgLy8gYSB0YWIpIGluIGFuIGludGVyYWN0aXZlIHNlc3Npb247IGAtLW5vLW9wZW5gIChvcHRzLm9wZW4gPT09IGZhbHNlKQogICAgICAgIC8vIGFsd2F5cyBzdXBwcmVzc2VzIGl0LgogICAgICAgIGlmICghcmV1c2VkICYmIG9wdHMub3BlbiAmJiBzaG91bGRBdXRvT3BlbigpKSB7CiAgICAgICAgICBvcGVuQnJvd3Nlcih1cmwpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICk7Cgpwcm9ncmFtCiAgLmNvbW1hbmQoJ21lYXN1cmUnKQogIC5hcmd1bWVudCgnPGE+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGUnKQogIC5hcmd1bWVudCgnW2JdJywgJ29wdGlvbmFsIHNlY29uZCBtb2R1bGU7IGlmIGdpdmVuLCBtZWFzdXJlcyBkaXN0YW5jZSBiZXR3ZWVuIHRoZSB0d28gcGFydHMnKQogIC5hY3Rpb24oYXN5bmMgKGE6IHN0cmluZywgYj86IHN0cmluZykgPT4gewogICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuTWVhc3VyZShyZXNvbHZlKGEpLCBiID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZXNvbHZlKGIpKTsKICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICBKU09OLnN0cmluZ2lmeSh7IG9rOiByZXN1bHQuZXJyb3JzLmxlbmd0aCA9PT0gMCwgLi4ucmVzdWx0IH0sIG51bGwsIDIpICsgJ1xuJwogICAgKTsKICAgIGlmIChyZXN1bHQuZXJyb3JzLmxlbmd0aCA+IDApIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdkaWZmJykKICAuYXJndW1lbnQoJzxhPicsICdwYXRoIHRvIHRoZSBiYXNlbGluZSAuYnJlcC50cyBtb2R1bGUnKQogIC5hcmd1bWVudCgnPGI+JywgJ3BhdGggdG8gdGhlIGNvbXBhcmlzb24gLmJyZXAudHMgbW9kdWxlJykKICAuYWN0aW9uKGFzeW5jIChhOiBzdHJpbmcsIGI6IHN0cmluZykgPT4gewogICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuRGlmZihyZXNvbHZlKGEpLCByZXNvbHZlKGIpKTsKICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICBKU09OLnN0cmluZ2lmeSh7IG9rOiByZXN1bHQuZXJyb3JzLmxlbmd0aCA9PT0gMCwgLi4ucmVzdWx0IH0sIG51bGwsIDIpICsgJ1xuJwogICAgKTsKICAgIGlmIChyZXN1bHQuZXJyb3JzLmxlbmd0aCA+IDApIHByb2Nlc3MuZXhpdENvZGUgPSAxOwogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdpbml0JykKICAuYXJndW1lbnQoJzxuYW1lPicsICdwYXJ0IG5hbWU7IHNjYWZmb2xkcyA8bmFtZT4uYnJlcC50cyArIHRzY29uZmlnLmpzb24gKyBSRUFETUUubWQnKQogIC5vcHRpb24oJy0tb3V0IDxkaXI+JywgJ3RhcmdldCBkaXJlY3RvcnkgKGRlZmF1bHRzIHRvIC4vPG5hbWU+KScpCiAgLmFjdGlvbigobmFtZTogc3RyaW5nLCBvcHRzOiB7IG91dD86IHN0cmluZyB9KSA9PiB7CiAgICBjb25zdCBkaXIgPSByZXNvbHZlKG9wdHMub3V0ID8/IG5hbWUpOwogICAgY29uc3QgcmVzdWx0ID0gc2NhZmZvbGRQYXJ0KG5hbWUsIGRpcik7CiAgICBmb3IgKGNvbnN0IGYgb2YgcmVzdWx0LmZpbGVzKSB7CiAgICAgIGNvbnN0IHRhZyA9IGYuY3JlYXRlZCA/ICdjcmVhdGVkJyA6ICdleGlzdHMgKGtlcHQpJzsKICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYCR7dGFnfTogJHtmLnBhdGh9XG5gKTsKICAgIH0KICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMikgKyAnXG4nKTsKICB9KTsKCnByb2dyYW0KICAuY29tbWFuZCgnd2F0Y2gnKQogIC5hcmd1bWVudCgnPGZpbGU+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGU7IHJlLXZlcmlmaWVzIG9uIGVhY2ggc2F2ZSB1bnRpbCBDdHJsLUMnKQogIC5hY3Rpb24oKGZpbGU6IHN0cmluZykgPT4gewogICAgY29uc3QgcGF0aCA9IHJlc29sdmUoZmlsZSk7CiAgICBjb25zdCBydW4gPSBhc3luYyAoKSA9PiB7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgeyByZXBvcnQsIHNoYXBlIH0gPSBhd2FpdCBydW5QYXJ0KHBhdGgpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShzZXJpYWxpemVSZXBvcnQocmVwb3J0KSArICdcbicpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBkaXNwb3NlU2hhcGUoc2hhcGUpOyAvLyBsaXZlIFdBU00gaGFuZGxlOyB0aGUgbG9vcCBydW5zIGluZGVmaW5pdGVseQogICAgICAgIH0KICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGB3YXRjaCBydW4gZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfVxuYCk7CiAgICAgIH0KICAgIH07CiAgICBjb25zdCB7IHRyaWdnZXIgfSA9IGRlYm91bmNlKHJ1biwgREVGQVVMVF9ERUJPVU5DRV9NUyk7CiAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgd2F0Y2hpbmcgJHtwYXRofSAoQ3RybC1DIHRvIHN0b3ApXG5gKTsKICAgIHZvaWQgcnVuKCk7IC8vIGluaXRpYWwgdmVyaWZ5CiAgICAvLyBXYXRjaCB0aGUgcGFyZW50IGRpcjogZWRpdG9ycyBvZnRlbiByZXBsYWNlIHRoZSBmaWxlIChyZW5hbWUpIG9uIHNhdmUsCiAgICAvLyB3aGljaCBkcm9wcyBhIHdhdGNoZXIgYm91bmQgdG8gdGhlIGZpbGUgaW5vZGUgaXRzZWxmLgogICAgY29uc3Qgd2F0Y2hlciA9IGZzV2F0Y2goZGlybmFtZShwYXRoKSwgKF9ldmVudCwgZmlsZW5hbWUpID0+IHsKICAgICAgaWYgKGZpbGVuYW1lID09PSB1bmRlZmluZWQgfHwgZmlsZW5hbWUgPT09IG51bGwpIHsKICAgICAgICB0cmlnZ2VyKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGlmIChiYXNlbmFtZShwYXRoKSA9PT0gZmlsZW5hbWUudG9TdHJpbmcoKSkgdHJpZ2dlcigpOwogICAgfSk7CiAgICBjb25zdCBzdG9wID0gKCkgPT4gewogICAgICB3YXRjaGVyLmNsb3NlKCk7CiAgICAgIHByb2Nlc3MuZXhpdCgwKTsKICAgIH07CiAgICBwcm9jZXNzLm9uKCdTSUdJTlQnLCBzdG9wKTsKICAgIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBzdG9wKTsgLy8gc3VwZXJ2aXNvcnMgKGRvY2tlciBzdG9wLCBzeXN0ZW1jdGwpIHNlbmQgU0lHVEVSTQogIH0pOwoKcHJvZ3JhbQogIC5jb21tYW5kKCdleHBvcnQnKQogIC5hcmd1bWVudCgnPGZpbGU+JywgJ3BhdGggdG8gYSAuYnJlcC50cyBtb2R1bGUnKQogIC5vcHRpb24oJy0tc3RlcCcsICd3cml0ZSBhIFNURVAgYXJ0aWZhY3QnKQogIC5vcHRpb24oJy0tZ2xiJywgJ3dyaXRlIGEgR0xCIGFydGlmYWN0JykKICAub3B0aW9uKCctLXN0bCcsICd3cml0ZSBhbiBTVEwgYXJ0aWZhY3QnKQogIC5vcHRpb24oJy0tYWxsJywgJ3dyaXRlIFNURVAgKyBHTEIgKyBTVEwnKQogIC5vcHRpb24oJy0tb3V0IDxkaXI+JywgJ291dHB1dCBkaXJlY3RvcnknLCAnLicpCiAgLmFjdGlvbigKICAgIGFzeW5jICgKICAgICAgZmlsZTogc3RyaW5nLAogICAgICBvcHRzOiB7IHN0ZXA/OiBib29sZWFuOyBnbGI/OiBib29sZWFuOyBzdGw/OiBib29sZWFuOyBhbGw/OiBib29sZWFuOyBvdXQ6IHN0cmluZyB9CiAgICApID0+IHsKICAgICAgY29uc3QgZm9ybWF0cyA9IG9wdHMuYWxsCiAgICAgICAgPyB7IHN0ZXA6IHRydWUsIGdsYjogdHJ1ZSwgc3RsOiB0cnVlIH0KICAgICAgICA6IHsgc3RlcDogQm9vbGVhbihvcHRzLnN0ZXApLCBnbGI6IEJvb2xlYW4ob3B0cy5nbGIpLCBzdGw6IEJvb2xlYW4ob3B0cy5zdGwpIH07CiAgICAgIGlmICghZm9ybWF0cy5zdGVwICYmICFmb3JtYXRzLmdsYiAmJiAhZm9ybWF0cy5zdGwpIHsKICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZSgnbm8gZm9ybWF0cyByZXF1ZXN0ZWQg4oCUIHBhc3MgLS1zdGVwLy0tZ2xiLy0tc3RsIG9yIC0tYWxsXG4nKTsKICAgICAgICBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhwb3J0UGFydChyZXNvbHZlKGZpbGUpLCBmb3JtYXRzLCByZXNvbHZlKG9wdHMub3V0KSk7CiAgICAgIGZvciAoY29uc3QgcCBvZiByZXN1bHQud3JpdHRlbikgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYHdyb3RlOiAke3B9XG5gKTsKICAgICAgZm9yIChjb25zdCBlIG9mIHJlc3VsdC5lcnJvcnMpIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBlcnJvcjogJHtlfVxuYCk7CiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKAogICAgICAgIEpTT04uc3RyaW5naWZ5KHsgb2s6IHJlc3VsdC5vaywgd3JpdHRlbjogcmVzdWx0LndyaXR0ZW4sIGVycm9yczogcmVzdWx0LmVycm9ycyB9LCBudWxsLCAyKSArCiAgICAgICAgICAnXG4nCiAgICAgICk7CiAgICAgIGlmICghcmVzdWx0Lm9rKSBwcm9jZXNzLmV4aXRDb2RlID0gMTsKICAgIH0KICApOwoKLy8gT25seSBkcml2ZSB0aGUgQ0xJIHdoZW4gcnVuIGFzIHRoZSBlbnRyeSBzY3JpcHQsIHNvIHRlc3RzIGNhbiBpbXBvcnQgdGhlCi8vIGd1YXJkZWQgbG9hZGVycyB3aXRob3V0IGNvbW1hbmRlciBwYXJzaW5nIHRoZSB0ZXN0IHJ1bm5lcidzIGFyZ3YuCi8vIFJlc29sdmUgc3ltbGlua3Mgb24gYm90aCBzaWRlczogdGhlIG5wbS1pbnN0YWxsZWQgYmluIChub2RlX21vZHVsZXMvLmJpbi9icmVwanMpCi8vIGlzIGEgc3ltbGluaywgc28gcHJvY2Vzcy5hcmd2WzFdIHdvdWxkIG90aGVyd2lzZSBuZXZlciBlcXVhbCB0aGUgcmVhbCBtb2R1bGUgcGF0aC4KZXhwb3J0IGZ1bmN0aW9uIGlzRW50cnlwb2ludChhcmd2MTogc3RyaW5nIHwgdW5kZWZpbmVkLCBtb2R1bGVVcmw6IHN0cmluZyk6IGJvb2xlYW4gewogIGlmICghYXJndjEpIHJldHVybiBmYWxzZTsKICB0cnkgewogICAgcmV0dXJuIHJlYWxwYXRoU3luYyhhcmd2MSkgPT09IHJlYWxwYXRoU3luYyhmaWxlVVJMVG9QYXRoKG1vZHVsZVVybCkpOwogIH0gY2F0Y2ggewogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKaWYgKGlzRW50cnlwb2ludChwcm9jZXNzLmFyZ3ZbMV0sIGltcG9ydC5tZXRhLnVybCkpIHsKICB2b2lkIHByb2dyYW0ucGFyc2VBc3luYygpOwp9Cg==", "" + {}.url));
39
+ }
40
+ /**
41
+ * Write `code` to a temp ESM directory, run the verify CLI with `makeArgs(partPath)` in a
42
+ * resource-bounded child process, and return the raw outcome. The temp *program* directory is
43
+ * always cleaned up; any artifacts the CLI writes elsewhere (e.g. an `--out` dir) are the caller's.
44
+ */
45
+ async function runVerifyCli(code, makeArgs, opts) {
46
+ const timeoutMs = positiveOrDefault(opts.timeoutMs, DEFAULT_TIMEOUT_MS);
47
+ const maxMemoryMb = positiveOrDefault(opts.maxMemoryMb, DEFAULT_MAX_MEMORY_MB);
48
+ const cliEntry = opts.cliEntry ?? defaultCliEntry();
49
+ const useTsx = cliEntry.endsWith(".ts");
50
+ const dir = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "brepjs-run-"));
51
+ try {
52
+ await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "package.json"), "{\"type\":\"module\"}\n");
53
+ const partPath = (0, node_path.join)(dir, "part.brep.ts");
54
+ await (0, node_fs_promises.writeFile)(partPath, code);
55
+ const cliArgs = makeArgs(partPath);
56
+ const cmd = useTsx ? "npx" : process.execPath;
57
+ const args = useTsx ? [
58
+ "tsx",
59
+ cliEntry,
60
+ ...cliArgs
61
+ ] : [cliEntry, ...cliArgs];
62
+ try {
63
+ const { stdout, stderr } = await execFileAsync(cmd, args, {
64
+ timeout: timeoutMs,
65
+ killSignal: "SIGKILL",
66
+ maxBuffer: MAX_OUTPUT_BYTES,
67
+ env: {
68
+ ...process.env,
69
+ NODE_OPTIONS: [process.env["NODE_OPTIONS"], `--max-old-space-size=${maxMemoryMb}`].filter(Boolean).join(" ")
70
+ }
71
+ });
72
+ return {
73
+ stdout,
74
+ stderr,
75
+ timedOut: false,
76
+ outputTooLarge: false,
77
+ exitCode: 0
78
+ };
79
+ } catch (err) {
80
+ const e = err;
81
+ return {
82
+ stdout: e.stdout ?? "",
83
+ stderr: e.stderr ?? (err instanceof Error ? err.message : String(err)),
84
+ timedOut: Boolean(e.killed) && e.code !== "ERR_CHILD_PROCESS_STDIO_MAXBUFFER",
85
+ outputTooLarge: e.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER",
86
+ exitCode: typeof e.code === "number" ? e.code : null
87
+ };
88
+ }
89
+ } finally {
90
+ await (0, node_fs_promises.rm)(dir, {
91
+ recursive: true,
92
+ force: true
93
+ });
94
+ }
95
+ }
96
+ function tryParse(out) {
97
+ if (!out.trim()) return null;
98
+ try {
99
+ return JSON.parse(out);
100
+ } catch {
101
+ return null;
102
+ }
103
+ }
104
+ /** Execute `code` (an agent-authored `.brep.ts` module) in an isolated, resource-bounded child. */
105
+ async function runProgram(code, opts = {}) {
106
+ const o = await runVerifyCli(code, (partPath) => [partPath, "--check"], opts);
107
+ const report = tryParse(o.stdout);
108
+ if (report) return {
109
+ outcome: "completed",
110
+ report
111
+ };
112
+ if (o.timedOut) return {
113
+ outcome: "timeout",
114
+ timeoutMs: positiveOrDefault(opts.timeoutMs, DEFAULT_TIMEOUT_MS)
115
+ };
116
+ if (o.outputTooLarge) return {
117
+ outcome: "crashed",
118
+ exitCode: null,
119
+ detail: "output exceeded size limit"
120
+ };
121
+ return {
122
+ outcome: "crashed",
123
+ exitCode: o.exitCode,
124
+ detail: o.stderr.slice(0, 2e3) || "no JSON report on stdout"
125
+ };
126
+ }
127
+ /**
128
+ * Execute `code` and export artifacts to `outDir`. Artifacts persist in `outDir` (the caller owns
129
+ * it); only the temp program directory is cleaned up. Returns the written paths and any errors.
130
+ */
131
+ async function exportProgram(code, outDir, formats = {
132
+ step: true,
133
+ glb: true,
134
+ stl: true
135
+ }, opts = {}) {
136
+ const formatFlags = [
137
+ formats.step ? "--step" : "",
138
+ formats.glb ? "--glb" : "",
139
+ formats.stl ? "--stl" : ""
140
+ ].filter(Boolean);
141
+ if (formatFlags.length === 0) return {
142
+ outcome: "crashed",
143
+ exitCode: 1,
144
+ detail: "no formats selected; pass at least one of step/glb/stl"
145
+ };
146
+ const o = await runVerifyCli(code, (partPath) => [
147
+ "export",
148
+ partPath,
149
+ ...formatFlags,
150
+ "--out",
151
+ outDir
152
+ ], opts);
153
+ const parsed = tryParse(o.stdout);
154
+ if (parsed) return {
155
+ outcome: "completed",
156
+ ok: parsed.ok,
157
+ written: parsed.written,
158
+ errors: parsed.errors
159
+ };
160
+ if (o.timedOut) return {
161
+ outcome: "timeout",
162
+ timeoutMs: positiveOrDefault(opts.timeoutMs, DEFAULT_TIMEOUT_MS)
163
+ };
164
+ if (o.outputTooLarge) return {
165
+ outcome: "crashed",
166
+ exitCode: null,
167
+ detail: "output exceeded size limit"
168
+ };
169
+ return {
170
+ outcome: "crashed",
171
+ exitCode: o.exitCode,
172
+ detail: o.stderr.slice(0, 2e3) || "no JSON result on stdout"
173
+ };
174
+ }
175
+ //#endregion
176
+ //#region src/sandbox/runRecord.ts
177
+ /**
178
+ * Run-record — a lightweight, append-only provenance envelope for sandbox executions.
179
+ *
180
+ * Every `run_program` call can emit one JSONL record capturing what ran and what came back
181
+ * (program source, outcome, validity, the content-addressed result hash, and the geometric
182
+ * summary). It is deliberately small and side-channel: it keeps a dataset/eval option open
183
+ * (program → outcome pairs) without changing the agent-facing contract.
184
+ */
185
+ /** Build a {@link RunRecord} from a program and its sandbox result. `now` is injectable for tests. */
186
+ function buildRunRecord(program, result, now = () => /* @__PURE__ */ new Date()) {
187
+ const ok = result.outcome === "completed" && result.report.ok;
188
+ const measurements = result.outcome === "completed" ? result.report.measurements : void 0;
189
+ const topology = result.outcome === "completed" ? result.report.topology : void 0;
190
+ const digest = JSON.stringify({
191
+ outcome: result.outcome,
192
+ ok,
193
+ measurements,
194
+ topology
195
+ });
196
+ const resultHash = (0, node_crypto.createHash)("sha256").update(`${program}${digest}`).digest("hex");
197
+ return {
198
+ timestamp: now().toISOString(),
199
+ program,
200
+ outcome: result.outcome,
201
+ ok,
202
+ resultHash,
203
+ ...measurements !== void 0 ? { measurements } : {},
204
+ ...topology !== void 0 ? { topology } : {}
205
+ };
206
+ }
207
+ /** Append a record as one JSON line to `filePath` (creating it if absent). */
208
+ async function appendRunRecord(filePath, record) {
209
+ await (0, node_fs_promises.appendFile)(filePath, `${JSON.stringify(record)}\n`);
210
+ }
211
+ //#endregion
212
+ //#region src/mcp/tools.ts
213
+ /** JSON Schema for `run_program` input (the low-level Server API takes plain JSON Schema). */
214
+ var RUN_PROGRAM_INPUT_SCHEMA = {
215
+ type: "object",
216
+ properties: {
217
+ code: {
218
+ type: "string",
219
+ description: "A brepjs .brep.ts module with a default-exported part function."
220
+ },
221
+ timeoutMs: {
222
+ type: "number",
223
+ description: "Optional wall-clock budget in milliseconds (default 30000)."
224
+ }
225
+ },
226
+ required: ["code"]
227
+ };
228
+ /**
229
+ * Execute an agent-authored brepjs program in the sandbox and return its verification report.
230
+ * `isError` is set when the part failed checks, timed out, or crashed — so the agent can branch.
231
+ */
232
+ async function runProgramTool(args) {
233
+ if (!args.code || !args.code.trim()) return {
234
+ content: [{
235
+ type: "text",
236
+ text: "run_program requires a non-empty \"code\" string."
237
+ }],
238
+ isError: true
239
+ };
240
+ const result = await runProgram(args.code, args.timeoutMs !== void 0 ? { timeoutMs: args.timeoutMs } : {});
241
+ const recordPath = process.env["BREPJS_RUN_RECORD_PATH"];
242
+ if (recordPath) appendRunRecord(recordPath, buildRunRecord(args.code, result)).catch((err) => {
243
+ console.warn(`run-record append failed (BREPJS_RUN_RECORD_PATH=${recordPath}):`, err);
244
+ });
245
+ if (result.outcome === "completed") {
246
+ const payload = {
247
+ outcome: "completed",
248
+ ok: result.report.ok,
249
+ report: result.report
250
+ };
251
+ return {
252
+ content: [{
253
+ type: "text",
254
+ text: JSON.stringify(payload, null, 2)
255
+ }],
256
+ isError: !result.report.ok
257
+ };
258
+ }
259
+ return {
260
+ content: [{
261
+ type: "text",
262
+ text: JSON.stringify(result, null, 2)
263
+ }],
264
+ isError: true
265
+ };
266
+ }
267
+ /** JSON Schema for `export_part` input. */
268
+ var EXPORT_PART_INPUT_SCHEMA = {
269
+ type: "object",
270
+ properties: {
271
+ code: {
272
+ type: "string",
273
+ description: "A brepjs .brep.ts module with a default-exported part function."
274
+ },
275
+ outDir: {
276
+ type: "string",
277
+ description: "Directory to write artifacts into."
278
+ },
279
+ formats: {
280
+ type: "object",
281
+ description: "Which artifacts to write; omit for all.",
282
+ properties: {
283
+ step: { type: "boolean" },
284
+ glb: { type: "boolean" },
285
+ stl: { type: "boolean" }
286
+ }
287
+ },
288
+ timeoutMs: {
289
+ type: "number",
290
+ description: "Optional wall-clock budget in ms (default 30000)."
291
+ }
292
+ },
293
+ required: ["code", "outDir"]
294
+ };
295
+ /**
296
+ * Build a part in the sandbox and export it to `outDir` (STEP/GLB/STL). Returns the written paths;
297
+ * `isError` is set when the export produced no valid solid, timed out, or crashed. The artifacts
298
+ * persist in `outDir` for the agent to hand off.
299
+ */
300
+ async function exportPartTool(args) {
301
+ if (!args.code || !args.code.trim()) return {
302
+ content: [{
303
+ type: "text",
304
+ text: "export_part requires a non-empty \"code\" string."
305
+ }],
306
+ isError: true
307
+ };
308
+ if (!args.outDir || !args.outDir.trim()) return {
309
+ content: [{
310
+ type: "text",
311
+ text: "export_part requires an \"outDir\" string."
312
+ }],
313
+ isError: true
314
+ };
315
+ const result = await exportProgram(args.code, args.outDir, args.formats, args.timeoutMs !== void 0 ? { timeoutMs: args.timeoutMs } : {});
316
+ if (result.outcome === "completed") {
317
+ const payload = {
318
+ outcome: "completed",
319
+ ok: result.ok,
320
+ written: result.written,
321
+ errors: result.errors
322
+ };
323
+ return {
324
+ content: [{
325
+ type: "text",
326
+ text: JSON.stringify(payload, null, 2)
327
+ }],
328
+ isError: !result.ok
329
+ };
330
+ }
331
+ return {
332
+ content: [{
333
+ type: "text",
334
+ text: JSON.stringify(result, null, 2)
335
+ }],
336
+ isError: true
337
+ };
338
+ }
339
+ //#endregion
340
+ //#region src/mcp/server.ts
341
+ /**
342
+ * brepjs-verify MCP server (stdio).
343
+ *
344
+ * Exposes the verify substrate to MCP-capable agents. The first tool, `run_program`, executes an
345
+ * agent-authored brepjs program in the sandbox and returns the verification report — the closed
346
+ * "build → verify" step the agent loop is built on. Uses the SDK's low-level `Server` with plain
347
+ * JSON-Schema tool definitions (no direct zod dependency in this package).
348
+ */
349
+ var pkgPath = (0, node_path.join)((0, node_path.dirname)((0, node_url.fileURLToPath)({}.url)), "..", "..", "package.json");
350
+ var server = new _modelcontextprotocol_sdk_server_index_js.Server({
351
+ name: "brepjs-verify",
352
+ version: JSON.parse((0, node_fs.readFileSync)(pkgPath, "utf8")).version
353
+ }, { capabilities: { tools: {} } });
354
+ server.setRequestHandler(_modelcontextprotocol_sdk_types_js.ListToolsRequestSchema, () => ({ tools: [{
355
+ name: "run_program",
356
+ description: "Execute an agent-authored brepjs program in an isolated sandbox and return the verification report (validity, measurements, topology). Use this to build a part and check it in one step.",
357
+ inputSchema: RUN_PROGRAM_INPUT_SCHEMA
358
+ }, {
359
+ name: "export_part",
360
+ description: "Build a brepjs part in the sandbox and export it to a directory (STEP/GLB/STL). Use this to hand off the final artifact once a part verifies.",
361
+ inputSchema: EXPORT_PART_INPUT_SCHEMA
362
+ }] }));
363
+ server.setRequestHandler(_modelcontextprotocol_sdk_types_js.CallToolRequestSchema, async (req) => {
364
+ if (req.params.name === "run_program") {
365
+ const a = req.params.arguments ?? {};
366
+ const code = typeof a["code"] === "string" ? a["code"] : "";
367
+ const timeoutMs = typeof a["timeoutMs"] === "number" && a["timeoutMs"] > 0 ? a["timeoutMs"] : void 0;
368
+ return runProgramTool({
369
+ code,
370
+ ...timeoutMs !== void 0 ? { timeoutMs } : {}
371
+ });
372
+ }
373
+ if (req.params.name === "export_part") {
374
+ const a = req.params.arguments ?? {};
375
+ const code = typeof a["code"] === "string" ? a["code"] : "";
376
+ const outDir = typeof a["outDir"] === "string" ? a["outDir"] : "";
377
+ const timeoutMs = typeof a["timeoutMs"] === "number" && a["timeoutMs"] > 0 ? a["timeoutMs"] : void 0;
378
+ const f = typeof a["formats"] === "object" && a["formats"] !== null ? a["formats"] : void 0;
379
+ const formats = f && (f["step"] === true || f["glb"] === true || f["stl"] === true) ? {
380
+ ...f["step"] === true ? { step: true } : {},
381
+ ...f["glb"] === true ? { glb: true } : {},
382
+ ...f["stl"] === true ? { stl: true } : {}
383
+ } : void 0;
384
+ return exportPartTool({
385
+ code,
386
+ outDir,
387
+ ...formats !== void 0 ? { formats } : {},
388
+ ...timeoutMs !== void 0 ? { timeoutMs } : {}
389
+ });
390
+ }
391
+ throw new Error(`Unknown tool: ${req.params.name}`);
392
+ });
393
+ async function main() {
394
+ await server.connect(new _modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport());
395
+ }
396
+ main().catch((err) => {
397
+ console.error("brepjs-verify MCP server failed to start:", err);
398
+ process.exit(1);
399
+ });
400
+ //#endregion
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * brepjs-verify MCP server (stdio).
4
+ *
5
+ * Exposes the verify substrate to MCP-capable agents. The first tool, `run_program`, executes an
6
+ * agent-authored brepjs program in the sandbox and returns the verification report — the closed
7
+ * "build → verify" step the agent loop is built on. Uses the SDK's low-level `Server` with plain
8
+ * JSON-Schema tool definitions (no direct zod dependency in this package).
9
+ */
10
+ export {};