@mastra/blaxel 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/shell-quote.ts","../src/sandbox/mounts/types.ts","../src/sandbox/mounts/s3.ts","../src/sandbox/mounts/gcs.ts","../src/sandbox/index.ts"],"names":["crypto","MastraSandbox","SandboxNotReadyError","SandboxInstance"],"mappings":";;;;;;;;;;;;;AAMO,SAAS,WAAW,GAAA,EAAqB;AAE9C,EAAA,IAAI,wBAAA,CAAyB,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,GAAA;AAE/C,EAAA,OAAO,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,GAAI,GAAA;AAC5C;;;ACLO,IAAM,UAAA,GAAa,kBAAA;AA2B1B,IAAM,gBAAA,GAAmB,qCAAA;AAElB,SAAS,mBAAmB,MAAA,EAAsB;AACvD,EAAA,IAAI,CAAC,gBAAA,CAAiB,IAAA,CAAK,MAAM,CAAA,EAAG;AAClC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,yBAAyB,MAAM,CAAA,kFAAA;AAAA,KACjC;AAAA,EACF;AACF;AAMO,SAAS,iBAAiB,QAAA,EAAwB;AACvD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,QAAQ,CAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,QAAQ,CAAA,CAAA,CAAG,CAAA;AAAA,EACvD;AACA,EAAA,IAAI,MAAA,CAAO,QAAA,KAAa,OAAA,IAAW,MAAA,CAAO,aAAa,QAAA,EAAU;AAC/D,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,MAAA,CAAO,QAAQ,CAAA,qCAAA,CAAuC,CAAA;AAAA,EACzG;AACF;AAQA,eAAsB,UAAA,CACpB,OAAA,EACA,OAAA,EACA,OAAA,EAC+D;AAC/D,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK;AAAA,IACxC,OAAA;AAAA,IACA,iBAAA,EAAmB,IAAA;AAAA,IACnB,GAAI,OAAA,EAAS,OAAA,IAAW,EAAE,OAAA,EAAS,KAAK,IAAA,CAAK,OAAA,CAAQ,OAAA,GAAU,GAAI,CAAA;AAAE,GACtE,CAAA;AAED,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,OAAO,QAAA,IAAY,CAAA;AAAA,IAC7B,MAAA,EAAQ,OAAO,MAAA,IAAU,EAAA;AAAA,IACzB,MAAA,EAAQ,OAAO,MAAA,IAAU;AAAA,GAC3B;AACF;AC9CA,eAAsB,OAAA,CAAQ,SAAA,EAAmB,MAAA,EAA6B,GAAA,EAAkC;AAC9G,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,GAAA;AAG5B,EAAA,kBAAA,CAAmB,OAAO,MAAM,CAAA;AAChC,EAAA,IAAI,OAAO,QAAA,EAAU;AACnB,IAAA,gBAAA,CAAiB,OAAO,QAAQ,CAAA;AAAA,EAClC;AAGA,EAAA,MAAM,WAAA,GAAc,MAAM,UAAA,CAAW,OAAA,EAAS,gCAAgC,CAAA;AAC9E,EAAA,IAAI,WAAA,CAAY,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA,EAAG;AAC5C,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,mDAAA,CAAqD,CAAA;AAC9E,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,gEAAA,CAAkE,CAAA;AAE3F,IAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,OAAA,EAAS,uBAAuB,EAAE,OAAA,EAAS,KAAO,CAAA;AACxF,IAAA,IAAI,YAAA,CAAa,aAAa,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA;AAAA,eAAA,EACoB,YAAA,CAAa,MAAA,IAAU,YAAA,CAAa,MAAM,CAAA;AAAA,OAChE;AAAA,IACF;AAEA,IAAA,MAAM,gBAAgB,MAAM,UAAA;AAAA,MAC1B,OAAA;AAAA,MACA,6EAAA;AAAA,MACA,EAAE,SAAS,IAAA;AAAO,KACpB;AAEA,IAAA,IAAI,aAAA,CAAc,aAAa,CAAA,EAAG;AAChC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA;;AAAA;;AAAA,eAAA,EAGoB,aAAA,CAAc,MAAA,IAAU,aAAA,CAAc,MAAM,CAAA;AAAA,OAClE;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,OAAA,EAAS,gBAAgB,CAAA;AAC3D,EAAA,IAAI,QAAA,CAAS,aAAa,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,SAAS,MAAA,IAAU,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,EAChF;AACA,EAAA,MAAM,CAAC,KAAK,GAAG,CAAA,GAAI,SAAS,MAAA,CAAO,IAAA,EAAK,CAAE,KAAA,CAAM,IAAI,CAAA;AAGpD,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,eAAA;AAGpD,EAAA,MAAM,SAAA,GAAYA,uBAAA,CAAO,UAAA,CAAW,KAAK,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACrF,EAAA,MAAM,eAAA,GAAkB,qBAAqB,SAAS,CAAA,CAAA;AAItD,EAAA,IAAI,CAAC,cAAA,IAAkB,MAAA,CAAO,QAAA,EAAU;AACtC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,+DAAA,EACwB,OAAO,QAAQ,CAAA,oFAAA;AAAA,KAEzC;AAAA,EACF;AAEA,EAAA,IAAI,cAAA,EAAgB;AAGlB,IAAA,MAAM,qBAAqB,CAAA,EAAG,MAAA,CAAO,WAAW,CAAA,CAAA,EAAI,OAAO,eAAe,CAAA,CAAA;AAC1E,IAAA,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA,MAAA,EAAS,eAAe,CAAA,CAAE,CAAA;AACpD,IAAA,MAAM,OAAA,CAAQ,EAAA,CAAG,KAAA,CAAM,eAAA,EAAiB,kBAAkB,CAAA;AAC1D,IAAA,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA,UAAA,EAAa,eAAe,CAAA,CAAE,CAAA;AAAA,EAC1D;AAGA,EAAA,MAAM,eAAyB,EAAC;AAEhC,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,YAAA,CAAa,IAAA,CAAK,CAAA,YAAA,EAAe,eAAe,CAAA,CAAE,CAAA;AAAA,EACpD,CAAA,MAAO;AAEL,IAAA,YAAA,CAAa,KAAK,iBAAiB,CAAA;AACnC,IAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,+DAAA,CAAiE,CAAA;AAAA,EAC7F;AAEA,EAAA,YAAA,CAAa,KAAK,aAAa,CAAA;AAG/B,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,YAAA,CAAa,KAAK,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,EAAI,CAAA,IAAA,EAAO,GAAG,CAAA,CAAE,CAAA;AAAA,EAC9C;AAEA,EAAA,IAAI,OAAO,QAAA,EAAU;AAEnB,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClD,IAAA,YAAA,CAAa,KAAK,CAAA,IAAA,EAAO,QAAQ,CAAA,CAAA,EAAI,wBAAA,EAA0B,SAAS,aAAa,CAAA;AAAA,EACvF;AAEA,EAAA,IAAI,OAAO,QAAA,EAAU;AACnB,IAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,IAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,sBAAA,CAAwB,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,eAAA,GAAkB,WAAW,SAAS,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,CAAA,KAAA,EAAQ,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,eAAe,CAAA,IAAA,EAAO,YAAA,CAAa,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA;AACzF,EAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,aAAA,CAAA,EAAiB,cAAA,GAAiB,SAAS,OAAA,CAAQ,eAAA,EAAiB,KAAK,CAAA,GAAI,QAAQ,CAAA;AAE/G,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,EAAS,UAAU,EAAE,OAAA,EAAS,KAAQ,CAAA;AACtE,EAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,aAAA,CAAA,EAAiB;AAAA,IACzC,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,QAAQ,MAAA,CAAO;AAAA,GAChB,CAAA;AACD,EAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,OAAO,MAAA,IAAU,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,EAChF;AACF;AC3HA,eAAsB,QAAA,CAAS,SAAA,EAAmB,MAAA,EAA8B,GAAA,EAAkC;AAChH,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,GAAA;AAG5B,EAAA,kBAAA,CAAmB,OAAO,MAAM,CAAA;AAEhC,EAAA,MAAM,eAAA,GAAkB,WAAW,SAAS,CAAA;AAG5C,EAAA,MAAM,WAAA,GAAc,MAAM,UAAA,CAAW,OAAA,EAAS,mCAAmC,CAAA;AACjF,EAAA,IAAI,WAAA,CAAY,MAAA,CAAO,QAAA,CAAS,WAAW,CAAA,EAAG;AAC5C,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,sDAAA,CAAwD,CAAA;AACjF,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,mEAAA,CAAqE,CAAA;AAG9F,IAAA,MAAM,iBAAiB,MAAM,UAAA;AAAA,MAC3B,OAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,MAAA,CAAO,IAAA,EAAK,IAAK,UAAA;AACjD,IAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,2BAAA,EAA8B,QAAQ,CAAA,CAAE,CAAA;AAGlE,IAAA,MAAM,aAAa,MAAM,UAAA;AAAA,MACvB,OAAA;AAAA,MACA,gGAAA;AAAA,MACA,EAAE,SAAS,IAAA;AAAQ,KACrB;AACA,IAAA,IAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC7B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA;AAAA,eAAA,EAAiE,UAAA,CAAW,MAAA,IAAU,UAAA,CAAW,MAAM,CAAA;AAAA,OACzG;AAAA,IACF;AAGA,IAAA,MAAM,gBAAgB,MAAM,UAAA;AAAA,MAC1B,OAAA;AAAA,MACA,0NACuG,QAAQ,CAAA,iGAAA,CAAA;AAAA,MAE/G,EAAE,SAAS,IAAA;AAAQ,KACrB;AAEA,IAAA,IAAI,aAAA,CAAc,aAAa,CAAA,EAAG;AAChC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA;;AAAA;;AAAA,eAAA,EAGoB,aAAA,CAAc,MAAA,IAAU,aAAA,CAAc,MAAM,CAAA;AAAA,OAClE;AAAA,IACF;AAGA,IAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,OAAA,EAAS,eAAe,CAAA;AAC9D,IAAA,IAAI,YAAA,CAAa,aAAa,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA;AAAA,gBAAA,EACqB,cAAc,MAAM;AAAA,EAAK,cAAc,MAAM,CAAA;AAAA,OACpE;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,OAAA,EAAS,gBAAgB,CAAA;AAC3D,EAAA,IAAI,QAAA,CAAS,aAAa,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,SAAS,MAAA,IAAU,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,EAChF;AACA,EAAA,MAAM,CAAC,KAAK,GAAG,CAAA,GAAI,SAAS,MAAA,CAAO,IAAA,EAAK,CAAE,KAAA,CAAM,IAAI,CAAA;AAIpD,EAAA,MAAM,cAAc,GAAA,IAAO,GAAA,GAAM,SAAS,GAAG,CAAA,OAAA,EAAU,GAAG,CAAA,CAAA,GAAK,EAAA;AAE/D,EAAA,MAAM,cAAA,GAAiB,CAAC,CAAC,MAAA,CAAO,iBAAA;AAChC,EAAA,IAAI,QAAA;AAEJ,EAAA,IAAI,cAAA,EAAgB;AAElB,IAAA,MAAM,SAAA,GAAYA,uBAAAA,CAAO,UAAA,CAAW,KAAK,CAAA,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAC,CAAA;AACrF,IAAA,MAAM,OAAA,GAAU,gBAAgB,SAAS,CAAA,KAAA,CAAA;AACzC,IAAA,MAAM,UAAA,CAAW,OAAA,EAAS,CAAA,MAAA,EAAS,OAAO,CAAA,CAAE,CAAA;AAC5C,IAAA,MAAM,OAAA,CAAQ,EAAA,CAAG,KAAA,CAAM,OAAA,EAAS,OAAO,iBAAkB,CAAA;AAIzD,IAAA,QAAA,GAAW,CAAA,mBAAA,EAAsB,OAAO,CAAA,gBAAA,EAAmB,WAAW,IAAI,MAAA,CAAO,MAAM,IAAI,eAAe,CAAA,CAAA;AAAA,EAC5G,CAAA,MAAO;AAGL,IAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,mEAAA,CAAqE,CAAA;AAE/F,IAAA,QAAA,GAAW,6CAA6C,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,MAAM,IAAI,eAAe,CAAA,CAAA;AAAA,EACzG;AAEA,EAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,cAAA,CAAA,EAAkB,QAAQ,CAAA;AAEpD,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,EAAS,UAAU,EAAE,OAAA,EAAS,KAAQ,CAAA;AACtE,EAAA,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,gBAAA,CAAA,EAAoB;AAAA,IAC5C,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,QAAQ,MAAA,CAAO;AAAA,GAChB,CAAA;AACD,EAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,OAAO,MAAA,IAAU,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,EACjF;AACF;;;ACvGA,IAAM,eAAA,GAAkB,uBAAA;AAGxB,SAAS,cAAc,KAAA,EAAwB;AAC7C,EAAA,IAAI,KAAA,YAAiB,KAAA,EAAO,OAAO,KAAA,CAAM,OAAA;AACzC,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,aAAa,KAAA,IAAS,OAAQ,KAAA,CAAc,OAAA,KAAY,QAAA,EAAU;AAC1G,IAAA,OAAQ,KAAA,CAAc,OAAA;AAAA,EACxB;AACA,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB;AACF;AAEA,SAAS,kBAAkB,SAAA,EAAyB;AAClD,EAAA,IAAI,CAAC,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA,EAAG;AACpC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,uBAAuB,SAAS,CAAA,8FAAA;AAAA,KAClC;AAAA,EACF;AACF;AAGA,IAAM,gBAAA,GAAmB,mBAAA;AA0FlB,IAAM,aAAA,GAAN,cAA4BC,uBAAA,CAAc;AAAA,EACtC,EAAA;AAAA,EACA,IAAA,GAAO,eAAA;AAAA,EACP,QAAA,GAAW,QAAA;AAAA;AAAA,EAGpB,MAAA,GAAyB,SAAA;AAAA,EAEjB,QAAA,GAAmC,IAAA;AAAA,EACnC,UAAA,GAA0B,IAAA;AAAA,EAC1B,WAAA,GAAc,KAAA;AAAA,EAEL,KAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,kBAAA;AAAA,EACA,KAAA;AAAA;AAAA,EAGjB,WAAA,CAAY,OAAA,GAAgC,EAAC,EAAG;AAC9C,IAAA,KAAA,CAAM,EAAE,GAAG,OAAA,EAAS,IAAA,EAAM,iBAAiB,CAAA;AAE3C,IAAA,IAAA,CAAK,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,IAAA,CAAK,UAAA,EAAW;AACxC,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,KAAA,IAAS,sBAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AAChC,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,OAAA;AACvB,IAAA,IAAA,CAAK,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,EAAC;AAC3B,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,EAAC;AACjC,IAAA,IAAA,CAAK,qBAAqB,OAAA,CAAQ,QAAA,IAAY,CAAC,MAAA,EAAQ,UAAU,MAAM,CAAA;AACvE,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC;AAAA,EACjC;AAAA,EAEQ,UAAA,GAAqB;AAC3B,IAAA,OAAO,kBAAkB,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAAA,EAC5F;AAAA,EAEA,IAAI,iBAAA,GAA+C;AACjD,IAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,EACd;AAAA,EAEA,IAAI,cAAA,GAAiC;AACnC,IAAA,OAAO,IAAA,CAAK,kBAAA,CAAmB,CAAC,CAAA,IAAK,MAAA;AAAA,EACvC;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,EA2BA,IAAI,QAAA,GAA4B;AAC9B,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,MAAA,MAAM,IAAIC,8BAAA,CAAqB,IAAA,CAAK,EAAE,CAAA;AAAA,IACxC;AACA,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAA,CAAM,UAAA,EAAiC,SAAA,EAAyC;AACpF,IAAA,iBAAA,CAAkB,SAAS,CAAA;AAE3B,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,MAAA,MAAM,IAAIA,8BAAA,CAAqB,IAAA,CAAK,EAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,WAAA,EAAc,SAAS,CAAA,IAAA,CAAM,CAAA;AAG5D,IAAA,MAAM,MAAA,GAAS,WAAW,cAAA,IAAiB;AAC3C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,KAAA,GAAQ,CAAA,YAAA,EAAe,UAAA,CAAW,EAAE,CAAA,iCAAA,CAAA;AAC1C,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAA;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,EAAW,EAAE,YAAY,KAAA,EAAO,OAAA,EAAS,OAAO,CAAA;AAChE,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,KAAA,EAAM;AAAA,IAC5C;AAGA,IAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,kBAAA,CAAmB,WAAW,MAAM,CAAA;AACrE,IAAA,IAAI,kBAAkB,UAAA,EAAY;AAChC,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,EAAG,UAAU,CAAA,6BAAA,EAAgC,UAAA,CAAW,QAAQ,CAAA,GAAA,EAAM,UAAA,CAAW,EAAE,CAAA,OAAA,EAAU,SAAS,CAAA,+BAAA;AAAA,OACxG;AACA,MAAA,IAAA,CAAK,OAAO,GAAA,CAAI,SAAA,EAAW,EAAE,KAAA,EAAO,SAAA,EAAW,QAAQ,CAAA;AACvD,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,IACpC,CAAA,MAAA,IAAW,kBAAkB,YAAA,EAAc;AAEzC,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,2DAAA,CAA6D,CAAA;AAC5F,MAAA,MAAM,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,IAC9B;AACA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,cAAA,EAAiB,MAAA,CAAO,IAAI,CAAA,CAAE,CAAA;AAG7D,IAAA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,EAAW,EAAE,YAAY,KAAA,EAAO,UAAA,EAAY,QAAQ,CAAA;AAGpE,IAAA,IAAI;AACF,MAAA,MAAM,cAAc,MAAM,UAAA;AAAA,QACxB,IAAA,CAAK,QAAA;AAAA,QACL,CAAA,MAAA,EAAS,SAAS,CAAA,mBAAA,EAAsB,SAAS,CAAA,kDAAA;AAAA,OACnD;AACA,MAAA,IAAI,WAAA,CAAY,MAAA,CAAO,IAAA,EAAK,KAAM,WAAA,EAAa;AAC7C,QAAA,MAAM,KAAA,GAAQ,mBAAmB,SAAS,CAAA,2HAAA,CAAA;AAC1C,QAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAA;AAC1C,QAAA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,EAAW,EAAE,YAAY,KAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,CAAA;AACxE,QAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,KAAA,EAAM;AAAA,MAC5C;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAGA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,8BAAA,EAAiC,SAAS,CAAA,GAAA,CAAK,CAAA;AAC9E,IAAA,MAAM,YAAA,GAAe,aAAa,SAAS,CAAA,CAAA,CAAA;AAE3C,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,kBAAA,EAAqB,YAAY,CAAA,CAAE,CAAA;AAClE,IAAA,MAAM,WAAA,GAAc,MAAM,UAAA,CAAW,IAAA,CAAK,UAAU,YAAY,CAAA;AAEhE,IAAA,IAAI,WAAA,CAAY,aAAa,CAAA,EAAG;AAC9B,MAAA,MAAM,aAAa,CAAA,kCAAA,EAAqC,SAAS,MAAM,WAAA,CAAY,MAAA,IAAU,YAAY,MAAM,CAAA,CAAA;AAC/G,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,kBAAA,EAAqB,SAAS,MAAM,UAAU,CAAA;AAC7E,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,EAAE,UAAA,EAAY,OAAO,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,CAAA;AACpF,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,SAAA,EAAW,OAAO,UAAA,EAAW;AAAA,IACxD;AACA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,yCAAA,EAA4C,SAAS,MAAM,WAAW,CAAA;AAGrG,IAAA,MAAM,QAAA,GAAyB;AAAA,MAC7B,SAAS,IAAA,CAAK,QAAA;AAAA,MACd,QAAQ,IAAA,CAAK;AAAA,KACf;AAEA,IAAA,IAAI;AACF,MAAA,QAAQ,OAAO,IAAA;AAAM,QACnB,KAAK,IAAA;AACH,UAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,uBAAA,EAA0B,SAAS,CAAA,GAAA,CAAK,CAAA;AACvE,UAAA,MAAM,OAAA,CAAQ,SAAA,EAAW,MAAA,EAA+B,QAAQ,CAAA;AAChE,UAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAE,CAAA;AACnE,UAAA;AAAA,QACF,KAAK,KAAA;AACH,UAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,wBAAA,EAA2B,SAAS,CAAA,GAAA,CAAK,CAAA;AACxE,UAAA,MAAM,QAAA,CAAS,SAAA,EAAW,MAAA,EAAgC,QAAQ,CAAA;AAClE,UAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,uBAAA,EAA0B,SAAS,CAAA,CAAE,CAAA;AACpE,UAAA;AAAA,QACF;AACE,UAAA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,EAAW;AAAA,YACzB,UAAA;AAAA,YACA,KAAA,EAAO,aAAA;AAAA,YACP,MAAA;AAAA,YACA,KAAA,EAAO,CAAA,wBAAA,EAA4B,MAAA,CAAiC,IAAI,CAAA;AAAA,WACzE,CAAA;AACD,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,KAAA;AAAA,YACT,SAAA;AAAA,YACA,KAAA,EAAO,CAAA,wBAAA,EAA4B,MAAA,CAAiC,IAAI,CAAA;AAAA,WAC1E;AAAA;AACJ,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,EAAG,UAAU,CAAA,iBAAA,EAAoB,UAAA,CAAW,QAAQ,CAAA,GAAA,EAAM,UAAA,CAAW,EAAE,CAAA,MAAA,EAAS,SAAS,CAAA,EAAA,CAAA;AAAA,QACzF;AAAA,OACF;AACA,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,EAAE,UAAA,EAAY,KAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,aAAA,CAAc,KAAK,CAAA,EAAG,CAAA;AAG9F,MAAA,IAAI;AACF,QAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAW,CAAA,OAAA,EAAU,SAAS,CAAA,qBAAA,CAAuB,CAAA;AAC3E,QAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,0CAAA,EAA6C,SAAS,CAAA,CAAE,CAAA;AAAA,MACzF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,WAAW,KAAA,EAAO,aAAA,CAAc,KAAK,CAAA,EAAE;AAAA,IAClE;AAGA,IAAA,IAAA,CAAK,OAAO,GAAA,CAAI,SAAA,EAAW,EAAE,KAAA,EAAO,SAAA,EAAW,QAAQ,CAAA;AAGvD,IAAA,MAAM,IAAA,CAAK,gBAAgB,SAAS,CAAA;AAEpC,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,SAAA,EAAY,SAAS,CAAA,CAAE,CAAA;AACtD,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,gBAAgB,SAAA,EAAkC;AAC9D,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAEpB,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,SAAS,CAAA;AAC5D,IAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe,SAAS,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,uBAAuB,QAAQ,CAAA,CAAA;AAClD,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAU,8BAA8B,CAAA;AAC9D,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,KAAA,CAAM,YAAY,aAAa,CAAA;AAAA,IACxD,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,yCAAA,EAA4C,UAAU,CAAA,CAAE,CAAA;AAAA,IACzF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,SAAA,EAAkC;AAC9C,IAAA,iBAAA,CAAkB,SAAS,CAAA;AAE3B,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,MAAA,MAAM,IAAIA,8BAAA,CAAqB,IAAA,CAAK,EAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,YAAA,EAAe,SAAS,CAAA,GAAA,CAAK,CAAA;AAE5D,IAAA,IAAI;AAEF,MAAA,MAAM,SAAS,MAAM,UAAA;AAAA,QACnB,IAAA,CAAK,QAAA;AAAA,QACL,CAAA,eAAA,EAAkB,SAAS,CAAA,yBAAA,EAA4B,SAAS,CAAA,CAAA;AAAA,OAClE;AACA,MAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,qBAAqB,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA;AAAA,MACtF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,mBAAmB,KAAK,CAAA;AAEvD,MAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAU,CAAA,WAAA,EAAc,SAAS,CAAA,qBAAA,CAAuB,CAAA;AAAA,IAChF;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,SAAS,CAAA;AAG5B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe,SAAS,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,uBAAuB,QAAQ,CAAA,CAAA;AAClD,IAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAU,CAAA,OAAA,EAAU,UAAU,CAAA,qBAAA,CAAuB,CAAA;AAI3E,IAAA,MAAM,cAAc,MAAM,UAAA,CAAW,KAAK,QAAA,EAAU,CAAA,OAAA,EAAU,SAAS,CAAA,MAAA,CAAQ,CAAA;AAC/E,IAAA,IAAI,WAAA,CAAY,aAAa,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,uBAAA,EAA0B,SAAS,CAAA,CAAE,CAAA;AAAA,IACtE,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,EAAG,UAAU,CAAA,WAAA,EAAc,SAAS,4BAA4B,WAAA,CAAY,MAAA,EAAQ,IAAA,EAAK,IAAK,WAAW,CAAA,CAAA;AAAA,OAC3G;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAA,GAAkE;AACtE,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,MAAO;AAAA,MAC7D,IAAA;AAAA,MACA,YAAY,KAAA,CAAM,UAAA,EAAY,QAAA,IAAY,KAAA,CAAM,QAAQ,IAAA,IAAQ;AAAA,KAClE,CAAE,CAAA;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAAgB,kBAAA,EAA6C;AACjE,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AAClB,MAAA,MAAM,IAAIA,8BAAA,CAAqB,IAAA,CAAK,EAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,wCAAwC,kBAAkB,CAAA;AAIzF,IAAA,MAAM,eAAe,MAAM,UAAA;AAAA,MACzB,IAAA,CAAK,QAAA;AAAA,MACL,CAAA,uEAAA;AAAA,KACF;AACA,IAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,MAAA,CAChC,IAAA,EAAK,CACL,KAAA,CAAM,IAAI,CAAA,CACV,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AAE3B,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,oCAAoC,aAAa,CAAA;AAGhF,IAAA,MAAM,aAAA,GAAgB,MAAM,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA,8CAAA,CAAgD,CAAA;AACtG,IAAA,MAAM,cAAc,aAAA,CAAc,MAAA,CAC/B,IAAA,EAAK,CACL,MAAM,IAAI,CAAA,CACV,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,MAAA,GAAS,CAAA,IAAK,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAC,CAAA;AAGvD,IAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAoB;AAClD,IAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AACpC,MAAA,MAAM,eAAe,MAAM,UAAA;AAAA,QACzB,IAAA,CAAK,QAAA;AAAA,QACL,4BAA4B,UAAU,CAAA,wBAAA;AAAA,OACxC;AACA,MAAA,MAAM,SAAS,IAAA,CAAK,MAAA,CAAO,mBAAmB,YAAA,CAAa,MAAA,CAAO,MAAM,CAAA;AACxE,MAAA,IAAI,MAAA,IAAU,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,EAAG;AAC/C,QAAA,iBAAA,CAAkB,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,UAAU,CAAA;AAAA,MAC/C;AAAA,IACF;AAGA,IAAA,MAAM,WAAA,GAAc,cAAc,MAAA,CAAO,CAAA,IAAA,KAAQ,CAAC,kBAAA,CAAmB,QAAA,CAAS,IAAI,CAAC,CAAA;AAEnF,IAAA,KAAA,MAAW,aAAa,WAAA,EAAa;AACnC,MAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,SAAS,CAAA,EAAG;AACpC,QAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,mCAAA,EAAsC,SAAS,CAAA,eAAA,CAAiB,CAAA;AAC/F,QAAA,MAAM,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,8BAAA,EAAiC,SAAS,CAAA,mBAAA,CAAqB,CAAA;AAAA,MAChG;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,mBAAA,GAAsB,IAAI,GAAA,CAAI,kBAAA,CAAmB,GAAA,CAAI,CAAA,CAAA,KAAK,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe,CAAC,CAAC,CAAC,CAAA;AAG9F,MAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoB;AAC7C,MAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,iBAAA,EAAmB;AAC5C,QAAA,YAAA,CAAa,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,MAC7B;AAEA,MAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AAEpC,QAAA,IAAI,CAAC,mBAAA,CAAoB,GAAA,CAAI,UAAU,CAAA,EAAG;AACxC,UAAA,MAAM,SAAA,GAAY,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA;AAE7C,UAAA,IAAI,SAAA,EAAW;AAEb,YAAA,IAAI,CAAC,aAAA,CAAc,QAAA,CAAS,SAAS,CAAA,EAAG;AACtC,cAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,+CAAA,EAAkD,SAAS,CAAA,CAAE,CAAA;AAG5F,cAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAW,CAAA,2BAAA,EAA8B,UAAU,CAAA,qBAAA,CAAuB,CAAA;AAGhG,cAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAW,CAAA,OAAA,EAAU,SAAS,CAAA,qBAAA,CAAuB,CAAA;AAAA,YAC7E;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,iCAAA,EAAoC,UAAU,CAAA,CAAE,CAAA;AAC/E,YAAA,MAAM,UAAA,CAAW,IAAA,CAAK,QAAA,EAAW,CAAA,2BAAA,EAA8B,UAAU,CAAA,qBAAA,CAAuB,CAAA;AAAA,UAClG;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAEN,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,wCAAA,CAA0C,CAAA;AAAA,IAC3E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,kBAAA,CACZ,SAAA,EACA,SAAA,EACoD;AACpD,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,QAAgB,IAAIA,8BAAA,CAAqB,KAAK,EAAE,CAAA;AAG1D,IAAA,MAAM,aAAa,MAAM,UAAA;AAAA,MACvB,IAAA,CAAK,QAAA;AAAA,MACL,kBAAkB,SAAS,CAAA,yCAAA;AAAA,KAC7B;AAEA,IAAA,IAAI,UAAA,CAAW,MAAA,CAAO,IAAA,EAAK,KAAM,SAAA,EAAW;AAC1C,MAAA,OAAO,aAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe,SAAS,CAAA;AACrD,IAAA,MAAM,UAAA,GAAa,uBAAuB,QAAQ,CAAA,CAAA;AAElD,IAAA,IAAI;AACF,MAAA,MAAM,eAAe,MAAM,UAAA,CAAW,KAAK,QAAA,EAAU,CAAA,KAAA,EAAQ,UAAU,CAAA,wBAAA,CAA0B,CAAA;AACjG,MAAA,MAAM,SAAS,IAAA,CAAK,MAAA,CAAO,mBAAmB,YAAA,CAAa,MAAA,CAAO,MAAM,CAAA;AAExE,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,OAAO,YAAA;AAAA,MACT;AAGA,MAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,MAAA,CAAO,iBAAA,CAAkB,SAAS,CAAA;AAC7D,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,GAAG,UAAU,CAAA,8BAAA,EAAiC,MAAA,CAAO,UAAU,wBAAwB,aAAa,CAAA,CAAA;AAAA,OACtG;AAEA,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,SAAA,IAAa,MAAA,CAAO,eAAe,aAAA,EAAe;AACpE,QAAA,OAAO,UAAA;AAAA,MACT;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAEA,IAAA,OAAO,YAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,KAAA,GAAuB;AAE3B,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,EAAE,CAAA;AAE9C,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,mBAAA,EAAsB,WAAW,CAAA,CAAE,CAAA;AAGlE,IAAA,MAAM,eAAA,GAAkB,MAAM,IAAA,CAAK,mBAAA,CAAoB,WAAW,CAAA;AAElE,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,IAAA,CAAK,QAAA,GAAW,eAAA;AAChB,MAAA,IAAA,CAAK,UAAA,uBAAiB,IAAA,EAAK;AAC3B,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,kCAAA,EAAqC,WAAW,CAAA,CAAE,CAAA;AAIjF,MAAA,MAAM,gBAAgB,KAAA,CAAM,IAAA,CAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AAC3D,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,gCAAA,CAAkC,CAAA;AACjE,MAAA,MAAM,IAAA,CAAK,gBAAgB,aAAa,CAAA;AACxC,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,8BAAA,CAAgC,CAAA;AAC/D,MAAA;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,uBAAA,EAA0B,WAAW,CAAA,CAAE,CAAA;AAEtE,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,QAAA,GAAW,MAAMC,oBAAA,CAAgB,MAAA,CAAO;AAAA,QAC3C,IAAA,EAAM,WAAA;AAAA,QACN,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,GAAI,IAAA,CAAK,OAAA,IAAW,EAAE,GAAA,EAAK,KAAK,OAAA,EAAQ;AAAA,QACxC,IAAA,EAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,MAAM,KAAK,CAAA,MAAO,EAAE,IAAA,EAAM,OAAM,CAAE,CAAA;AAAA,QACvE,MAAA,EAAQ;AAAA,UACN,GAAG,IAAA,CAAK,MAAA;AAAA,UACR,qBAAqB,IAAA,CAAK;AAAA,SAC5B;AAAA,QACA,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,MAAM;AAAA,UAC1B,MAAM,CAAA,CAAE,IAAA;AAAA,UACR,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,QAAA,EAAU,EAAE,QAAA,IAAY;AAAA,SAC1B,CAAE;AAAA,OACH,CAAA;AAAA,IACH,SAAS,WAAA,EAAa;AAGpB,MAAA,IAAI,uBAAuB,KAAA,EAAO;AAChC,QAAA,MAAM,WAAA;AAAA,MACR;AACA,MAAA,MAAM,IAAI,KAAA,CAAM,aAAA,CAAc,WAAW,CAAC,CAAA;AAAA,IAC5C;AAEA,IAAA,IAAA,CAAK,UAAA,uBAAiB,IAAA,EAAK;AAC3B,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,gBAAA,EAAmB,WAAW,CAAA,UAAA,EAAa,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EAEnG;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,EAAA,EAAoB;AACxC,IAAA,MAAM,OAAO,EAAA,CACV,WAAA,GACA,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,KAAA,EAAO,GAAG,EAClB,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA,CACpB,KAAA,CAAM,GAAG,EAAE,CAAA;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,+CAA+C,EAAE,CAAA,uDAAA;AAAA,OACnD;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,oBAAoB,WAAA,EAAsD;AACtF,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAMA,oBAAA,CAAgB,GAAA,CAAI,WAAW,CAAA;AAGtD,MAAA,IAAI,QAAA,CAAS,WAAW,UAAA,EAAY;AAClC,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,4BAA4B,WAAW,CAAA,UAAA,EAAa,QAAA,CAAS,MAAM,CAAA,CAAA,CAAG,CAAA;AACrG,QAAA,OAAO,QAAA;AAAA,MACT;AAEA,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,GAAG,UAAU,CAAA,eAAA,EAAkB,WAAW,CAAA,eAAA,EAAkB,SAAS,MAAM,CAAA,kBAAA;AAAA,OAC7E;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,+BAAA,EAAkC,WAAW,KAAK,CAAC,CAAA;AAAA,IACpF;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IAAA,GAAsB;AAG1B,IAAA,KAAA,MAAW,SAAA,IAAa,CAAC,GAAG,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA,EAAM,CAAA,EAAG;AACvD,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,MAC9B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAA,GAAyB;AAG7B,IAAA,KAAA,MAAW,SAAA,IAAa,CAAC,GAAG,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA,EAAM,CAAA,EAAG;AACvD,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,MAC9B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK,SAAS,MAAA,EAAO;AAAA,MAC7B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAA4B;AAChC,IAAA,OAAO,IAAA,CAAK,MAAA,KAAW,SAAA,IAAa,IAAA,CAAK,QAAA,KAAa,IAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAAgC;AACpC,IAAA,OAAO;AAAA,MACL,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,SAAA,EAAW,IAAA,CAAK,UAAA,oBAAc,IAAI,IAAA,EAAK;AAAA,MACvC,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,MAAO;AAAA,QAC9D,IAAA;AAAA,QACA,YAAY,KAAA,CAAM,UAAA,EAAY,QAAA,IAAY,KAAA,CAAM,QAAQ,IAAA,IAAQ;AAAA,OAClE,CAAE,CAAA;AAAA,MACF,QAAA,EAAU;AAAA,QACR,GAAG,IAAA,CAAK,MAAA;AAAA,QACR,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,aAAA,EAAe,KAAK,QAAA,EAAU;AAAA;AAChC,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAA,GAA0B;AACxB,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,IAAA;AACvC,IAAA,MAAM,SAAA,GAAY,UAAA,GAAa,CAAA,GAAI,CAAA,CAAA,EAAI,UAAU,CAAA,gCAAA,CAAA,GAAqC,EAAA;AACtF,IAAA,OAAO,sDAAsD,SAAS,CAAA,CAAA;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,aAAA,GAA0C;AACtD,IAAA,MAAM,KAAK,aAAA,EAAc;AACzB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAmB,KAAA,EAAyB;AAClD,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,MAAM,QAAA,GAAW,cAAc,KAAK,CAAA;AACpC,IAAA,OACE,QAAA,CAAS,QAAA,CAAS,YAAY,CAAA,IAC9B,QAAA,CAAS,SAAS,uBAAuB,CAAA,IACzC,QAAA,CAAS,QAAA,CAAS,mBAAmB,CAAA;AAAA,EAEzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,oBAAA,GAA6B;AACnC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAGhB,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,CAAA,IAAK,IAAA,CAAK,OAAO,OAAA,EAAS;AAC/C,MAAA,IAAI,KAAA,CAAM,KAAA,KAAU,SAAA,IAAa,KAAA,CAAM,UAAU,UAAA,EAAY;AAC3D,QAAA,IAAA,CAAK,OAAO,GAAA,CAAI,IAAA,EAAM,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,MAC5C;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,SAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,eACJ,OAAA,EACA,IAAA,GAAiB,EAAC,EAClB,OAAA,GAAiC,EAAC,EACV;AACxB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,YAAA,EAAe,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI,OAAO,CAAA;AAClF,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,aAAA,EAAc;AAEzC,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,GAAG,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAAK,OAAA;AAEvF,IAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,YAAA,EAAe,WAAW,CAAA,CAAE,CAAA;AAE3D,IAAA,IAAI;AAGF,MAAA,MAAM,YAAY,EAAE,GAAG,KAAK,GAAA,EAAK,GAAG,QAAQ,GAAA,EAAI;AAChD,MAAA,MAAM,YAAY,MAAA,CAAO,WAAA;AAAA,QACvB,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,CAAE,MAAA,CAAO,CAAC,KAAA,KAAqC,KAAA,CAAM,CAAC,CAAA,KAAM,MAAS;AAAA,OAC/F;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK;AAAA,QACxC,OAAA,EAAS,WAAA;AAAA,QACT,YAAY,OAAA,CAAQ,GAAA;AAAA,QACpB,GAAA,EAAK,SAAA;AAAA,QACL,iBAAA,EAAmB,IAAA;AAAA,QACnB,GAAI,OAAA,CAAQ,OAAA,IAAW,EAAE,OAAA,EAAS,KAAK,IAAA,CAAK,OAAA,CAAQ,OAAA,GAAU,GAAI,CAAA,EAAE;AAAA,QACpE,GAAI,OAAA,CAAQ,QAAA,IAAY,OAAA,CAAQ,QAAA,GAC5B;AAAA,UACE,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,UAAU,OAAA,CAAQ;AAAA,YAEpB;AAAC,OACN,CAAA;AAED,MAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AACrC,MAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,CAAA;AACpC,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,EAAA;AAChC,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,EAAA;AAEhC,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,eAAe,QAAQ,CAAA,EAAA,EAAK,eAAe,CAAA,GAAA,CAAK,CAAA;AAC/E,MAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,GAAG,UAAU,CAAA;AAAA,EAAa,MAAM,CAAA,CAAE,CAAA;AAChE,MAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,GAAG,UAAU,CAAA;AAAA,EAAa,MAAM,CAAA,CAAE,CAAA;AAEhE,MAAA,OAAO;AAAA,QACL,SAAS,QAAA,KAAa,CAAA;AAAA,QACtB,QAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA,eAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AAEd,MAAA,IAAI,KAAK,kBAAA,CAAmB,KAAK,CAAA,IAAK,CAAC,KAAK,WAAA,EAAa;AACvD,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,QAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS,MAAM,OAAO,CAAA;AAAA,QACzD,CAAA,SAAE;AACA,UAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,QACrB;AAAA,MACF;AAEA,MAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAErC,MAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAElC,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,EAAG,UAAU,qBAAqB,eAAe,CAAA,KAAA,EAAQ,MAAM,CAAA,CAAE,CAAA;AAEnF,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,QAAA,EAAU,CAAA;AAAA,QACV,MAAA,EAAQ,EAAA;AAAA,QACR,MAAA;AAAA,QACA,eAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF","file":"index.cjs","sourcesContent":["/**\n * Shell-quote a single argument for safe use in a command string.\n *\n * Arguments containing only safe characters are returned as-is.\n * All others are wrapped in single quotes with embedded single quotes escaped.\n */\nexport function shellQuote(arg: string): string {\n // Safe characters that don't need quoting\n if (/^[a-zA-Z0-9._\\-/@:=]+$/.test(arg)) return arg;\n // Wrap in single quotes, escaping any embedded single quotes\n return \"'\" + arg.replace(/'/g, \"'\\\\''\") + \"'\";\n}\n","/**\n * Shared types for Blaxel mount operations.\n */\n\nimport type { SandboxInstance } from '@blaxel/core';\n\nexport const LOG_PREFIX = '[@mastra/blaxel]';\n\nimport type { BlaxelGCSMountConfig } from './gcs';\nimport type { BlaxelS3MountConfig } from './s3';\n\n/**\n * Union of mount configs supported by Blaxel sandbox.\n */\nexport type BlaxelMountConfig = BlaxelS3MountConfig | BlaxelGCSMountConfig;\n\n/**\n * Context for mount operations.\n */\nexport interface MountContext {\n sandbox: SandboxInstance;\n logger: {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n };\n}\n\n/**\n * Validate a bucket name before interpolating into shell commands.\n * Covers S3, GCS, and S3-compatible (R2, MinIO) naming rules.\n */\nconst SAFE_BUCKET_NAME = /^[a-z0-9][a-z0-9.\\-]{1,61}[a-z0-9]$/;\n\nexport function validateBucketName(bucket: string): void {\n if (!SAFE_BUCKET_NAME.test(bucket)) {\n throw new Error(\n `Invalid bucket name: \"${bucket}\". Bucket names must be 3-63 characters, lowercase alphanumeric, hyphens, or dots.`,\n );\n }\n}\n\n/**\n * Validate an endpoint URL before interpolating into shell commands.\n * Only http and https schemes are allowed.\n */\nexport function validateEndpoint(endpoint: string): void {\n let parsed: URL;\n try {\n parsed = new URL(endpoint);\n } catch {\n throw new Error(`Invalid endpoint URL: \"${endpoint}\"`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error(`Invalid endpoint URL scheme: \"${parsed.protocol}\". Only http: and https: are allowed.`);\n }\n}\n\n/**\n * Run a command in the Blaxel sandbox and return the result.\n * Wraps the process.exec API to match the command execution pattern used in mount operations.\n *\n * Does NOT throw on non-zero exit codes — callers should check `exitCode` themselves.\n */\nexport async function runCommand(\n sandbox: SandboxInstance,\n command: string,\n options?: { timeout?: number },\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const result = await sandbox.process.exec({\n command,\n waitForCompletion: true,\n ...(options?.timeout && { timeout: Math.ceil(options.timeout / 1000) }),\n });\n\n return {\n exitCode: result.exitCode ?? 0,\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n };\n}\n","import crypto from 'node:crypto';\n\nimport type { FilesystemMountConfig } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../../utils/shell-quote';\nimport { LOG_PREFIX, validateBucketName, validateEndpoint, runCommand } from './types';\nimport type { MountContext } from './types';\n\n/**\n * S3 mount config for Blaxel (mounted via s3fs-fuse).\n *\n * If credentials are not provided, the bucket will be mounted as read-only\n * using the `public_bucket=1` option (for public AWS S3 buckets only).\n *\n * Note: S3-compatible services (R2, MinIO, etc.) always require credentials.\n */\nexport interface BlaxelS3MountConfig extends FilesystemMountConfig {\n type: 's3';\n /** S3 bucket name */\n bucket: string;\n /** AWS region */\n region: string;\n /** S3 endpoint for S3-compatible storage (MinIO, etc.) */\n endpoint?: string;\n /** AWS access key ID (optional - omit for public buckets) */\n accessKeyId?: string;\n /** AWS secret access key (optional - omit for public buckets) */\n secretAccessKey?: string;\n /** Mount as read-only (even if credentials have write access) */\n readOnly?: boolean;\n}\n\n/**\n * Mount an S3 bucket using s3fs-fuse.\n */\nexport async function mountS3(mountPath: string, config: BlaxelS3MountConfig, ctx: MountContext): Promise<void> {\n const { sandbox, logger } = ctx;\n\n // Validate inputs before interpolating into shell commands\n validateBucketName(config.bucket);\n if (config.endpoint) {\n validateEndpoint(config.endpoint);\n }\n\n // Check if s3fs is installed\n const checkResult = await runCommand(sandbox, 'which s3fs || echo \"not found\"');\n if (checkResult.stdout.includes('not found')) {\n logger.warn(`${LOG_PREFIX} s3fs not found, attempting runtime installation...`);\n logger.info(`${LOG_PREFIX} Tip: For faster startup, pre-install s3fs in your sandbox image`);\n\n const updateResult = await runCommand(sandbox, 'apt-get update 2>&1', { timeout: 60000 });\n if (updateResult.exitCode !== 0) {\n throw new Error(\n `Failed to update package lists for s3fs installation.\\n` +\n `Error details: ${updateResult.stderr || updateResult.stdout}`,\n );\n }\n\n const installResult = await runCommand(\n sandbox,\n 'apt-get install -y s3fs fuse 2>&1 || apt-get install -y s3fs-fuse fuse 2>&1',\n { timeout: 120000 },\n );\n\n if (installResult.exitCode !== 0) {\n throw new Error(\n `Failed to install s3fs. ` +\n `For S3 mounting, your sandbox image needs s3fs and fuse packages.\\n\\n` +\n `Pre-install in your image: apt-get install -y s3fs fuse\\n\\n` +\n `Error details: ${installResult.stderr || installResult.stdout}`,\n );\n }\n }\n\n // Get user's uid/gid for proper file ownership\n const idResult = await runCommand(sandbox, 'id -u && id -g');\n if (idResult.exitCode !== 0) {\n throw new Error(`Failed to get uid/gid: ${idResult.stderr || idResult.stdout}`);\n }\n const [uid, gid] = idResult.stdout.trim().split('\\n');\n\n // Determine if we have credentials or using public bucket mode\n const hasCredentials = config.accessKeyId && config.secretAccessKey;\n\n // Use a mount-specific credentials path to avoid races with concurrent mounts\n const mountHash = crypto.createHash('md5').update(mountPath).digest('hex').slice(0, 8);\n const credentialsPath = `/tmp/.passwd-s3fs-${mountHash}`;\n\n // S3-compatible services (R2, MinIO, etc.) require credentials\n // public_bucket=1 only works for truly public AWS S3 buckets\n if (!hasCredentials && config.endpoint) {\n throw new Error(\n `S3-compatible storage requires credentials. ` +\n `Detected endpoint: ${config.endpoint}. ` +\n `The public_bucket option only works for AWS S3 public buckets, not R2, MinIO, etc.`,\n );\n }\n\n if (hasCredentials) {\n // Write credentials file (remove old one first to avoid permission issues)\n // s3fs requires the file to have 600 permissions (no \"others\" access)\n const credentialsContent = `${config.accessKeyId}:${config.secretAccessKey}`;\n await runCommand(sandbox, `rm -f ${credentialsPath}`);\n await sandbox.fs.write(credentialsPath, credentialsContent);\n await runCommand(sandbox, `chmod 600 ${credentialsPath}`);\n }\n\n // Build mount options\n const mountOptions: string[] = [];\n\n if (hasCredentials) {\n mountOptions.push(`passwd_file=${credentialsPath}`);\n } else {\n // Public bucket mode - read-only access without credentials\n mountOptions.push('public_bucket=1');\n logger.debug(`${LOG_PREFIX} No credentials provided, mounting as public bucket (read-only)`);\n }\n\n mountOptions.push('allow_other'); // Allow non-root users to access the mount\n\n // Set uid/gid so mounted files are owned by user, not root\n if (uid && gid) {\n mountOptions.push(`uid=${uid}`, `gid=${gid}`);\n }\n\n if (config.endpoint) {\n // For S3-compatible storage (MinIO, R2, etc.)\n const endpoint = config.endpoint.replace(/\\/$/, '');\n mountOptions.push(`url=${endpoint}`, 'use_path_request_style', 'sigv4', 'nomultipart');\n }\n\n if (config.readOnly) {\n mountOptions.push('ro');\n logger.debug(`${LOG_PREFIX} Mounting as read-only`);\n }\n\n const quotedMountPath = shellQuote(mountPath);\n const mountCmd = `s3fs ${config.bucket} ${quotedMountPath} -o ${mountOptions.join(' -o ')}`;\n logger.debug(`${LOG_PREFIX} Mounting S3:`, hasCredentials ? mountCmd.replace(credentialsPath, '***') : mountCmd);\n\n const result = await runCommand(sandbox, mountCmd, { timeout: 60_000 });\n logger.debug(`${LOG_PREFIX} s3fs result:`, {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n });\n if (result.exitCode !== 0) {\n throw new Error(`Failed to mount S3 bucket: ${result.stderr || result.stdout}`);\n }\n}\n","import crypto from 'node:crypto';\n\nimport type { FilesystemMountConfig } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../../utils/shell-quote';\n\nimport { LOG_PREFIX, validateBucketName, runCommand } from './types';\nimport type { MountContext } from './types';\n\n/**\n * GCS mount config for Blaxel (mounted via gcsfuse).\n *\n * If credentials are not provided, the bucket will be mounted as read-only\n * using anonymous access (for public buckets only).\n */\nexport interface BlaxelGCSMountConfig extends FilesystemMountConfig {\n type: 'gcs';\n /** GCS bucket name */\n bucket: string;\n /** Service account key JSON (optional - omit for public buckets) */\n serviceAccountKey?: string;\n}\n\n/**\n * Mount a GCS bucket using gcsfuse.\n */\nexport async function mountGCS(mountPath: string, config: BlaxelGCSMountConfig, ctx: MountContext): Promise<void> {\n const { sandbox, logger } = ctx;\n\n // Validate inputs before interpolating into shell commands\n validateBucketName(config.bucket);\n\n const quotedMountPath = shellQuote(mountPath);\n\n // Install gcsfuse if not present\n const checkResult = await runCommand(sandbox, 'which gcsfuse || echo \"not found\"');\n if (checkResult.stdout.includes('not found')) {\n logger.warn(`${LOG_PREFIX} gcsfuse not found, attempting runtime installation...`);\n logger.info(`${LOG_PREFIX} Tip: For faster startup, pre-install gcsfuse in your sandbox image`);\n\n // Detect distro codename for the gcsfuse repo (default to bookworm for Debian)\n const codenameResult = await runCommand(\n sandbox,\n 'cat /etc/os-release 2>/dev/null | grep VERSION_CODENAME | cut -d= -f2 || echo bookworm',\n );\n const codename = codenameResult.stdout.trim() || 'bookworm';\n logger.debug(`${LOG_PREFIX} Detected distro codename: ${codename}`);\n\n // Ensure required tools and keyring directory exist\n const prepResult = await runCommand(\n sandbox,\n 'apt-get update && apt-get install -y curl gnupg lsb-release fuse && mkdir -p /etc/apt/keyrings',\n { timeout: 120_000 },\n );\n if (prepResult.exitCode !== 0) {\n throw new Error(\n `Failed to install gcsfuse prerequisites.\\n` + `Error details: ${prepResult.stderr || prepResult.stdout}`,\n );\n }\n\n // Add gcsfuse repo and install\n const installResult = await runCommand(\n sandbox,\n 'curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/gcsfuse.gpg && ' +\n `echo \"deb [signed-by=/etc/apt/keyrings/gcsfuse.gpg] https://packages.cloud.google.com/apt gcsfuse-${codename} main\" | tee /etc/apt/sources.list.d/gcsfuse.list && ` +\n 'apt-get update && apt-get install -y gcsfuse',\n { timeout: 120_000 },\n );\n\n if (installResult.exitCode !== 0) {\n throw new Error(\n `Failed to install gcsfuse. ` +\n `For GCS mounting, your sandbox image needs gcsfuse and fuse packages.\\n\\n` +\n `Pre-install in your image: apt-get install -y gcsfuse fuse\\n\\n` +\n `Error details: ${installResult.stderr || installResult.stdout}`,\n );\n }\n\n // Verify installation\n const verifyResult = await runCommand(sandbox, 'which gcsfuse');\n if (verifyResult.exitCode !== 0) {\n throw new Error(\n `gcsfuse installation appeared to succeed but binary not found on PATH.\\n` +\n `Install output: ${installResult.stdout}\\n${installResult.stderr}`,\n );\n }\n }\n\n // Get user's uid/gid for proper file ownership\n const idResult = await runCommand(sandbox, 'id -u && id -g');\n if (idResult.exitCode !== 0) {\n throw new Error(`Failed to get uid/gid: ${idResult.stderr || idResult.stdout}`);\n }\n const [uid, gid] = idResult.stdout.trim().split('\\n');\n\n // Build gcsfuse flags\n // Note: gcsfuse uses --uid/--gid flags, not -o uid=X style\n const uidGidFlags = uid && gid ? `--uid=${uid} --gid=${gid}` : '';\n\n const hasCredentials = !!config.serviceAccountKey;\n let mountCmd: string;\n\n if (hasCredentials) {\n // Use a mount-specific key path to avoid races with concurrent mounts\n const mountHash = crypto.createHash('md5').update(mountPath).digest('hex').slice(0, 8);\n const keyPath = `/tmp/gcs-key-${mountHash}.json`;\n await runCommand(sandbox, `rm -f ${keyPath}`);\n await sandbox.fs.write(keyPath, config.serviceAccountKey!);\n\n // Mount with credentials using --key-file flag\n // -o allow_other lets non-root users access the FUSE mount\n mountCmd = `gcsfuse --key-file=${keyPath} -o allow_other ${uidGidFlags} ${config.bucket} ${quotedMountPath}`;\n } else {\n // Public bucket mode - read-only access without credentials\n // Use --anonymous-access flag (not -o option)\n logger.debug(`${LOG_PREFIX} No credentials provided, mounting GCS as public bucket (read-only)`);\n\n mountCmd = `gcsfuse --anonymous-access -o allow_other ${uidGidFlags} ${config.bucket} ${quotedMountPath}`;\n }\n\n logger.debug(`${LOG_PREFIX} Mounting GCS:`, mountCmd);\n\n const result = await runCommand(sandbox, mountCmd, { timeout: 60_000 });\n logger.debug(`${LOG_PREFIX} gcsfuse result:`, {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n });\n if (result.exitCode !== 0) {\n throw new Error(`Failed to mount GCS bucket: ${result.stderr || result.stdout}`);\n }\n}\n","/**\n * Blaxel Sandbox Provider\n *\n * A Blaxel sandbox implementation that supports mounting\n * cloud filesystems (S3, GCS, R2) via FUSE.\n *\n * @see https://docs.blaxel.ai\n */\n\nimport { SandboxInstance } from '@blaxel/core';\nimport type {\n SandboxInfo,\n ExecuteCommandOptions,\n CommandResult,\n WorkspaceFilesystem,\n MountResult,\n FilesystemMountConfig,\n ProviderStatus,\n MountManager,\n MastraSandboxOptions,\n} from '@mastra/core/workspace';\nimport { MastraSandbox, SandboxNotReadyError } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../utils/shell-quote';\nimport { mountS3, mountGCS, LOG_PREFIX, runCommand } from './mounts';\nimport type { BlaxelMountConfig, BlaxelS3MountConfig, BlaxelGCSMountConfig, MountContext } from './mounts';\n\n/** Allowlist pattern for mount paths — absolute path with safe characters only. */\nconst SAFE_MOUNT_PATH = /^\\/[a-zA-Z0-9_.\\-/]+$/;\n\n/** Convert an unknown error to a readable string. */\nfunction errorToString(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n if (error && typeof error === 'object' && 'message' in error && typeof (error as any).message === 'string') {\n return (error as any).message;\n }\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n}\n\nfunction validateMountPath(mountPath: string): void {\n if (!SAFE_MOUNT_PATH.test(mountPath)) {\n throw new Error(\n `Invalid mount path: ${mountPath}. Must be an absolute path with alphanumeric, dash, dot, underscore, or slash characters only.`,\n );\n }\n}\n\n/** Allowlist for marker filenames from ls output — e.g. \"mount-abc123\" */\nconst SAFE_MARKER_NAME = /^mount-[a-z0-9]+$/;\n\n// =============================================================================\n// Blaxel Sandbox Options\n// =============================================================================\n\n/**\n * Runtime types supported by Blaxel.\n */\nexport type SandboxRuntime = 'node' | 'python' | 'bash' | 'ruby' | 'go' | 'rust' | 'java' | 'cpp' | 'r';\n\n/**\n * Blaxel sandbox provider configuration.\n */\nexport interface BlaxelSandboxOptions extends MastraSandboxOptions {\n /** Unique identifier for this sandbox instance */\n id?: string;\n /**\n * Docker image to use for the sandbox.\n *\n * @default 'blaxel/py-app:latest'\n */\n image?: string;\n /**\n * Memory allocation in MB.\n *\n * @default 4096\n */\n memory?: number;\n /**\n * Execution timeout as a duration string (e.g. '5m', '1h').\n * This maps to the Blaxel sandbox TTL.\n */\n timeout?: string;\n /** Environment variables to set in the sandbox */\n env?: Record<string, string>;\n /** Custom labels for the sandbox */\n labels?: Record<string, string>;\n /** Supported runtimes (default: ['node', 'python', 'bash']) */\n runtimes?: SandboxRuntime[];\n /**\n * Ports to expose from the sandbox.\n * Each entry should have a `target` (port number) and optionally `name` and `protocol`.\n */\n ports?: Array<{ name?: string; target: number; protocol?: 'HTTP' | 'TCP' | 'UDP' }>;\n}\n\n// =============================================================================\n// Blaxel Sandbox Implementation\n// =============================================================================\n\n/**\n * Blaxel cloud sandbox implementation.\n *\n * Features:\n * - Single sandbox instance lifecycle\n * - Supports mounting cloud filesystems (S3, GCS, R2) via FUSE\n * - Automatic sandbox reconnection via `createIfNotExists`\n * - Automatic sandbox timeout handling with retry\n *\n * @example Basic usage\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { BlaxelSandbox } from '@mastra/blaxel';\n *\n * const sandbox = new BlaxelSandbox({\n * timeout: '5m',\n * });\n *\n * const workspace = new Workspace({ sandbox });\n * const result = await workspace.executeCode('console.log(\"Hello!\")');\n * ```\n *\n * @example With S3 filesystem mounting\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { BlaxelSandbox } from '@mastra/blaxel';\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const workspace = new Workspace({\n * mounts: {\n * '/bucket': new S3Filesystem({\n * bucket: 'my-bucket',\n * region: 'us-east-1',\n * }),\n * },\n * sandbox: new BlaxelSandbox({ timeout: '5m' }),\n * });\n * ```\n */\nexport class BlaxelSandbox extends MastraSandbox {\n readonly id: string;\n readonly name = 'BlaxelSandbox';\n readonly provider = 'blaxel';\n\n // Status is managed by base class lifecycle methods\n status: ProviderStatus = 'pending';\n\n private _sandbox: SandboxInstance | null = null;\n private _createdAt: Date | null = null;\n private _isRetrying = false;\n\n private readonly image: string;\n private readonly memory: number;\n private readonly timeout?: string;\n private readonly env: Record<string, string>;\n private readonly labels: Record<string, string>;\n private readonly configuredRuntimes: SandboxRuntime[];\n private readonly ports: Array<{ name?: string; target: number; protocol?: 'HTTP' | 'TCP' | 'UDP' }>;\n declare readonly mounts: MountManager; // Non-optional (initialized by BaseSandbox)\n\n constructor(options: BlaxelSandboxOptions = {}) {\n super({ ...options, name: 'BlaxelSandbox' });\n\n this.id = options.id ?? this.generateId();\n this.image = options.image ?? 'blaxel/py-app:latest';\n this.memory = options.memory ?? 4096;\n this.timeout = options.timeout;\n this.env = options.env ?? {};\n this.labels = options.labels ?? {};\n this.configuredRuntimes = options.runtimes ?? ['node', 'python', 'bash'];\n this.ports = options.ports ?? [];\n }\n\n private generateId(): string {\n return `blaxel-sandbox-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n get supportedRuntimes(): readonly SandboxRuntime[] {\n return this.configuredRuntimes;\n }\n\n get defaultRuntime(): SandboxRuntime {\n return this.configuredRuntimes[0] ?? 'node';\n }\n\n /**\n * Get the underlying Blaxel SandboxInstance for direct access to Blaxel APIs.\n *\n * Use this when you need to access Blaxel features not exposed through the\n * WorkspaceSandbox interface (e.g., filesystem, process management, previews, etc.).\n *\n * @throws {SandboxNotReadyError} If the sandbox has not been started\n *\n * @example Direct file operations\n * ```typescript\n * const blaxelSandbox = sandbox.instance;\n * await blaxelSandbox.fs.write('/tmp/test.txt', 'Hello');\n * const content = await blaxelSandbox.fs.read('/tmp/test.txt');\n * const files = await blaxelSandbox.fs.ls('/tmp');\n * ```\n *\n * @example Process management\n * ```typescript\n * const blaxelSandbox = sandbox.instance;\n * const proc = await blaxelSandbox.process.exec({\n * command: 'node server.js',\n * waitForCompletion: false,\n * });\n * ```\n */\n get instance(): SandboxInstance {\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n return this._sandbox;\n }\n\n // ---------------------------------------------------------------------------\n // Mount Support\n // ---------------------------------------------------------------------------\n\n /**\n * Mount a filesystem at a path in the sandbox.\n * Uses FUSE tools (s3fs, gcsfuse) to mount cloud storage.\n */\n async mount(filesystem: WorkspaceFilesystem, mountPath: string): Promise<MountResult> {\n validateMountPath(mountPath);\n\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Mounting \"${mountPath}\"...`);\n\n // Get mount config - MountManager validates this exists before calling mount()\n const config = filesystem.getMountConfig?.() as BlaxelMountConfig | undefined;\n if (!config) {\n const error = `Filesystem \"${filesystem.id}\" does not provide a mount config`;\n this.logger.error(`${LOG_PREFIX} ${error}`);\n this.mounts.set(mountPath, { filesystem, state: 'error', error });\n return { success: false, mountPath, error };\n }\n\n // Check if already mounted with matching config (e.g., when reconnecting to existing sandbox)\n const existingMount = await this.checkExistingMount(mountPath, config);\n if (existingMount === 'matching') {\n this.logger.debug(\n `${LOG_PREFIX} Detected existing mount for ${filesystem.provider} (\"${filesystem.id}\") at \"${mountPath}\" with correct config, skipping`,\n );\n this.mounts.set(mountPath, { state: 'mounted', config });\n return { success: true, mountPath };\n } else if (existingMount === 'mismatched') {\n // Different config - unmount and re-mount\n this.logger.debug(`${LOG_PREFIX} Config mismatch, unmounting to re-mount with new config...`);\n await this.unmount(mountPath);\n }\n this.logger.debug(`${LOG_PREFIX} Config type: ${config.type}`);\n\n // Mark as mounting (handles direct mount() calls; MountManager also sets this for processPending)\n this.mounts.set(mountPath, { filesystem, state: 'mounting', config });\n\n // Check if directory exists and is non-empty (would shadow existing files)\n try {\n const checkResult = await runCommand(\n this._sandbox,\n `[ -d \"${mountPath}\" ] && [ \"$(ls -A \"${mountPath}\" 2>/dev/null)\" ] && echo \"non-empty\" || echo \"ok\"`,\n );\n if (checkResult.stdout.trim() === 'non-empty') {\n const error = `Cannot mount at ${mountPath}: directory exists and is not empty. Mounting would hide existing files. Use a different path or empty the directory first.`;\n this.logger.error(`${LOG_PREFIX} ${error}`);\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error });\n return { success: false, mountPath, error };\n }\n } catch {\n // Check failed, proceed anyway\n }\n\n // Create mount directory (Blaxel sandboxes run as root by default)\n this.logger.debug(`${LOG_PREFIX} Creating mount directory for ${mountPath}...`);\n const mkdirCommand = `mkdir -p \"${mountPath}\"`;\n\n this.logger.debug(`${LOG_PREFIX} Running command: ${mkdirCommand}`);\n const mkdirResult = await runCommand(this._sandbox, mkdirCommand);\n\n if (mkdirResult.exitCode !== 0) {\n const mkdirError = `Failed to create mount directory \"${mountPath}\": ${mkdirResult.stderr || mkdirResult.stdout}`;\n this.logger.debug(`${LOG_PREFIX} mkdir error for \"${mountPath}\":`, mkdirError);\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error: mkdirError });\n return { success: false, mountPath, error: mkdirError };\n }\n this.logger.debug(`${LOG_PREFIX} Created mount directory for mount path \"${mountPath}\":`, mkdirResult);\n\n // Create mount context for mount operations\n const mountCtx: MountContext = {\n sandbox: this._sandbox,\n logger: this.logger,\n };\n\n try {\n switch (config.type) {\n case 's3':\n this.logger.debug(`${LOG_PREFIX} Mounting S3 bucket at ${mountPath}...`);\n await mountS3(mountPath, config as BlaxelS3MountConfig, mountCtx);\n this.logger.debug(`${LOG_PREFIX} Mounted S3 bucket at ${mountPath}`);\n break;\n case 'gcs':\n this.logger.debug(`${LOG_PREFIX} Mounting GCS bucket at ${mountPath}...`);\n await mountGCS(mountPath, config as BlaxelGCSMountConfig, mountCtx);\n this.logger.debug(`${LOG_PREFIX} Mounted GCS bucket at ${mountPath}`);\n break;\n default:\n this.mounts.set(mountPath, {\n filesystem,\n state: 'unsupported',\n config,\n error: `Unsupported mount type: ${(config as FilesystemMountConfig).type}`,\n });\n return {\n success: false,\n mountPath,\n error: `Unsupported mount type: ${(config as FilesystemMountConfig).type}`,\n };\n }\n } catch (error) {\n this.logger.error(\n `${LOG_PREFIX} Error mounting \"${filesystem.provider}\" (${filesystem.id}) at \"${mountPath}\":`,\n error,\n );\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error: errorToString(error) });\n\n // Clean up the directory we created since mount failed\n try {\n await runCommand(this._sandbox!, `rmdir \"${mountPath}\" 2>/dev/null || true`);\n this.logger.debug(`${LOG_PREFIX} Cleaned up directory after failed mount: ${mountPath}`);\n } catch {\n // Ignore cleanup errors\n }\n\n return { success: false, mountPath, error: errorToString(error) };\n }\n\n // Mark as mounted\n this.mounts.set(mountPath, { state: 'mounted', config });\n\n // Write marker file so we can detect config changes on reconnect\n await this.writeMarkerFile(mountPath);\n\n this.logger.debug(`${LOG_PREFIX} Mounted ${mountPath}`);\n return { success: true, mountPath };\n }\n\n /**\n * Write marker file for detecting config changes on reconnect.\n * Stores both the mount path and config hash in the file.\n */\n private async writeMarkerFile(mountPath: string): Promise<void> {\n if (!this._sandbox) return;\n\n const markerContent = this.mounts.getMarkerContent(mountPath);\n if (!markerContent) return;\n\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n try {\n await runCommand(this._sandbox, 'mkdir -p /tmp/.mastra-mounts');\n await this._sandbox.fs.write(markerPath, markerContent);\n } catch {\n // Non-fatal - marker is just for optimization\n this.logger.debug(`${LOG_PREFIX} Warning: Could not write marker file at ${markerPath}`);\n }\n }\n\n /**\n * Unmount a filesystem from a path in the sandbox.\n */\n async unmount(mountPath: string): Promise<void> {\n validateMountPath(mountPath);\n\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Unmounting ${mountPath}...`);\n\n try {\n // Use fusermount for FUSE mounts, fall back to umount\n const result = await runCommand(\n this._sandbox,\n `fusermount -u \"${mountPath}\" 2>/dev/null || umount \"${mountPath}\"`,\n );\n if (result.exitCode !== 0) {\n this.logger.debug(`${LOG_PREFIX} Unmount warning: ${result.stderr || result.stdout}`);\n }\n } catch (error) {\n this.logger.debug(`${LOG_PREFIX} Unmount error:`, error);\n // Try lazy unmount as last resort\n await runCommand(this._sandbox, `umount -l \"${mountPath}\" 2>/dev/null || true`);\n }\n\n this.mounts.delete(mountPath);\n\n // Clean up marker file\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n await runCommand(this._sandbox, `rm -f \"${markerPath}\" 2>/dev/null || true`);\n\n // Remove empty mount directory (only if empty, rmdir fails on non-empty)\n // Use || true so a non-empty or missing directory doesn't abort unmount\n const rmdirResult = await runCommand(this._sandbox, `rmdir \"${mountPath}\" 2>&1`);\n if (rmdirResult.exitCode === 0) {\n this.logger.debug(`${LOG_PREFIX} Unmounted and removed ${mountPath}`);\n } else {\n this.logger.debug(\n `${LOG_PREFIX} Unmounted ${mountPath} (directory not removed: ${rmdirResult.stderr?.trim() || 'not empty'})`,\n );\n }\n }\n\n /**\n * Get list of current mounts in the sandbox.\n */\n async getMounts(): Promise<Array<{ path: string; filesystem: string }>> {\n return Array.from(this.mounts.entries).map(([path, entry]) => ({\n path,\n filesystem: entry.filesystem?.provider ?? entry.config?.type ?? 'unknown',\n }));\n }\n\n /**\n * Unmount all stale mounts that are not in the expected mounts list.\n * Also cleans up orphaned directories and marker files from failed mount attempts.\n * Call this after reconnecting to an existing sandbox to clean up old mounts.\n */\n async reconcileMounts(expectedMountPaths: string[]): Promise<void> {\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Reconciling mounts. Expected paths:`, expectedMountPaths);\n\n // Get current FUSE mounts in the sandbox\n // Use || true to prevent failure when no FUSE mounts exist (grep exits 1 on no match)\n const mountsResult = await runCommand(\n this._sandbox,\n `grep -E 'fuse\\\\.(s3fs|gcsfuse)' /proc/mounts | awk '{print $2}' || true`,\n );\n const currentMounts = mountsResult.stdout\n .trim()\n .split('\\n')\n .filter(p => p.length > 0);\n\n this.logger.debug(`${LOG_PREFIX} Current FUSE mounts in sandbox:`, currentMounts);\n\n // Read our marker files to know which mounts WE created\n const markersResult = await runCommand(this._sandbox, `ls /tmp/.mastra-mounts/ 2>/dev/null || echo \"\"`);\n const markerFiles = markersResult.stdout\n .trim()\n .split('\\n')\n .filter(f => f.length > 0 && SAFE_MARKER_NAME.test(f));\n\n // Build a map of mount paths -> marker filenames for mounts WE created\n const managedMountPaths = new Map<string, string>();\n for (const markerFile of markerFiles) {\n const markerResult = await runCommand(\n this._sandbox,\n `cat \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || echo \"\"`,\n );\n const parsed = this.mounts.parseMarkerContent(markerResult.stdout.trim());\n if (parsed && SAFE_MOUNT_PATH.test(parsed.path)) {\n managedMountPaths.set(parsed.path, markerFile);\n }\n }\n\n // Find mounts that exist but shouldn't — only unmount if WE created them (have a marker)\n const staleMounts = currentMounts.filter(path => !expectedMountPaths.includes(path));\n\n for (const stalePath of staleMounts) {\n if (managedMountPaths.has(stalePath)) {\n this.logger.debug(`${LOG_PREFIX} Found stale managed FUSE mount at ${stalePath}, unmounting...`);\n await this.unmount(stalePath);\n } else {\n this.logger.debug(`${LOG_PREFIX} Found external FUSE mount at ${stalePath}, leaving untouched`);\n }\n }\n\n // Clean up orphaned marker files and empty directories from failed mounts\n try {\n const expectedMarkerFiles = new Set(expectedMountPaths.map(p => this.mounts.markerFilename(p)));\n\n // Build a reverse map: markerFile -> mountPath\n const markerToPath = new Map<string, string>();\n for (const [path, file] of managedMountPaths) {\n markerToPath.set(file, path);\n }\n\n for (const markerFile of markerFiles) {\n // If this marker file doesn't correspond to an expected mount path, clean it up\n if (!expectedMarkerFiles.has(markerFile)) {\n const mountPath = markerToPath.get(markerFile);\n\n if (mountPath) {\n // Only clean up directory if not currently FUSE mounted\n if (!currentMounts.includes(mountPath)) {\n this.logger.debug(`${LOG_PREFIX} Cleaning up orphaned marker and directory for ${mountPath}`);\n\n // Remove marker file\n await runCommand(this._sandbox!, `rm -f \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || true`);\n\n // Try to remove the directory (will fail if not empty or doesn't exist, which is fine)\n await runCommand(this._sandbox!, `rmdir \"${mountPath}\" 2>/dev/null || true`);\n }\n } else {\n // Malformed marker file - just delete it\n this.logger.debug(`${LOG_PREFIX} Removing malformed marker file: ${markerFile}`);\n await runCommand(this._sandbox!, `rm -f \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || true`);\n }\n }\n }\n } catch {\n // Ignore errors during orphan cleanup\n this.logger.debug(`${LOG_PREFIX} Error during orphan cleanup (non-fatal)`);\n }\n }\n\n /**\n * Check if a path is already mounted and if the config matches.\n *\n * @param mountPath - The mount path to check\n * @param newConfig - The new config to compare against the stored config\n * @returns 'not_mounted' | 'matching' | 'mismatched'\n */\n private async checkExistingMount(\n mountPath: string,\n newConfig: BlaxelMountConfig,\n ): Promise<'not_mounted' | 'matching' | 'mismatched'> {\n if (!this._sandbox) throw new SandboxNotReadyError(this.id);\n\n // Check if path is a mount point\n const mountCheck = await runCommand(\n this._sandbox,\n `mountpoint -q \"${mountPath}\" && echo \"mounted\" || echo \"not mounted\"`,\n );\n\n if (mountCheck.stdout.trim() !== 'mounted') {\n return 'not_mounted';\n }\n\n // Path is mounted - check if config matches via marker file\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n\n try {\n const markerResult = await runCommand(this._sandbox, `cat \"${markerPath}\" 2>/dev/null || echo \"\"`);\n const parsed = this.mounts.parseMarkerContent(markerResult.stdout.trim());\n\n if (!parsed) {\n return 'mismatched';\n }\n\n // Compute hash of the NEW config and compare with stored hash\n const newConfigHash = this.mounts.computeConfigHash(newConfig);\n this.logger.debug(\n `${LOG_PREFIX} Marker check - stored hash: \"${parsed.configHash}\", new config hash: \"${newConfigHash}\"`,\n );\n\n if (parsed.path === mountPath && parsed.configHash === newConfigHash) {\n return 'matching';\n }\n } catch {\n // Marker doesn't exist or can't be read - treat as mismatched\n }\n\n return 'mismatched';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle (overrides base class protected methods)\n // ---------------------------------------------------------------------------\n\n /**\n * Start the Blaxel sandbox.\n * Uses `createIfNotExists` to reconnect to an existing sandbox or create a new one.\n *\n * Status management and mount processing are handled by the base class.\n */\n async start(): Promise<void> {\n // Already have a sandbox instance\n if (this._sandbox) {\n return;\n }\n\n const sandboxName = this.toSandboxName(this.id);\n\n this.logger.debug(`${LOG_PREFIX} Starting sandbox: ${sandboxName}`);\n\n // Try to get an existing sandbox first\n const existingSandbox = await this.findExistingSandbox(sandboxName);\n\n if (existingSandbox) {\n this._sandbox = existingSandbox;\n this._createdAt = new Date();\n this.logger.debug(`${LOG_PREFIX} Reconnected to existing sandbox: ${sandboxName}`);\n\n // Clean up stale mounts from previous config\n // (processPending is called by base class after start completes)\n const expectedPaths = Array.from(this.mounts.entries.keys());\n this.logger.debug(`${LOG_PREFIX} Running mount reconciliation...`);\n await this.reconcileMounts(expectedPaths);\n this.logger.debug(`${LOG_PREFIX} Mount reconciliation complete`);\n return;\n }\n\n // Create a new sandbox\n this.logger.debug(`${LOG_PREFIX} Creating new sandbox: ${sandboxName}`);\n\n try {\n this._sandbox = await SandboxInstance.create({\n name: sandboxName,\n image: this.image,\n memory: this.memory,\n ...(this.timeout && { ttl: this.timeout }),\n envs: Object.entries(this.env).map(([name, value]) => ({ name, value })),\n labels: {\n ...this.labels,\n 'mastra-sandbox-id': this.id,\n },\n ports: this.ports.map(p => ({\n name: p.name,\n target: p.target,\n protocol: p.protocol ?? 'HTTP',\n })),\n });\n } catch (createError) {\n // Blaxel API may throw plain objects instead of Error instances.\n // Wrap them so downstream code (instanceof Error checks) works correctly.\n if (createError instanceof Error) {\n throw createError;\n }\n throw new Error(errorToString(createError));\n }\n\n this._createdAt = new Date();\n this.logger.debug(`${LOG_PREFIX} Sandbox ready: ${sandboxName} (status: ${this._sandbox.status})`);\n // Note: processPending is called by base class after start completes\n }\n\n /**\n * Convert a logical sandbox ID to a valid Blaxel sandbox name.\n * Blaxel sandbox names must be DNS-safe (lowercase alphanumeric and hyphens).\n */\n private toSandboxName(id: string): string {\n const name = id\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 63);\n if (!name) {\n throw new Error(\n `Cannot derive a valid sandbox name from id \"${id}\". ID must contain at least one alphanumeric character.`,\n );\n }\n return name;\n }\n\n /**\n * Find an existing sandbox with the given name.\n * Returns the connected sandbox if found and running, null otherwise.\n */\n private async findExistingSandbox(sandboxName: string): Promise<SandboxInstance | null> {\n try {\n const existing = await SandboxInstance.get(sandboxName);\n\n // Only reuse if the sandbox is actually deployed (running)\n if (existing.status === 'DEPLOYED') {\n this.logger.debug(`${LOG_PREFIX} Found existing sandbox: ${sandboxName} (status: ${existing.status})`);\n return existing;\n }\n\n this.logger.debug(\n `${LOG_PREFIX} Found sandbox ${sandboxName} but status is ${existing.status}, creating new one`,\n );\n } catch (e) {\n this.logger.debug(`${LOG_PREFIX} No existing sandbox found for ${sandboxName}:`, e);\n }\n\n return null;\n }\n\n /**\n * Stop the Blaxel sandbox.\n * Unmounts all filesystems and releases the sandbox reference.\n * Status management is handled by the base class.\n */\n async stop(): Promise<void> {\n // Unmount all filesystems before stopping\n // Collect keys first since unmount() mutates the map\n for (const mountPath of [...this.mounts.entries.keys()]) {\n try {\n await this.unmount(mountPath);\n } catch {\n // Best-effort unmount; sandbox may already be dead\n }\n }\n\n this._sandbox = null;\n }\n\n /**\n * Destroy the Blaxel sandbox and clean up all resources.\n * Unmounts filesystems, deletes the sandbox, and clears mount state.\n * Status management is handled by the base class.\n */\n async destroy(): Promise<void> {\n // Unmount all filesystems\n // Collect keys first since unmount() mutates the map\n for (const mountPath of [...this.mounts.entries.keys()]) {\n try {\n await this.unmount(mountPath);\n } catch {\n // Ignore errors during cleanup\n }\n }\n\n if (this._sandbox) {\n try {\n await this._sandbox.delete();\n } catch {\n // Ignore errors during destroy\n }\n }\n\n this._sandbox = null;\n this.mounts.clear();\n }\n\n /**\n * Check if the sandbox is ready for operations.\n */\n async isReady(): Promise<boolean> {\n return this.status === 'running' && this._sandbox !== null;\n }\n\n /**\n * Get information about the current state of the sandbox.\n */\n async getInfo(): Promise<SandboxInfo> {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n createdAt: this._createdAt ?? new Date(),\n mounts: Array.from(this.mounts.entries).map(([path, entry]) => ({\n path,\n filesystem: entry.filesystem?.provider ?? entry.config?.type ?? 'unknown',\n })),\n metadata: {\n ...this.labels,\n image: this.image,\n memory: this.memory,\n sandboxStatus: this._sandbox?.status,\n },\n };\n }\n\n /**\n * Get instructions describing this Blaxel sandbox.\n * Used by agents to understand the execution environment.\n */\n getInstructions(): string {\n const mountCount = this.mounts.entries.size;\n const mountInfo = mountCount > 0 ? ` ${mountCount} filesystem(s) mounted via FUSE.` : '';\n return `Cloud sandbox with /home/user as working directory.${mountInfo}`;\n }\n\n // ---------------------------------------------------------------------------\n // Internal Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Ensure the sandbox is started and return the Blaxel SandboxInstance.\n * Uses base class ensureRunning() for status management and error handling.\n * @throws {SandboxNotReadyError} if sandbox fails to start\n */\n private async ensureSandbox(): Promise<SandboxInstance> {\n await this.ensureRunning();\n return this._sandbox!;\n }\n\n /**\n * Check if an error indicates the sandbox itself is dead/gone.\n * Does NOT include code execution timeouts (those are the user's code taking too long).\n */\n private isSandboxDeadError(error: unknown): boolean {\n if (!error) return false;\n const errorStr = errorToString(error);\n return (\n errorStr.includes('TERMINATED') ||\n errorStr.includes('sandbox was not found') ||\n errorStr.includes('Sandbox not found')\n );\n }\n\n /**\n * Handle sandbox timeout by clearing the instance and resetting state.\n *\n * Bypasses the normal stop() lifecycle because the sandbox is already dead —\n * we can't unmount filesystems or run cleanup commands. Instead we reset\n * mount states to 'pending' so they get re-mounted when start() runs again.\n */\n private handleSandboxTimeout(): void {\n this._sandbox = null;\n\n // Reset mounted entries to pending so they get re-mounted on restart\n for (const [path, entry] of this.mounts.entries) {\n if (entry.state === 'mounted' || entry.state === 'mounting') {\n this.mounts.set(path, { state: 'pending' });\n }\n }\n\n this.status = 'stopped';\n }\n\n // ---------------------------------------------------------------------------\n // Command Execution\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a shell command in the sandbox.\n * Automatically starts the sandbox if not already running.\n * Retries once if the sandbox is found to be dead.\n */\n async executeCommand(\n command: string,\n args: string[] = [],\n options: ExecuteCommandOptions = {},\n ): Promise<CommandResult> {\n this.logger.debug(`${LOG_PREFIX} Executing: ${command} ${args.join(' ')}`, options);\n const sandbox = await this.ensureSandbox();\n\n const startTime = Date.now();\n const fullCommand = args.length > 0 ? `${command} ${args.map(shellQuote).join(' ')}` : command;\n\n this.logger.debug(`${LOG_PREFIX} Executing: ${fullCommand}`);\n\n try {\n // Merge sandbox default env with per-command env (per-command overrides)\n // Filter out undefined values to get Record<string, string>\n const mergedEnv = { ...this.env, ...options.env };\n const envRecord = Object.fromEntries(\n Object.entries(mergedEnv).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n\n const result = await sandbox.process.exec({\n command: fullCommand,\n workingDir: options.cwd,\n env: envRecord,\n waitForCompletion: true,\n ...(options.timeout && { timeout: Math.ceil(options.timeout / 1000) }),\n ...(options.onStdout || options.onStderr\n ? {\n onStdout: options.onStdout,\n onStderr: options.onStderr,\n }\n : {}),\n });\n\n const executionTimeMs = Date.now() - startTime;\n const exitCode = result.exitCode ?? 0;\n const stdout = result.stdout ?? '';\n const stderr = result.stderr ?? '';\n\n this.logger.debug(`${LOG_PREFIX} Exit code: ${exitCode} (${executionTimeMs}ms)`);\n if (stdout) this.logger.debug(`${LOG_PREFIX} stdout:\\n${stdout}`);\n if (stderr) this.logger.debug(`${LOG_PREFIX} stderr:\\n${stderr}`);\n\n return {\n success: exitCode === 0,\n exitCode,\n stdout,\n stderr,\n executionTimeMs,\n command,\n args,\n };\n } catch (error) {\n // Handle sandbox-is-dead errors - retry once (not infinitely)\n if (this.isSandboxDeadError(error) && !this._isRetrying) {\n this.handleSandboxTimeout();\n this._isRetrying = true;\n try {\n return await this.executeCommand(command, args, options);\n } finally {\n this._isRetrying = false;\n }\n }\n\n const executionTimeMs = Date.now() - startTime;\n\n const stderr = errorToString(error);\n\n this.logger.debug(`${LOG_PREFIX} Execution error (${executionTimeMs}ms): ${stderr}`);\n\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr,\n executionTimeMs,\n command,\n args,\n };\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/shell-quote.ts","../src/sandbox/mounts/types.ts","../src/sandbox/mounts/s3.ts","../src/sandbox/mounts/gcs.ts","../src/sandbox/process-manager.ts","../src/sandbox/index.ts"],"names":["crypto","ProcessHandle","SandboxProcessManager","MastraSandbox","SandboxNotReadyError","SandboxInstance"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Shell-quote a single argument for safe use in a command string.\n *\n * Arguments containing only safe characters are returned as-is.\n * All others are wrapped in single quotes with embedded single quotes escaped.\n */\nexport function shellQuote(arg: string): string {\n // Safe characters that don't need quoting\n if (/^[a-zA-Z0-9._\\-/@:=]+$/.test(arg)) return arg;\n // Wrap in single quotes, escaping any embedded single quotes\n return \"'\" + arg.replace(/'/g, \"'\\\\''\") + \"'\";\n}\n","/**\n * Shared types for Blaxel mount operations.\n */\n\nimport type { SandboxInstance } from '@blaxel/core';\n\nexport const LOG_PREFIX = '[@mastra/blaxel]';\n\nimport type { BlaxelGCSMountConfig } from './gcs';\nimport type { BlaxelS3MountConfig } from './s3';\n\n/**\n * Union of mount configs supported by Blaxel sandbox.\n */\nexport type BlaxelMountConfig = BlaxelS3MountConfig | BlaxelGCSMountConfig;\n\n/**\n * Context for mount operations.\n */\nexport interface MountContext {\n sandbox: SandboxInstance;\n logger: {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n };\n}\n\n/**\n * Validate a bucket name before interpolating into shell commands.\n * Covers S3, GCS, and S3-compatible (R2, MinIO) naming rules.\n */\nconst SAFE_BUCKET_NAME = /^[a-z0-9][a-z0-9.\\-]{1,61}[a-z0-9]$/;\n\nexport function validateBucketName(bucket: string): void {\n if (!SAFE_BUCKET_NAME.test(bucket)) {\n throw new Error(\n `Invalid bucket name: \"${bucket}\". Bucket names must be 3-63 characters, lowercase alphanumeric, hyphens, or dots.`,\n );\n }\n}\n\n/**\n * Validate an endpoint URL before interpolating into shell commands.\n * Only http and https schemes are allowed.\n */\nexport function validateEndpoint(endpoint: string): void {\n let parsed: URL;\n try {\n parsed = new URL(endpoint);\n } catch {\n throw new Error(`Invalid endpoint URL: \"${endpoint}\"`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error(`Invalid endpoint URL scheme: \"${parsed.protocol}\". Only http: and https: are allowed.`);\n }\n}\n\n/**\n * Detected system package manager.\n */\nexport type PackageManager = 'apt' | 'apk' | 'unknown';\n\n/**\n * Detect the system package manager available in the sandbox.\n * Returns 'apt' for Debian/Ubuntu, 'apk' for Alpine, or 'unknown'.\n */\nexport async function detectPackageManager(sandbox: SandboxInstance): Promise<PackageManager> {\n const result = await runCommand(\n sandbox,\n 'which apt-get >/dev/null 2>&1 && echo \"apt\" || (which apk >/dev/null 2>&1 && echo \"apk\" || echo \"unknown\")',\n );\n const pm = result.stdout.trim();\n if (pm === 'apt') return 'apt';\n if (pm === 'apk') return 'apk';\n return 'unknown';\n}\n\n/**\n * Run a command in the Blaxel sandbox and return the result.\n * Wraps the process.exec API to match the command execution pattern used in mount operations.\n *\n * Does NOT throw on non-zero exit codes — callers should check `exitCode` themselves.\n */\nexport async function runCommand(\n sandbox: SandboxInstance,\n command: string,\n options?: { timeout?: number },\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const result = await sandbox.process.exec({\n command,\n waitForCompletion: true,\n ...(options?.timeout && { timeout: Math.ceil(options.timeout / 1000) }),\n });\n\n return {\n exitCode: result.exitCode ?? 0,\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n };\n}\n","import crypto from 'node:crypto';\n\nimport type { FilesystemMountConfig } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../../utils/shell-quote';\nimport { LOG_PREFIX, validateBucketName, validateEndpoint, runCommand, detectPackageManager } from './types';\nimport type { MountContext } from './types';\n\n/**\n * S3 mount config for Blaxel (mounted via s3fs-fuse).\n *\n * If credentials are not provided, the bucket will be mounted as read-only\n * using the `public_bucket=1` option (for public AWS S3 buckets only).\n *\n * Note: S3-compatible services (R2, MinIO, etc.) always require credentials.\n */\nexport interface BlaxelS3MountConfig extends FilesystemMountConfig {\n type: 's3';\n /** S3 bucket name */\n bucket: string;\n /** AWS region */\n region: string;\n /** S3 endpoint for S3-compatible storage (MinIO, etc.) */\n endpoint?: string;\n /** AWS access key ID (optional - omit for public buckets) */\n accessKeyId?: string;\n /** AWS secret access key (optional - omit for public buckets) */\n secretAccessKey?: string;\n /** Mount as read-only (even if credentials have write access) */\n readOnly?: boolean;\n}\n\n/**\n * Mount an S3 bucket using s3fs-fuse.\n */\nexport async function mountS3(mountPath: string, config: BlaxelS3MountConfig, ctx: MountContext): Promise<void> {\n const { sandbox, logger } = ctx;\n\n // Validate inputs before interpolating into shell commands\n validateBucketName(config.bucket);\n if (config.endpoint) {\n validateEndpoint(config.endpoint);\n }\n\n // Check if s3fs is installed\n const checkResult = await runCommand(sandbox, 'which s3fs || echo \"not found\"');\n if (checkResult.stdout.includes('not found')) {\n logger.warn(`${LOG_PREFIX} s3fs not found, attempting runtime installation...`);\n logger.info(`${LOG_PREFIX} Tip: For faster startup, pre-install s3fs in your sandbox image`);\n\n const pm = await detectPackageManager(sandbox);\n logger.debug(`${LOG_PREFIX} Detected package manager: ${pm}`);\n\n if (pm === 'apt') {\n const updateResult = await runCommand(sandbox, 'apt-get update 2>&1', { timeout: 60000 });\n if (updateResult.exitCode !== 0) {\n throw new Error(\n `Failed to update package lists for s3fs installation.\\n` +\n `Error details: ${updateResult.stderr || updateResult.stdout}`,\n );\n }\n\n const installResult = await runCommand(\n sandbox,\n 'apt-get install -y s3fs fuse 2>&1 || apt-get install -y s3fs-fuse fuse 2>&1',\n { timeout: 120000 },\n );\n\n if (installResult.exitCode !== 0) {\n throw new Error(\n `Failed to install s3fs. ` +\n `For S3 mounting, your sandbox image needs s3fs and fuse packages.\\n\\n` +\n `Pre-install in your image: apt-get install -y s3fs fuse\\n\\n` +\n `Error details: ${installResult.stderr || installResult.stdout}`,\n );\n }\n } else if (pm === 'apk') {\n // Alpine Linux — s3fs-fuse is in the community repo\n const installResult = await runCommand(sandbox, 'apk add --no-cache s3fs-fuse fuse 2>&1', { timeout: 120000 });\n\n if (installResult.exitCode !== 0) {\n throw new Error(\n `Failed to install s3fs on Alpine Linux. ` +\n `Ensure the Alpine community repository is enabled.\\n\\n` +\n `Pre-install in your image: apk add --no-cache s3fs-fuse fuse\\n\\n` +\n `Error details: ${installResult.stderr || installResult.stdout}`,\n );\n }\n } else {\n throw new Error(\n `Cannot install s3fs: no supported package manager found (need apt-get or apk).\\n` +\n `Use a Debian-based image (e.g. blaxel/ts-app:latest) or Alpine-based image (e.g. blaxel/node:latest), ` +\n `or pre-install s3fs in your custom image.`,\n );\n }\n }\n\n // Get user's uid/gid for proper file ownership\n const idResult = await runCommand(sandbox, 'id -u && id -g');\n if (idResult.exitCode !== 0) {\n throw new Error(`Failed to get uid/gid: ${idResult.stderr || idResult.stdout}`);\n }\n const [uid, gid] = idResult.stdout.trim().split('\\n');\n\n // Determine if we have credentials or using public bucket mode\n const hasCredentials = config.accessKeyId && config.secretAccessKey;\n\n // Use a mount-specific credentials path to avoid races with concurrent mounts\n const mountHash = crypto.createHash('md5').update(mountPath).digest('hex').slice(0, 8);\n const credentialsPath = `/tmp/.passwd-s3fs-${mountHash}`;\n\n // S3-compatible services (R2, MinIO, etc.) require credentials\n // public_bucket=1 only works for truly public AWS S3 buckets\n if (!hasCredentials && config.endpoint) {\n throw new Error(\n `S3-compatible storage requires credentials. ` +\n `Detected endpoint: ${config.endpoint}. ` +\n `The public_bucket option only works for AWS S3 public buckets, not R2, MinIO, etc.`,\n );\n }\n\n if (hasCredentials) {\n // Write credentials file (remove old one first to avoid permission issues)\n // s3fs requires the file to have 600 permissions (no \"others\" access)\n const credentialsContent = `${config.accessKeyId}:${config.secretAccessKey}`;\n await runCommand(sandbox, `rm -f ${credentialsPath}`);\n await sandbox.fs.write(credentialsPath, credentialsContent);\n await runCommand(sandbox, `chmod 600 ${credentialsPath}`);\n }\n\n // Build mount options\n const mountOptions: string[] = [];\n\n if (hasCredentials) {\n mountOptions.push(`passwd_file=${credentialsPath}`);\n } else {\n // Public bucket mode - read-only access without credentials\n mountOptions.push('public_bucket=1');\n logger.debug(`${LOG_PREFIX} No credentials provided, mounting as public bucket (read-only)`);\n }\n\n mountOptions.push('allow_other'); // Allow non-root users to access the mount\n\n // Set uid/gid so mounted files are owned by user, not root\n if (uid && gid) {\n mountOptions.push(`uid=${uid}`, `gid=${gid}`);\n }\n\n if (config.endpoint) {\n // For S3-compatible storage (MinIO, R2, etc.)\n const endpoint = config.endpoint.replace(/\\/$/, '');\n mountOptions.push(`url=${endpoint}`, 'use_path_request_style', 'sigv4', 'nomultipart');\n }\n\n if (config.readOnly) {\n mountOptions.push('ro');\n logger.debug(`${LOG_PREFIX} Mounting as read-only`);\n }\n\n const quotedMountPath = shellQuote(mountPath);\n const mountCmd = `s3fs ${config.bucket} ${quotedMountPath} -o ${mountOptions.join(' -o ')}`;\n logger.debug(`${LOG_PREFIX} Mounting S3:`, hasCredentials ? mountCmd.replace(credentialsPath, '***') : mountCmd);\n\n const result = await runCommand(sandbox, mountCmd, { timeout: 60_000 });\n logger.debug(`${LOG_PREFIX} s3fs result:`, {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n });\n if (result.exitCode !== 0) {\n throw new Error(`Failed to mount S3 bucket: ${result.stderr || result.stdout}`);\n }\n}\n","import crypto from 'node:crypto';\n\nimport type { FilesystemMountConfig } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../../utils/shell-quote';\n\nimport { LOG_PREFIX, validateBucketName, runCommand, detectPackageManager } from './types';\nimport type { MountContext } from './types';\n\n/**\n * GCS mount config for Blaxel (mounted via gcsfuse).\n *\n * If credentials are not provided, the bucket will be mounted as read-only\n * using anonymous access (for public buckets only).\n */\nexport interface BlaxelGCSMountConfig extends FilesystemMountConfig {\n type: 'gcs';\n /** GCS bucket name */\n bucket: string;\n /** Service account key JSON (optional - omit for public buckets) */\n serviceAccountKey?: string;\n}\n\n/**\n * Mount a GCS bucket using gcsfuse.\n */\nexport async function mountGCS(mountPath: string, config: BlaxelGCSMountConfig, ctx: MountContext): Promise<void> {\n const { sandbox, logger } = ctx;\n\n // Validate inputs before interpolating into shell commands\n validateBucketName(config.bucket);\n\n const quotedMountPath = shellQuote(mountPath);\n\n // Install gcsfuse if not present\n const checkResult = await runCommand(sandbox, 'which gcsfuse || echo \"not found\"');\n if (checkResult.stdout.includes('not found')) {\n logger.warn(`${LOG_PREFIX} gcsfuse not found, attempting runtime installation...`);\n\n const pm = await detectPackageManager(sandbox);\n logger.debug(`${LOG_PREFIX} Detected package manager: ${pm}`);\n\n if (pm === 'apk') {\n throw new Error(\n `gcsfuse is not available on Alpine Linux. ` +\n `Google only provides gcsfuse packages for Debian/Ubuntu.\\n\\n` +\n `Use a Debian-based Blaxel image for GCS mounts:\\n` +\n ` new BlaxelSandbox({ image: 'blaxel/ts-app:latest' })\\n` +\n ` new BlaxelSandbox({ image: 'blaxel/py-app:latest' })`,\n );\n }\n\n if (pm !== 'apt') {\n throw new Error(\n `Cannot install gcsfuse: no supported package manager found (need apt-get).\\n` +\n `gcsfuse is only available on Debian/Ubuntu-based images.\\n\\n` +\n `Use a Debian-based Blaxel image:\\n` +\n ` new BlaxelSandbox({ image: 'blaxel/ts-app:latest' })`,\n );\n }\n\n logger.info(`${LOG_PREFIX} Tip: For faster startup, pre-install gcsfuse in your sandbox image`);\n\n // Detect distro codename for the gcsfuse repo (default to bookworm for Debian)\n const codenameResult = await runCommand(\n sandbox,\n 'cat /etc/os-release 2>/dev/null | grep VERSION_CODENAME | cut -d= -f2 || echo bookworm',\n );\n const codename = codenameResult.stdout.trim() || 'bookworm';\n logger.debug(`${LOG_PREFIX} Detected distro codename: ${codename}`);\n\n // Ensure required tools and keyring directory exist\n const prepResult = await runCommand(\n sandbox,\n 'apt-get update && apt-get install -y curl gnupg lsb-release fuse && mkdir -p /etc/apt/keyrings',\n { timeout: 120_000 },\n );\n if (prepResult.exitCode !== 0) {\n throw new Error(\n `Failed to install gcsfuse prerequisites.\\n` + `Error details: ${prepResult.stderr || prepResult.stdout}`,\n );\n }\n\n // Add gcsfuse repo and install\n const installResult = await runCommand(\n sandbox,\n 'curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/gcsfuse.gpg && ' +\n `echo \"deb [signed-by=/etc/apt/keyrings/gcsfuse.gpg] https://packages.cloud.google.com/apt gcsfuse-${codename} main\" | tee /etc/apt/sources.list.d/gcsfuse.list && ` +\n 'apt-get update && apt-get install -y gcsfuse',\n { timeout: 120_000 },\n );\n\n if (installResult.exitCode !== 0) {\n throw new Error(\n `Failed to install gcsfuse. ` +\n `For GCS mounting, your sandbox image needs gcsfuse and fuse packages.\\n\\n` +\n `Pre-install in your image: apt-get install -y gcsfuse fuse\\n\\n` +\n `Error details: ${installResult.stderr || installResult.stdout}`,\n );\n }\n\n // Verify installation\n const verifyResult = await runCommand(sandbox, 'which gcsfuse');\n if (verifyResult.exitCode !== 0) {\n throw new Error(\n `gcsfuse installation appeared to succeed but binary not found on PATH.\\n` +\n `Install output: ${installResult.stdout}\\n${installResult.stderr}`,\n );\n }\n }\n\n // Get user's uid/gid for proper file ownership\n const idResult = await runCommand(sandbox, 'id -u && id -g');\n if (idResult.exitCode !== 0) {\n throw new Error(`Failed to get uid/gid: ${idResult.stderr || idResult.stdout}`);\n }\n const [uid, gid] = idResult.stdout.trim().split('\\n');\n\n // Build gcsfuse flags\n // Note: gcsfuse uses --uid/--gid flags, not -o uid=X style\n const uidGidFlags = uid && gid ? `--uid=${uid} --gid=${gid}` : '';\n\n const hasCredentials = !!config.serviceAccountKey;\n let mountCmd: string;\n\n if (hasCredentials) {\n // Use a mount-specific key path to avoid races with concurrent mounts\n const mountHash = crypto.createHash('md5').update(mountPath).digest('hex').slice(0, 8);\n const keyPath = `/tmp/gcs-key-${mountHash}.json`;\n await runCommand(sandbox, `rm -f ${keyPath}`);\n await sandbox.fs.write(keyPath, config.serviceAccountKey!);\n\n // Mount with credentials using --key-file flag\n // -o allow_other lets non-root users access the FUSE mount\n mountCmd = `gcsfuse --key-file=${keyPath} -o allow_other ${uidGidFlags} ${config.bucket} ${quotedMountPath}`;\n } else {\n // Public bucket mode - read-only access without credentials\n // Use --anonymous-access flag (not -o option)\n logger.debug(`${LOG_PREFIX} No credentials provided, mounting GCS as public bucket (read-only)`);\n\n mountCmd = `gcsfuse --anonymous-access -o allow_other ${uidGidFlags} ${config.bucket} ${quotedMountPath}`;\n }\n\n logger.debug(`${LOG_PREFIX} Mounting GCS:`, mountCmd);\n\n const result = await runCommand(sandbox, mountCmd, { timeout: 60_000 });\n logger.debug(`${LOG_PREFIX} gcsfuse result:`, {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n });\n if (result.exitCode !== 0) {\n throw new Error(`Failed to mount GCS bucket: ${result.stderr || result.stdout}`);\n }\n}\n","/**\n * Blaxel Process Manager\n *\n * Implements SandboxProcessManager for Blaxel cloud sandboxes.\n * Wraps the Blaxel SDK's process API (exec, list, get, kill, streamLogs)\n * for background process management.\n *\n * Key limitation: Blaxel sandboxes do not support stdin.\n * ProcessHandle.sendStdin() throws and the writer stream will error.\n */\n\nimport type { SandboxInstance } from '@blaxel/core';\nimport { ProcessHandle, SandboxProcessManager } from '@mastra/core/workspace';\nimport type { CommandResult, ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace';\nimport type { BlaxelSandbox } from './index';\n\n// =============================================================================\n// Blaxel Process Handle\n// =============================================================================\n\n/**\n * Wraps a Blaxel background process to conform to Mastra's ProcessHandle.\n * Not exported — internal to this module.\n *\n * Uses streamLogs() for real-time output and get() for exit code resolution.\n */\nclass BlaxelProcessHandle extends ProcessHandle {\n readonly pid: number;\n\n private readonly _identifier: string;\n private readonly _sandbox: SandboxInstance;\n private readonly _startTime: number;\n\n private _exitCode: number | undefined;\n private _waitPromise: Promise<CommandResult> | null = null;\n private _streamingDone: Promise<void> | null = null;\n private _closeStream: (() => void) | null = null;\n private _killed = false;\n\n constructor(\n pid: number,\n identifier: string,\n sandbox: SandboxInstance,\n startTime: number,\n options?: SpawnProcessOptions,\n ) {\n super(options);\n this.pid = pid;\n this._identifier = identifier;\n this._sandbox = sandbox;\n this._startTime = startTime;\n }\n\n get exitCode(): number | undefined {\n return this._exitCode;\n }\n\n /** @internal Set by the process manager after streaming starts. */\n set streamControl(control: { close: () => void; wait: () => Promise<void> }) {\n this._closeStream = control.close;\n this._streamingDone = control.wait();\n\n // Auto-resolve exit code when streaming ends\n this._streamingDone.then(() => this._resolveExitCode()).catch(() => this._resolveExitCode());\n }\n\n /** Fetch exit code from Blaxel and set _exitCode. No-op if already set. */\n private async _resolveExitCode(): Promise<void> {\n if (this._exitCode !== undefined) return;\n try {\n const proc = await this._sandbox.process.get(this._identifier);\n this._exitCode = proc.status === 'completed' ? (proc.exitCode ?? 0) : (proc.exitCode ?? 1);\n } catch {\n if (this._exitCode === undefined) {\n this._exitCode = 1;\n }\n }\n }\n\n async wait(): Promise<CommandResult> {\n // Idempotent — cache the promise so repeated calls return the same result\n if (!this._waitPromise) {\n this._waitPromise = this._doWait();\n }\n return this._waitPromise;\n }\n\n private async _doWait(): Promise<CommandResult> {\n // Wait for streaming to complete\n if (this._streamingDone) {\n await this._streamingDone.catch(() => {});\n }\n\n // If killed during wait, return with kill exit code\n if (this._killed) {\n return {\n success: false,\n exitCode: this._exitCode ?? 137,\n stdout: this.stdout,\n stderr: this.stderr,\n executionTimeMs: Date.now() - this._startTime,\n };\n }\n\n // Ensure exit code is resolved\n await this._resolveExitCode();\n\n return {\n success: this._exitCode === 0,\n exitCode: this._exitCode ?? 1,\n stdout: this.stdout,\n stderr: this.stderr,\n executionTimeMs: Date.now() - this._startTime,\n };\n }\n\n async kill(): Promise<boolean> {\n if (this._exitCode !== undefined) return false;\n this._killed = true;\n this._exitCode = 137; // SIGKILL\n this._closeStream?.();\n try {\n await this._sandbox.process.kill(this._identifier);\n } catch {\n // Process may already be gone\n }\n return true;\n }\n\n async sendStdin(_data: string): Promise<void> {\n throw new Error('Blaxel sandboxes do not support stdin');\n }\n}\n\n// =============================================================================\n// Blaxel Process Manager\n// =============================================================================\n\nexport interface BlaxelProcessManagerOptions {\n env?: Record<string, string | undefined>;\n}\n\n/**\n * Blaxel implementation of SandboxProcessManager.\n * Uses the Blaxel SDK's process API for background process management.\n */\nexport class BlaxelProcessManager extends SandboxProcessManager<BlaxelSandbox> {\n constructor(opts: BlaxelProcessManagerOptions = {}) {\n super({ env: opts.env });\n }\n\n async spawn(command: string, options: SpawnProcessOptions = {}): Promise<ProcessHandle> {\n return this.sandbox.retryOnDead(async () => {\n const blaxel = this.sandbox.instance;\n\n // Merge default env with per-spawn env\n const mergedEnv = { ...this.env, ...options.env };\n const envs = Object.fromEntries(\n Object.entries(mergedEnv).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n\n // Spawn as background process\n const result = await blaxel.process.exec({\n command,\n waitForCompletion: false,\n workingDir: options.cwd,\n ...(Object.keys(envs).length > 0 && { env: envs }),\n ...(options.timeout && { timeout: Math.ceil(options.timeout / 1000) }),\n });\n\n // Blaxel PIDs are numeric strings (e.g. \"412\") — parse to number for ProcessHandle.\n // Keep the original string as _identifier for SDK calls (streamLogs, get, kill).\n const identifier = result.pid;\n const pid = parseInt(identifier, 10);\n const handle = new BlaxelProcessHandle(pid, identifier, blaxel, Date.now(), options);\n\n // Start streaming logs — route to handle's emitters\n const streamControl = blaxel.process.streamLogs(identifier, {\n onStdout: (data: string) => handle.emitStdout(data),\n onStderr: (data: string) => handle.emitStderr(data),\n onError: (err: Error | string) => {\n const msg = err instanceof Error ? err.message : String(err);\n handle.emitStderr(msg);\n },\n });\n\n handle.streamControl = streamControl;\n this._tracked.set(pid, handle);\n return handle;\n });\n }\n\n async list(): Promise<ProcessInfo[]> {\n const result: ProcessInfo[] = [];\n for (const [pid, handle] of this._tracked) {\n result.push({\n pid,\n command: handle.command,\n running: handle.exitCode === undefined,\n exitCode: handle.exitCode,\n });\n }\n return result;\n }\n\n async get(pid: number): Promise<ProcessHandle | undefined> {\n return this._tracked.get(pid);\n }\n}\n","/**\n * Blaxel Sandbox Provider\n *\n * A Blaxel sandbox implementation that supports mounting\n * cloud filesystems (S3, GCS, R2) via FUSE.\n *\n * @see https://docs.blaxel.ai\n */\n\nimport { SandboxInstance } from '@blaxel/core';\nimport type {\n SandboxInfo,\n ExecuteCommandOptions,\n CommandResult,\n WorkspaceFilesystem,\n MountResult,\n FilesystemMountConfig,\n ProviderStatus,\n MountManager,\n MastraSandboxOptions,\n} from '@mastra/core/workspace';\nimport { MastraSandbox, SandboxNotReadyError } from '@mastra/core/workspace';\n\nimport { shellQuote } from '../utils/shell-quote';\nimport { mountS3, mountGCS, LOG_PREFIX, runCommand } from './mounts';\nimport type { BlaxelMountConfig, BlaxelS3MountConfig, BlaxelGCSMountConfig, MountContext } from './mounts';\nimport { BlaxelProcessManager } from './process-manager';\n\n/** Allowlist pattern for mount paths — absolute path with safe characters only. */\nconst SAFE_MOUNT_PATH = /^\\/[a-zA-Z0-9_.\\-/]+$/;\n\n/** Convert an unknown error to a readable string. */\nfunction errorToString(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n if (error && typeof error === 'object' && 'message' in error && typeof (error as any).message === 'string') {\n return (error as any).message;\n }\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n}\n\nfunction validateMountPath(mountPath: string): void {\n if (!SAFE_MOUNT_PATH.test(mountPath)) {\n throw new Error(\n `Invalid mount path: ${mountPath}. Must be an absolute path with alphanumeric, dash, dot, underscore, or slash characters only.`,\n );\n }\n}\n\n/** Allowlist for marker filenames from ls output — e.g. \"mount-abc123\" */\nconst SAFE_MARKER_NAME = /^mount-[a-z0-9]+$/;\n\n// =============================================================================\n// Blaxel Sandbox Options\n// =============================================================================\n\n/**\n * Runtime types supported by Blaxel.\n */\nexport type SandboxRuntime = 'node' | 'python' | 'bash' | 'ruby' | 'go' | 'rust' | 'java' | 'cpp' | 'r';\n\n/**\n * Blaxel sandbox provider configuration.\n */\nexport interface BlaxelSandboxOptions extends Omit<MastraSandboxOptions, 'processes'> {\n /** Unique identifier for this sandbox instance */\n id?: string;\n /**\n * Docker image to use for the sandbox.\n *\n * Debian-based images (`ts-app`, `py-app`, `jupyter-*`) support both S3 and GCS mounts.\n * Alpine-based images (`node`, `nextjs`, `vite`) support S3 mounts only (gcsfuse is unavailable on Alpine).\n *\n * @default 'blaxel/ts-app:latest'\n */\n image?: string;\n /**\n * Memory allocation in MB.\n *\n * @default 4096\n */\n memory?: number;\n /**\n * Execution timeout as a duration string (e.g. '5m', '1h').\n * This maps to the Blaxel sandbox TTL.\n */\n timeout?: string;\n /** Environment variables to set in the sandbox */\n env?: Record<string, string>;\n /** Custom labels for the sandbox */\n labels?: Record<string, string>;\n /** Supported runtimes (default: ['node', 'python', 'bash']) */\n runtimes?: SandboxRuntime[];\n /**\n * Ports to expose from the sandbox.\n * Each entry should have a `target` (port number) and optionally `name` and `protocol`.\n */\n ports?: Array<{ name?: string; target: number; protocol?: 'HTTP' | 'TCP' | 'UDP' }>;\n}\n\n// =============================================================================\n// Blaxel Sandbox Implementation\n// =============================================================================\n\n/**\n * Blaxel cloud sandbox implementation.\n *\n * Features:\n * - Single sandbox instance lifecycle\n * - Supports mounting cloud filesystems (S3, GCS, R2) via FUSE\n * - Automatic sandbox reconnection via `createIfNotExists`\n * - Automatic sandbox timeout handling with retry\n *\n * @example Basic usage\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { BlaxelSandbox } from '@mastra/blaxel';\n *\n * const sandbox = new BlaxelSandbox({\n * timeout: '5m',\n * });\n *\n * const workspace = new Workspace({ sandbox });\n * const result = await workspace.executeCode('console.log(\"Hello!\")');\n * ```\n *\n * @example With S3 filesystem mounting\n * ```typescript\n * import { Workspace } from '@mastra/core/workspace';\n * import { BlaxelSandbox } from '@mastra/blaxel';\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const workspace = new Workspace({\n * mounts: {\n * '/bucket': new S3Filesystem({\n * bucket: 'my-bucket',\n * region: 'us-east-1',\n * }),\n * },\n * sandbox: new BlaxelSandbox({ timeout: '5m' }),\n * });\n * ```\n */\nexport class BlaxelSandbox extends MastraSandbox {\n readonly id: string;\n readonly name = 'BlaxelSandbox';\n readonly provider = 'blaxel';\n\n // Status is managed by base class lifecycle methods\n status: ProviderStatus = 'pending';\n\n private _sandbox: SandboxInstance | null = null;\n private _createdAt: Date | null = null;\n private _isRetrying = false;\n\n private readonly image: string;\n private readonly memory: number;\n private readonly timeout?: string;\n private readonly env: Record<string, string>;\n private readonly labels: Record<string, string>;\n private readonly configuredRuntimes: SandboxRuntime[];\n private readonly ports: Array<{ name?: string; target: number; protocol?: 'HTTP' | 'TCP' | 'UDP' }>;\n declare readonly mounts: MountManager; // Non-optional (initialized by BaseSandbox)\n\n constructor(options: BlaxelSandboxOptions = {}) {\n super({\n ...options,\n name: 'BlaxelSandbox',\n processes: new BlaxelProcessManager({ env: options.env }),\n });\n\n this.id = options.id ?? this.generateId();\n this.image = options.image ?? 'blaxel/ts-app:latest';\n this.memory = options.memory ?? 4096;\n this.timeout = options.timeout;\n this.env = options.env ?? {};\n this.labels = options.labels ?? {};\n this.configuredRuntimes = options.runtimes ?? ['node', 'python', 'bash'];\n this.ports = options.ports ?? [];\n }\n\n private generateId(): string {\n return `blaxel-sandbox-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n }\n\n get supportedRuntimes(): readonly SandboxRuntime[] {\n return this.configuredRuntimes;\n }\n\n get defaultRuntime(): SandboxRuntime {\n return this.configuredRuntimes[0] ?? 'node';\n }\n\n /**\n * Get the underlying Blaxel SandboxInstance for direct access to Blaxel APIs.\n *\n * Use this when you need to access Blaxel features not exposed through the\n * WorkspaceSandbox interface (e.g., filesystem, process management, previews, etc.).\n *\n * @throws {SandboxNotReadyError} If the sandbox has not been started\n *\n * @example Direct file operations\n * ```typescript\n * const blaxelSandbox = sandbox.instance;\n * await blaxelSandbox.fs.write('/tmp/test.txt', 'Hello');\n * const content = await blaxelSandbox.fs.read('/tmp/test.txt');\n * const files = await blaxelSandbox.fs.ls('/tmp');\n * ```\n *\n * @example Process management\n * ```typescript\n * const blaxelSandbox = sandbox.instance;\n * const proc = await blaxelSandbox.process.exec({\n * command: 'node server.js',\n * waitForCompletion: false,\n * });\n * ```\n */\n get instance(): SandboxInstance {\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n return this._sandbox;\n }\n\n // ---------------------------------------------------------------------------\n // Mount Support\n // ---------------------------------------------------------------------------\n\n /**\n * Mount a filesystem at a path in the sandbox.\n * Uses FUSE tools (s3fs, gcsfuse) to mount cloud storage.\n */\n async mount(filesystem: WorkspaceFilesystem, mountPath: string): Promise<MountResult> {\n validateMountPath(mountPath);\n\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Mounting \"${mountPath}\"...`);\n\n // Get mount config - MountManager validates this exists before calling mount()\n const config = filesystem.getMountConfig?.() as BlaxelMountConfig | undefined;\n if (!config) {\n const error = `Filesystem \"${filesystem.id}\" does not provide a mount config`;\n this.logger.error(`${LOG_PREFIX} ${error}`);\n this.mounts.set(mountPath, { filesystem, state: 'error', error });\n return { success: false, mountPath, error };\n }\n\n // Check if already mounted with matching config (e.g., when reconnecting to existing sandbox)\n const existingMount = await this.checkExistingMount(mountPath, config);\n if (existingMount === 'matching') {\n this.logger.debug(\n `${LOG_PREFIX} Detected existing mount for ${filesystem.provider} (\"${filesystem.id}\") at \"${mountPath}\" with correct config, skipping`,\n );\n this.mounts.set(mountPath, { state: 'mounted', config });\n return { success: true, mountPath };\n } else if (existingMount === 'mismatched') {\n // Different config - unmount and re-mount\n this.logger.debug(`${LOG_PREFIX} Config mismatch, unmounting to re-mount with new config...`);\n await this.unmount(mountPath);\n }\n this.logger.debug(`${LOG_PREFIX} Config type: ${config.type}`);\n\n // Mark as mounting (handles direct mount() calls; MountManager also sets this for processPending)\n this.mounts.set(mountPath, { filesystem, state: 'mounting', config });\n\n // Check if directory exists and is non-empty (would shadow existing files)\n try {\n const checkResult = await runCommand(\n this._sandbox,\n `[ -d \"${mountPath}\" ] && [ \"$(ls -A \"${mountPath}\" 2>/dev/null)\" ] && echo \"non-empty\" || echo \"ok\"`,\n );\n if (checkResult.stdout.trim() === 'non-empty') {\n const error = `Cannot mount at ${mountPath}: directory exists and is not empty. Mounting would hide existing files. Use a different path or empty the directory first.`;\n this.logger.error(`${LOG_PREFIX} ${error}`);\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error });\n return { success: false, mountPath, error };\n }\n } catch {\n // Check failed, proceed anyway\n }\n\n // Create mount directory (Blaxel sandboxes run as root by default)\n this.logger.debug(`${LOG_PREFIX} Creating mount directory for ${mountPath}...`);\n const mkdirCommand = `mkdir -p \"${mountPath}\"`;\n\n this.logger.debug(`${LOG_PREFIX} Running command: ${mkdirCommand}`);\n const mkdirResult = await runCommand(this._sandbox, mkdirCommand);\n\n if (mkdirResult.exitCode !== 0) {\n const mkdirError = `Failed to create mount directory \"${mountPath}\": ${mkdirResult.stderr || mkdirResult.stdout}`;\n this.logger.debug(`${LOG_PREFIX} mkdir error for \"${mountPath}\":`, mkdirError);\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error: mkdirError });\n return { success: false, mountPath, error: mkdirError };\n }\n this.logger.debug(`${LOG_PREFIX} Created mount directory for mount path \"${mountPath}\":`, mkdirResult);\n\n // Create mount context for mount operations\n const mountCtx: MountContext = {\n sandbox: this._sandbox,\n logger: this.logger,\n };\n\n try {\n switch (config.type) {\n case 's3':\n this.logger.debug(`${LOG_PREFIX} Mounting S3 bucket at ${mountPath}...`);\n await mountS3(mountPath, config as BlaxelS3MountConfig, mountCtx);\n this.logger.debug(`${LOG_PREFIX} Mounted S3 bucket at ${mountPath}`);\n break;\n case 'gcs':\n this.logger.debug(`${LOG_PREFIX} Mounting GCS bucket at ${mountPath}...`);\n await mountGCS(mountPath, config as BlaxelGCSMountConfig, mountCtx);\n this.logger.debug(`${LOG_PREFIX} Mounted GCS bucket at ${mountPath}`);\n break;\n default:\n this.mounts.set(mountPath, {\n filesystem,\n state: 'unsupported',\n config,\n error: `Unsupported mount type: ${(config as FilesystemMountConfig).type}`,\n });\n return {\n success: false,\n mountPath,\n error: `Unsupported mount type: ${(config as FilesystemMountConfig).type}`,\n };\n }\n } catch (error) {\n this.logger.error(\n `${LOG_PREFIX} Error mounting \"${filesystem.provider}\" (${filesystem.id}) at \"${mountPath}\":`,\n error,\n );\n this.mounts.set(mountPath, { filesystem, state: 'error', config, error: errorToString(error) });\n\n // Clean up the directory we created since mount failed\n try {\n await runCommand(this._sandbox!, `rmdir \"${mountPath}\" 2>/dev/null || true`);\n this.logger.debug(`${LOG_PREFIX} Cleaned up directory after failed mount: ${mountPath}`);\n } catch {\n // Ignore cleanup errors\n }\n\n return { success: false, mountPath, error: errorToString(error) };\n }\n\n // Mark as mounted\n this.mounts.set(mountPath, { state: 'mounted', config });\n\n // Write marker file so we can detect config changes on reconnect\n await this.writeMarkerFile(mountPath);\n\n this.logger.debug(`${LOG_PREFIX} Mounted ${mountPath}`);\n return { success: true, mountPath };\n }\n\n /**\n * Write marker file for detecting config changes on reconnect.\n * Stores both the mount path and config hash in the file.\n */\n private async writeMarkerFile(mountPath: string): Promise<void> {\n if (!this._sandbox) return;\n\n const markerContent = this.mounts.getMarkerContent(mountPath);\n if (!markerContent) return;\n\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n try {\n await runCommand(this._sandbox, 'mkdir -p /tmp/.mastra-mounts');\n await this._sandbox.fs.write(markerPath, markerContent);\n } catch {\n // Non-fatal - marker is just for optimization\n this.logger.debug(`${LOG_PREFIX} Warning: Could not write marker file at ${markerPath}`);\n }\n }\n\n /**\n * Unmount a filesystem from a path in the sandbox.\n */\n async unmount(mountPath: string): Promise<void> {\n validateMountPath(mountPath);\n\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Unmounting ${mountPath}...`);\n\n try {\n // Use fusermount for FUSE mounts, fall back to umount\n const result = await runCommand(\n this._sandbox,\n `fusermount -u \"${mountPath}\" 2>/dev/null || umount \"${mountPath}\"`,\n );\n if (result.exitCode !== 0) {\n this.logger.debug(`${LOG_PREFIX} Unmount warning: ${result.stderr || result.stdout}`);\n }\n } catch (error) {\n this.logger.debug(`${LOG_PREFIX} Unmount error:`, error);\n // Try lazy unmount as last resort\n await runCommand(this._sandbox, `umount -l \"${mountPath}\" 2>/dev/null || true`);\n }\n\n this.mounts.delete(mountPath);\n\n // Clean up marker file\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n await runCommand(this._sandbox, `rm -f \"${markerPath}\" 2>/dev/null || true`);\n\n // Remove empty mount directory (only if empty, rmdir fails on non-empty)\n // Use || true so a non-empty or missing directory doesn't abort unmount\n const rmdirResult = await runCommand(this._sandbox, `rmdir \"${mountPath}\" 2>&1`);\n if (rmdirResult.exitCode === 0) {\n this.logger.debug(`${LOG_PREFIX} Unmounted and removed ${mountPath}`);\n } else {\n this.logger.debug(\n `${LOG_PREFIX} Unmounted ${mountPath} (directory not removed: ${rmdirResult.stderr?.trim() || 'not empty'})`,\n );\n }\n }\n\n /**\n * Get list of current mounts in the sandbox.\n */\n async getMounts(): Promise<Array<{ path: string; filesystem: string }>> {\n return Array.from(this.mounts.entries).map(([path, entry]) => ({\n path,\n filesystem: entry.filesystem?.provider ?? entry.config?.type ?? 'unknown',\n }));\n }\n\n /**\n * Unmount all stale mounts that are not in the expected mounts list.\n * Also cleans up orphaned directories and marker files from failed mount attempts.\n * Call this after reconnecting to an existing sandbox to clean up old mounts.\n */\n async reconcileMounts(expectedMountPaths: string[]): Promise<void> {\n if (!this._sandbox) {\n throw new SandboxNotReadyError(this.id);\n }\n\n this.logger.debug(`${LOG_PREFIX} Reconciling mounts. Expected paths:`, expectedMountPaths);\n\n // Get current FUSE mounts in the sandbox\n // Use || true to prevent failure when no FUSE mounts exist (grep exits 1 on no match)\n const mountsResult = await runCommand(\n this._sandbox,\n `grep -E 'fuse\\\\.(s3fs|gcsfuse)' /proc/mounts | awk '{print $2}' || true`,\n );\n const currentMounts = mountsResult.stdout\n .trim()\n .split('\\n')\n .filter(p => p.length > 0);\n\n this.logger.debug(`${LOG_PREFIX} Current FUSE mounts in sandbox:`, currentMounts);\n\n // Read our marker files to know which mounts WE created\n const markersResult = await runCommand(this._sandbox, `ls /tmp/.mastra-mounts/ 2>/dev/null || echo \"\"`);\n const markerFiles = markersResult.stdout\n .trim()\n .split('\\n')\n .filter(f => f.length > 0 && SAFE_MARKER_NAME.test(f));\n\n // Build a map of mount paths -> marker filenames for mounts WE created\n const managedMountPaths = new Map<string, string>();\n for (const markerFile of markerFiles) {\n const markerResult = await runCommand(\n this._sandbox,\n `cat \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || echo \"\"`,\n );\n const parsed = this.mounts.parseMarkerContent(markerResult.stdout.trim());\n if (parsed && SAFE_MOUNT_PATH.test(parsed.path)) {\n managedMountPaths.set(parsed.path, markerFile);\n }\n }\n\n // Find mounts that exist but shouldn't — only unmount if WE created them (have a marker)\n const staleMounts = currentMounts.filter(path => !expectedMountPaths.includes(path));\n\n for (const stalePath of staleMounts) {\n if (managedMountPaths.has(stalePath)) {\n this.logger.debug(`${LOG_PREFIX} Found stale managed FUSE mount at ${stalePath}, unmounting...`);\n await this.unmount(stalePath);\n } else {\n this.logger.debug(`${LOG_PREFIX} Found external FUSE mount at ${stalePath}, leaving untouched`);\n }\n }\n\n // Clean up orphaned marker files and empty directories from failed mounts\n try {\n const expectedMarkerFiles = new Set(expectedMountPaths.map(p => this.mounts.markerFilename(p)));\n\n // Build a reverse map: markerFile -> mountPath\n const markerToPath = new Map<string, string>();\n for (const [path, file] of managedMountPaths) {\n markerToPath.set(file, path);\n }\n\n for (const markerFile of markerFiles) {\n // If this marker file doesn't correspond to an expected mount path, clean it up\n if (!expectedMarkerFiles.has(markerFile)) {\n const mountPath = markerToPath.get(markerFile);\n\n if (mountPath) {\n // Only clean up directory if not currently FUSE mounted\n if (!currentMounts.includes(mountPath)) {\n this.logger.debug(`${LOG_PREFIX} Cleaning up orphaned marker and directory for ${mountPath}`);\n\n // Remove marker file\n await runCommand(this._sandbox!, `rm -f \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || true`);\n\n // Try to remove the directory (will fail if not empty or doesn't exist, which is fine)\n await runCommand(this._sandbox!, `rmdir \"${mountPath}\" 2>/dev/null || true`);\n }\n } else {\n // Malformed marker file - just delete it\n this.logger.debug(`${LOG_PREFIX} Removing malformed marker file: ${markerFile}`);\n await runCommand(this._sandbox!, `rm -f \"/tmp/.mastra-mounts/${markerFile}\" 2>/dev/null || true`);\n }\n }\n }\n } catch {\n // Ignore errors during orphan cleanup\n this.logger.debug(`${LOG_PREFIX} Error during orphan cleanup (non-fatal)`);\n }\n }\n\n /**\n * Check if a path is already mounted and if the config matches.\n *\n * @param mountPath - The mount path to check\n * @param newConfig - The new config to compare against the stored config\n * @returns 'not_mounted' | 'matching' | 'mismatched'\n */\n private async checkExistingMount(\n mountPath: string,\n newConfig: BlaxelMountConfig,\n ): Promise<'not_mounted' | 'matching' | 'mismatched'> {\n if (!this._sandbox) throw new SandboxNotReadyError(this.id);\n\n // Check if path is a mount point\n const mountCheck = await runCommand(\n this._sandbox,\n `mountpoint -q \"${mountPath}\" && echo \"mounted\" || echo \"not mounted\"`,\n );\n\n if (mountCheck.stdout.trim() !== 'mounted') {\n return 'not_mounted';\n }\n\n // Path is mounted - check if config matches via marker file\n const filename = this.mounts.markerFilename(mountPath);\n const markerPath = `/tmp/.mastra-mounts/${filename}`;\n\n try {\n const markerResult = await runCommand(this._sandbox, `cat \"${markerPath}\" 2>/dev/null || echo \"\"`);\n const parsed = this.mounts.parseMarkerContent(markerResult.stdout.trim());\n\n if (!parsed) {\n return 'mismatched';\n }\n\n // Compute hash of the NEW config and compare with stored hash\n const newConfigHash = this.mounts.computeConfigHash(newConfig);\n this.logger.debug(\n `${LOG_PREFIX} Marker check - stored hash: \"${parsed.configHash}\", new config hash: \"${newConfigHash}\"`,\n );\n\n if (parsed.path === mountPath && parsed.configHash === newConfigHash) {\n return 'matching';\n }\n } catch {\n // Marker doesn't exist or can't be read - treat as mismatched\n }\n\n return 'mismatched';\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle (overrides base class protected methods)\n // ---------------------------------------------------------------------------\n\n /**\n * Start the Blaxel sandbox.\n * Uses `createIfNotExists` to reconnect to an existing sandbox or create a new one.\n *\n * Status management and mount processing are handled by the base class.\n */\n async start(): Promise<void> {\n // Already have a sandbox instance\n if (this._sandbox) {\n return;\n }\n\n const sandboxName = this.toSandboxName(this.id);\n\n this.logger.debug(`${LOG_PREFIX} Starting sandbox: ${sandboxName}`);\n\n // Try to get an existing sandbox first\n const existingSandbox = await this.findExistingSandbox(sandboxName);\n\n if (existingSandbox) {\n this._sandbox = existingSandbox;\n this._createdAt = new Date();\n this.logger.debug(`${LOG_PREFIX} Reconnected to existing sandbox: ${sandboxName}`);\n\n // Clean up stale mounts from previous config\n // (processPending is called by base class after start completes)\n const expectedPaths = Array.from(this.mounts.entries.keys());\n this.logger.debug(`${LOG_PREFIX} Running mount reconciliation...`);\n await this.reconcileMounts(expectedPaths);\n this.logger.debug(`${LOG_PREFIX} Mount reconciliation complete`);\n return;\n }\n\n // Create a new sandbox\n this.logger.debug(`${LOG_PREFIX} Creating new sandbox: ${sandboxName}`);\n\n try {\n this._sandbox = await SandboxInstance.create({\n name: sandboxName,\n image: this.image,\n memory: this.memory,\n ...(this.timeout && { ttl: this.timeout }),\n labels: {\n ...this.labels,\n 'mastra-sandbox-id': this.id,\n },\n ports: this.ports.map(p => ({\n name: p.name,\n target: p.target,\n protocol: p.protocol ?? 'HTTP',\n })),\n });\n } catch (createError) {\n // Blaxel API may throw plain objects instead of Error instances.\n // Wrap them so downstream code (instanceof Error checks) works correctly.\n if (createError instanceof Error) {\n throw createError;\n }\n throw new Error(errorToString(createError));\n }\n\n this._createdAt = new Date();\n this.logger.debug(`${LOG_PREFIX} Sandbox ready: ${sandboxName} (status: ${this._sandbox.status})`);\n\n // Note: processPending is called by base class after start completes\n }\n\n /**\n * Convert a logical sandbox ID to a valid Blaxel sandbox name.\n * Blaxel sandbox names must be DNS-safe (lowercase alphanumeric and hyphens).\n */\n private toSandboxName(id: string): string {\n const name = id\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 63);\n if (!name) {\n throw new Error(\n `Cannot derive a valid sandbox name from id \"${id}\". ID must contain at least one alphanumeric character.`,\n );\n }\n return name;\n }\n\n /**\n * Find an existing sandbox with the given name.\n * Returns the connected sandbox if found and running, null otherwise.\n */\n private async findExistingSandbox(sandboxName: string): Promise<SandboxInstance | null> {\n try {\n const existing = await SandboxInstance.get(sandboxName);\n\n // Only reuse if the sandbox is actually deployed (running)\n if (existing.status === 'DEPLOYED') {\n this.logger.debug(`${LOG_PREFIX} Found existing sandbox: ${sandboxName} (status: ${existing.status})`);\n return existing;\n }\n\n this.logger.debug(\n `${LOG_PREFIX} Found sandbox ${sandboxName} but status is ${existing.status}, creating new one`,\n );\n } catch (e) {\n this.logger.debug(`${LOG_PREFIX} No existing sandbox found for ${sandboxName}:`, e);\n }\n\n return null;\n }\n\n /**\n * Stop the Blaxel sandbox.\n * Unmounts all filesystems and releases the sandbox reference.\n * Status management is handled by the base class.\n */\n async stop(): Promise<void> {\n // Kill all tracked processes before stopping\n if (this.processes) {\n try {\n const procs = await this.processes.list();\n await Promise.all(procs.filter(p => p.running).map(p => this.processes!.kill(p.pid)));\n } catch {\n // Best-effort cleanup\n }\n }\n\n // Unmount all filesystems before stopping\n // Collect keys first since unmount() mutates the map\n for (const mountPath of [...this.mounts.entries.keys()]) {\n try {\n await this.unmount(mountPath);\n } catch {\n // Best-effort unmount; sandbox may already be dead\n }\n }\n\n this._sandbox = null;\n }\n\n /**\n * Destroy the Blaxel sandbox and clean up all resources.\n * Unmounts filesystems, deletes the sandbox, and clears mount state.\n * Status management is handled by the base class.\n */\n async destroy(): Promise<void> {\n // Kill all tracked processes before destroying\n if (this.processes) {\n try {\n const procs = await this.processes.list();\n await Promise.all(procs.filter(p => p.running).map(p => this.processes!.kill(p.pid)));\n } catch {\n // Best-effort cleanup\n }\n }\n\n // Unmount all filesystems\n // Collect keys first since unmount() mutates the map\n for (const mountPath of [...this.mounts.entries.keys()]) {\n try {\n await this.unmount(mountPath);\n } catch {\n // Ignore errors during cleanup\n }\n }\n\n if (this._sandbox) {\n try {\n await this._sandbox.delete();\n } catch {\n // Ignore errors during destroy\n }\n }\n\n this._sandbox = null;\n this.mounts.clear();\n }\n\n /**\n * Check if the sandbox is ready for operations.\n */\n async isReady(): Promise<boolean> {\n return this.status === 'running' && this._sandbox !== null;\n }\n\n /**\n * Get information about the current state of the sandbox.\n */\n async getInfo(): Promise<SandboxInfo> {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n status: this.status,\n createdAt: this._createdAt ?? new Date(),\n mounts: Array.from(this.mounts.entries).map(([path, entry]) => ({\n path,\n filesystem: entry.filesystem?.provider ?? entry.config?.type ?? 'unknown',\n })),\n metadata: {\n ...this.labels,\n image: this.image,\n memory: this.memory,\n sandboxStatus: this._sandbox?.status,\n },\n };\n }\n\n /**\n * Get instructions describing this Blaxel sandbox.\n * Used by agents to understand the execution environment.\n */\n getInstructions(): string {\n const mountCount = this.mounts.entries.size;\n const mountInfo = mountCount > 0 ? ` ${mountCount} filesystem(s) mounted via FUSE.` : '';\n return `Cloud sandbox.${mountInfo}`;\n }\n\n // ---------------------------------------------------------------------------\n // Internal Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Ensure the sandbox is started and return the Blaxel SandboxInstance.\n * Uses base class ensureRunning() for status management and error handling.\n * @throws {SandboxNotReadyError} if sandbox fails to start\n */\n private async ensureSandbox(): Promise<SandboxInstance> {\n await this.ensureRunning();\n return this._sandbox!;\n }\n\n /**\n * Check if an error indicates the sandbox itself is dead/gone.\n * Does NOT include code execution timeouts (those are the user's code taking too long).\n */\n private isSandboxDeadError(error: unknown): boolean {\n if (!error) return false;\n const errorStr = errorToString(error).toLowerCase();\n return (\n errorStr.includes('terminated') ||\n errorStr.includes('sandbox was not found') ||\n errorStr.includes('sandbox not found') ||\n errorStr.includes('\"not found\"')\n );\n }\n\n /**\n * Handle sandbox timeout by clearing the instance and resetting state.\n *\n * Bypasses the normal stop() lifecycle because the sandbox is already dead —\n * we can't unmount filesystems or run cleanup commands. Instead we reset\n * mount states to 'pending' so they get re-mounted when start() runs again.\n */\n private handleSandboxTimeout(): void {\n this._sandbox = null;\n\n // Reset mounted entries to pending so they get re-mounted on restart\n for (const [path, entry] of this.mounts.entries) {\n if (entry.state === 'mounted' || entry.state === 'mounting') {\n this.mounts.set(path, { state: 'pending' });\n }\n }\n\n this.status = 'stopped';\n }\n\n /**\n * Execute an operation with automatic retry if the sandbox is found to be dead.\n *\n * When the Blaxel sandbox times out or crashes mid-operation, this method\n * resets sandbox state, restarts it, and retries the operation once.\n *\n * @internal Used by BlaxelProcessManager to handle dead sandboxes during spawn.\n */\n async retryOnDead<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (this.isSandboxDeadError(error) && !this._isRetrying) {\n this.handleSandboxTimeout();\n this._isRetrying = true;\n try {\n await this.ensureRunning();\n return await fn();\n } finally {\n this._isRetrying = false;\n }\n }\n throw error;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Command Execution\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a shell command in the sandbox.\n * Automatically starts the sandbox if not already running.\n * Retries once if the sandbox is found to be dead.\n */\n async executeCommand(\n command: string,\n args: string[] = [],\n options: ExecuteCommandOptions = {},\n ): Promise<CommandResult> {\n this.logger.debug(`${LOG_PREFIX} Executing: ${command} ${args.join(' ')}`, options);\n const sandbox = await this.ensureSandbox();\n\n const startTime = Date.now();\n const fullCommand = args.length > 0 ? `${command} ${args.map(shellQuote).join(' ')}` : command;\n\n this.logger.debug(`${LOG_PREFIX} Executing: ${fullCommand}`);\n\n // Accumulate output so partial stdout/stderr is available when abort/timeout wins the race\n let capturedStdout = '';\n let capturedStderr = '';\n\n try {\n // Merge sandbox default env with per-command env (per-command overrides)\n // Filter out undefined values to get Record<string, string>\n const mergedEnv = { ...this.env, ...options.env };\n const envRecord = Object.fromEntries(\n Object.entries(mergedEnv).filter((entry): entry is [string, string] => entry[1] !== undefined),\n );\n\n // Pass timeout to Blaxel API (in seconds) AND enforce client-side via Promise.race.\n // The API enforces timeout for non-streaming requests, but when onStdout/onStderr\n // callbacks are present the SDK uses a streaming path that ignores the timeout param.\n // Promise.race ensures timeout is always enforced regardless of code path.\n const apiTimeout = options.timeout ? Math.ceil(options.timeout / 1000) : undefined;\n\n const execPromise = sandbox.process.exec({\n command: fullCommand,\n workingDir: options.cwd,\n env: envRecord,\n waitForCompletion: true,\n ...(apiTimeout && { timeout: apiTimeout }),\n onStdout: (data: string) => {\n capturedStdout += data;\n options.onStdout?.(data);\n },\n onStderr: (data: string) => {\n capturedStderr += data;\n options.onStderr?.(data);\n },\n });\n\n // Build race competitors: timeout and abort signal\n const racePromises: Promise<never>[] = [];\n let timer: ReturnType<typeof setTimeout> | undefined;\n let abortHandler: (() => void) | undefined;\n\n if (options.timeout) {\n racePromises.push(\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n // Best-effort cleanup: kill the process on the sandbox.\n // The streaming exec path doesn't expose the process ID until it completes,\n // so we attempt to kill by command string.\n runCommand(sandbox, `pkill -f ${shellQuote(fullCommand)}`, { timeout: 5000 }).catch(() => {});\n reject(new Error(`Command timed out after ${options.timeout}ms`));\n }, options.timeout!);\n }),\n );\n }\n\n if (options.abortSignal) {\n if (options.abortSignal.aborted) {\n runCommand(sandbox, `pkill -f ${shellQuote(fullCommand)}`, { timeout: 5000 }).catch(() => {});\n throw new Error('Process aborted');\n }\n racePromises.push(\n new Promise<never>((_, reject) => {\n abortHandler = () => {\n runCommand(sandbox, `pkill -f ${shellQuote(fullCommand)}`, { timeout: 5000 }).catch(() => {});\n reject(new Error('Process aborted'));\n };\n options.abortSignal!.addEventListener('abort', abortHandler, { once: true });\n }),\n );\n }\n\n let result;\n try {\n if (racePromises.length > 0) {\n result = await Promise.race([execPromise, ...racePromises]);\n } else {\n result = await execPromise;\n }\n } finally {\n if (timer) clearTimeout(timer);\n if (abortHandler && options.abortSignal) {\n options.abortSignal.removeEventListener('abort', abortHandler);\n }\n }\n\n const executionTimeMs = Date.now() - startTime;\n const exitCode = result.exitCode ?? 0;\n const stdout = capturedStdout || result.stdout || '';\n const stderr = capturedStderr || result.stderr || '';\n\n this.logger.debug(`${LOG_PREFIX} Exit code: ${exitCode} (${executionTimeMs}ms)`);\n if (stdout) this.logger.debug(`${LOG_PREFIX} stdout:\\n${stdout}`);\n if (stderr) this.logger.debug(`${LOG_PREFIX} stderr:\\n${stderr}`);\n\n return {\n success: exitCode === 0,\n exitCode,\n stdout,\n stderr,\n executionTimeMs,\n command,\n args,\n };\n } catch (error) {\n // Handle sandbox-is-dead errors - retry once (not infinitely)\n if (this.isSandboxDeadError(error) && !this._isRetrying) {\n this.handleSandboxTimeout();\n this._isRetrying = true;\n try {\n return await this.executeCommand(command, args, options);\n } finally {\n this._isRetrying = false;\n }\n }\n\n const executionTimeMs = Date.now() - startTime;\n\n return {\n success: false,\n exitCode: 1,\n stdout: capturedStdout,\n stderr: capturedStderr || errorToString(error),\n executionTimeMs,\n command,\n args,\n };\n }\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { BlaxelSandbox, type BlaxelSandboxOptions, type SandboxRuntime } from './sandbox/index.js';
2
+ export { BlaxelProcessManager, type BlaxelProcessManagerOptions } from './sandbox/process-manager.js';
2
3
  export { type BlaxelS3MountConfig, type BlaxelGCSMountConfig, type BlaxelMountConfig } from './sandbox/mounts/index.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}