sandboxedjs 0.1.89 → 0.1.91
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/index.cjs +132 -30
- package/dist/index.js +132 -30
- package/package.json +3 -1
- package/dist/agent.cjs.map +0 -1
- package/dist/agent.js.map +0 -1
- package/dist/browser-host.cjs.map +0 -1
- package/dist/browser-host.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/python/wheels/MarkupSafe-3.0.2-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/MarkupSafe-3.0.3-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/PyYAML-6.0.2-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/PyYAML-6.0.3-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/aiohttp-3.14.3-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/cffi-2.1.1-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/httptools-0.8.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/index.json +0 -485
- package/dist/python/wheels/msgpack-1.1.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/numpy-2.2.6-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/pydantic_core-2.23.2-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/pydantic_core-2.46.5-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/pydantic_core-2.49.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_c_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_cython_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_meson_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_native_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_patched_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_pep517_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_rust_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_setuptools_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/sbx_yaml_probe-1.0.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/siphash24-1.9-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/xxhash-4.0.1-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python/wheels/zstandard-0.25.0-cp313-cp313-emscripten_5_0_6_wasm32.whl +0 -0
- package/dist/python-abi.cjs.map +0 -1
- package/dist/python-abi.js.map +0 -1
- package/dist/python-worker.js.map +0 -1
- package/dist/rolldown-wasi-worker.js.map +0 -1
- package/dist/service-worker.js.map +0 -1
- package/dist/worker-entry.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sandboxedjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.91",
|
|
4
4
|
"description": "A Linux-like container that runs entirely inside Node.js — POSIX shell, ~140 coreutils, Node.js and Python runtimes, virtual filesystem and networking. No Docker, no VM, no native modules.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
},
|
|
43
43
|
"files": [
|
|
44
44
|
"dist",
|
|
45
|
+
"!dist/python/wheels",
|
|
46
|
+
"!dist/**/*.map",
|
|
45
47
|
"bin",
|
|
46
48
|
"README.md",
|
|
47
49
|
"LICENSE"
|
package/dist/agent.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent/backend.ts","../src/agent/prompts.ts"],"names":[],"mappings":";;;AAmCA,IAAM,iBAAA,uBAAwB,GAAA,CAAI;AAAA,EAChC,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,IAAA;AAAA,EAAM,KAAA;AAAA,EACvE,MAAA;AAAA,EAAQ,IAAA;AAAA,EAAM,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACpE,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,IAAA;AAAA,EAAM;AACpC,CAAC,CAAA;AAED,IAAM,iBAAA,GAA4C;AAAA,EAChD,GAAA,EAAK,WAAA;AAAA,EAAa,GAAA,EAAK,YAAA;AAAA,EAAc,IAAA,EAAM,YAAA;AAAA,EAAc,GAAA,EAAK,WAAA;AAAA,EAC9D,IAAA,EAAM,YAAA;AAAA,EAAc,GAAA,EAAK,eAAA;AAAA,EAAiB,GAAA,EAAK,iBAAA;AAAA,EAC/C,IAAA,EAAM,kBAAA;AAAA,EAAoB,EAAA,EAAI,iBAAA;AAAA,EAAmB,EAAA,EAAI,mBAAA;AAAA,EACrD,IAAA,EAAM,WAAA;AAAA,EAAa,GAAA,EAAK,UAAA;AAAA,EAAY,EAAA,EAAI,eAAA;AAAA,EAAiB,IAAA,EAAM;AACjE,CAAA;AAEA,SAAS,YAAY,QAAA,EAA0B;AAC7C,EAAA,MAAM,OAAO,QAAA,CAAS,KAAA,CAAM,SAAS,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AACzD,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAChC,EAAA,OAAO,GAAA,GAAM,IAAI,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAA,CAAE,aAAY,GAAI,EAAA;AACvD;AAOA,SAAS,aAAa,OAAA,EAAyB;AAC7C,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,KAAK,CAAA,EAAG;AAC1C,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA;AACpB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAC1B,QAAA,CAAA,IAAK,CAAA;AACL,QAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAC1B,UAAA,CAAA,IAAK,CAAA;AACL,UAAA,GAAA,IAAO,UAAA;AAAA,QACT,CAAA,MAAO;AACL,UAAA,GAAA,IAAO,IAAA;AAAA,QACT;AAAA,MACF,CAAA,MAAO;AACL,QAAA,GAAA,IAAO,OAAA;AAAA,MACT;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,GAAA,EAAK;AACrB,MAAA,GAAA,IAAO,MAAA;AAAA,IACT,CAAA,MAAO;AACL,MAAA,GAAA,IAAO,EAAA,CAAG,OAAA,CAAQ,mBAAA,EAAqB,MAAM,CAAA;AAAA,IAC/C;AAAA,EACF;AACA,EAAA,OAAO,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,CAAG,CAAA;AAC9B;AAEA,SAAS,QAAA,CAAS,MAAc,IAAA,EAAsB;AACpD,EAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAChE;AAGA,SAAS,gBAAgB,QAAA,EAAiC;AACxD,EAAA,OAAO,SAAS,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,0BAA0B,QAAQ,CAAA,CAAA;AAC7E;AAEA,SAAS,aAAa,KAAA,EAAwB;AAC5C,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D;AAEA,SAAS,WAAA,CAAY,MAAkB,QAAA,EAA2B;AAChE,EAAA,IAAI,kBAAkB,GAAA,CAAI,WAAA,CAAY,QAAQ,CAAC,GAAG,OAAO,IAAA;AACzD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,IAAI,CAAA;AACpC,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,EAAQ,IAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AAClD,EAAA,OAAO,KAAA;AACT;AAqBO,IAAM,qBAAN,MAA6D;AAAA,EAUlE,WAAA,CACW,SAAA,EACT,OAAA,GAAqC,EAAC,EACtC;AAFS,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAGT,IAAA,IAAA,CAAK,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,YAAA,EAAe,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AAC9E,IAAA,IAAA,CAAK,MAAM,OAAA,CAAQ,GAAA;AACnB,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA;AACtC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAChD,IAAA,IAAA,CAAK,gBAAA,GAAmB,QAAQ,gBAAA,IAAoB,GAAA;AACpD,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAChD,IAAA,IAAA,CAAK,mBAAA,GAAsB,QAAQ,mBAAA,IAAuB,GAAA;AAAA,EAC5D;AAAA,EAVW,SAAA;AAAA,EAVF,EAAA;AAAA,EAEQ,GAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,mBAAA;AAAA,EAejB,MAAM,QAAQ,OAAA,EAA2C;AACvD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,OAAA,EAAS;AAAA,QAChD,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,WAAW,IAAA,CAAK;AAAA,OACjB,CAAA;AACD,MAAA,IAAI,SAAS,MAAA,CAAO,MAAA;AACpB,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,IAAI,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,cAAA,EAAgB;AAEvC,QAAA,MAAA,GAAS,CAAA,8BAAA,EAAiC,KAAK,cAAc,CAAA;AAAA,EAAiB,MAAA,CAAO,KAAA,CAAM,CAAC,IAAA,CAAK,cAAc,CAAC,CAAA,CAAA;AAChH,QAAA,SAAA,GAAY,IAAA;AAAA,MACd;AACA,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,MAAA,IAAU;AAAA,yBAAA,EAA8B,KAAK,SAAS,CAAA,GAAA,CAAA;AAAA,MACxD;AACA,MAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAA,CAAO,UAAU,SAAA,EAAU;AAAA,IACxD,SAAS,KAAA,EAAO;AAGd,MAAA,OAAO,EAAE,QAAQ,YAAA,CAAa,KAAK,GAAG,QAAA,EAAU,CAAA,EAAG,WAAW,KAAA,EAAM;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,GAAG,IAAA,EAAiC;AACxC,IAAA,MAAM,OAAA,GAAU,gBAAgB,IAAI,CAAA;AACpC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,QAAQ,IAAI,CAAA;AACpD,MAAA,MAAM,QAAoB,EAAC;AAC3B,MAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAChC,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,KAAK,IAAI,CAAA;AAC/C,UAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY;AAChC,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,IAAA,EAAM,KAAA,GAAQ,CAAA,EAAG,IAAI,CAAA,CAAA,CAAA,GAAM,IAAA;AAAA,YAC3B,MAAA,EAAQ,KAAA;AAAA,YACR,IAAA,EAAM,KAAA,GAAQ,KAAA,CAAA,GAAY,KAAA,CAAM,IAAA;AAAA,YAChC,aAAa,IAAI,IAAA,CAAK,KAAA,CAAM,OAAO,EAAE,WAAA;AAAY,WAClD,CAAA;AAAA,QACH,CAAA,CAAA,MAAQ;AAEN,UAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,QAC3B;AAAA,MACF;AACA,MAAA,OAAO,EAAE,KAAA,EAAM;AAAA,IACjB,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,MAAA,GAAS,GAAG,KAAA,EAAqC;AAC5E,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AACrD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,WAAA,CAAY,QAAQ,CAAC,CAAA;AACxD,MAAA,IAAI,WAAA,CAAY,GAAA,EAAK,QAAQ,CAAA,EAAG;AAC9B,QAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,QAAA,EAAU,YAAY,0BAAA,EAA2B;AAAA,MAC1E;AACA,MAAA,MAAM,IAAA,GAAO,IAAI,WAAA,EAAY,CAAE,OAAO,GAAG,CAAA;AACzC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE7B,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA,KAAM,EAAA,EAAI,KAAA,CAAM,GAAA,EAAI;AAClE,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA;AAChC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,CAAI,KAAA,CAAM,QAAQ,KAAA,IAAS,KAAA,IAAS,KAAK,gBAAA,CAAiB,CAAA;AAC3E,MAAA,OAAO;AAAA,QACL,SAAS,KAAA,CAAM,KAAA,CAAM,OAAO,GAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,QAC1C,UAAU,QAAA,IAAY,YAAA;AAAA,QACtB,YAAY,KAAA,CAAM,MAAA;AAAA,QAClB,SAAA,EAAW,KAAA;AAAA,QACX,OAAA,EAAS,GAAA;AAAA,QACT,UAAA,EAAY,GAAA,GAAM,KAAA,CAAM,MAAA,GAAS,GAAA,GAAM,KAAA;AAAA,OACzC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,QAAA,EAA0C;AACtD,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AACrD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,WAAA,CAAY,QAAQ,CAAC,CAAA;AACxD,MAAA,IAAI,WAAA,CAAY,GAAA,EAAK,QAAQ,CAAA,EAAG;AAC9B,QAAA,OAAO,EAAE,MAAM,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,QAAA,IAAY,4BAA2B,EAAE;AAAA,MACpF;AACA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,GAAG,CAAA,EAAG,QAAA,EAAU,QAAA,IAAY,YAAA;AAAa,OACrF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CAAM,QAAA,EAAkB,OAAA,EAAuC;AACnE,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,SAAS,KAAA,CAAM,CAAA,EAAG,SAAS,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,GAAA;AAC/D,MAAA,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,KAAA,CAAM,QAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACzD,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,MAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CACJ,QAAA,EACA,SAAA,EACA,SAAA,EACA,aAAa,KAAA,EACQ;AACrB,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,QAAA,CAAS,UAAU,MAAM,CAAA;AAC9D,MAAA,MAAM,WAAA,GAAc,cAAc,EAAA,GAAK,CAAA,GAAI,KAAK,KAAA,CAAM,SAAS,EAAE,MAAA,GAAS,CAAA;AAC1E,MAAA,IAAI,gBAAgB,CAAA,EAAG;AACrB,QAAA,OAAO,EAAE,OAAO,CAAA,oBAAA,EAAuB,QAAQ,KAAK,IAAA,CAAK,SAAA,CAAU,SAAS,CAAC,CAAA,CAAA,EAAG;AAAA,MAClF;AACA,MAAA,IAAI,WAAA,GAAc,CAAA,IAAK,CAAC,UAAA,EAAY;AAClC,QAAA,OAAO;AAAA,UACL,KAAA,EACE,CAAA,eAAA,EAAkB,WAAW,CAAA,UAAA,EAAa,QAAQ,CAAA,yEAAA;AAAA,SAEtD;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,UAAA,GACZ,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,CAAE,IAAA,CAAK,SAAS,CAAA,GACpC,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AACrC,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAY;AAAA,IACvC,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAAA,EAAyC;AACpD,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,EAAA,CAAG,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,CAAA;AACtE,MAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAO,GAAA,EAA0B;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,UAAA,CAAW,GAAG,IAAI,OAAA,GAAU,QAAA,CAAS,IAAA,EAAM,OAAO,CAAC,CAAA;AACxF,MAAA,MAAM,QAAoB,EAAC;AAC3B,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,KAAA,MAAW,aAAa,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,EAAG;AAC1D,QAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA,EAAG;AAC9B,QAAA,IAAI,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,cAAA,EAAgB;AACvC,UAAA,SAAA,GAAY,IAAA;AACZ,UAAA;AAAA,QACF;AACA,QAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAAA,MAChC;AACA,MAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAAA,IAC5B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CACJ,OAAA,EACA,IAAA,EACA,MACA,QAAA,EACqB;AACrB,IAAA,MAAM,OAAO,IAAA,IAAQ,GAAA;AACrB,IAAA,MAAM,GAAA,GAAM,YAAY,IAAA,CAAK,mBAAA;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,GACX,YAAA,CAAa,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,CAAA,GACrD,IAAA;AACJ,MAAA,MAAM,UAAuB,EAAC;AAC9B,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,KAAA,EAAO,KAAA,MAAW,aAAa,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,EAAG;AACjE,QAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AACvC,QAAA,IAAI,GAAA;AACJ,QAAA,IAAI;AACF,UAAA,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,SAAS,CAAA;AAAA,QAClD,CAAA,CAAA,MAAQ;AACN,UAAA;AAAA,QACF;AACA,QAAA,IAAI,WAAA,CAAY,GAAA,EAAK,SAAS,CAAA,EAAG;AACjC,QAAA,MAAM,KAAA,GAAQ,IAAI,WAAA,EAAY,CAAE,OAAO,GAAG,CAAA,CAAE,MAAM,IAAI,CAAA;AACtD,QAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA,EAAG;AACxC,UAAA,IAAI,CAAC,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG;AACjC,UAAA,IAAI,OAAA,CAAQ,UAAU,GAAA,EAAK;AACzB,YAAA,SAAA,GAAY,IAAA;AACZ,YAAA,MAAM,KAAA;AAAA,UACR;AACA,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA,GAAI,CAAA,EAAG,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA;AAAA,QAC/D;AAAA,MACF;AACA,MAAA,OAAO,EAAE,SAAS,SAAA,EAAU;AAAA,IAC9B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,KAAA,EAAmE;AACnF,IAAA,MAAM,UAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,OAAO,CAAA,IAAK,KAAA,EAAO;AACvC,MAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,gBAAgB,CAAA;AACtD,QAAA;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,SAAS,KAAA,CAAM,CAAA,EAAG,SAAS,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,GAAA;AAC/D,QAAA,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,KAAA,CAAM,QAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACzD,QAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,MAAM,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AACN,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,qBAAqB,CAAA;AAAA,MAC7D;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,KAAA,EAAkD;AACpE,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,YAAY,KAAA,EAAO;AAC5B,MAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,gBAAgB,CAAA;AACrE,QAAA;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,KAAK,QAAQ,CAAA;AACnD,QAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,gBAAgB,CAAA;AACrE,UAAA;AAAA,QACF;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,SAAS,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AAAA,UAClD,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH,CAAA,CAAA,MAAQ;AACN,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,kBAAkB,CAAA;AAAA,MACzE;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;;;ACrYO,IAAM,0BAAA,GAA6B,CAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA,oEAAA;AA4DnC,IAAM,mBAAA,GAAsB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAA;AAyCnC,SAAS,KAAA,CAAM,IAAA,EAAc,WAAA,EAAqB,IAAA,EAA4B;AAC5E,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA,EAAS,CAAA;AAAA,MAAA,EAAc,IAAI;AAAA,aAAA,EAAkB,WAAW;AAAA;;AAAA,EAAY,IAAI;AAAA;AAAA,GAC1E;AACF;AASO,IAAM,cAAA,GAAiC;AAAA,EAC5C,KAAA;AAAA,IACE,cAAA;AAAA,IACA,6GAAA;AAAA,IACA,CAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,mEAAA;AAAA,GA8CF;AAAA,EACA,KAAA;AAAA,IACE,cAAA;AAAA,IACA,oHAAA;AAAA,IACA,CAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,iEAAA;AAAA,GAiDF;AAAA,EACA,KAAA;AAAA,IACE,aAAA;AAAA,IACA,mGAAA;AAAA,IACA,CAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,6BAAA;AAAA,GAaF;AAAA,EACA,KAAA;AAAA,IACE,eAAA;AAAA,IACA,sGAAA;AAAA,IACA,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wEAAA;AAAA;AAcJ;AAMO,SAAS,mBAAA,CACd,OAAA,GAAgC,EAAC,EACzB;AACR,EAAA,MAAM,KAAA,GAAQ,CAAC,0BAAA,EAA4B,mBAAmB,CAAA;AAC9D,EAAA,IAAI,OAAA,CAAQ,WAAW,KAAA,EAAO;AAC5B,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,CAAA;;AAAA,EAAe,cAAA,CAAe,GAAA;AAAA,QAC5B,CAAC,KAAA,KAAU,CAAA,GAAA,EAAM,KAAA,CAAM,IAAI;;AAAA,EAAO,MAAM,WAAW;;AAAA,EAAO,KAAA,CAAM,QAAQ,KAAA,CAAM,OAAO,EAAE,CAAC,CAAA,CAAE,MAAM,CAAA;AAAA,OAClG,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,KAChB;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAC1B;AASA,eAAsB,oBAAA,CACpB,SAAA,EACA,SAAA,GAAY,SAAA,EACK;AACjB,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,MAAM,IAAI,CAAA,CAAA;AACtC,IAAA,MAAM,UAAU,EAAA,CAAG,KAAA,CAAM,KAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACjD,IAAA,MAAM,UAAU,EAAA,CAAG,SAAA,CAAU,GAAG,GAAG,CAAA,SAAA,CAAA,EAAa,MAAM,OAAO,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,SAAA;AACT","file":"agent.cjs","sourcesContent":["import type { Container } from \"../container/container.js\";\nimport type {\n DeleteResult,\n EditResult,\n ExecuteResponse,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GlobResult,\n GrepMatch,\n GrepResult,\n LsResult,\n ReadRawResult,\n ReadResult,\n SandboxBackendProtocolV2,\n WriteResult,\n} from \"./protocol.js\";\n\nexport interface SandboxedJsBackendOptions {\n /** Identity reported to Deep Agents. Defaults to a random per-instance id. */\n id?: string;\n /** Working directory every `execute` starts in. Defaults to the container's. */\n cwd?: string;\n /** Wall-clock limit for a single `execute`. Default 120_000ms. */\n timeoutMs?: number;\n /** Characters of combined output kept per command before truncating. Default 30_000. */\n maxOutputChars?: number;\n /** Default line window for `read`. Default 500. */\n defaultReadLimit?: number;\n /** Cap on entries returned by `glob`. Default 1_000. */\n maxGlobResults?: number;\n /** Cap on matches returned by `grep` when the caller gives no `maxCount`. Default 200. */\n defaultGrepMaxCount?: number;\n}\n\nconst BINARY_EXTENSIONS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"ico\", \"bmp\", \"pdf\", \"zip\", \"gz\", \"tar\",\n \"wasm\", \"so\", \"dylib\", \"dll\", \"exe\", \"woff\", \"woff2\", \"ttf\", \"otf\", \"mp3\",\n \"mp4\", \"mov\", \"avi\", \"bin\", \"db\", \"sqlite\",\n]);\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n png: \"image/png\", jpg: \"image/jpeg\", jpeg: \"image/jpeg\", gif: \"image/gif\",\n webp: \"image/webp\", svg: \"image/svg+xml\", pdf: \"application/pdf\",\n json: \"application/json\", js: \"text/javascript\", ts: \"text/x-typescript\",\n html: \"text/html\", css: \"text/css\", md: \"text/markdown\", wasm: \"application/wasm\",\n};\n\nfunction extensionOf(filePath: string): string {\n const base = filePath.slice(filePath.lastIndexOf(\"/\") + 1);\n const dot = base.lastIndexOf(\".\");\n return dot > 0 ? base.slice(dot + 1).toLowerCase() : \"\";\n}\n\n/**\n * `**` crosses `/`, `*` and `?` do not, and a leading `**\\/` also matches\n * depth zero — the same subset of glob semantics Deep Agents' own backends\n * document for their `glob` tool.\n */\nfunction globToRegExp(pattern: string): RegExp {\n let out = \"\";\n for (let i = 0; i < pattern.length; i += 1) {\n const ch = pattern[i];\n if (ch === \"*\") {\n if (pattern[i + 1] === \"*\") {\n i += 1;\n if (pattern[i + 1] === \"/\") {\n i += 1;\n out += \"(?:.*/)?\";\n } else {\n out += \".*\";\n }\n } else {\n out += \"[^/]*\";\n }\n } else if (ch === \"?\") {\n out += \"[^/]\";\n } else {\n out += ch.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n }\n return new RegExp(`^${out}$`);\n}\n\nfunction joinPath(base: string, name: string): string {\n return base.endsWith(\"/\") ? `${base}${name}` : `${base}/${name}`;\n}\n\n/** Deep Agents' file tools take absolute paths; a relative one is a caller bug. */\nfunction requireAbsolute(filePath: string): string | null {\n return filePath.startsWith(\"/\") ? null : `Path must be absolute: ${filePath}`;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction looksBinary(data: Uint8Array, filePath: string): boolean {\n if (BINARY_EXTENSIONS.has(extensionOf(filePath))) return true;\n const window = data.subarray(0, 1024);\n for (const byte of window) if (byte === 0) return true;\n return false;\n}\n\n/**\n * A sandboxedjs {@link Container} behind the LangChain Deep Agents backend\n * contract.\n *\n * Deep Agents' `BaseSandbox` derives its filesystem tools from `execute` by\n * shelling out to `find`, `stat`, `awk` and `grep`. This backend answers them\n * from {@link Container.fs} instead: the container's filesystem is an in-process\n * object, so going through the shell would only add parsing and quoting bugs\n * between the agent and data already in memory. `execute` still runs the real\n * POSIX shell, so agent-authored commands behave the way the agent expects.\n *\n * ```ts\n * const box = await createContainer({ cwd: \"/app\", network: { allowOutbound: true } });\n * const agent = createDeepAgent({ model, backend: new SandboxedJsBackend(box) });\n * ```\n *\n * The instance holds the container but does not own it: call\n * {@link Container.dispose} yourself when the run is over.\n */\nexport class SandboxedJsBackend implements SandboxBackendProtocolV2 {\n readonly id: string;\n\n private readonly cwd: string | undefined;\n private readonly timeoutMs: number;\n private readonly maxOutputChars: number;\n private readonly defaultReadLimit: number;\n private readonly maxGlobResults: number;\n private readonly defaultGrepMaxCount: number;\n\n constructor(\n readonly container: Container,\n options: SandboxedJsBackendOptions = {},\n ) {\n this.id = options.id ?? `sandboxedjs-${Math.random().toString(36).slice(2, 10)}`;\n this.cwd = options.cwd;\n this.timeoutMs = options.timeoutMs ?? 120_000;\n this.maxOutputChars = options.maxOutputChars ?? 30_000;\n this.defaultReadLimit = options.defaultReadLimit ?? 500;\n this.maxGlobResults = options.maxGlobResults ?? 1_000;\n this.defaultGrepMaxCount = options.defaultGrepMaxCount ?? 200;\n }\n\n async execute(command: string): Promise<ExecuteResponse> {\n try {\n const result = await this.container.exec(command, {\n cwd: this.cwd,\n timeoutMs: this.timeoutMs,\n });\n let output = result.output;\n let truncated = false;\n if (output.length > this.maxOutputChars) {\n /* Keep the tail: a failing command's diagnosis is at the end. */\n output = `[output truncated to the last ${this.maxOutputChars} characters]\\n${output.slice(-this.maxOutputChars)}`;\n truncated = true;\n }\n if (result.timedOut) {\n output += `\\n[command timed out after ${this.timeoutMs}ms]`;\n }\n return { output, exitCode: result.exitCode, truncated };\n } catch (error) {\n /* A container-level failure is still a tool result: the agent has to be\n * able to read what went wrong and try something else. */\n return { output: errorMessage(error), exitCode: 1, truncated: false };\n }\n }\n\n async ls(path: string): Promise<LsResult> {\n const invalid = requireAbsolute(path);\n if (invalid) return { error: invalid };\n try {\n const entries = await this.container.fs.readdir(path);\n const files: FileInfo[] = [];\n for (const name of entries) {\n const full = joinPath(path, name);\n try {\n const stats = await this.container.fs.stat(full);\n const isDir = stats.isDirectory();\n files.push({\n path: isDir ? `${full}/` : full,\n is_dir: isDir,\n size: isDir ? undefined : stats.size,\n modified_at: new Date(stats.mtimeMs).toISOString(),\n });\n } catch {\n /* A dangling symlink still belongs in the listing. */\n files.push({ path: full });\n }\n }\n return { files };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async read(filePath: string, offset = 0, limit?: number): Promise<ReadResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const raw = await this.container.fs.readFile(filePath);\n const mimeType = MIME_BY_EXTENSION[extensionOf(filePath)];\n if (looksBinary(raw, filePath)) {\n return { content: raw, mimeType: mimeType ?? \"application/octet-stream\" };\n }\n const text = new TextDecoder().decode(raw);\n const lines = text.split(\"\\n\");\n /* A trailing newline yields a final empty element that is not a line. */\n if (lines.length > 1 && lines[lines.length - 1] === \"\") lines.pop();\n const start = Math.max(0, offset);\n const end = Math.min(lines.length, start + (limit ?? this.defaultReadLimit));\n return {\n content: lines.slice(start, end).join(\"\\n\"),\n mimeType: mimeType ?? \"text/plain\",\n totalLines: lines.length,\n startLine: start,\n endLine: end,\n nextOffset: end < lines.length ? end : undefined,\n };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async readRaw(filePath: string): Promise<ReadRawResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const raw = await this.container.fs.readFile(filePath);\n const mimeType = MIME_BY_EXTENSION[extensionOf(filePath)];\n if (looksBinary(raw, filePath)) {\n return { data: { content: raw, mimeType: mimeType ?? \"application/octet-stream\" } };\n }\n return {\n data: { content: new TextDecoder().decode(raw), mimeType: mimeType ?? \"text/plain\" },\n };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async write(filePath: string, content: string): Promise<WriteResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const parent = filePath.slice(0, filePath.lastIndexOf(\"/\")) || \"/\";\n await this.container.fs.mkdir(parent, { recursive: true });\n await this.container.fs.writeFile(filePath, content);\n return { path: filePath };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n ): Promise<EditResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const text = await this.container.fs.readFile(filePath, \"utf8\");\n const occurrences = oldString === \"\" ? 0 : text.split(oldString).length - 1;\n if (occurrences === 0) {\n return { error: `String not found in ${filePath}: ${JSON.stringify(oldString)}` };\n }\n if (occurrences > 1 && !replaceAll) {\n return {\n error:\n `String appears ${occurrences} times in ${filePath}. ` +\n `Provide more surrounding context to make it unique, or pass replaceAll.`,\n };\n }\n const updated = replaceAll\n ? text.split(oldString).join(newString)\n : text.replace(oldString, newString);\n await this.container.fs.writeFile(filePath, updated);\n return { path: filePath, occurrences };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async delete(filePath: string): Promise<DeleteResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n await this.container.fs.rm(filePath, { recursive: true, force: false });\n return { path: filePath };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async glob(pattern: string, path = \"/\"): Promise<GlobResult> {\n try {\n const matcher = globToRegExp(pattern.startsWith(\"/\") ? pattern : joinPath(path, pattern));\n const files: FileInfo[] = [];\n let truncated = false;\n for (const candidate of await this.container.fs.walk(path)) {\n if (!matcher.test(candidate)) continue;\n if (files.length >= this.maxGlobResults) {\n truncated = true;\n break;\n }\n files.push({ path: candidate });\n }\n return { files, truncated };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async grep(\n pattern: string,\n path?: string | null,\n glob?: string | null,\n maxCount?: number | null,\n ): Promise<GrepResult> {\n const root = path ?? \"/\";\n const cap = maxCount ?? this.defaultGrepMaxCount;\n try {\n const filter = glob\n ? globToRegExp(glob.includes(\"/\") ? glob : `**/${glob}`)\n : null;\n const matches: GrepMatch[] = [];\n let truncated = false;\n outer: for (const candidate of await this.container.fs.walk(root)) {\n if (filter && !filter.test(candidate)) continue;\n let raw: Uint8Array;\n try {\n raw = await this.container.fs.readFile(candidate);\n } catch {\n continue; /* Directories and unreadable entries are not grep targets. */\n }\n if (looksBinary(raw, candidate)) continue;\n const lines = new TextDecoder().decode(raw).split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n if (!lines[i].includes(pattern)) continue;\n if (matches.length >= cap) {\n truncated = true;\n break outer;\n }\n matches.push({ path: candidate, line: i + 1, text: lines[i] });\n }\n }\n return { matches, truncated };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async uploadFiles(files: Array<[string, Uint8Array]>): Promise<FileUploadResponse[]> {\n const results: FileUploadResponse[] = [];\n for (const [filePath, content] of files) {\n if (!filePath.startsWith(\"/\")) {\n results.push({ path: filePath, error: \"invalid_path\" });\n continue;\n }\n try {\n const parent = filePath.slice(0, filePath.lastIndexOf(\"/\")) || \"/\";\n await this.container.fs.mkdir(parent, { recursive: true });\n await this.container.fs.writeFile(filePath, content);\n results.push({ path: filePath, error: null });\n } catch {\n results.push({ path: filePath, error: \"permission_denied\" });\n }\n }\n return results;\n }\n\n async downloadFiles(paths: string[]): Promise<FileDownloadResponse[]> {\n const results: FileDownloadResponse[] = [];\n for (const filePath of paths) {\n if (!filePath.startsWith(\"/\")) {\n results.push({ path: filePath, content: null, error: \"invalid_path\" });\n continue;\n }\n try {\n const stats = await this.container.fs.stat(filePath);\n if (stats.isDirectory()) {\n results.push({ path: filePath, content: null, error: \"is_directory\" });\n continue;\n }\n results.push({\n path: filePath,\n content: await this.container.fs.readFile(filePath),\n error: null,\n });\n } catch {\n results.push({ path: filePath, content: null, error: \"file_not_found\" });\n }\n }\n return results;\n }\n}\n","import type { Container } from \"../container/container.js\";\n\n/**\n * What the agent's environment actually is.\n *\n * Every claim here is a behaviour this package implements. Coding agents fail\n * in a sandbox mostly by assuming a host they do not have — reaching for\n * `docker`, `sudo`, `systemctl`, `curl localhost:3000`, or a background process\n * that outlives the turn. Saying plainly what exists is what stops that.\n */\nexport const SANDBOX_ENVIRONMENT_PROMPT = `# Your environment\n\nYou are working inside a sandboxedjs container: a Linux-like environment that\nruns entirely inside a JavaScript process. There is no Docker, no VM, and no\nhost machine you can reach. Everything below is real and available to you.\n\n## What you have\n\n- A POSIX shell (\\`sh\\`/\\`bash\\` syntax): pipes, redirection, \\`&&\\`, \\`||\\`,\n subshells, globs, heredocs, variables, functions, \\`for\\`/\\`while\\`/\\`case\\`.\n- Around 140 coreutils: \\`ls cat cp mv rm mkdir find grep sed awk head tail\n sort uniq wc diff patch tar gzip curl chmod ln touch echo printf test\\` and\n the rest of the usual set.\n- Node.js, with \\`node\\`, \\`npm\\` and \\`npx\\`. \\`npm install\\` resolves against\n the real npm registry when outbound network is enabled.\n- Python 3 via \\`python3\\` and \\`pip\\`, when the host enabled the Python runtime.\n- A writable virtual filesystem rooted at \\`/\\`, persistent for the life of the\n container.\n- A virtual network stack. Servers you start inside the container really listen\n on their ports and can really be requested.\n\n## What you do not have\n\n- No Docker, no VM, no \\`systemctl\\`, no \\`service\\`, no \\`apt\\`/\\`apt-get\\`,\n no \\`yum\\`, no \\`brew\\`. Never try to install system packages.\n- No \\`sudo\\` and no reason for it: you already run as the container's user and\n the filesystem is yours.\n- No access to the host machine, its files, its network interfaces, or its\n environment variables. Nothing outside the container exists for you.\n- No GUI, no browser, no interactive editors. Do not run \\`vim\\`, \\`nano\\`,\n \\`less\\`, or \\`top\\`; they will hang or fail. Read files by reading them and\n edit them by editing them.\n- No long-running foreground commands. A command that never exits will hit the\n execution timeout and the turn is wasted.\n\n## Running servers\n\nStart servers in the background and never block on them:\n\n\\`\\`\\`sh\nnode server.js > /tmp/server.log 2>&1 &\n\\`\\`\\`\n\nThen poll the log for readiness rather than requesting the port immediately.\nDo not run a dev server in the foreground. Do not use \\`curl localhost:PORT\\`\nto prove a server works unless you started it in the background first — the\nhost, not you, is the one that will connect to it.\n\n## How your work is used\n\nThe container is the deliverable. Files you write to the filesystem are what\nthe user receives and what a preview will serve. Write real, complete files to\nreal paths — do not print a project to stdout and call it done.`;\n\n/**\n * Operating rules, in the register a coding harness uses.\n *\n * Deliberately about this environment rather than about coding in general: the\n * host's own system prompt owns the latter, and repeating it only dilutes both.\n */\nexport const SANDBOX_AGENT_RULES = `# Rules\n\n1. Verify before you claim. If you say a server runs or a build passes, you\n ran it in this container and read the output. Never report success you have\n not observed.\n2. One command, one purpose. Chain with \\`&&\\` when steps depend on each other\n so a failure stops the chain instead of hiding under a later success.\n3. Read a file before editing it. Edits are literal string replacements; they\n fail when you are guessing at the current contents.\n4. Use absolute paths in file tools. Use \\`cd\\` inside a single shell command\n when a command needs a working directory.\n5. Install dependencies with \\`npm install <pkg>\\`, in the directory that has\n the \\`package.json\\`. Do not hand-write \\`node_modules\\` or invent versions\n in \\`package.json\\` — let the installer resolve them.\n6. Background every server and long task, redirect its output to a log file,\n then poll the log. Never leave a command running in the foreground.\n7. Keep command output small. Pipe noisy commands through \\`tail\\`, \\`head\\`\n or \\`grep\\`. Output is truncated past the backend's limit and you will lose\n the part you needed.\n8. When a command fails, read stderr and fix the cause. Do not retry the same\n command unchanged, and do not work around a failure by faking its result.\n9. Prefer the project's own tooling — \\`npm run build\\`, \\`npm test\\`,\n \\`npx vite\\` — over reimplementing what it already does.\n10. Do not attempt to escape the container, reach the host, or disable the\n network policy. Outbound access is the host's decision, not yours.\n11. Prefer the non-interactive form of a command when one exists — pass the\n flags that pre-answer its questions. A generator that asks nothing is\n faster and its result is the same every run.\n12. An interactive prompt is not a failure. If a command stops on a question\n or a menu, answer it: send the text, or the arrow keys and Enter that the\n prompt names. Read what is on screen before answering, and do not send a\n second answer until the screen has changed.`;\n\n/** A Deep Agents skill: markdown with the frontmatter its loader parses. */\nexport interface SandboxSkill {\n name: string;\n description: string;\n /** Full file content, frontmatter included, ready to write to disk. */\n content: string;\n}\n\nfunction skill(name: string, description: string, body: string): SandboxSkill {\n return {\n name,\n description,\n content: `---\\nname: ${name}\\ndescription: ${description}\\n---\\n\\n${body}\\n`,\n };\n}\n\n/**\n * Skills covering the workflows that break first in a sandbox.\n *\n * Each is a procedure that has to be followed exactly once to work, and that a\n * model otherwise improvises differently every run — which is what makes an\n * agent look unstable when the container underneath is fine.\n */\nexport const SANDBOX_SKILLS: SandboxSkill[] = [\n skill(\n \"node-service\",\n \"Scaffold, install, run and verify a Node.js HTTP service (Express, Fastify, plain http) inside the sandbox.\",\n `# Building a Node HTTP service\n\nFollow these steps in order. Do not skip verification.\n\n1. Create the project directory and manifest:\n\n \\`\\`\\`sh\n mkdir -p /app && cd /app && npm init -y\n \\`\\`\\`\n\n2. Install dependencies in one command:\n\n \\`\\`\\`sh\n cd /app && npm install express\n \\`\\`\\`\n\n Read the output. If it ends in an \\`ENOTFOUND\\` or network error, outbound\n access is disabled for this container — say so and stop, rather than\n inventing a dependency-free rewrite the user did not ask for.\n\n3. Write the server to a real file. Bind to \\`0.0.0.0\\` and log a line on\n listen, so readiness is observable:\n\n \\`\\`\\`js\n const express = require(\"express\");\n const app = express();\n app.get(\"/\", (_req, res) => res.send(\"hello world\"));\n const port = Number(process.env.PORT) || 3000;\n app.listen(port, \"0.0.0.0\", () => console.log(\\`listening on \\${port}\\`));\n \\`\\`\\`\n\n4. Start it in the background and wait for the log line:\n\n \\`\\`\\`sh\n cd /app && node server.js > /tmp/server.log 2>&1 &\n sleep 1 && cat /tmp/server.log\n \\`\\`\\`\n\n5. Verify it answers:\n\n \\`\\`\\`sh\n curl -s -i http://127.0.0.1:3000/ | head -20\n \\`\\`\\`\n\n A non-2xx status or an empty response means the server is not working. Read\n \\`/tmp/server.log\\` and fix the cause before reporting anything.`,\n ),\n skill(\n \"frontend-app\",\n \"Create and run a Vite frontend (React, Vue, Svelte, vanilla) inside the sandbox without an interactive scaffolder.\",\n `# Building a frontend app\n\nA generator works here — the sandbox can answer its prompts — but writing the\nfiles yourself is faster and deterministic, and you control exactly what the\nproject contains. Prefer it unless the framework's initializer does real work\nyou would otherwise have to reproduce. If you do run one, answer its prompts.\n\n1. Write \\`/app/package.json\\`. Give the dependencies real version ranges and\n let the installer resolve them:\n\n \\`\\`\\`json\n {\n \"name\": \"app\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": { \"dev\": \"vite\", \"build\": \"vite build\", \"preview\": \"vite preview\" },\n \"dependencies\": { \"react\": \"^19.0.0\", \"react-dom\": \"^19.0.0\" },\n \"devDependencies\": { \"@vitejs/plugin-react\": \"^5.0.0\", \"vite\": \"^7.0.0\" }\n }\n \\`\\`\\`\n\n2. Write the four files a Vite app actually needs: \\`index.html\\` with\n \\`<div id=\"root\">\\` and a module script pointing at \\`/src/main.jsx\\`,\n \\`vite.config.js\\` registering the framework plugin, \\`src/main.jsx\\`\n mounting the root, and \\`src/App.jsx\\`.\n\n3. Install once, and read the output:\n\n \\`\\`\\`sh\n cd /app && npm install\n \\`\\`\\`\n\n4. Prove it compiles before claiming anything works:\n\n \\`\\`\\`sh\n cd /app && npm run build 2>&1 | tail -30\n \\`\\`\\`\n\n5. Only if a live preview is wanted, start the dev server in the background\n and confirm it came up:\n\n \\`\\`\\`sh\n cd /app && npx vite --host 0.0.0.0 --port 5173 > /tmp/vite.log 2>&1 &\n sleep 3 && tail -20 /tmp/vite.log\n \\`\\`\\`\n\nCheck the installed major versions before using an API from a package —\n\\`cat /app/node_modules/react/package.json\\`. A remembered API from a\ndifferent major is the most common cause of a build failure here.`,\n ),\n skill(\n \"verify-work\",\n \"Check that generated code actually builds, runs and passes its tests before reporting completion.\",\n `# Verifying before reporting\n\nNever report a task complete on the strength of having written files.\n\n- If the project has tests: \\`cd <dir> && npm test 2>&1 | tail -40\\`\n- If it has a build: \\`cd <dir> && npm run build 2>&1 | tail -40\\`\n- If it has neither and it is a script: run it and read the output.\n- If it is a service: start it in the background and request it (see the\n \\`node-service\\` skill).\n\nThen state what you ran and what it printed. If something fails and you cannot\nfix it, say exactly what fails and what you tried. A wrong claim of success is\nworse than an honest failure.`,\n ),\n skill(\n \"debug-failure\",\n \"Diagnose a failing command, build, install or server inside the sandbox instead of retrying blindly.\",\n `# Debugging inside the sandbox\n\n1. Re-read the actual error. The cause is usually the first error line, not\n the last.\n2. Confirm the state you assumed: \\`ls -la\\` the directory, \\`cat\\` the config,\n \\`cat package.json\\`. Most failures are a wrong path or a missing install.\n3. Check the log of anything backgrounded: \\`tail -50 /tmp/*.log\\`.\n4. For a module resolution error, verify the package is installed where you\n think: \\`ls /app/node_modules/<pkg>/package.json\\`.\n5. For a port that will not answer, check the process is alive (\\`ps\\`) and the\n log shows a listen line. A crashed server leaves no port behind.\n6. Change exactly one thing, then re-run. Do not retry an unchanged command,\n and do not delete the work to start over unless nothing else is left.`,\n ),\n];\n\n/**\n * The whole prompt in one string, for hosts that do not use Deep Agents' skills\n * middleware and just want to append it to a system prompt.\n */\nexport function sandboxSystemPrompt(\n options: { skills?: boolean } = {},\n): string {\n const parts = [SANDBOX_ENVIRONMENT_PROMPT, SANDBOX_AGENT_RULES];\n if (options.skills !== false) {\n parts.push(\n `# Skills\\n\\n${SANDBOX_SKILLS.map(\n (entry) => `## ${entry.name}\\n\\n${entry.description}\\n\\n${entry.content.split(\"---\\n\")[2].trim()}`,\n ).join(\"\\n\\n\")}`,\n );\n }\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Write the skills into the container as files, one directory each.\n *\n * This is the layout Deep Agents' skills middleware discovers: point its\n * `sources` at the same directory and it loads them itself, so the host does\n * not have to put any of this in its system prompt.\n */\nexport async function installSandboxSkills(\n container: Container,\n directory = \"/skills\",\n): Promise<string> {\n for (const entry of SANDBOX_SKILLS) {\n const dir = `${directory}/${entry.name}`;\n await container.fs.mkdir(dir, { recursive: true });\n await container.fs.writeFile(`${dir}/SKILL.md`, entry.content);\n }\n return directory;\n}\n"]}
|
package/dist/agent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent/backend.ts","../src/agent/prompts.ts"],"names":[],"mappings":";AAmCA,IAAM,iBAAA,uBAAwB,GAAA,CAAI;AAAA,EAChC,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,IAAA;AAAA,EAAM,KAAA;AAAA,EACvE,MAAA;AAAA,EAAQ,IAAA;AAAA,EAAM,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,MAAA;AAAA,EAAQ,OAAA;AAAA,EAAS,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EACpE,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,KAAA;AAAA,EAAO,IAAA;AAAA,EAAM;AACpC,CAAC,CAAA;AAED,IAAM,iBAAA,GAA4C;AAAA,EAChD,GAAA,EAAK,WAAA;AAAA,EAAa,GAAA,EAAK,YAAA;AAAA,EAAc,IAAA,EAAM,YAAA;AAAA,EAAc,GAAA,EAAK,WAAA;AAAA,EAC9D,IAAA,EAAM,YAAA;AAAA,EAAc,GAAA,EAAK,eAAA;AAAA,EAAiB,GAAA,EAAK,iBAAA;AAAA,EAC/C,IAAA,EAAM,kBAAA;AAAA,EAAoB,EAAA,EAAI,iBAAA;AAAA,EAAmB,EAAA,EAAI,mBAAA;AAAA,EACrD,IAAA,EAAM,WAAA;AAAA,EAAa,GAAA,EAAK,UAAA;AAAA,EAAY,EAAA,EAAI,eAAA;AAAA,EAAiB,IAAA,EAAM;AACjE,CAAA;AAEA,SAAS,YAAY,QAAA,EAA0B;AAC7C,EAAA,MAAM,OAAO,QAAA,CAAS,KAAA,CAAM,SAAS,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AACzD,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAChC,EAAA,OAAO,GAAA,GAAM,IAAI,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAA,CAAE,aAAY,GAAI,EAAA;AACvD;AAOA,SAAS,aAAa,OAAA,EAAyB;AAC7C,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,KAAK,CAAA,EAAG;AAC1C,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA;AACpB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAC1B,QAAA,CAAA,IAAK,CAAA;AACL,QAAA,IAAI,OAAA,CAAQ,CAAA,GAAI,CAAC,CAAA,KAAM,GAAA,EAAK;AAC1B,UAAA,CAAA,IAAK,CAAA;AACL,UAAA,GAAA,IAAO,UAAA;AAAA,QACT,CAAA,MAAO;AACL,UAAA,GAAA,IAAO,IAAA;AAAA,QACT;AAAA,MACF,CAAA,MAAO;AACL,QAAA,GAAA,IAAO,OAAA;AAAA,MACT;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,GAAA,EAAK;AACrB,MAAA,GAAA,IAAO,MAAA;AAAA,IACT,CAAA,MAAO;AACL,MAAA,GAAA,IAAO,EAAA,CAAG,OAAA,CAAQ,mBAAA,EAAqB,MAAM,CAAA;AAAA,IAC/C;AAAA,EACF;AACA,EAAA,OAAO,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,CAAG,CAAA;AAC9B;AAEA,SAAS,QAAA,CAAS,MAAc,IAAA,EAAsB;AACpD,EAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAA,GAAK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAChE;AAGA,SAAS,gBAAgB,QAAA,EAAiC;AACxD,EAAA,OAAO,SAAS,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,0BAA0B,QAAQ,CAAA,CAAA;AAC7E;AAEA,SAAS,aAAa,KAAA,EAAwB;AAC5C,EAAA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC9D;AAEA,SAAS,WAAA,CAAY,MAAkB,QAAA,EAA2B;AAChE,EAAA,IAAI,kBAAkB,GAAA,CAAI,WAAA,CAAY,QAAQ,CAAC,GAAG,OAAO,IAAA;AACzD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,IAAI,CAAA;AACpC,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,EAAQ,IAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AAClD,EAAA,OAAO,KAAA;AACT;AAqBO,IAAM,qBAAN,MAA6D;AAAA,EAUlE,WAAA,CACW,SAAA,EACT,OAAA,GAAqC,EAAC,EACtC;AAFS,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAGT,IAAA,IAAA,CAAK,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,YAAA,EAAe,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AAC9E,IAAA,IAAA,CAAK,MAAM,OAAA,CAAQ,GAAA;AACnB,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA;AACtC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAChD,IAAA,IAAA,CAAK,gBAAA,GAAmB,QAAQ,gBAAA,IAAoB,GAAA;AACpD,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAChD,IAAA,IAAA,CAAK,mBAAA,GAAsB,QAAQ,mBAAA,IAAuB,GAAA;AAAA,EAC5D;AAAA,EAVW,SAAA;AAAA,EAVF,EAAA;AAAA,EAEQ,GAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,mBAAA;AAAA,EAejB,MAAM,QAAQ,OAAA,EAA2C;AACvD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,OAAA,EAAS;AAAA,QAChD,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,WAAW,IAAA,CAAK;AAAA,OACjB,CAAA;AACD,MAAA,IAAI,SAAS,MAAA,CAAO,MAAA;AACpB,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,IAAI,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,cAAA,EAAgB;AAEvC,QAAA,MAAA,GAAS,CAAA,8BAAA,EAAiC,KAAK,cAAc,CAAA;AAAA,EAAiB,MAAA,CAAO,KAAA,CAAM,CAAC,IAAA,CAAK,cAAc,CAAC,CAAA,CAAA;AAChH,QAAA,SAAA,GAAY,IAAA;AAAA,MACd;AACA,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA,MAAA,IAAU;AAAA,yBAAA,EAA8B,KAAK,SAAS,CAAA,GAAA,CAAA;AAAA,MACxD;AACA,MAAA,OAAO,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAA,CAAO,UAAU,SAAA,EAAU;AAAA,IACxD,SAAS,KAAA,EAAO;AAGd,MAAA,OAAO,EAAE,QAAQ,YAAA,CAAa,KAAK,GAAG,QAAA,EAAU,CAAA,EAAG,WAAW,KAAA,EAAM;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,GAAG,IAAA,EAAiC;AACxC,IAAA,MAAM,OAAA,GAAU,gBAAgB,IAAI,CAAA;AACpC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,QAAQ,IAAI,CAAA;AACpD,MAAA,MAAM,QAAoB,EAAC;AAC3B,MAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AAChC,QAAA,IAAI;AACF,UAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,KAAK,IAAI,CAAA;AAC/C,UAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY;AAChC,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,IAAA,EAAM,KAAA,GAAQ,CAAA,EAAG,IAAI,CAAA,CAAA,CAAA,GAAM,IAAA;AAAA,YAC3B,MAAA,EAAQ,KAAA;AAAA,YACR,IAAA,EAAM,KAAA,GAAQ,KAAA,CAAA,GAAY,KAAA,CAAM,IAAA;AAAA,YAChC,aAAa,IAAI,IAAA,CAAK,KAAA,CAAM,OAAO,EAAE,WAAA;AAAY,WAClD,CAAA;AAAA,QACH,CAAA,CAAA,MAAQ;AAEN,UAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,QAC3B;AAAA,MACF;AACA,MAAA,OAAO,EAAE,KAAA,EAAM;AAAA,IACjB,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,MAAA,GAAS,GAAG,KAAA,EAAqC;AAC5E,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AACrD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,WAAA,CAAY,QAAQ,CAAC,CAAA;AACxD,MAAA,IAAI,WAAA,CAAY,GAAA,EAAK,QAAQ,CAAA,EAAG;AAC9B,QAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,QAAA,EAAU,YAAY,0BAAA,EAA2B;AAAA,MAC1E;AACA,MAAA,MAAM,IAAA,GAAO,IAAI,WAAA,EAAY,CAAE,OAAO,GAAG,CAAA;AACzC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE7B,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA,KAAM,EAAA,EAAI,KAAA,CAAM,GAAA,EAAI;AAClE,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA;AAChC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,CAAI,KAAA,CAAM,QAAQ,KAAA,IAAS,KAAA,IAAS,KAAK,gBAAA,CAAiB,CAAA;AAC3E,MAAA,OAAO;AAAA,QACL,SAAS,KAAA,CAAM,KAAA,CAAM,OAAO,GAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,QAC1C,UAAU,QAAA,IAAY,YAAA;AAAA,QACtB,YAAY,KAAA,CAAM,MAAA;AAAA,QAClB,SAAA,EAAW,KAAA;AAAA,QACX,OAAA,EAAS,GAAA;AAAA,QACT,UAAA,EAAY,GAAA,GAAM,KAAA,CAAM,MAAA,GAAS,GAAA,GAAM,KAAA;AAAA,OACzC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,QAAA,EAA0C;AACtD,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AACrD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,WAAA,CAAY,QAAQ,CAAC,CAAA;AACxD,MAAA,IAAI,WAAA,CAAY,GAAA,EAAK,QAAQ,CAAA,EAAG;AAC9B,QAAA,OAAO,EAAE,MAAM,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,QAAA,IAAY,4BAA2B,EAAE;AAAA,MACpF;AACA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,GAAG,CAAA,EAAG,QAAA,EAAU,QAAA,IAAY,YAAA;AAAa,OACrF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CAAM,QAAA,EAAkB,OAAA,EAAuC;AACnE,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,SAAS,KAAA,CAAM,CAAA,EAAG,SAAS,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,GAAA;AAC/D,MAAA,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,KAAA,CAAM,QAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACzD,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,MAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CACJ,QAAA,EACA,SAAA,EACA,SAAA,EACA,aAAa,KAAA,EACQ;AACrB,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,QAAA,CAAS,UAAU,MAAM,CAAA;AAC9D,MAAA,MAAM,WAAA,GAAc,cAAc,EAAA,GAAK,CAAA,GAAI,KAAK,KAAA,CAAM,SAAS,EAAE,MAAA,GAAS,CAAA;AAC1E,MAAA,IAAI,gBAAgB,CAAA,EAAG;AACrB,QAAA,OAAO,EAAE,OAAO,CAAA,oBAAA,EAAuB,QAAQ,KAAK,IAAA,CAAK,SAAA,CAAU,SAAS,CAAC,CAAA,CAAA,EAAG;AAAA,MAClF;AACA,MAAA,IAAI,WAAA,GAAc,CAAA,IAAK,CAAC,UAAA,EAAY;AAClC,QAAA,OAAO;AAAA,UACL,KAAA,EACE,CAAA,eAAA,EAAkB,WAAW,CAAA,UAAA,EAAa,QAAQ,CAAA,yEAAA;AAAA,SAEtD;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,UAAA,GACZ,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,CAAE,IAAA,CAAK,SAAS,CAAA,GACpC,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,SAAS,CAAA;AACrC,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAY;AAAA,IACvC,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAAA,EAAyC;AACpD,IAAA,MAAM,OAAA,GAAU,gBAAgB,QAAQ,CAAA;AACxC,IAAA,IAAI,OAAA,EAAS,OAAO,EAAE,KAAA,EAAO,OAAA,EAAQ;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,EAAA,CAAG,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,CAAA;AACtE,MAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAO,GAAA,EAA0B;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,OAAA,CAAQ,UAAA,CAAW,GAAG,IAAI,OAAA,GAAU,QAAA,CAAS,IAAA,EAAM,OAAO,CAAC,CAAA;AACxF,MAAA,MAAM,QAAoB,EAAC;AAC3B,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,KAAA,MAAW,aAAa,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,EAAG;AAC1D,QAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA,EAAG;AAC9B,QAAA,IAAI,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,cAAA,EAAgB;AACvC,UAAA,SAAA,GAAY,IAAA;AACZ,UAAA;AAAA,QACF;AACA,QAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAAA,MAChC;AACA,MAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAAA,IAC5B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CACJ,OAAA,EACA,IAAA,EACA,MACA,QAAA,EACqB;AACrB,IAAA,MAAM,OAAO,IAAA,IAAQ,GAAA;AACrB,IAAA,MAAM,GAAA,GAAM,YAAY,IAAA,CAAK,mBAAA;AAC7B,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,GACX,YAAA,CAAa,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,CAAA,GACrD,IAAA;AACJ,MAAA,MAAM,UAAuB,EAAC;AAC9B,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,KAAA,EAAO,KAAA,MAAW,aAAa,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,EAAG;AACjE,QAAA,IAAI,MAAA,IAAU,CAAC,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AACvC,QAAA,IAAI,GAAA;AACJ,QAAA,IAAI;AACF,UAAA,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,SAAS,CAAA;AAAA,QAClD,CAAA,CAAA,MAAQ;AACN,UAAA;AAAA,QACF;AACA,QAAA,IAAI,WAAA,CAAY,GAAA,EAAK,SAAS,CAAA,EAAG;AACjC,QAAA,MAAM,KAAA,GAAQ,IAAI,WAAA,EAAY,CAAE,OAAO,GAAG,CAAA,CAAE,MAAM,IAAI,CAAA;AACtD,QAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA,EAAG;AACxC,UAAA,IAAI,CAAC,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG;AACjC,UAAA,IAAI,OAAA,CAAQ,UAAU,GAAA,EAAK;AACzB,YAAA,SAAA,GAAY,IAAA;AACZ,YAAA,MAAM,KAAA;AAAA,UACR;AACA,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA,GAAI,CAAA,EAAG,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA;AAAA,QAC/D;AAAA,MACF;AACA,MAAA,OAAO,EAAE,SAAS,SAAA,EAAU;AAAA,IAC9B,SAAS,KAAA,EAAO;AACd,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,KAAA,EAAmE;AACnF,IAAA,MAAM,UAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,OAAO,CAAA,IAAK,KAAA,EAAO;AACvC,MAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,gBAAgB,CAAA;AACtD,QAAA;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,SAAS,KAAA,CAAM,CAAA,EAAG,SAAS,WAAA,CAAY,GAAG,CAAC,CAAA,IAAK,GAAA;AAC/D,QAAA,MAAM,IAAA,CAAK,UAAU,EAAA,CAAG,KAAA,CAAM,QAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACzD,QAAA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAA,CAAU,UAAU,OAAO,CAAA;AACnD,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,MAAM,CAAA;AAAA,MAC9C,CAAA,CAAA,MAAQ;AACN,QAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,qBAAqB,CAAA;AAAA,MAC7D;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,KAAA,EAAkD;AACpE,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,YAAY,KAAA,EAAO;AAC5B,MAAA,IAAI,CAAC,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,EAAG;AAC7B,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,gBAAgB,CAAA;AACrE,QAAA;AAAA,MACF;AACA,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,KAAK,QAAQ,CAAA;AACnD,QAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,gBAAgB,CAAA;AACrE,UAAA;AAAA,QACF;AACA,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,SAAS,MAAM,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,SAAS,QAAQ,CAAA;AAAA,UAClD,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH,CAAA,CAAA,MAAQ;AACN,QAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,IAAA,EAAM,KAAA,EAAO,kBAAkB,CAAA;AAAA,MACzE;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;;;ACrYO,IAAM,0BAAA,GAA6B,CAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA,oEAAA;AA4DnC,IAAM,mBAAA,GAAsB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+CAAA;AAyCnC,SAAS,KAAA,CAAM,IAAA,EAAc,WAAA,EAAqB,IAAA,EAA4B;AAC5E,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA,EAAS,CAAA;AAAA,MAAA,EAAc,IAAI;AAAA,aAAA,EAAkB,WAAW;AAAA;;AAAA,EAAY,IAAI;AAAA;AAAA,GAC1E;AACF;AASO,IAAM,cAAA,GAAiC;AAAA,EAC5C,KAAA;AAAA,IACE,cAAA;AAAA,IACA,6GAAA;AAAA,IACA,CAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,mEAAA;AAAA,GA8CF;AAAA,EACA,KAAA;AAAA,IACE,cAAA;AAAA,IACA,oHAAA;AAAA,IACA,CAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,iEAAA;AAAA,GAiDF;AAAA,EACA,KAAA;AAAA,IACE,aAAA;AAAA,IACA,mGAAA;AAAA,IACA,CAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,6BAAA;AAAA,GAaF;AAAA,EACA,KAAA;AAAA,IACE,eAAA;AAAA,IACA,sGAAA;AAAA,IACA,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wEAAA;AAAA;AAcJ;AAMO,SAAS,mBAAA,CACd,OAAA,GAAgC,EAAC,EACzB;AACR,EAAA,MAAM,KAAA,GAAQ,CAAC,0BAAA,EAA4B,mBAAmB,CAAA;AAC9D,EAAA,IAAI,OAAA,CAAQ,WAAW,KAAA,EAAO;AAC5B,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,CAAA;;AAAA,EAAe,cAAA,CAAe,GAAA;AAAA,QAC5B,CAAC,KAAA,KAAU,CAAA,GAAA,EAAM,KAAA,CAAM,IAAI;;AAAA,EAAO,MAAM,WAAW;;AAAA,EAAO,KAAA,CAAM,QAAQ,KAAA,CAAM,OAAO,EAAE,CAAC,CAAA,CAAE,MAAM,CAAA;AAAA,OAClG,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,KAChB;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAC1B;AASA,eAAsB,oBAAA,CACpB,SAAA,EACA,SAAA,GAAY,SAAA,EACK;AACjB,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,MAAM,IAAI,CAAA,CAAA;AACtC,IAAA,MAAM,UAAU,EAAA,CAAG,KAAA,CAAM,KAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AACjD,IAAA,MAAM,UAAU,EAAA,CAAG,SAAA,CAAU,GAAG,GAAG,CAAA,SAAA,CAAA,EAAa,MAAM,OAAO,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,SAAA;AACT","file":"agent.js","sourcesContent":["import type { Container } from \"../container/container.js\";\nimport type {\n DeleteResult,\n EditResult,\n ExecuteResponse,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GlobResult,\n GrepMatch,\n GrepResult,\n LsResult,\n ReadRawResult,\n ReadResult,\n SandboxBackendProtocolV2,\n WriteResult,\n} from \"./protocol.js\";\n\nexport interface SandboxedJsBackendOptions {\n /** Identity reported to Deep Agents. Defaults to a random per-instance id. */\n id?: string;\n /** Working directory every `execute` starts in. Defaults to the container's. */\n cwd?: string;\n /** Wall-clock limit for a single `execute`. Default 120_000ms. */\n timeoutMs?: number;\n /** Characters of combined output kept per command before truncating. Default 30_000. */\n maxOutputChars?: number;\n /** Default line window for `read`. Default 500. */\n defaultReadLimit?: number;\n /** Cap on entries returned by `glob`. Default 1_000. */\n maxGlobResults?: number;\n /** Cap on matches returned by `grep` when the caller gives no `maxCount`. Default 200. */\n defaultGrepMaxCount?: number;\n}\n\nconst BINARY_EXTENSIONS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"ico\", \"bmp\", \"pdf\", \"zip\", \"gz\", \"tar\",\n \"wasm\", \"so\", \"dylib\", \"dll\", \"exe\", \"woff\", \"woff2\", \"ttf\", \"otf\", \"mp3\",\n \"mp4\", \"mov\", \"avi\", \"bin\", \"db\", \"sqlite\",\n]);\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n png: \"image/png\", jpg: \"image/jpeg\", jpeg: \"image/jpeg\", gif: \"image/gif\",\n webp: \"image/webp\", svg: \"image/svg+xml\", pdf: \"application/pdf\",\n json: \"application/json\", js: \"text/javascript\", ts: \"text/x-typescript\",\n html: \"text/html\", css: \"text/css\", md: \"text/markdown\", wasm: \"application/wasm\",\n};\n\nfunction extensionOf(filePath: string): string {\n const base = filePath.slice(filePath.lastIndexOf(\"/\") + 1);\n const dot = base.lastIndexOf(\".\");\n return dot > 0 ? base.slice(dot + 1).toLowerCase() : \"\";\n}\n\n/**\n * `**` crosses `/`, `*` and `?` do not, and a leading `**\\/` also matches\n * depth zero — the same subset of glob semantics Deep Agents' own backends\n * document for their `glob` tool.\n */\nfunction globToRegExp(pattern: string): RegExp {\n let out = \"\";\n for (let i = 0; i < pattern.length; i += 1) {\n const ch = pattern[i];\n if (ch === \"*\") {\n if (pattern[i + 1] === \"*\") {\n i += 1;\n if (pattern[i + 1] === \"/\") {\n i += 1;\n out += \"(?:.*/)?\";\n } else {\n out += \".*\";\n }\n } else {\n out += \"[^/]*\";\n }\n } else if (ch === \"?\") {\n out += \"[^/]\";\n } else {\n out += ch.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n }\n return new RegExp(`^${out}$`);\n}\n\nfunction joinPath(base: string, name: string): string {\n return base.endsWith(\"/\") ? `${base}${name}` : `${base}/${name}`;\n}\n\n/** Deep Agents' file tools take absolute paths; a relative one is a caller bug. */\nfunction requireAbsolute(filePath: string): string | null {\n return filePath.startsWith(\"/\") ? null : `Path must be absolute: ${filePath}`;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction looksBinary(data: Uint8Array, filePath: string): boolean {\n if (BINARY_EXTENSIONS.has(extensionOf(filePath))) return true;\n const window = data.subarray(0, 1024);\n for (const byte of window) if (byte === 0) return true;\n return false;\n}\n\n/**\n * A sandboxedjs {@link Container} behind the LangChain Deep Agents backend\n * contract.\n *\n * Deep Agents' `BaseSandbox` derives its filesystem tools from `execute` by\n * shelling out to `find`, `stat`, `awk` and `grep`. This backend answers them\n * from {@link Container.fs} instead: the container's filesystem is an in-process\n * object, so going through the shell would only add parsing and quoting bugs\n * between the agent and data already in memory. `execute` still runs the real\n * POSIX shell, so agent-authored commands behave the way the agent expects.\n *\n * ```ts\n * const box = await createContainer({ cwd: \"/app\", network: { allowOutbound: true } });\n * const agent = createDeepAgent({ model, backend: new SandboxedJsBackend(box) });\n * ```\n *\n * The instance holds the container but does not own it: call\n * {@link Container.dispose} yourself when the run is over.\n */\nexport class SandboxedJsBackend implements SandboxBackendProtocolV2 {\n readonly id: string;\n\n private readonly cwd: string | undefined;\n private readonly timeoutMs: number;\n private readonly maxOutputChars: number;\n private readonly defaultReadLimit: number;\n private readonly maxGlobResults: number;\n private readonly defaultGrepMaxCount: number;\n\n constructor(\n readonly container: Container,\n options: SandboxedJsBackendOptions = {},\n ) {\n this.id = options.id ?? `sandboxedjs-${Math.random().toString(36).slice(2, 10)}`;\n this.cwd = options.cwd;\n this.timeoutMs = options.timeoutMs ?? 120_000;\n this.maxOutputChars = options.maxOutputChars ?? 30_000;\n this.defaultReadLimit = options.defaultReadLimit ?? 500;\n this.maxGlobResults = options.maxGlobResults ?? 1_000;\n this.defaultGrepMaxCount = options.defaultGrepMaxCount ?? 200;\n }\n\n async execute(command: string): Promise<ExecuteResponse> {\n try {\n const result = await this.container.exec(command, {\n cwd: this.cwd,\n timeoutMs: this.timeoutMs,\n });\n let output = result.output;\n let truncated = false;\n if (output.length > this.maxOutputChars) {\n /* Keep the tail: a failing command's diagnosis is at the end. */\n output = `[output truncated to the last ${this.maxOutputChars} characters]\\n${output.slice(-this.maxOutputChars)}`;\n truncated = true;\n }\n if (result.timedOut) {\n output += `\\n[command timed out after ${this.timeoutMs}ms]`;\n }\n return { output, exitCode: result.exitCode, truncated };\n } catch (error) {\n /* A container-level failure is still a tool result: the agent has to be\n * able to read what went wrong and try something else. */\n return { output: errorMessage(error), exitCode: 1, truncated: false };\n }\n }\n\n async ls(path: string): Promise<LsResult> {\n const invalid = requireAbsolute(path);\n if (invalid) return { error: invalid };\n try {\n const entries = await this.container.fs.readdir(path);\n const files: FileInfo[] = [];\n for (const name of entries) {\n const full = joinPath(path, name);\n try {\n const stats = await this.container.fs.stat(full);\n const isDir = stats.isDirectory();\n files.push({\n path: isDir ? `${full}/` : full,\n is_dir: isDir,\n size: isDir ? undefined : stats.size,\n modified_at: new Date(stats.mtimeMs).toISOString(),\n });\n } catch {\n /* A dangling symlink still belongs in the listing. */\n files.push({ path: full });\n }\n }\n return { files };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async read(filePath: string, offset = 0, limit?: number): Promise<ReadResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const raw = await this.container.fs.readFile(filePath);\n const mimeType = MIME_BY_EXTENSION[extensionOf(filePath)];\n if (looksBinary(raw, filePath)) {\n return { content: raw, mimeType: mimeType ?? \"application/octet-stream\" };\n }\n const text = new TextDecoder().decode(raw);\n const lines = text.split(\"\\n\");\n /* A trailing newline yields a final empty element that is not a line. */\n if (lines.length > 1 && lines[lines.length - 1] === \"\") lines.pop();\n const start = Math.max(0, offset);\n const end = Math.min(lines.length, start + (limit ?? this.defaultReadLimit));\n return {\n content: lines.slice(start, end).join(\"\\n\"),\n mimeType: mimeType ?? \"text/plain\",\n totalLines: lines.length,\n startLine: start,\n endLine: end,\n nextOffset: end < lines.length ? end : undefined,\n };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async readRaw(filePath: string): Promise<ReadRawResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const raw = await this.container.fs.readFile(filePath);\n const mimeType = MIME_BY_EXTENSION[extensionOf(filePath)];\n if (looksBinary(raw, filePath)) {\n return { data: { content: raw, mimeType: mimeType ?? \"application/octet-stream\" } };\n }\n return {\n data: { content: new TextDecoder().decode(raw), mimeType: mimeType ?? \"text/plain\" },\n };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async write(filePath: string, content: string): Promise<WriteResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const parent = filePath.slice(0, filePath.lastIndexOf(\"/\")) || \"/\";\n await this.container.fs.mkdir(parent, { recursive: true });\n await this.container.fs.writeFile(filePath, content);\n return { path: filePath };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n ): Promise<EditResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n const text = await this.container.fs.readFile(filePath, \"utf8\");\n const occurrences = oldString === \"\" ? 0 : text.split(oldString).length - 1;\n if (occurrences === 0) {\n return { error: `String not found in ${filePath}: ${JSON.stringify(oldString)}` };\n }\n if (occurrences > 1 && !replaceAll) {\n return {\n error:\n `String appears ${occurrences} times in ${filePath}. ` +\n `Provide more surrounding context to make it unique, or pass replaceAll.`,\n };\n }\n const updated = replaceAll\n ? text.split(oldString).join(newString)\n : text.replace(oldString, newString);\n await this.container.fs.writeFile(filePath, updated);\n return { path: filePath, occurrences };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async delete(filePath: string): Promise<DeleteResult> {\n const invalid = requireAbsolute(filePath);\n if (invalid) return { error: invalid };\n try {\n await this.container.fs.rm(filePath, { recursive: true, force: false });\n return { path: filePath };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async glob(pattern: string, path = \"/\"): Promise<GlobResult> {\n try {\n const matcher = globToRegExp(pattern.startsWith(\"/\") ? pattern : joinPath(path, pattern));\n const files: FileInfo[] = [];\n let truncated = false;\n for (const candidate of await this.container.fs.walk(path)) {\n if (!matcher.test(candidate)) continue;\n if (files.length >= this.maxGlobResults) {\n truncated = true;\n break;\n }\n files.push({ path: candidate });\n }\n return { files, truncated };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async grep(\n pattern: string,\n path?: string | null,\n glob?: string | null,\n maxCount?: number | null,\n ): Promise<GrepResult> {\n const root = path ?? \"/\";\n const cap = maxCount ?? this.defaultGrepMaxCount;\n try {\n const filter = glob\n ? globToRegExp(glob.includes(\"/\") ? glob : `**/${glob}`)\n : null;\n const matches: GrepMatch[] = [];\n let truncated = false;\n outer: for (const candidate of await this.container.fs.walk(root)) {\n if (filter && !filter.test(candidate)) continue;\n let raw: Uint8Array;\n try {\n raw = await this.container.fs.readFile(candidate);\n } catch {\n continue; /* Directories and unreadable entries are not grep targets. */\n }\n if (looksBinary(raw, candidate)) continue;\n const lines = new TextDecoder().decode(raw).split(\"\\n\");\n for (let i = 0; i < lines.length; i += 1) {\n if (!lines[i].includes(pattern)) continue;\n if (matches.length >= cap) {\n truncated = true;\n break outer;\n }\n matches.push({ path: candidate, line: i + 1, text: lines[i] });\n }\n }\n return { matches, truncated };\n } catch (error) {\n return { error: errorMessage(error) };\n }\n }\n\n async uploadFiles(files: Array<[string, Uint8Array]>): Promise<FileUploadResponse[]> {\n const results: FileUploadResponse[] = [];\n for (const [filePath, content] of files) {\n if (!filePath.startsWith(\"/\")) {\n results.push({ path: filePath, error: \"invalid_path\" });\n continue;\n }\n try {\n const parent = filePath.slice(0, filePath.lastIndexOf(\"/\")) || \"/\";\n await this.container.fs.mkdir(parent, { recursive: true });\n await this.container.fs.writeFile(filePath, content);\n results.push({ path: filePath, error: null });\n } catch {\n results.push({ path: filePath, error: \"permission_denied\" });\n }\n }\n return results;\n }\n\n async downloadFiles(paths: string[]): Promise<FileDownloadResponse[]> {\n const results: FileDownloadResponse[] = [];\n for (const filePath of paths) {\n if (!filePath.startsWith(\"/\")) {\n results.push({ path: filePath, content: null, error: \"invalid_path\" });\n continue;\n }\n try {\n const stats = await this.container.fs.stat(filePath);\n if (stats.isDirectory()) {\n results.push({ path: filePath, content: null, error: \"is_directory\" });\n continue;\n }\n results.push({\n path: filePath,\n content: await this.container.fs.readFile(filePath),\n error: null,\n });\n } catch {\n results.push({ path: filePath, content: null, error: \"file_not_found\" });\n }\n }\n return results;\n }\n}\n","import type { Container } from \"../container/container.js\";\n\n/**\n * What the agent's environment actually is.\n *\n * Every claim here is a behaviour this package implements. Coding agents fail\n * in a sandbox mostly by assuming a host they do not have — reaching for\n * `docker`, `sudo`, `systemctl`, `curl localhost:3000`, or a background process\n * that outlives the turn. Saying plainly what exists is what stops that.\n */\nexport const SANDBOX_ENVIRONMENT_PROMPT = `# Your environment\n\nYou are working inside a sandboxedjs container: a Linux-like environment that\nruns entirely inside a JavaScript process. There is no Docker, no VM, and no\nhost machine you can reach. Everything below is real and available to you.\n\n## What you have\n\n- A POSIX shell (\\`sh\\`/\\`bash\\` syntax): pipes, redirection, \\`&&\\`, \\`||\\`,\n subshells, globs, heredocs, variables, functions, \\`for\\`/\\`while\\`/\\`case\\`.\n- Around 140 coreutils: \\`ls cat cp mv rm mkdir find grep sed awk head tail\n sort uniq wc diff patch tar gzip curl chmod ln touch echo printf test\\` and\n the rest of the usual set.\n- Node.js, with \\`node\\`, \\`npm\\` and \\`npx\\`. \\`npm install\\` resolves against\n the real npm registry when outbound network is enabled.\n- Python 3 via \\`python3\\` and \\`pip\\`, when the host enabled the Python runtime.\n- A writable virtual filesystem rooted at \\`/\\`, persistent for the life of the\n container.\n- A virtual network stack. Servers you start inside the container really listen\n on their ports and can really be requested.\n\n## What you do not have\n\n- No Docker, no VM, no \\`systemctl\\`, no \\`service\\`, no \\`apt\\`/\\`apt-get\\`,\n no \\`yum\\`, no \\`brew\\`. Never try to install system packages.\n- No \\`sudo\\` and no reason for it: you already run as the container's user and\n the filesystem is yours.\n- No access to the host machine, its files, its network interfaces, or its\n environment variables. Nothing outside the container exists for you.\n- No GUI, no browser, no interactive editors. Do not run \\`vim\\`, \\`nano\\`,\n \\`less\\`, or \\`top\\`; they will hang or fail. Read files by reading them and\n edit them by editing them.\n- No long-running foreground commands. A command that never exits will hit the\n execution timeout and the turn is wasted.\n\n## Running servers\n\nStart servers in the background and never block on them:\n\n\\`\\`\\`sh\nnode server.js > /tmp/server.log 2>&1 &\n\\`\\`\\`\n\nThen poll the log for readiness rather than requesting the port immediately.\nDo not run a dev server in the foreground. Do not use \\`curl localhost:PORT\\`\nto prove a server works unless you started it in the background first — the\nhost, not you, is the one that will connect to it.\n\n## How your work is used\n\nThe container is the deliverable. Files you write to the filesystem are what\nthe user receives and what a preview will serve. Write real, complete files to\nreal paths — do not print a project to stdout and call it done.`;\n\n/**\n * Operating rules, in the register a coding harness uses.\n *\n * Deliberately about this environment rather than about coding in general: the\n * host's own system prompt owns the latter, and repeating it only dilutes both.\n */\nexport const SANDBOX_AGENT_RULES = `# Rules\n\n1. Verify before you claim. If you say a server runs or a build passes, you\n ran it in this container and read the output. Never report success you have\n not observed.\n2. One command, one purpose. Chain with \\`&&\\` when steps depend on each other\n so a failure stops the chain instead of hiding under a later success.\n3. Read a file before editing it. Edits are literal string replacements; they\n fail when you are guessing at the current contents.\n4. Use absolute paths in file tools. Use \\`cd\\` inside a single shell command\n when a command needs a working directory.\n5. Install dependencies with \\`npm install <pkg>\\`, in the directory that has\n the \\`package.json\\`. Do not hand-write \\`node_modules\\` or invent versions\n in \\`package.json\\` — let the installer resolve them.\n6. Background every server and long task, redirect its output to a log file,\n then poll the log. Never leave a command running in the foreground.\n7. Keep command output small. Pipe noisy commands through \\`tail\\`, \\`head\\`\n or \\`grep\\`. Output is truncated past the backend's limit and you will lose\n the part you needed.\n8. When a command fails, read stderr and fix the cause. Do not retry the same\n command unchanged, and do not work around a failure by faking its result.\n9. Prefer the project's own tooling — \\`npm run build\\`, \\`npm test\\`,\n \\`npx vite\\` — over reimplementing what it already does.\n10. Do not attempt to escape the container, reach the host, or disable the\n network policy. Outbound access is the host's decision, not yours.\n11. Prefer the non-interactive form of a command when one exists — pass the\n flags that pre-answer its questions. A generator that asks nothing is\n faster and its result is the same every run.\n12. An interactive prompt is not a failure. If a command stops on a question\n or a menu, answer it: send the text, or the arrow keys and Enter that the\n prompt names. Read what is on screen before answering, and do not send a\n second answer until the screen has changed.`;\n\n/** A Deep Agents skill: markdown with the frontmatter its loader parses. */\nexport interface SandboxSkill {\n name: string;\n description: string;\n /** Full file content, frontmatter included, ready to write to disk. */\n content: string;\n}\n\nfunction skill(name: string, description: string, body: string): SandboxSkill {\n return {\n name,\n description,\n content: `---\\nname: ${name}\\ndescription: ${description}\\n---\\n\\n${body}\\n`,\n };\n}\n\n/**\n * Skills covering the workflows that break first in a sandbox.\n *\n * Each is a procedure that has to be followed exactly once to work, and that a\n * model otherwise improvises differently every run — which is what makes an\n * agent look unstable when the container underneath is fine.\n */\nexport const SANDBOX_SKILLS: SandboxSkill[] = [\n skill(\n \"node-service\",\n \"Scaffold, install, run and verify a Node.js HTTP service (Express, Fastify, plain http) inside the sandbox.\",\n `# Building a Node HTTP service\n\nFollow these steps in order. Do not skip verification.\n\n1. Create the project directory and manifest:\n\n \\`\\`\\`sh\n mkdir -p /app && cd /app && npm init -y\n \\`\\`\\`\n\n2. Install dependencies in one command:\n\n \\`\\`\\`sh\n cd /app && npm install express\n \\`\\`\\`\n\n Read the output. If it ends in an \\`ENOTFOUND\\` or network error, outbound\n access is disabled for this container — say so and stop, rather than\n inventing a dependency-free rewrite the user did not ask for.\n\n3. Write the server to a real file. Bind to \\`0.0.0.0\\` and log a line on\n listen, so readiness is observable:\n\n \\`\\`\\`js\n const express = require(\"express\");\n const app = express();\n app.get(\"/\", (_req, res) => res.send(\"hello world\"));\n const port = Number(process.env.PORT) || 3000;\n app.listen(port, \"0.0.0.0\", () => console.log(\\`listening on \\${port}\\`));\n \\`\\`\\`\n\n4. Start it in the background and wait for the log line:\n\n \\`\\`\\`sh\n cd /app && node server.js > /tmp/server.log 2>&1 &\n sleep 1 && cat /tmp/server.log\n \\`\\`\\`\n\n5. Verify it answers:\n\n \\`\\`\\`sh\n curl -s -i http://127.0.0.1:3000/ | head -20\n \\`\\`\\`\n\n A non-2xx status or an empty response means the server is not working. Read\n \\`/tmp/server.log\\` and fix the cause before reporting anything.`,\n ),\n skill(\n \"frontend-app\",\n \"Create and run a Vite frontend (React, Vue, Svelte, vanilla) inside the sandbox without an interactive scaffolder.\",\n `# Building a frontend app\n\nA generator works here — the sandbox can answer its prompts — but writing the\nfiles yourself is faster and deterministic, and you control exactly what the\nproject contains. Prefer it unless the framework's initializer does real work\nyou would otherwise have to reproduce. If you do run one, answer its prompts.\n\n1. Write \\`/app/package.json\\`. Give the dependencies real version ranges and\n let the installer resolve them:\n\n \\`\\`\\`json\n {\n \"name\": \"app\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": { \"dev\": \"vite\", \"build\": \"vite build\", \"preview\": \"vite preview\" },\n \"dependencies\": { \"react\": \"^19.0.0\", \"react-dom\": \"^19.0.0\" },\n \"devDependencies\": { \"@vitejs/plugin-react\": \"^5.0.0\", \"vite\": \"^7.0.0\" }\n }\n \\`\\`\\`\n\n2. Write the four files a Vite app actually needs: \\`index.html\\` with\n \\`<div id=\"root\">\\` and a module script pointing at \\`/src/main.jsx\\`,\n \\`vite.config.js\\` registering the framework plugin, \\`src/main.jsx\\`\n mounting the root, and \\`src/App.jsx\\`.\n\n3. Install once, and read the output:\n\n \\`\\`\\`sh\n cd /app && npm install\n \\`\\`\\`\n\n4. Prove it compiles before claiming anything works:\n\n \\`\\`\\`sh\n cd /app && npm run build 2>&1 | tail -30\n \\`\\`\\`\n\n5. Only if a live preview is wanted, start the dev server in the background\n and confirm it came up:\n\n \\`\\`\\`sh\n cd /app && npx vite --host 0.0.0.0 --port 5173 > /tmp/vite.log 2>&1 &\n sleep 3 && tail -20 /tmp/vite.log\n \\`\\`\\`\n\nCheck the installed major versions before using an API from a package —\n\\`cat /app/node_modules/react/package.json\\`. A remembered API from a\ndifferent major is the most common cause of a build failure here.`,\n ),\n skill(\n \"verify-work\",\n \"Check that generated code actually builds, runs and passes its tests before reporting completion.\",\n `# Verifying before reporting\n\nNever report a task complete on the strength of having written files.\n\n- If the project has tests: \\`cd <dir> && npm test 2>&1 | tail -40\\`\n- If it has a build: \\`cd <dir> && npm run build 2>&1 | tail -40\\`\n- If it has neither and it is a script: run it and read the output.\n- If it is a service: start it in the background and request it (see the\n \\`node-service\\` skill).\n\nThen state what you ran and what it printed. If something fails and you cannot\nfix it, say exactly what fails and what you tried. A wrong claim of success is\nworse than an honest failure.`,\n ),\n skill(\n \"debug-failure\",\n \"Diagnose a failing command, build, install or server inside the sandbox instead of retrying blindly.\",\n `# Debugging inside the sandbox\n\n1. Re-read the actual error. The cause is usually the first error line, not\n the last.\n2. Confirm the state you assumed: \\`ls -la\\` the directory, \\`cat\\` the config,\n \\`cat package.json\\`. Most failures are a wrong path or a missing install.\n3. Check the log of anything backgrounded: \\`tail -50 /tmp/*.log\\`.\n4. For a module resolution error, verify the package is installed where you\n think: \\`ls /app/node_modules/<pkg>/package.json\\`.\n5. For a port that will not answer, check the process is alive (\\`ps\\`) and the\n log shows a listen line. A crashed server leaves no port behind.\n6. Change exactly one thing, then re-run. Do not retry an unchanged command,\n and do not delete the work to start over unless nothing else is left.`,\n ),\n];\n\n/**\n * The whole prompt in one string, for hosts that do not use Deep Agents' skills\n * middleware and just want to append it to a system prompt.\n */\nexport function sandboxSystemPrompt(\n options: { skills?: boolean } = {},\n): string {\n const parts = [SANDBOX_ENVIRONMENT_PROMPT, SANDBOX_AGENT_RULES];\n if (options.skills !== false) {\n parts.push(\n `# Skills\\n\\n${SANDBOX_SKILLS.map(\n (entry) => `## ${entry.name}\\n\\n${entry.description}\\n\\n${entry.content.split(\"---\\n\")[2].trim()}`,\n ).join(\"\\n\\n\")}`,\n );\n }\n return parts.join(\"\\n\\n\");\n}\n\n/**\n * Write the skills into the container as files, one directory each.\n *\n * This is the layout Deep Agents' skills middleware discovers: point its\n * `sources` at the same directory and it loads them itself, so the host does\n * not have to put any of this in its system prompt.\n */\nexport async function installSandboxSkills(\n container: Container,\n directory = \"/skills\",\n): Promise<string> {\n for (const entry of SANDBOX_SKILLS) {\n const dir = `${directory}/${entry.name}`;\n await container.fs.mkdir(dir, { recursive: true });\n await container.fs.writeFile(`${dir}/SKILL.md`, entry.content);\n }\n return directory;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hosting/browser-host.ts"],"names":["realpath","resolve","stat","path","relative","sep","isAbsolute","readFile","extname","createServer"],"mappings":";;;;;;;AAMO,IAAM,uBAAA,GAA0B,OAAO,MAAA,CAAO;AAAA,EACnD,4BAAA,EAA8B,aAAA;AAAA,EAC9B,8BAAA,EAAgC;AAClC,CAAC;AAED,IAAM,IAAA,GAA+B;AAAA,EACnC,OAAA,EAAS,0BAAA;AAAA,EAA4B,KAAA,EAAO,gCAAA;AAAA,EAC5C,MAAA,EAAQ,gCAAA;AAAA,EAAkC,MAAA,EAAQ,yBAAA;AAAA,EAClD,OAAA,EAAS,kBAAA;AAAA,EAAoB,OAAA,EAAS,kBAAA;AAAA,EACtC,MAAA,EAAQ,eAAA;AAAA,EAAiB,MAAA,EAAQ,WAAA;AAAA,EAAa,MAAA,EAAQ,YAAA;AAAA,EACtD,OAAA,EAAS,YAAA;AAAA,EAAc,MAAA,EAAQ,cAAA;AAAA,EAAgB,OAAA,EAAS,YAAA;AAAA,EACxD,OAAA,EAAS,WAAA;AAAA,EAAa,QAAA,EAAU,YAAA;AAAA,EAAc,MAAA,EAAQ;AACxD,CAAA;AAOA,eAAsB,gBAAgB,OAAA,EAI+B;AACnE,EAAA,MAAM,OAAO,MAAMA,iBAAA,CAASC,YAAA,CAAQ,OAAA,CAAQ,SAAS,CAAC,CAAA;AACtD,EAAA,IAAI,CAAA,CAAE,MAAMC,aAAA,CAAK,IAAI,CAAA,EAAG,aAAY,EAAG,MAAM,IAAI,KAAA,CAAM,0CAA0C,CAAA;AACjG,EAAA,MAAM,MAAA,GAAS,CAACC,MAAA,KAAiB;AAC/B,IAAA,MAAM,GAAA,GAAMC,aAAA,CAAS,IAAA,EAAMD,MAAI,CAAA;AAC/B,IAAA,OAAO,GAAA,KAAQ,IAAA,IAAQ,CAAC,GAAA,CAAI,UAAA,CAAW,CAAA,EAAA,EAAKE,QAAG,CAAA,CAAE,CAAA,IAAK,CAACC,eAAA,CAAW,GAAG,CAAA;AAAA,EACvE,CAAA;AACA,EAAA,MAAM,MAAA,GAAS,OAAO,GAAA,EAAsB,GAAA,KAAwB;AAClE,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,uBAAuB,CAAA,EAAG,GAAA,CAAI,SAAA,CAAU,IAAA,EAAM,KAAK,CAAA;AAC9F,IAAA,GAAA,CAAI,SAAA,CAAU,0BAA0B,SAAS,CAAA;AACjD,IAAA,GAAA,CAAI,SAAA,CAAU,iBAAiB,UAAU,CAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,EAAgB,IAAA,KAAiB;AAC9C,MAAA,GAAA,CAAI,UAAA,GAAa,MAAA;AACjB,MAAA,GAAA,CAAI,SAAA,CAAU,gBAAgB,2BAA2B,CAAA;AACzD,MAAA,GAAA,CAAI,GAAA,CAAI,GAAA,CAAI,MAAA,KAAW,MAAA,GAAS,SAAY,IAAI,CAAA;AAAA,IAClD,CAAA;AACA,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,KAAA,IAAS,GAAA,CAAI,WAAW,MAAA,EAAQ;AACjD,MAAA,GAAA,CAAI,SAAA,CAAU,SAAS,WAAW,CAAA;AAClC,MAAA,KAAA,CAAM,KAAK,oBAAoB,CAAA;AAC/B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAAE,MAAA,QAAA,GAAW,kBAAA,CAAA,CAAoB,IAAI,GAAA,IAAO,GAAA,EAAK,MAAM,GAAG,CAAA,CAAE,CAAC,CAAE,CAAA;AAAA,IAAG,CAAA,CAAA,MAChE;AAAE,MAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AAAG,MAAA;AAAA,IAAQ;AAE3C,IAAA,IAAI,SAAS,QAAA,CAAS,IAAI,KAAK,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,IAAK,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,UAAA,CAAW,GAAG,CAAC,CAAA,EAAG;AAC1G,MAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAG,MAAA;AAAA,IAC3B;AACA,IAAA,IAAI,SAAA,GAAYL,YAAA,CAAQ,IAAA,EAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,GAAI,QAAA,GAAW,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAE,CAAA,CAAE,CAAA;AACxF,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,MAAA,CAAO,SAAS,CAAA,EAAG;AAAE,QAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAG,QAAA;AAAA,MAAQ;AAC3D,MAAA,IAAA,CAAK,MAAMC,cAAK,SAAS,CAAA,EAAG,aAAY,EAAG,SAAA,GAAYD,YAAA,CAAQ,SAAA,EAAW,YAAY,CAAA;AACtF,MAAA,SAAA,GAAY,MAAMD,kBAAS,SAAS,CAAA;AAEpC,MAAA,IAAI,CAAC,MAAA,CAAO,SAAS,CAAA,EAAG;AAAE,QAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAG,QAAA;AAAA,MAAQ;AAC3D,MAAA,IAAI,EAAE,MAAME,aAAA,CAAK,SAAS,CAAA,EAAG,QAAO,EAAG;AAAE,QAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAG,QAAA;AAAA,MAAQ;AAC1E,MAAA,MAAM,IAAA,GAAO,MAAMK,iBAAA,CAAS,SAAS,CAAA;AACrC,MAAA,GAAA,CAAI,UAAU,cAAA,EAAgB,IAAA,CAAKC,aAAQ,SAAS,CAAC,KAAK,0BAA0B,CAAA;AACpF,MAAA,GAAA,CAAI,SAAA,CAAU,gBAAA,EAAkB,IAAA,CAAK,UAAU,CAAA;AAC/C,MAAA,GAAA,CAAI,GAAA,CAAI,GAAA,CAAI,MAAA,KAAW,MAAA,GAAS,SAAY,IAAI,CAAA;AAAA,IAClD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAQ,KAAA,CAAgC,IAAA;AAC9C,MAAA,KAAA,CAAM,SAAS,QAAA,IAAY,IAAA,KAAS,SAAA,GAAY,GAAA,GAAM,KAAK,sBAAsB,CAAA;AAAA,IACnF;AAAA,EACF,CAAA;AACA,EAAA,MAAM,MAAA,GAASC,iBAAA,CAAa,CAAC,GAAA,EAAK,GAAA,KAAQ;AAAE,IAAA,KAAK,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EAAG,CAAC,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,WAAA;AACrC,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,IAAA,EAAM,MAAA,KAAW;AACxC,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,MAAM,CAAA;AAC3B,IAAA,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,IAAA,IAAQ,IAAA,EAAM,UAAU,MAAM;AAAE,MAAA,MAAA,CAAO,GAAA,CAAI,SAAS,MAAM,CAAA;AAAG,MAAA,IAAA,EAAK;AAAA,IAAG,CAAC,CAAA;AAAA,EAC9F,CAAC,CAAA;AACD,EAAA,MAAM,OAAA,GAAU,OAAO,OAAA,EAAQ;AAC/B,EAAA,IAAI,CAAC,WAAW,OAAO,OAAA,KAAY,UAAU,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAC9F,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,GAAA,EAAK,CAAA,OAAA,EAAU,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,GAAI,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,CAAA,GAAM,QAAQ,CAAA,CAAA,EAAI,OAAA,CAAQ,IAAI,CAAA,CAAA;AAAA,IAClF,OAAO,MAAM,IAAI,OAAA,CAAc,CAAC,MAAM,MAAA,KAAW;AAC/C,MAAA,MAAA,CAAO,MAAM,CAAA,KAAA,KAAS,KAAA,GAAQ,OAAO,KAAK,CAAA,GAAI,MAAM,CAAA;AACpD,MAAA,MAAA,CAAO,oBAAA,EAAqB;AAAA,IAC9B,CAAC;AAAA,GACH;AACF","file":"browser-host.cjs","sourcesContent":["/** Node-side hosting for a built SandboxedJs browser application. */\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { readFile, realpath, stat } from \"node:fs/promises\";\nimport { extname, isAbsolute, relative, resolve, sep } from \"node:path\";\n\n/** These must be sent on the host document, not just the guest's HTTP responses. */\nexport const browserIsolationHeaders = Object.freeze({\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n});\n\nconst mime: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\", \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\", \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json\", \".wasm\": \"application/wasm\",\n \".svg\": \"image/svg+xml\", \".png\": \"image/png\", \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\", \".ico\": \"image/x-icon\", \".webp\": \"image/webp\",\n \".woff\": \"font/woff\", \".woff2\": \"font/woff2\", \".txt\": \"text/plain; charset=utf-8\",\n};\n\n/**\n * Serve a built host application with the prerequisites for guest workers and\n * threaded WASM. Loopback-only by default; use HTTPS at a reverse proxy for\n * remote access. An arbitrary HTTP origin is not a secure browser context.\n */\nexport async function serveBrowserApp(options: {\n directory: string;\n port?: number;\n hostname?: string;\n}): Promise<{ server: Server; url: string; close(): Promise<void> }> {\n const root = await realpath(resolve(options.directory));\n if (!(await stat(root)).isDirectory()) throw new Error(\"Browser app directory is not a directory\");\n const inside = (path: string) => {\n const rel = relative(root, path);\n return rel !== \"..\" && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n };\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n for (const [name, value] of Object.entries(browserIsolationHeaders)) res.setHeader(name, value);\n res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n const reply = (status: number, body: string) => {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n res.end(req.method === \"HEAD\" ? undefined : body);\n };\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n res.setHeader(\"Allow\", \"GET, HEAD\");\n reply(405, \"Method not allowed\");\n return;\n }\n let pathname: string;\n try { pathname = decodeURIComponent((req.url ?? \"/\").split(\"?\")[0]!); }\n catch { reply(400, \"Invalid URL\"); return; }\n // Reject traversal, hidden files, and platform-dependent separators before resolving.\n if (pathname.includes(\"\\0\") || pathname.includes(\"\\\\\") || pathname.split(\"/\").some(p => p.startsWith(\".\"))) {\n reply(403, \"Forbidden\"); return;\n }\n let candidate = resolve(root, `.${pathname.startsWith(\"/\") ? pathname : `/${pathname}`}`);\n try {\n if (!inside(candidate)) { reply(403, \"Forbidden\"); return; }\n if ((await stat(candidate)).isDirectory()) candidate = resolve(candidate, \"index.html\");\n candidate = await realpath(candidate);\n // A symlink inside the web root must not expose files outside it.\n if (!inside(candidate)) { reply(403, \"Forbidden\"); return; }\n if (!(await stat(candidate)).isFile()) { reply(404, \"Not found\"); return; }\n const body = await readFile(candidate);\n res.setHeader(\"Content-Type\", mime[extname(candidate)] ?? \"application/octet-stream\");\n res.setHeader(\"Content-Length\", body.byteLength);\n res.end(req.method === \"HEAD\" ? undefined : body);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n reply(code === \"ENOENT\" || code === \"ENOTDIR\" ? 404 : 500, \"Unable to serve file\");\n }\n };\n const server = createServer((req, res) => { void handle(req, res); });\n const hostname = options.hostname ?? \"127.0.0.1\";\n await new Promise<void>((done, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 4173, hostname, () => { server.off(\"error\", reject); done(); });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") throw new Error(\"Browser host has no TCP address\");\n return {\n server,\n url: `http://${hostname.includes(\":\") ? `[${hostname}]` : hostname}:${address.port}`,\n close: () => new Promise<void>((done, reject) => {\n server.close(error => error ? reject(error) : done());\n server.closeIdleConnections();\n }),\n };\n}\n"]}
|
package/dist/browser-host.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hosting/browser-host.ts"],"names":[],"mappings":"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","file":"browser-host.js","sourcesContent":["/** Node-side hosting for a built SandboxedJs browser application. */\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { readFile, realpath, stat } from \"node:fs/promises\";\nimport { extname, isAbsolute, relative, resolve, sep } from \"node:path\";\n\n/** These must be sent on the host document, not just the guest's HTTP responses. */\nexport const browserIsolationHeaders = Object.freeze({\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n});\n\nconst mime: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\", \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\", \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json\", \".wasm\": \"application/wasm\",\n \".svg\": \"image/svg+xml\", \".png\": \"image/png\", \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\", \".ico\": \"image/x-icon\", \".webp\": \"image/webp\",\n \".woff\": \"font/woff\", \".woff2\": \"font/woff2\", \".txt\": \"text/plain; charset=utf-8\",\n};\n\n/**\n * Serve a built host application with the prerequisites for guest workers and\n * threaded WASM. Loopback-only by default; use HTTPS at a reverse proxy for\n * remote access. An arbitrary HTTP origin is not a secure browser context.\n */\nexport async function serveBrowserApp(options: {\n directory: string;\n port?: number;\n hostname?: string;\n}): Promise<{ server: Server; url: string; close(): Promise<void> }> {\n const root = await realpath(resolve(options.directory));\n if (!(await stat(root)).isDirectory()) throw new Error(\"Browser app directory is not a directory\");\n const inside = (path: string) => {\n const rel = relative(root, path);\n return rel !== \"..\" && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n };\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n for (const [name, value] of Object.entries(browserIsolationHeaders)) res.setHeader(name, value);\n res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n const reply = (status: number, body: string) => {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"text/plain; charset=utf-8\");\n res.end(req.method === \"HEAD\" ? undefined : body);\n };\n if (req.method !== \"GET\" && req.method !== \"HEAD\") {\n res.setHeader(\"Allow\", \"GET, HEAD\");\n reply(405, \"Method not allowed\");\n return;\n }\n let pathname: string;\n try { pathname = decodeURIComponent((req.url ?? \"/\").split(\"?\")[0]!); }\n catch { reply(400, \"Invalid URL\"); return; }\n // Reject traversal, hidden files, and platform-dependent separators before resolving.\n if (pathname.includes(\"\\0\") || pathname.includes(\"\\\\\") || pathname.split(\"/\").some(p => p.startsWith(\".\"))) {\n reply(403, \"Forbidden\"); return;\n }\n let candidate = resolve(root, `.${pathname.startsWith(\"/\") ? pathname : `/${pathname}`}`);\n try {\n if (!inside(candidate)) { reply(403, \"Forbidden\"); return; }\n if ((await stat(candidate)).isDirectory()) candidate = resolve(candidate, \"index.html\");\n candidate = await realpath(candidate);\n // A symlink inside the web root must not expose files outside it.\n if (!inside(candidate)) { reply(403, \"Forbidden\"); return; }\n if (!(await stat(candidate)).isFile()) { reply(404, \"Not found\"); return; }\n const body = await readFile(candidate);\n res.setHeader(\"Content-Type\", mime[extname(candidate)] ?? \"application/octet-stream\");\n res.setHeader(\"Content-Length\", body.byteLength);\n res.end(req.method === \"HEAD\" ? undefined : body);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n reply(code === \"ENOENT\" || code === \"ENOTDIR\" ? 404 : 500, \"Unable to serve file\");\n }\n };\n const server = createServer((req, res) => { void handle(req, res); });\n const hostname = options.hostname ?? \"127.0.0.1\";\n await new Promise<void>((done, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 4173, hostname, () => { server.off(\"error\", reject); done(); });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") throw new Error(\"Browser host has no TCP address\");\n return {\n server,\n url: `http://${hostname.includes(\":\") ? `[${hostname}]` : hostname}:${address.port}`,\n close: () => new Promise<void>((done, reject) => {\n server.close(error => error ? reject(error) : done());\n server.closeIdleConnections();\n }),\n };\n}\n"]}
|