momentic-mobile 0.97.2 → 0.97.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +11 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/remote-control-static/assets/index-DjJNg2Cy.css +1 -0
- package/remote-control-static/index.html +2 -2
- package/run-viewer-static/assets/{index-CBPtWGQ3.js → index-CCJYlcfW.js} +2 -2
- package/run-viewer-static/assets/index-DU_9AugN.css +1 -0
- package/run-viewer-static/index.html +2 -2
- package/static/assets/index-DOj9MkLm.css +1 -0
- package/static/assets/{index-iqLQzcAy.js → index-hFdTt-mS.js} +83 -83
- package/static/index.html +2 -2
- package/remote-control-static/assets/index-C_Frew96.css +0 -1
- package/run-viewer-static/assets/index-BNtEJX1M.css +0 -1
- package/static/assets/index-C6To0L9S.css +0 -1
- /package/remote-control-static/assets/{index-zHV5qe9h.js → index-DhkYAtGe.js} +0 -0
package/bin/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="087d1813-e067-50ce-a81e-c75a44ad3120")}catch(e){}}();
|
|
4
4
|
import * as oT from 'http';
|
|
5
5
|
import oT__default, { createServer } from 'http';
|
|
6
6
|
import * as nT from 'https';
|
|
@@ -176,7 +176,7 @@ To resolve the conflict:`,iP(l,e))),i=c):Pe.warn("A view or instrument with the
|
|
|
176
176
|
`,nP(l,e),`To resolve the conflict:
|
|
177
177
|
`,iP(l,e));}}catch(u){o={error:u};}finally{try{s&&!s.done&&(n=a.return)&&n.call(a);}finally{if(o)throw o.error}}return i},t}();var zH=function(){function t(e){this._backingStorages=e;}return t.prototype.record=function(e,r,o,n){this._backingStorages.forEach(function(i){i.record(e,r,o,n);});},t}();Wt();Wt();var $H=function(){function t(e,r){this._instrumentName=e,this._valueType=r,this._buffer=new Xi;}return t.prototype.observe=function(e,r){if(r===void 0&&(r={}),typeof e!="number"){Pe.warn("non-number value provided to metric "+this._instrumentName+": "+e);return}this._valueType===Hn.INT&&!Number.isInteger(e)&&(Pe.warn("INT value type cannot accept a floating-point value for "+this._instrumentName+", ignoring the fractional digits."),e=Math.trunc(e),!Number.isInteger(e))||this._buffer.set(r,e);},t}();var jH=function(){function t(){this._buffer=new Map;}return t.prototype.observe=function(e,r,o){if(o===void 0&&(o={}),!!ig(e)){var n=this._buffer.get(e);if(n==null&&(n=new Xi,this._buffer.set(e,n)),typeof r!="number"){Pe.warn("non-number value provided to metric "+e._descriptor.name+": "+r);return}e._descriptor.valueType===Hn.INT&&!Number.isInteger(r)&&(Pe.warn("INT value type cannot accept a floating-point value for "+e._descriptor.name+", ignoring the fractional digits."),r=Math.trunc(r),!Number.isInteger(r))||n.set(o,r);}},t}();var sP=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},lP=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},HH=function(t,e){var r=typeof Symbol=="function"&&t[Symbol.iterator];if(!r)return t;var o=r.call(t),n,i=[],a;try{for(;(e===void 0||e-- >0)&&!(n=o.next()).done;)i.push(n.value);}catch(s){a={error:s};}finally{try{n&&!n.done&&(r=o.return)&&r.call(o);}finally{if(a)throw a.error}}return i},GH=function(t,e,r){if(arguments.length===2)for(var o=0,n=e.length,i;o<n;o++)(i||!(o in e))&&(i||(i=Array.prototype.slice.call(e,0,o)),i[o]=e[o]);return t.concat(i||Array.prototype.slice.call(e))},WH=function(){function t(){this._callbacks=[],this._batchCallbacks=[];}return t.prototype.addCallback=function(e,r){var o=this._findCallback(e,r);o>=0||this._callbacks.push({callback:e,instrument:r});},t.prototype.removeCallback=function(e,r){var o=this._findCallback(e,r);o<0||this._callbacks.splice(o,1);},t.prototype.addBatchCallback=function(e,r){var o=new Set(r.filter(ig));if(o.size===0){Pe.error("BatchObservableCallback is not associated with valid instruments",r);return}var n=this._findBatchCallback(e,o);n>=0||this._batchCallbacks.push({callback:e,instruments:o});},t.prototype.removeBatchCallback=function(e,r){var o=new Set(r.filter(ig)),n=this._findBatchCallback(e,o);n<0||this._batchCallbacks.splice(n,1);},t.prototype.observe=function(e,r){return sP(this,void 0,void 0,function(){var o,n,i,a;return lP(this,function(s){switch(s.label){case 0:return o=this._observeCallbacks(e,r),n=this._observeBatchCallbacks(e,r),[4,Kj(GH(GH([],HH(o),false),HH(n),false))];case 1:return i=s.sent(),a=i.filter(Yj).map(function(c){return c.reason}),[2,a]}})})},t.prototype._observeCallbacks=function(e,r){var o=this;return this._callbacks.map(function(n){var i=n.callback,a=n.instrument;return sP(o,void 0,void 0,function(){var s,c;return lP(this,function(l){switch(l.label){case 0:return s=new $H(a._descriptor.name,a._descriptor.valueType),c=Promise.resolve(i(s)),r!=null&&(c=Fl(c,r)),[4,c];case 1:return l.sent(),a._metricStorages.forEach(function(u){u.record(s._buffer,e);}),[2]}})})})},t.prototype._observeBatchCallbacks=function(e,r){var o=this;return this._batchCallbacks.map(function(n){var i=n.callback,a=n.instruments;return sP(o,void 0,void 0,function(){var s,c;return lP(this,function(l){switch(l.label){case 0:return s=new jH,c=Promise.resolve(i(s)),r!=null&&(c=Fl(c,r)),[4,c];case 1:return l.sent(),a.forEach(function(u){var d=s._buffer.get(u);d!=null&&u._metricStorages.forEach(function(m){m.record(d,e);});}),[2]}})})})},t.prototype._findCallback=function(e,r){return this._callbacks.findIndex(function(o){return o.callback===e&&o.instrument===r})},t.prototype._findBatchCallback=function(e,r){return this._batchCallbacks.findIndex(function(o){return o.callback===e&&Xj(o.instruments,r)})},t}();var Xme=function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n;}||function(o,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(o[i]=n[i]);},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function o(){this.constructor=e;}e.prototype=r===null?Object.create(r):(o.prototype=r.prototype,new o);}}(),qH=function(t){Xme(e,t);function e(r,o,n,i,a){var s=t.call(this,r)||this;return s._attributesProcessor=n,s._aggregationCardinalityLimit=a,s._deltaMetricStorage=new XE(o,s._aggregationCardinalityLimit),s._temporalMetricStorage=new JE(o,i),s}return e.prototype.record=function(r,o,n,i){o=this._attributesProcessor.process(o,n),this._deltaMetricStorage.record(r,o,n,i);},e.prototype.collect=function(r,o){var n=this._deltaMetricStorage.collect();return this._temporalMetricStorage.buildMetrics(r,this._instrumentDescriptor,n,o)},e}(YE);var KH=function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n;}||function(o,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(o[i]=n[i]);},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function o(){this.constructor=e;}e.prototype=r===null?Object.create(r):(o.prototype=r.prototype,new o);}}(),Lm=function(){function t(){}return t.Noop=function(){return Zme},t}();var Jme=function(t){KH(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.process=function(r,o){return r},e}(Lm);var YH=function(t){KH(e,t);function e(r){var o=t.call(this)||this;return o._allowedAttributeNames=r,o}return e.prototype.process=function(r,o){var n=this,i={};return Object.keys(r).filter(function(a){return n._allowedAttributeNames.includes(a)}).forEach(function(a){return i[a]=r[a]}),i},e}(Lm);var Zme=new Jme;var Qme=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},epe=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},tpe=function(t,e){var r=typeof Symbol=="function"&&t[Symbol.iterator];if(!r)return t;var o=r.call(t),n,i=[],a;try{for(;(e===void 0||e-- >0)&&!(n=o.next()).done;)i.push(n.value);}catch(s){a={error:s};}finally{try{n&&!n.done&&(r=o.return)&&r.call(o);}finally{if(a)throw a.error}}return i},XH=function(){function t(e,r){this._meterProviderSharedState=e,this._instrumentationScope=r,this.metricStorageRegistry=new VH,this.observableRegistry=new WH,this.meter=new kH(this);}return t.prototype.registerMetricStorage=function(e){var r=this._registerMetricStorage(e,qH);return r.length===1?r[0]:new zH(r)},t.prototype.registerAsyncMetricStorage=function(e){var r=this._registerMetricStorage(e,BH);return r},t.prototype.collect=function(e,r,o){return Qme(this,void 0,void 0,function(){var n,i,a;return epe(this,function(s){switch(s.label){case 0:return [4,this.observableRegistry.observe(r,o?.timeoutMillis)];case 1:return n=s.sent(),i=this.metricStorageRegistry.getStorages(e),i.length===0?[2,null]:(a=i.map(function(c){return c.collect(e,r)}).filter(Wj),a.length===0?[2,{errors:n}]:[2,{scopeMetrics:{scope:this._instrumentationScope,metrics:a},errors:n}])}})})},t.prototype._registerMetricStorage=function(e,r){var o=this,n=this._meterProviderSharedState.viewRegistry.findViews(e,this._instrumentationScope),i=n.map(function(c){var l=Qj(c,e),u=o.metricStorageRegistry.findOrUpdateCompatibleStorage(l);if(u!=null)return u;var d=c.aggregation.createAggregator(l),m=new r(l,d,c.attributesProcessor,o._meterProviderSharedState.metricCollectors,c.aggregationCardinalityLimit);return o.metricStorageRegistry.register(m),m});if(i.length===0){var a=this._meterProviderSharedState.selectAggregations(e.type),s=a.map(function(c){var l=tpe(c,2),u=l[0],d=l[1],m=o.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(u,e);if(m!=null)return m;var p=d.createAggregator(e),f=u.selectCardinalityLimit(e.type),h=new r(e,p,Lm.Noop(),[u],f);return o.metricStorageRegistry.registerForCollector(u,h),h});i=i.concat(s);}return i},t}();var rpe=function(t){var e=typeof Symbol=="function"&&Symbol.iterator,r=e&&t[e],o=0;if(r)return r.call(t);if(t&&typeof t.length=="number")return {next:function(){return t&&o>=t.length&&(t=void 0),{value:t&&t[o++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},JH=function(){function t(e){this.resource=e,this.viewRegistry=new MH,this.metricCollectors=[],this.meterSharedStates=new Map;}return t.prototype.getMeterSharedState=function(e){var r=qj(e),o=this.meterSharedStates.get(r);return o==null&&(o=new XH(this,e),this.meterSharedStates.set(r,o)),o},t.prototype.selectAggregations=function(e){var r,o,n=[];try{for(var i=rpe(this.metricCollectors),a=i.next();!a.done;a=i.next()){var s=a.value;n.push([s,s.selectAggregation(e)]);}}catch(c){r={error:c};}finally{try{a&&!a.done&&(o=i.return)&&o.call(i);}finally{if(r)throw r.error}}return n},t}();ja();var ZE=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},QE=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},ope=function(t,e){var r=typeof Symbol=="function"&&t[Symbol.iterator];if(!r)return t;var o=r.call(t),n,i=[],a;try{for(;(e===void 0||e-- >0)&&!(n=o.next()).done;)i.push(n.value);}catch(s){a={error:s};}finally{try{n&&!n.done&&(r=o.return)&&r.call(o);}finally{if(a)throw a.error}}return i},npe=function(t,e,r){if(arguments.length===2)for(var o=0,n=e.length,i;o<n;o++)(i||!(o in e))&&(i||(i=Array.prototype.slice.call(e,0,o)),i[o]=e[o]);return t.concat(i||Array.prototype.slice.call(e))},ZH=function(){function t(e,r){this._sharedState=e,this._metricReader=r;}return t.prototype.collect=function(e){return ZE(this,void 0,void 0,function(){var r,o,n,i,a=this;return QE(this,function(s){switch(s.label){case 0:return r=Tu(Date.now()),o=[],n=[],i=Array.from(this._sharedState.meterSharedStates.values()).map(function(c){return ZE(a,void 0,void 0,function(){var l;return QE(this,function(u){switch(u.label){case 0:return [4,c.collect(this,r,e)];case 1:return l=u.sent(),l?.scopeMetrics!=null&&o.push(l.scopeMetrics),l?.errors!=null&&n.push.apply(n,npe([],ope(l.errors),false)),[2]}})})}),[4,Promise.all(i)];case 1:return s.sent(),[2,{resourceMetrics:{resource:this._sharedState.resource,scopeMetrics:o},errors:n}]}})})},t.prototype.forceFlush=function(e){return ZE(this,void 0,void 0,function(){return QE(this,function(r){switch(r.label){case 0:return [4,this._metricReader.forceFlush(e)];case 1:return r.sent(),[2]}})})},t.prototype.shutdown=function(e){return ZE(this,void 0,void 0,function(){return QE(this,function(r){switch(r.label){case 0:return [4,this._metricReader.shutdown(e)];case 1:return r.sent(),[2]}})})},t.prototype.selectAggregationTemporality=function(e){return this._metricReader.selectAggregationTemporality(e)},t.prototype.selectAggregation=function(e){return this._metricReader.selectAggregation(e)},t.prototype.selectCardinalityLimit=function(e){var r,o,n;return (n=(o=(r=this._metricReader).selectCardinalityLimit)===null||o===void 0?void 0:o.call(r,e))!==null&&n!==void 0?n:2e3},t}();var QH=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},eG=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},tG=function(t){var e=typeof Symbol=="function"&&Symbol.iterator,r=e&&t[e],o=0;if(r)return r.call(t);if(t&&typeof t.length=="number")return {next:function(){return t&&o>=t.length&&(t=void 0),{value:t&&t[o++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function ipe(t,e){var r=e??Dm.empty();return t?Dm.default().merge(r):r}var cP=function(){function t(e){var r,o,n,i,a;if(this._shutdown=false,this._sharedState=new JH(ipe((a=e?.mergeResourceWithDefaults)!==null&&a!==void 0?a:true,e?.resource)),e?.views!=null&&e.views.length>0)try{for(var s=tG(e.views),c=s.next();!c.done;c=s.next()){var l=c.value;this._sharedState.viewRegistry.addView(l);}}catch(p){r={error:p};}finally{try{c&&!c.done&&(o=s.return)&&o.call(s);}finally{if(r)throw r.error}}if(e?.readers!=null&&e.readers.length>0)try{for(var u=tG(e.readers),d=u.next();!d.done;d=u.next()){var m=d.value;this.addMetricReader(m);}}catch(p){n={error:p};}finally{try{d&&!d.done&&(i=u.return)&&i.call(u);}finally{if(n)throw n.error}}}return t.prototype.getMeter=function(e,r,o){return r===void 0&&(r=""),o===void 0&&(o={}),this._shutdown?(Pe.warn("A shutdown MeterProvider cannot provide a Meter"),gx()):this._sharedState.getMeterSharedState({name:e,version:r,schemaUrl:o.schemaUrl}).meter},t.prototype.addMetricReader=function(e){var r=new ZH(this._sharedState,e);e.setMetricProducer(r),this._sharedState.metricCollectors.push(r);},t.prototype.shutdown=function(e){return QH(this,void 0,void 0,function(){return eG(this,function(r){switch(r.label){case 0:return this._shutdown?(Pe.warn("shutdown may only be called once per MeterProvider"),[2]):(this._shutdown=true,[4,Promise.all(this._sharedState.metricCollectors.map(function(o){return o.shutdown(e)}))]);case 1:return r.sent(),[2]}})})},t.prototype.forceFlush=function(e){return QH(this,void 0,void 0,function(){return eG(this,function(r){switch(r.label){case 0:return this._shutdown?(Pe.warn("invalid attempt to force flush after MeterProvider shutdown"),[2]):[4,Promise.all(this._sharedState.metricCollectors.map(function(o){return o.forceFlush(e)}))];case 1:return r.sent(),[2]}})})},t}();var ape=/[\^$\\.+?()[\]{}|]/g,eT=function(){function t(e){e==="*"?(this._matchAll=true,this._regexp=/.*/):(this._matchAll=false,this._regexp=new RegExp(t.escapePattern(e)));}return t.prototype.match=function(e){return this._matchAll?true:this._regexp.test(e)},t.escapePattern=function(e){return "^"+e.replace(ape,"\\$&").replace("*",".*")+"$"},t.hasWildcard=function(e){return e.includes("*")},t}();var km=function(){function t(e){this._matchAll=e===void 0,this._pattern=e;}return t.prototype.match=function(e){return !!(this._matchAll||e===this._pattern)},t}();var rG=function(){function t(e){var r;this._nameFilter=new eT((r=e?.name)!==null&&r!==void 0?r:"*"),this._type=e?.type,this._unitFilter=new km(e?.unit);}return t.prototype.getType=function(){return this._type},t.prototype.getNameFilter=function(){return this._nameFilter},t.prototype.getUnitFilter=function(){return this._unitFilter},t}();var oG=function(){function t(e){this._nameFilter=new km(e?.name),this._versionFilter=new km(e?.version),this._schemaUrlFilter=new km(e?.schemaUrl);}return t.prototype.getNameFilter=function(){return this._nameFilter},t.prototype.getVersionFilter=function(){return this._versionFilter},t.prototype.getSchemaUrlFilter=function(){return this._schemaUrlFilter},t}();function spe(t){return t.instrumentName==null&&t.instrumentType==null&&t.instrumentUnit==null&&t.meterName==null&&t.meterVersion==null&&t.meterSchemaUrl==null}var ag=function(){function t(e){var r;if(spe(e))throw new Error("Cannot create view with no selector arguments supplied");if(e.name!=null&&(e?.instrumentName==null||eT.hasWildcard(e.instrumentName)))throw new Error("Views with a specified name must be declared with an instrument selector that selects at most one instrument per meter.");e.attributeKeys!=null?this.attributesProcessor=new YH(e.attributeKeys):this.attributesProcessor=Lm.Noop(),this.name=e.name,this.description=e.description,this.aggregation=(r=e.aggregation)!==null&&r!==void 0?r:vn.Default(),this.instrumentSelector=new rG({name:e.instrumentName,type:e.instrumentType,unit:e.instrumentUnit}),this.meterSelector=new oG({name:e.meterName,version:e.meterVersion,schemaUrl:e.meterSchemaUrl}),this.aggregationCardinalityLimit=e.aggregationCardinalityLimit;}return t}();var Vl;(function(t){t[t.DELTA=0]="DELTA",t[t.CUMULATIVE=1]="CUMULATIVE",t[t.LOWMEMORY=2]="LOWMEMORY";})(Vl||(Vl={}));var uP=function(){function t(e){this._delegate=e;}return t.prototype.export=function(e,r){this._delegate.export(e,r);},t.prototype.forceFlush=function(){return this._delegate.forceFlush()},t.prototype.shutdown=function(){return this._delegate.shutdown()},t}();function cpe(t){if(!Number.isNaN(t)&&Number.isFinite(t)&&t>0)return t;throw new Error("Configuration: timeoutMillis is invalid, expected number greater than 0 (actual: '"+t+"')")}function tT(t){if(t!=null)return function(){return t}}function nG(t,e,r){var o,n,i,a,s,c;return {timeoutMillis:cpe((n=(o=t.timeoutMillis)!==null&&o!==void 0?o:e.timeoutMillis)!==null&&n!==void 0?n:r.timeoutMillis),concurrencyLimit:(a=(i=t.concurrencyLimit)!==null&&i!==void 0?i:e.concurrencyLimit)!==null&&a!==void 0?a:r.concurrencyLimit,compression:(c=(s=t.compression)!==null&&s!==void 0?s:e.compression)!==null&&c!==void 0?c:r.compression}}function iG(){return {timeoutMillis:1e4,concurrencyLimit:30,compression:"none"}}var upe=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},dpe=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},mpe=function(){function t(e){this._sendingPromises=[],this._concurrencyLimit=e;}return t.prototype.pushPromise=function(e){var r=this;if(this.hasReachedLimit())throw new Error("Concurrency Limit reached");this._sendingPromises.push(e);var o=function(){var n=r._sendingPromises.indexOf(e);r._sendingPromises.splice(n,1);};e.then(o,o);},t.prototype.hasReachedLimit=function(){return this._sendingPromises.length>=this._concurrencyLimit},t.prototype.awaitAll=function(){return upe(this,void 0,void 0,function(){return dpe(this,function(e){switch(e.label){case 0:return [4,Promise.all(this._sendingPromises)];case 1:return e.sent(),[2]}})})},t}();function aG(t){return new mpe(t.concurrencyLimit)}ja();dP();Wt();function ppe(t){return Object.prototype.hasOwnProperty.call(t,"partialSuccess")}function sG(){return {handleResponse:function(t){t==null||!ppe(t)||t.partialSuccess==null||Object.keys(t.partialSuccess).length===0||Pe.warn("Received Partial Success response:",JSON.stringify(t.partialSuccess));}}}Wt();var fpe=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},hpe=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},gpe=function(){function t(e,r,o,n,i){this._transport=e,this._serializer=r,this._responseHandler=o,this._promiseQueue=n,this._timeout=i,this._diagLogger=Pe.createComponentLogger({namespace:"OTLPExportDelegate"});}return t.prototype.export=function(e,r){var o=this;if(this._diagLogger.debug("items to be sent",e),this._promiseQueue.hasReachedLimit()){r({code:Gn.FAILED,error:new Error("Concurrent export limit reached")});return}var n=this._serializer.serializeRequest(e);if(n==null){r({code:Gn.FAILED,error:new Error("Nothing to send")});return}this._promiseQueue.pushPromise(this._transport.send(n,this._timeout).then(function(i){if(i.status==="success"){if(i.data!=null)try{o._responseHandler.handleResponse(o._serializer.deserializeResponse(i.data));}catch(a){o._diagLogger.warn("Export succeeded but could not deserialize response - is the response specification compliant?",a,i.data);}r({code:Gn.SUCCESS});return}else if(i.status==="failure"&&i.error){r({code:Gn.FAILED,error:i.error});return}else i.status==="retryable"?r({code:Gn.FAILED,error:new sg("Export failed with retryable status")}):r({code:Gn.FAILED,error:new sg("Export failed with unknown error")});},function(i){return r({code:Gn.FAILED,error:i})}));},t.prototype.forceFlush=function(){return this._promiseQueue.awaitAll()},t.prototype.shutdown=function(){return fpe(this,void 0,void 0,function(){return hpe(this,function(e){switch(e.label){case 0:return this._diagLogger.debug("shutdown started"),[4,this.forceFlush()];case 1:return e.sent(),this._transport.shutdown(),[2]}})})},t}();function lG(t,e){return new gpe(t.transport,t.serializer,sG(),t.promiseHandler,e.timeout)}Wt();var Spe=function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n;}||function(o,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(o[i]=n[i]);},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function o(){this.constructor=e;}e.prototype=r===null?Object.create(r):(o.prototype=r.prototype,new o);}}(),mP=function(){return Do.CUMULATIVE},cG=function(t){switch(t){case Fe.COUNTER:case Fe.OBSERVABLE_COUNTER:case Fe.GAUGE:case Fe.HISTOGRAM:case Fe.OBSERVABLE_GAUGE:return Do.DELTA;case Fe.UP_DOWN_COUNTER:case Fe.OBSERVABLE_UP_DOWN_COUNTER:return Do.CUMULATIVE}},uG=function(t){switch(t){case Fe.COUNTER:case Fe.HISTOGRAM:return Do.DELTA;case Fe.GAUGE:case Fe.UP_DOWN_COUNTER:case Fe.OBSERVABLE_UP_DOWN_COUNTER:case Fe.OBSERVABLE_COUNTER:case Fe.OBSERVABLE_GAUGE:return Do.CUMULATIVE}};function bpe(){var t=Xh(),e=t.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE.trim().toLowerCase();return e==="cumulative"?mP:e==="delta"?cG:e==="lowmemory"?uG:(Pe.warn("OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to '"+t.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE+"', but only 'cumulative' and 'delta' are allowed. Using default ('cumulative') instead."),mP)}function ype(t){return t!=null?t===Vl.DELTA?cG:t===Vl.LOWMEMORY?uG:mP:bpe()}function Epe(t){return t?.aggregationPreference?t.aggregationPreference:function(e){return vn.Default()}}var dG=function(t){Spe(e,t);function e(r,o){var n=t.call(this,r)||this;return n._aggregationSelector=Epe(o),n._aggregationTemporalitySelector=ype(o?.temporalityPreference),n}return e.prototype.selectAggregation=function(r){return this._aggregationSelector(r)},e.prototype.selectAggregationTemporality=function(r){return this._aggregationTemporalitySelector(r)},e}(uP);ja();function pG(t){var e=BigInt(1e9);return BigInt(t[0])*e+BigInt(t[1])}function Tpe(t){var e=Number(BigInt.asUintN(32,t)),r=Number(BigInt.asUintN(32,t>>BigInt(32)));return {low:e,high:r}}function fG(t){var e=pG(t);return Tpe(e)}function vpe(t){var e=pG(t);return e.toString()}var Cpe=typeof BigInt<"u"?vpe:zx;function mG(t){return t}function hG(t){if(t!==void 0)return Jh(t)}var Ape={encodeHrTime:fG,encodeSpanContext:Jh,encodeOptionalSpanContext:hG};function gG(t){var e,r;if(t===void 0)return Ape;var o=(e=t.useLongBits)!==null&&e!==void 0?e:true,n=(r=t.useHex)!==null&&r!==void 0?r:false;return {encodeHrTime:o?fG:Cpe,encodeSpanContext:n?mG:Jh,encodeOptionalSpanContext:n?mG:hG}}var wpe=function(t,e){var r=typeof Symbol=="function"&&t[Symbol.iterator];if(!r)return t;var o=r.call(t),n,i=[],a;try{for(;(e===void 0||e-- >0)&&!(n=o.next()).done;)i.push(n.value);}catch(s){a={error:s};}finally{try{n&&!n.done&&(r=o.return)&&r.call(o);}finally{if(a)throw a.error}}return i};function SG(t){return {attributes:lg(t.attributes),droppedAttributesCount:0}}function bG(t){return {name:t.name,version:t.version}}function lg(t){return Object.keys(t).map(function(e){return yG(e,t[e])})}function yG(t,e){return {key:t,value:EG(e)}}function EG(t){var e=typeof t;return e==="string"?{stringValue:t}:e==="number"?Number.isInteger(t)?{intValue:t}:{doubleValue:t}:e==="boolean"?{boolValue:t}:t instanceof Uint8Array?{bytesValue:t}:Array.isArray(t)?{arrayValue:{values:t.map(EG)}}:e==="object"&&t!=null?{kvlistValue:{values:Object.entries(t).map(function(r){var o=wpe(r,2),n=o[0],i=o[1];return yG(n,i)})}}:{}}Wt();function Rpe(t,e){var r=gG(e);return {resource:SG(t.resource),schemaUrl:void 0,scopeMetrics:_pe(t.scopeMetrics,r)}}function _pe(t,e){return Array.from(t.map(function(r){return {scope:bG(r.scope),metrics:r.metrics.map(function(o){return Mpe(o,e)}),schemaUrl:r.scope.schemaUrl}}))}function Mpe(t,e){var r={name:t.descriptor.name,description:t.descriptor.description,unit:t.descriptor.unit},o=Ope(t.aggregationTemporality);switch(t.dataPointType){case Lo.SUM:r.sum={aggregationTemporality:o,isMonotonic:t.isMonotonic,dataPoints:TG(t,e)};break;case Lo.GAUGE:r.gauge={dataPoints:TG(t,e)};break;case Lo.HISTOGRAM:r.histogram={aggregationTemporality:o,dataPoints:Ppe(t,e)};break;case Lo.EXPONENTIAL_HISTOGRAM:r.exponentialHistogram={aggregationTemporality:o,dataPoints:Ipe(t,e)};break}return r}function xpe(t,e,r){var o={attributes:lg(t.attributes),startTimeUnixNano:r.encodeHrTime(t.startTime),timeUnixNano:r.encodeHrTime(t.endTime)};switch(e){case Hn.INT:o.asInt=t.value;break;case Hn.DOUBLE:o.asDouble=t.value;break}return o}function TG(t,e){return t.dataPoints.map(function(r){return xpe(r,t.descriptor.valueType,e)})}function Ppe(t,e){return t.dataPoints.map(function(r){var o=r.value;return {attributes:lg(r.attributes),bucketCounts:o.buckets.counts,explicitBounds:o.buckets.boundaries,count:o.count,sum:o.sum,min:o.min,max:o.max,startTimeUnixNano:e.encodeHrTime(r.startTime),timeUnixNano:e.encodeHrTime(r.endTime)}})}function Ipe(t,e){return t.dataPoints.map(function(r){var o=r.value;return {attributes:lg(r.attributes),count:o.count,min:o.min,max:o.max,sum:o.sum,positive:{offset:o.positive.offset,bucketCounts:o.positive.bucketCounts},negative:{offset:o.negative.offset,bucketCounts:o.negative.bucketCounts},scale:o.scale,zeroCount:o.zeroCount,startTimeUnixNano:e.encodeHrTime(r.startTime),timeUnixNano:e.encodeHrTime(r.endTime)}})}function Ope(t){switch(t){case Do.DELTA:return 1;case Do.CUMULATIVE:return 2}}function vG(t,e){return {resourceMetrics:t.map(function(r){return Rpe(r,e)})}}var rT={serializeRequest:function(t){var e=vG([t],{useLongBits:false}),r=new TextEncoder;return r.encode(JSON.stringify(e))},deserializeResponse:function(t){var e=new TextDecoder;return JSON.parse(e.decode(t))}};var CG="0.57.2";var Fpe=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},Upe=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},Bpe=function(){function t(e){this._parameters=e,this._send=null,this._agent=null;}return t.prototype.send=function(e,r){return Fpe(this,void 0,void 0,function(){var o,n,i,a=this;return Upe(this,function(s){return this._send==null&&(o=(PG(),nne(xG)),n=o.sendWithHttp,i=o.createHttpAgent,this._agent=i(this._parameters.url,this._parameters.agentOptions),this._send=n),[2,new Promise(function(c){var l;(l=a._send)===null||l===void 0||l.call(a,a._parameters,a._agent,e,function(u){c(u);},r);})]})})},t.prototype.shutdown=function(){},t}();function IG(t){return new Bpe(t)}var Vpe=function(t,e,r,o){function n(i){return i instanceof r?i:new r(function(a){a(i);})}return new(r||(r=Promise))(function(i,a){function s(u){try{l(o.next(u));}catch(d){a(d);}}function c(u){try{l(o.throw(u));}catch(d){a(d);}}function l(u){u.done?i(u.value):n(u.value).then(s,c);}l((o=o.apply(t,[])).next());})},zpe=function(t,e){var r={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},o,n,i,a;return a={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(a[Symbol.iterator]=function(){return this}),a;function s(l){return function(u){return c([l,u])}}function c(l){if(o)throw new TypeError("Generator is already executing.");for(;r;)try{if(o=1,n&&(i=l[0]&2?n.return:l[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,l[1])).done)return i;switch(n=0,i&&(l=[l[0]&2,i.value]),l[0]){case 0:case 1:i=l;break;case 4:return r.label++,{value:l[1],done:!1};case 5:r.label++,n=l[1],l=[0];continue;case 7:l=r.ops.pop(),r.trys.pop();continue;default:if(i=r.trys,!(i=i.length>0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]<i[3])){r.label=l[1];break}if(l[0]===6&&r.label<i[1]){r.label=i[1],i=l;break}if(i&&r.label<i[2]){r.label=i[2],r.ops.push(l);break}i[2]&&r.ops.pop(),r.trys.pop();continue}l=e.call(t,r);}catch(u){l=[6,u],n=0;}finally{o=i=0;}if(l[0]&5)throw l[1];return {value:l[0]?l[1]:void 0,done:true}}},$pe=5,jpe=1e3,Hpe=5e3,Gpe=1.5,OG=.2;function Wpe(){return Math.random()*(2*OG)-OG}var qpe=function(){function t(e){this._transport=e;}return t.prototype.retry=function(e,r,o){var n=this;return new Promise(function(i,a){setTimeout(function(){n._transport.send(e,r).then(i,a);},o);})},t.prototype.send=function(e,r){var o;return Vpe(this,void 0,void 0,function(){var n,i,a,s,c,l,u;return zpe(this,function(d){switch(d.label){case 0:return n=Date.now()+r,[4,this._transport.send(e,r)];case 1:i=d.sent(),a=$pe,s=jpe,d.label=2;case 2:return i.status==="retryable"&&a>0?(a--,c=Math.max(Math.min(s,Hpe)+Wpe(),0),s=s*Gpe,l=(o=i.retryInMillis)!==null&&o!==void 0?o:c,u=n-Date.now(),l>u?[2,i]:[4,this.retry(e,u,l)]):[3,4];case 3:return i=d.sent(),[3,2];case 4:return [2,i]}})})},t.prototype.shutdown=function(){return this._transport.shutdown()},t}();function NG(t){return new qpe(t.transport)}function fP(t,e){return lG({transport:NG({transport:IG(t)}),serializer:e,promiseHandler:aG(t)},{timeout:t.timeoutMillis})}Wt();function DG(t){var e,r=(e=process.env[t])===null||e===void 0?void 0:e.trim();if(r!=null&&r!==""){var o=Number(r);if(!Number.isNaN(o)&&Number.isFinite(o)&&o>0)return o;Pe.warn("Configuration: "+t+" is invalid, expected number greater than 0 (actual: "+r+")");}}function Kpe(t){var e=DG("OTEL_EXPORTER_OTLP_"+t+"_TIMEOUT"),r=DG("OTEL_EXPORTER_OTLP_TIMEOUT");return e??r}function LG(t){var e,r=(e=process.env[t])===null||e===void 0?void 0:e.trim();if(r!==""){if(r==null||r==="none"||r==="gzip")return r;Pe.warn("Configuration: "+t+" is invalid, expected 'none' or 'gzip' (actual: '"+r+"')");}}function Ype(t){var e=LG("OTEL_EXPORTER_OTLP_"+t+"_COMPRESSION"),r=LG("OTEL_EXPORTER_OTLP_COMPRESSION");return e??r}function kG(t){return {timeoutMillis:Kpe(t),compression:Ype(t)}}Wt();var Xpe=function(t,e){var r=typeof Symbol=="function"&&t[Symbol.iterator];if(!r)return t;var o=r.call(t),n,i=[],a;try{for(;(e===void 0||e-- >0)&&!(n=o.next()).done;)i.push(n.value);}catch(s){a={error:s};}finally{try{n&&!n.done&&(r=o.return)&&r.call(o);}finally{if(a)throw a.error}}return i};function FG(t){return function(){var e,r={};return Object.entries((e=t?.())!==null&&e!==void 0?e:{}).forEach(function(o){var n=Xpe(o,2),i=n[0],a=n[1];typeof a<"u"?r[i]=String(a):Pe.warn('Header "'+i+'" has invalid value ('+a+") and will be ignored");}),r}}var Au=function(){return Au=Object.assign||function(t){for(var e,r=1,o=arguments.length;r<o;r++){e=arguments[r];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);}return t},Au.apply(this,arguments)};function Jpe(t,e,r){var o=Au({},r()),n={};return function(){return e!=null&&Object.assign(n,e()),t!=null&&Object.assign(n,t()),Object.assign(n,o)}}function Zpe(t){if(t!=null)try{return new URL(t),t}catch{throw new Error("Configuration: Could not parse user-provided export URL: '"+t+"'")}}function UG(t,e,r){var o,n,i,a;return Au(Au({},nG(t,e,r)),{headers:Jpe(FG(t.headers),e.headers,r.headers),url:(n=(o=Zpe(t.url))!==null&&o!==void 0?o:e.url)!==null&&n!==void 0?n:r.url,agentOptions:(a=(i=t.agentOptions)!==null&&i!==void 0?i:e.agentOptions)!==null&&a!==void 0?a:r.agentOptions})}function BG(t,e){return Au(Au({},iG()),{headers:function(){return t},url:"http://localhost:4318/"+e,agentOptions:{keepAlive:true}})}ja();Wt();var iT=function(){return iT=Object.assign||function(t){for(var e,r=1,o=arguments.length;r<o;r++){e=arguments[r];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);}return t},iT.apply(this,arguments)};function Qpe(t){var e,r,o=(e=process.env["OTEL_EXPORTER_OTLP_"+t+"_HEADERS"])===null||e===void 0?void 0:e.trim(),n=(r=process.env.OTEL_EXPORTER_OTLP_HEADERS)===null||r===void 0?void 0:r.trim(),i=rg.parseKeyPairsIntoRecord(o),a=rg.parseKeyPairsIntoRecord(n);if(!(Object.keys(i).length===0&&Object.keys(a).length===0))return Object.assign({},rg.parseKeyPairsIntoRecord(n),rg.parseKeyPairsIntoRecord(o))}function efe(t){try{var e=new URL(t);return e.toString()}catch{Pe.warn("Configuration: Could not parse environment-provided export URL: '"+t+"', falling back to undefined");return}}function tfe(t,e){try{new URL(t);}catch{Pe.warn("Configuration: Could not parse environment-provided export URL: '"+t+"', falling back to undefined");return}t.endsWith("/")||(t=t+"/"),t+=e;try{new URL(t);}catch{Pe.warn("Configuration: Provided URL appended with '"+e+"' is not a valid URL, using 'undefined' instead of '"+t+"'");return}return t}function rfe(t){var e,r=(e=process.env.OTEL_EXPORTER_OTLP_ENDPOINT)===null||e===void 0?void 0:e.trim();if(!(r==null||r===""))return tfe(r,t)}function ofe(t){var e,r=(e=process.env["OTEL_EXPORTER_OTLP_"+t+"_ENDPOINT"])===null||e===void 0?void 0:e.trim();if(!(r==null||r===""))return efe(r)}function VG(t,e){var r;return iT(iT({},kG(t)),{url:(r=ofe(t))!==null&&r!==void 0?r:rfe(e),headers:tT(Qpe(t))})}Wt();function nfe(t){return t?.keepAlive!=null&&(t.httpAgentOptions!=null?t.httpAgentOptions.keepAlive==null&&(t.httpAgentOptions.keepAlive=t.keepAlive):t.httpAgentOptions={keepAlive:t.keepAlive}),t.httpAgentOptions}function hP(t,e,r,o){return t.metadata&&Pe.warn("Metadata cannot be set when using http"),UG({url:t.url,headers:tT(t.headers),concurrencyLimit:t.concurrencyLimit,timeoutMillis:t.timeoutMillis,compression:t.compression,agentOptions:nfe(t)},VG(e,r),BG(o,r))}var ife=function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n;}||function(o,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(o[i]=n[i]);},t(e,r)};return function(e,r){if(typeof r!="function"&&r!==null)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");t(e,r);function o(){this.constructor=e;}e.prototype=r===null?Object.create(r):(o.prototype=r.prototype,new o);}}(),aT=function(){return aT=Object.assign||function(t){for(var e,r=1,o=arguments.length;r<o;r++){e=arguments[r];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);}return t},aT.apply(this,arguments)},afe={"User-Agent":"OTel-OTLP-Exporter-JavaScript/"+CG},cg=function(t){ife(e,t);function e(r){return t.call(this,fP(hP(r??{},"METRICS","v1/metrics",aT(aT({},afe),{"Content-Type":"application/json"})),rT),r)||this}return e}(dG);var sfe="deployment.environment";var lfe="service.name";var cfe="service.instance.id";var zG=sfe;var $G=lfe;var jG=cfe;Wt();rP();function dfe(){return new cg({url:`${c2}/v1/metrics`,headers:{"x-momentic-metrics-api-key":u2},temporalityPreference:Vl.DELTA})}var mfe=[new ag({instrumentName:"test_event_duration",instrumentType:Fe.HISTOGRAM,aggregation:new Nm([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],false)}),new ag({instrumentName:"test_step_duration",instrumentType:Fe.HISTOGRAM,aggregation:new Nm([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],false)}),new ag({instrumentName:"test_mobile_step_duration",instrumentType:Fe.HISTOGRAM,aggregation:new Nm([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],false)})],sT=class{globalAttributes;provider;meter;counterCache=new Map;histogramCache=new Map;observableGaugeCache=new Map;gaugeValues=new Map;getCounter(e){let r=this.counterCache.get(e);if(r)return r;let o=this.meter.createCounter(e);return this.counterCache.set(e,o),o}getHistogram(e){let r=this.histogramCache.get(e);if(r)return r;let o=this.meter.createHistogram(e);return this.histogramCache.set(e,o),o}ensureObservableGauge(e){let r=this.observableGaugeCache.get(e);if(r)return r;let o=this.meter.createObservableGauge(e);return o.addCallback(n=>{let i=this.gaugeValues.get(e);i!==void 0&&n.observe(i,this.globalAttributes);}),this.observableGaugeCache.set(e,o),o}constructor(e){this.globalAttributes={...e.globalAttributes??{}};let r=typeof process<"u"?"production":"unknown",o=new Dm({[$G]:e.serviceName,[zG]:r,[jG]:typeof process<"u"&&process.env.SERVICE_INSTANCE_ID?process.env.SERVICE_INSTANCE_ID:v4$1()}),n=dfe(),i=new tP({exporter:n,exportIntervalMillis:e.exportIntervalMs??6e4});this.provider=new cP({resource:o,readers:[i],views:mfe}),AE.setGlobalMeterProvider(this.provider),this.meter=AE.getMeter("momentic-serverless");}increment(e,r,o){try{let n=Dx(o,this.globalAttributes);this.getCounter(e).add(typeof r=="number"?r:1,n);}catch{}}gauge(e,r){try{this.ensureObservableGauge(e),this.gaugeValues.set(e,r);}catch{}}distribution(e,r,o){try{let n=Dx(o,this.globalAttributes);this.getHistogram(e).record(r,n);}catch{}}async flush(){try{await this.provider.forceFlush();}catch{}}async recordDuration({fn:e,name:r,tags:o,timeoutMs:n}){let i=Date.now();try{return await Nx({fn:e,name:r,tags:o,timeoutMs:n})}finally{this.distribution(r,Date.now()-i,o);}}};var _t=new Yh;function HG(t){if(!t.disabled)try{_t=new sT(t);}catch{_t=new Yh;}}var ffe=1e4;async function ug(t){return new Promise(e=>{exec(t,{timeout:ffe},(r,o,n)=>{e({command:t,stdout:o,stderr:n,error:r?.message??null,timedOut:r?.killed??false});});})}async function hfe(t){if(platform()==="win32")return ug(`tracert ${t}`);let r=await ug(`traceroute ${t}`);return r.stderr.includes("not found")||r.error?.includes("not found")?ug(`tracepath ${t}`):r}async function Fm(t){let r=platform()==="win32",o=r?`ping -n 3 ${t}`:`ping -c 3 ${t}`,i=`curl -w "\\n\\ntime_namelookup: %{time_namelookup}s\\ntime_connect: %{time_connect}s\\ntime_appconnect: %{time_appconnect}s\\ntime_starttransfer: %{time_starttransfer}s\\ntime_total: %{time_total}s\\n" -o ${r?"NUL":"/dev/null"} -s ${t}`,[a,s,c]=await Promise.all([ug(o),hfe(t),ug(i)]);return {ping:a,traceroute:s,curl:c}}var gP;function WG(t){gP=t;}function lT(t){Jb(t,Ft)||gP&&gP(t);}Wt();async function XG(){}async function Ji(t){return t.fn(void 0);}function an(t=process.stdout){let e=supportsColor?supportsColor.level:0,r=process.env.LC_ALL??process.env.LC_CTYPE??process.env.LANG??"",o=process.env.MOMENTIC_NO_UNICODE===void 0&&process.env.TERM!=="linux"&&(process.platform==="win32"||/utf-?8/i.test(r));return {isTTY:!!t.isTTY,colorLevel:e,unicode:o,columns:t.columns??-1,ci:gu}}var yP=class extends Console{_buffer=[];Console=Console;constructor(){super({write:e=>(this._buffer.push(e),true)});}_log(e){this._buffer.push(e);}debug(e,...r){this._log(format(e,...r));}error(e,...r){this._log(format(e,...r));}info(e,...r){this._log(format(e,...r));}log(e,...r){this._log(format(e,...r));}warn(e,...r){this._log(format(e,...r));}flushed(){return this._buffer.length>0?this._buffer.join(`
|
|
178
178
|
`):void 0}};function QG(t){let e=globalThis.console,r=new yP;globalThis.console=r;try{t();}finally{let o=r.flushed();o&&process.stdout.write(`${o}
|
|
179
|
-
`),globalThis.console=e;}}var bfe={PASS:{glyph:"\u2713",asciiGlyph:"v",paint:Ki.green,isTerminal:true},FAIL:{glyph:"\u2718",asciiGlyph:"x",paint:Ki.red,isTerminal:true},SKIP:{glyph:"\u2212",asciiGlyph:"-",paint:Ki.dim,isTerminal:true},CANCEL:{glyph:"\u2298",asciiGlyph:"o",paint:Ki.yellow,isTerminal:true},RETRY:{glyph:"\u21BB",asciiGlyph:"~",paint:Ki.yellow,isTerminal:false},RUNNING:{glyph:"\u203A",asciiGlyph:">",paint:Ki.dim,isTerminal:false}},yfe={PASSED:"PASS",FAILED:"FAIL",CANCELLED:"CANCEL",RETRYING:"RETRY",RUNNING:"RUNNING",SKIP:"SKIP",RUN:"RUNNING",RETRY:"RETRY"};function eW(t,e){let r=yfe[t];if(!r)return;let{glyph:o,asciiGlyph:n,paint:i,isTerminal:a}=bfe[r],s=e.colorLevel>0&&e.isTTY,c=e.unicode?o:n;return {badge:s?i(c):c,isTerminal:a}}function wu(t,e){return !e.isTTY||e.colorLevel===0?t:`\x1B]8;;${t}\x07${t}\x1B]8;;\x07`}function tW(){let t=ej(),e=[];t.lowMemorySamples>0&&e.push(`memory low ${t.lowMemorySamples}x`),t.highCpuSamples>0&&e.push(`CPU saturated ${t.highCpuSamples}x`),t.highHeapSamples>0&&e.push(`heap near limit ${t.highHeapSamples}x`),e.length!==0&&(I.log(""),I.warn(`Machine was under pressure during this run (${e.join(", ")}). Slowdowns and timeouts may be related.`));}var Pt=_m({app:"cli",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:"0.97.
|
|
179
|
+
`),globalThis.console=e;}}var bfe={PASS:{glyph:"\u2713",asciiGlyph:"v",paint:Ki.green,isTerminal:true},FAIL:{glyph:"\u2718",asciiGlyph:"x",paint:Ki.red,isTerminal:true},SKIP:{glyph:"\u2212",asciiGlyph:"-",paint:Ki.dim,isTerminal:true},CANCEL:{glyph:"\u2298",asciiGlyph:"o",paint:Ki.yellow,isTerminal:true},RETRY:{glyph:"\u21BB",asciiGlyph:"~",paint:Ki.yellow,isTerminal:false},RUNNING:{glyph:"\u203A",asciiGlyph:">",paint:Ki.dim,isTerminal:false}},yfe={PASSED:"PASS",FAILED:"FAIL",CANCELLED:"CANCEL",RETRYING:"RETRY",RUNNING:"RUNNING",SKIP:"SKIP",RUN:"RUNNING",RETRY:"RETRY"};function eW(t,e){let r=yfe[t];if(!r)return;let{glyph:o,asciiGlyph:n,paint:i,isTerminal:a}=bfe[r],s=e.colorLevel>0&&e.isTTY,c=e.unicode?o:n;return {badge:s?i(c):c,isTerminal:a}}function wu(t,e){return !e.isTTY||e.colorLevel===0?t:`\x1B]8;;${t}\x07${t}\x1B]8;;\x07`}function tW(){let t=ej(),e=[];t.lowMemorySamples>0&&e.push(`memory low ${t.lowMemorySamples}x`),t.highCpuSamples>0&&e.push(`CPU saturated ${t.highCpuSamples}x`),t.highHeapSamples>0&&e.push(`heap near limit ${t.highHeapSamples}x`),e.length!==0&&(I.log(""),I.warn(`Machine was under pressure during this run (${e.join(", ")}). Slowdowns and timeouts may be related.`));}var Pt=_m({app:"cli",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:"0.97.3"});function EP(t){if(!t)return;t=t.toLowerCase();let e=Hy.safeParse(t);if(e.success)return I.setMinLevel(e.data),e.data}var TP=" ";function rW(t){let e={passed:[],failed:[],cancelled:[],quarantinedPassed:[],quarantinedFailed:[]};for(let r of t)switch(r.status){case "PASSED":(r.quarantined?e.quarantinedPassed:e.passed).push(r);break;case "FAILED":(r.quarantined?e.quarantinedFailed:e.failed).push(r);break;case "CANCELLED":e.cancelled.push(r);break}return e}function oW(t){let e=rW(t),r=e.failed.filter(o=>o.failureDetails?.classification?.action==="heal").length;return {passed:e.passed.length,failed:e.failed.length,cancelled:e.cancelled.length,quarantinedPassed:e.quarantinedPassed.length,quarantinedFailed:e.quarantinedFailed.length,healElectedFailures:r}}function nW(t){return t.failed-t.healElectedFailures>0||t.cancelled>0}function iW({results:t,startTime:e,getPath:r,getUrl:o,printFailureBody:n,getCancellationReason:i,recoveredCount:a,skippedCount:s,videoRecordingActive:c}){let{passed:l,failed:u,cancelled:d,quarantinedPassed:m,quarantinedFailed:p}=rW(t),f=an(),h=f.unicode?"\u2500":"-",S=process.stdout?.columns||80,b=(y,T,v,w)=>{let N=` ${T+1}) ${r(y)} `,D=Math.max(3,S-N.length-2);I.log(""),I.log(v(`${N}${h.repeat(D)}`)),I.log(""),w();let x=o(y);x&&(I.log(""),I.log(`${TP}${wu(x,f)}`));};QG(()=>{u.forEach((x,A)=>{b(x,A,Ki.red.bold,()=>n?.(x));}),d.forEach((x,A)=>{b(x,u.length+A,Ki.yellow.bold,()=>{let B=i?.(x)??"Cancelled";I.log(`${TP}${Ki.yellow.bold(B)}`);});});let y=(x,A,B)=>{x.length!==0&&(I.log(""),I.log(` ${B(`${x.length} ${A}`)}`),x.forEach(O=>{I.dimmed(`${TP}${r(O)}`);}));};y(u,"failed",Ki.red.bold),y(p,"failed",x=>Ki.red.bold(`${x} (quarantined)`)),y(d,"cancelled",Ki.yellow.bold),s&&(I.log(""),I.log(` ${Ki.yellow.bold(`${s} skipped`)}`));let T=l.length+m.length,v=Math.max(1,Math.round((Date.now()-e)/1e3)),w=[];m.length>0&&w.push(`${m.length} quarantined`),a&&a>0&&w.push(`${a} recovered`);let N=w.length>0?` (${w.join(", ")})`:"",D=Tfe(t,f,c);I.log(""),I.log(` ${Ki.green.bold(`${T} passed${N} (${v}s)`)}${D}`),tW();});}function Tfe(t,e,r=false){let o=t.length;if(o===0)return "";let n=t.filter(s=>s.usedRemoteBrowser).length;return n===0?"":`${e.unicode?" \xB7 ":" | "}${n}/${o} ran on remote browser${r?" (video saved async)":""}`}var aW=" ".repeat(6);var vfe=(t,e,r,o)=>{if(r==="length"||r==="prototype"||r==="arguments"||r==="caller")return;let n=Object.getOwnPropertyDescriptor(t,r),i=Object.getOwnPropertyDescriptor(e,r);!Cfe(n,i)&&o||Object.defineProperty(t,r,i);},Cfe=function(t,e){return t===void 0||t.configurable||t.writable===e.writable&&t.enumerable===e.enumerable&&t.configurable===e.configurable&&(t.writable||t.value===e.value)},Afe=(t,e)=>{let r=Object.getPrototypeOf(e);r!==Object.getPrototypeOf(t)&&Object.setPrototypeOf(t,r);},wfe=(t,e)=>`/* Wrapped ${t}*/
|
|
180
180
|
${e}`,Rfe=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),_fe=Object.getOwnPropertyDescriptor(Function.prototype.toString,"name"),Mfe=(t,e,r)=>{let o=r===""?"":`with ${r.trim()}() `,n=wfe.bind(null,o,e.toString());Object.defineProperty(n,"name",_fe);let{writable:i,enumerable:a,configurable:s}=Rfe;Object.defineProperty(t,"toString",{value:n,writable:i,enumerable:a,configurable:s});};function vP(t,e,{ignoreNonConfigurable:r=false}={}){let{name:o}=t;for(let n of Reflect.ownKeys(e))vfe(t,e,n,r);return Afe(t,e),Mfe(t,e,o),t}var cT=new WeakMap,sW=(t,e={})=>{if(typeof t!="function")throw new TypeError("Expected a function");let r,o=0,n=t.displayName||t.name||"<anonymous>",i=function(...a){if(cT.set(i,++o),o===1)r=t.apply(this,a),t=void 0;else if(e.throw===true)throw new Error(`Function \`${n}\` can only be called once`);return r};return vP(i,t),cT.set(i,o),i};sW.callCount=t=>{if(!cT.has(t))throw new Error(`The given function \`${t.name}\` is not wrapped by the \`onetime\` package`);return cT.get(t)};var lW=sW;var Ru=[];Ru.push("SIGHUP","SIGINT","SIGTERM");process.platform!=="win32"&&Ru.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&Ru.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var uT=t=>!!t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function",CP=Symbol.for("signal-exit emitter"),AP=globalThis,xfe=Object.defineProperty.bind(Object),wP=class{emitted={afterExit:false,exit:false};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(AP[CP])return AP[CP];xfe(AP,CP,{value:this,writable:false,enumerable:false,configurable:false});}on(e,r){this.listeners[e].push(r);}removeListener(e,r){let o=this.listeners[e],n=o.indexOf(r);n!==-1&&(n===0&&o.length===1?o.length=0:o.splice(n,1));}emit(e,r,o){if(this.emitted[e])return false;this.emitted[e]=true;let n=false;for(let i of this.listeners[e])n=i(r,o)===true||n;return e==="exit"&&(n=this.emit("afterExit",r,o)||n),n}},dT=class{},Pfe=t=>({onExit(e,r){return t.onExit(e,r)},load(){return t.load()},unload(){return t.unload()}}),RP=class extends dT{onExit(){return ()=>{}}load(){}unload(){}},_P=class extends dT{#a=MP.platform==="win32"?"SIGINT":"SIGHUP";#r=new wP;#e;#n;#m;#t={};#i=false;constructor(e){super(),this.#e=e,this.#t={};for(let r of Ru)this.#t[r]=()=>{let o=this.#e.listeners(r),{count:n}=this.#r,i=e;if(typeof i.__signal_exit_emitter__=="object"&&typeof i.__signal_exit_emitter__.count=="number"&&(n+=i.__signal_exit_emitter__.count),o.length===n){this.unload();let a=this.#r.emit("exit",null,r),s=r==="SIGHUP"?this.#a:r;a||e.kill(e.pid,s);}};this.#m=e.reallyExit,this.#n=e.emit;}onExit(e,r){if(!uT(this.#e))return ()=>{};this.#i===false&&this.load();let o=r?.alwaysLast?"afterExit":"exit";return this.#r.on(o,e),()=>{this.#r.removeListener(o,e),this.#r.listeners.exit.length===0&&this.#r.listeners.afterExit.length===0&&this.unload();}}load(){if(!this.#i){this.#i=true,this.#r.count+=1;for(let e of Ru)try{let r=this.#t[e];r&&this.#e.on(e,r);}catch{}this.#e.emit=(e,...r)=>this.#p(e,...r),this.#e.reallyExit=e=>this.#o(e);}}unload(){this.#i&&(this.#i=false,Ru.forEach(e=>{let r=this.#t[e];if(!r)throw new Error("Listener not defined for signal: "+e);try{this.#e.removeListener(e,r);}catch{}}),this.#e.emit=this.#n,this.#e.reallyExit=this.#m,this.#r.count-=1);}#o(e){return uT(this.#e)?(this.#e.exitCode=e||0,this.#r.emit("exit",this.#e.exitCode,null),this.#m.call(this.#e,this.#e.exitCode)):0}#p(e,...r){let o=this.#n;if(e==="exit"&&uT(this.#e)){typeof r[0]=="number"&&(this.#e.exitCode=r[0]);let n=o.call(this.#e,e,...r);return this.#r.emit("exit",this.#e.exitCode,null),n}else return o.call(this.#e,e,...r)}},MP=globalThis.process,{onExit:cW}=Pfe(uT(MP)?new _P(MP):new RP);var uW=Zi.stderr.isTTY?Zi.stderr:Zi.stdout.isTTY?Zi.stdout:void 0,Ife=uW?lW(()=>{cW(()=>{uW.write("\x1B[?25h");},{alwaysLast:true});}):()=>{},dW=Ife;var pT=false,Bm={};Bm.show=(t=Zi.stderr)=>{t.isTTY&&(pT=false,t.write("\x1B[?25h"));};Bm.hide=(t=Zi.stderr)=>{t.isTTY&&(dW(),pT=true,t.write("\x1B[?25l"));};Bm.toggle=(t,e)=>{t!==void 0&&(pT=t),pT?Bm.show(e):Bm.hide(e);};var xP=Bm;var fg=xf(PP());function IP(){return Zi.platform!=="win32"?Zi.env.TERM!=="linux":!!Zi.env.CI||!!Zi.env.WT_SESSION||!!Zi.env.TERMINUS_SUBLIME||Zi.env.ConEmuTask==="{cmd::Cmder}"||Zi.env.TERM_PROGRAM==="Terminus-Sublime"||Zi.env.TERM_PROGRAM==="vscode"||Zi.env.TERM==="xterm-256color"||Zi.env.TERM==="alacritty"||Zi.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var Nfe={info:Ki.blue("\u2139"),success:Ki.green("\u2714"),warning:Ki.yellow("\u26A0"),error:Ki.red("\u2716")},Dfe={info:Ki.blue("i"),success:Ki.green("\u221A"),warning:Ki.yellow("\u203C"),error:Ki.red("\xD7")},Lfe=IP()?Nfe:Dfe,mg=Lfe;function OP({onlyFirst:t=false}={}){let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t?void 0:"g")}var kfe=OP();function pg(t){if(typeof t!="string")throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);return t.replace(kfe,"")}function gW(t){return t===161||t===164||t===167||t===168||t===170||t===173||t===174||t>=176&&t<=180||t>=182&&t<=186||t>=188&&t<=191||t===198||t===208||t===215||t===216||t>=222&&t<=225||t===230||t>=232&&t<=234||t===236||t===237||t===240||t===242||t===243||t>=247&&t<=250||t===252||t===254||t===257||t===273||t===275||t===283||t===294||t===295||t===299||t>=305&&t<=307||t===312||t>=319&&t<=322||t===324||t>=328&&t<=331||t===333||t===338||t===339||t===358||t===359||t===363||t===462||t===464||t===466||t===468||t===470||t===472||t===474||t===476||t===593||t===609||t===708||t===711||t>=713&&t<=715||t===717||t===720||t>=728&&t<=731||t===733||t===735||t>=768&&t<=879||t>=913&&t<=929||t>=931&&t<=937||t>=945&&t<=961||t>=963&&t<=969||t===1025||t>=1040&&t<=1103||t===1105||t===8208||t>=8211&&t<=8214||t===8216||t===8217||t===8220||t===8221||t>=8224&&t<=8226||t>=8228&&t<=8231||t===8240||t===8242||t===8243||t===8245||t===8251||t===8254||t===8308||t===8319||t>=8321&&t<=8324||t===8364||t===8451||t===8453||t===8457||t===8467||t===8470||t===8481||t===8482||t===8486||t===8491||t===8531||t===8532||t>=8539&&t<=8542||t>=8544&&t<=8555||t>=8560&&t<=8569||t===8585||t>=8592&&t<=8601||t===8632||t===8633||t===8658||t===8660||t===8679||t===8704||t===8706||t===8707||t===8711||t===8712||t===8715||t===8719||t===8721||t===8725||t===8730||t>=8733&&t<=8736||t===8739||t===8741||t>=8743&&t<=8748||t===8750||t>=8756&&t<=8759||t===8764||t===8765||t===8776||t===8780||t===8786||t===8800||t===8801||t>=8804&&t<=8807||t===8810||t===8811||t===8814||t===8815||t===8834||t===8835||t===8838||t===8839||t===8853||t===8857||t===8869||t===8895||t===8978||t>=9312&&t<=9449||t>=9451&&t<=9547||t>=9552&&t<=9587||t>=9600&&t<=9615||t>=9618&&t<=9621||t===9632||t===9633||t>=9635&&t<=9641||t===9650||t===9651||t===9654||t===9655||t===9660||t===9661||t===9664||t===9665||t>=9670&&t<=9672||t===9675||t>=9678&&t<=9681||t>=9698&&t<=9701||t===9711||t===9733||t===9734||t===9737||t===9742||t===9743||t===9756||t===9758||t===9792||t===9794||t===9824||t===9825||t>=9827&&t<=9829||t>=9831&&t<=9834||t===9836||t===9837||t===9839||t===9886||t===9887||t===9919||t>=9926&&t<=9933||t>=9935&&t<=9939||t>=9941&&t<=9953||t===9955||t===9960||t===9961||t>=9963&&t<=9969||t===9972||t>=9974&&t<=9977||t===9979||t===9980||t===9982||t===9983||t===10045||t>=10102&&t<=10111||t>=11094&&t<=11097||t>=12872&&t<=12879||t>=57344&&t<=63743||t>=65024&&t<=65039||t===65533||t>=127232&&t<=127242||t>=127248&&t<=127277||t>=127280&&t<=127337||t>=127344&&t<=127373||t===127375||t===127376||t>=127387&&t<=127404||t>=917760&&t<=917999||t>=983040&&t<=1048573||t>=1048576&&t<=1114109}function SW(t){return t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510}function bW(t){return t>=4352&&t<=4447||t===8986||t===8987||t===9001||t===9002||t>=9193&&t<=9196||t===9200||t===9203||t===9725||t===9726||t===9748||t===9749||t>=9776&&t<=9783||t>=9800&&t<=9811||t===9855||t>=9866&&t<=9871||t===9875||t===9889||t===9898||t===9899||t===9917||t===9918||t===9924||t===9925||t===9934||t===9940||t===9962||t===9970||t===9971||t===9973||t===9978||t===9981||t===9989||t===9994||t===9995||t===10024||t===10060||t===10062||t>=10067&&t<=10069||t===10071||t>=10133&&t<=10135||t===10160||t===10175||t===11035||t===11036||t===11088||t===11093||t>=11904&&t<=11929||t>=11931&&t<=12019||t>=12032&&t<=12245||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12353&&t<=12438||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12773||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=42124||t>=42128&&t<=42182||t>=43360&&t<=43388||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=94176&&t<=94180||t>=94192&&t<=94198||t>=94208&&t<=101589||t>=101631&&t<=101662||t>=101760&&t<=101874||t>=110576&&t<=110579||t>=110581&&t<=110587||t===110589||t===110590||t>=110592&&t<=110882||t===110898||t>=110928&&t<=110930||t===110933||t>=110948&&t<=110951||t>=110960&&t<=111355||t>=119552&&t<=119638||t>=119648&&t<=119670||t===126980||t===127183||t===127374||t>=127377&&t<=127386||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t===127568||t===127569||t>=127584&&t<=127589||t>=127744&&t<=127776||t>=127789&&t<=127797||t>=127799&&t<=127868||t>=127870&&t<=127891||t>=127904&&t<=127946||t>=127951&&t<=127955||t>=127968&&t<=127984||t===127988||t>=127992&&t<=128062||t===128064||t>=128066&&t<=128252||t>=128255&&t<=128317||t>=128331&&t<=128334||t>=128336&&t<=128359||t===128378||t===128405||t===128406||t===128420||t>=128507&&t<=128591||t>=128640&&t<=128709||t===128716||t>=128720&&t<=128722||t>=128725&&t<=128728||t>=128732&&t<=128735||t===128747||t===128748||t>=128756&&t<=128764||t>=128992&&t<=129003||t===129008||t>=129292&&t<=129338||t>=129340&&t<=129349||t>=129351&&t<=129535||t>=129648&&t<=129660||t>=129664&&t<=129674||t>=129678&&t<=129734||t===129736||t>=129741&&t<=129756||t>=129759&&t<=129770||t>=129775&&t<=129784||t>=131072&&t<=196605||t>=196608&&t<=262141}function Ffe(t){if(!Number.isSafeInteger(t))throw new TypeError(`Expected a code point, got \`${typeof t}\`.`)}function yW(t,{ambiguousAsWide:e=false}={}){return Ffe(t),SW(t)||bW(t)||e&&gW(t)?2:1}var EW=()=>/[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;var Ufe=new Intl.Segmenter,Bfe=/^\p{Default_Ignorable_Code_Point}$/u;function NP(t,e={}){if(typeof t!="string"||t.length===0)return 0;let{ambiguousIsNarrow:r=true,countAnsiEscapeCodes:o=false}=e;if(o||(t=pg(t)),t.length===0)return 0;let n=0,i={ambiguousAsWide:!r};for(let{segment:a}of Ufe.segment(t)){let s=a.codePointAt(0);if(!(s<=31||s>=127&&s<=159)&&!(s>=8203&&s<=8207||s===65279)&&!(s>=768&&s<=879||s>=6832&&s<=6911||s>=7616&&s<=7679||s>=8400&&s<=8447||s>=65056&&s<=65071)&&!(s>=55296&&s<=57343)&&!(s>=65024&&s<=65039)&&!Bfe.test(a)){if(EW().test(a)){n+=2;continue}n+=yW(s,i);}}return n}function DP({stream:t=process.stdout}={}){return !!(t&&t.isTTY&&process.env.TERM!=="dumb"&&!("CI"in process.env))}function LP(){let{env:t}=Zi,{TERM:e,TERM_PROGRAM:r}=t;return Zi.platform!=="win32"?e!=="linux":!!t.WT_SESSION||!!t.TERMINUS_SUBLIME||t.ConEmuTask==="{cmd::Cmder}"||r==="Terminus-Sublime"||r==="vscode"||e==="xterm-256color"||e==="alacritty"||e==="rxvt-unicode"||e==="rxvt-unicode-256color"||t.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var Vfe=3,kP=class{#a=0;start(){this.#a++,this.#a===1&&this.#r();}stop(){if(this.#a<=0)throw new Error("`stop` called more times than `start`");this.#a--,this.#a===0&&this.#e();}#r(){Zi.platform==="win32"||!Zi.stdin.isTTY||(Zi.stdin.setRawMode(true),Zi.stdin.on("data",this.#n),Zi.stdin.resume());}#e(){Zi.stdin.isTTY&&(Zi.stdin.off("data",this.#n),Zi.stdin.pause(),Zi.stdin.setRawMode(false));}#n(e){e[0]===Vfe&&Zi.emit("SIGINT");}},zfe=new kP,FP=zfe;xf(PP());var UP=class{#a=0;#r=false;#e=0;#n=-1;#m=0;#t;#i;#o;#p;#h;#c;#u;#d;#g;#s;#l;color;constructor(e){typeof e=="string"&&(e={text:e}),this.#t={color:"cyan",stream:Zi.stderr,discardStdin:true,hideCursor:true,...e},this.color=this.#t.color,this.spinner=this.#t.spinner,this.#h=this.#t.interval,this.#o=this.#t.stream,this.#c=typeof this.#t.isEnabled=="boolean"?this.#t.isEnabled:DP({stream:this.#o}),this.#u=typeof this.#t.isSilent=="boolean"?this.#t.isSilent:false,this.text=this.#t.text,this.prefixText=this.#t.prefixText,this.suffixText=this.#t.suffixText,this.indent=this.#t.indent,Zi.env.NODE_ENV==="test"&&(this._stream=this.#o,this._isEnabled=this.#c,Object.defineProperty(this,"_linesToClear",{get(){return this.#a},set(r){this.#a=r;}}),Object.defineProperty(this,"_frameIndex",{get(){return this.#n}}),Object.defineProperty(this,"_lineCount",{get(){return this.#e}}));}get indent(){return this.#d}set indent(e=0){if(!(e>=0&&Number.isInteger(e)))throw new Error("The `indent` option must be an integer from 0 and up");this.#d=e,this.#f();}get interval(){return this.#h??this.#i.interval??100}get spinner(){return this.#i}set spinner(e){if(this.#n=-1,this.#h=void 0,typeof e=="object"){if(e.frames===void 0)throw new Error("The given spinner must have a `frames` property");this.#i=e;}else if(!LP())this.#i=fg.default.line;else if(e===void 0)this.#i=fg.default.dots;else if(e!=="default"&&fg.default[e])this.#i=fg.default[e];else throw new Error(`There is no built-in spinner named '${e}'. See https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json for a full list.`)}get text(){return this.#g}set text(e=""){this.#g=e,this.#f();}get prefixText(){return this.#s}set prefixText(e=""){this.#s=e,this.#f();}get suffixText(){return this.#l}set suffixText(e=""){this.#l=e,this.#f();}get isSpinning(){return this.#p!==void 0}#S(e=this.#s,r=" "){return typeof e=="string"&&e!==""?e+r:typeof e=="function"?e()+r:""}#b(e=this.#l,r=" "){return typeof e=="string"&&e!==""?r+e:typeof e=="function"?r+e():""}#f(){let e=this.#o.columns??80,r=this.#S(this.#s,"-"),o=this.#b(this.#l,"-"),n=" ".repeat(this.#d)+r+"--"+this.#g+"--"+o;this.#e=0;for(let i of pg(n).split(`
|
|
181
181
|
`))this.#e+=Math.max(1,Math.ceil(NP(i,{countAnsiEscapeCodes:true})/e));}get isEnabled(){return this.#c&&!this.#u}set isEnabled(e){if(typeof e!="boolean")throw new TypeError("The `isEnabled` option must be a boolean");this.#c=e;}get isSilent(){return this.#u}set isSilent(e){if(typeof e!="boolean")throw new TypeError("The `isSilent` option must be a boolean");this.#u=e;}frame(){let e=Date.now();(this.#n===-1||e-this.#m>=this.interval)&&(this.#n=++this.#n%this.#i.frames.length,this.#m=e);let{frames:r}=this.#i,o=r[this.#n];this.color&&(o=Ki[this.color](o));let n=typeof this.#s=="string"&&this.#s!==""?this.#s+" ":"",i=typeof this.text=="string"?" "+this.text:"",a=typeof this.#l=="string"&&this.#l!==""?" "+this.#l:"";return n+o+i+a}clear(){if(!this.#c||!this.#o.isTTY)return this;this.#o.cursorTo(0);for(let e=0;e<this.#a;e++)e>0&&this.#o.moveCursor(0,-1),this.#o.clearLine(1);return (this.#d||this.lastIndent!==this.#d)&&this.#o.cursorTo(this.#d),this.lastIndent=this.#d,this.#a=0,this}render(){return this.#u?this:(this.clear(),this.#o.write(this.frame()),this.#a=this.#e,this)}start(e){return e&&(this.text=e),this.#u?this:this.#c?this.isSpinning?this:(this.#t.hideCursor&&xP.hide(this.#o),this.#t.discardStdin&&Zi.stdin.isTTY&&(this.#r=true,FP.start()),this.render(),this.#p=setInterval(this.render.bind(this),this.interval),this):(this.text&&this.#o.write(`- ${this.text}
|
|
182
182
|
`),this)}stop(){return this.#c?(clearInterval(this.#p),this.#p=void 0,this.#n=0,this.clear(),this.#t.hideCursor&&xP.show(this.#o),this.#t.discardStdin&&Zi.stdin.isTTY&&this.#r&&(FP.stop(),this.#r=false),this):this}succeed(e){return this.stopAndPersist({symbol:mg.success,text:e})}fail(e){return this.stopAndPersist({symbol:mg.error,text:e})}warn(e){return this.stopAndPersist({symbol:mg.warning,text:e})}info(e){return this.stopAndPersist({symbol:mg.info,text:e})}stopAndPersist(e={}){if(this.#u)return this;let r=e.prefixText??this.#s,o=this.#S(r," "),n=e.symbol??" ",i=e.text??this.text,s=typeof i=="string"?(n?" ":"")+i:"",c=e.suffixText??this.#l,l=this.#b(c," "),u=o+n+s+l+`
|
|
@@ -205,7 +205,7 @@ ${r}`:r}var Phe="[FAILED]";async function FT(t,e,r,{numStepsWithScreenshots:o=5,
|
|
|
205
205
|
`),a=Bg.parse(i);return mK.set(e,{mtimeMs:r.mtimeMs,size:r.size,parsed:a}),{parsed:structuredClone(a),stats:r}}function av(t,e){let r=[];for(let o of t.config.environments??[]){if(o.baseUrl)continue;let n=Lu(o.name,t,e);n.variables[s_]||r.push(n);}return r}function sSe(t){return t.includes("${")?t.replace(/\$\{([^}]+)\}/g,(e,r)=>{let o=r.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:(:-|-)([\s\S]*))?$/);if(!o)return process.env[r]||"";let n=o[1];if(!n)return "";let i=o[2],a=o[3],s=process.env[n];return i===":-"?s&&s!==""?s:a||"":i==="-"?s!==void 0?s:a||"":s||""}):t}function lSe(t){let{envVariables:e,project:r}=t;if(!e)return {};let o={};for(let[n,i]of Object.entries(e)){if(typeof i=="string"){let s=sSe(i);s&&(o[n]=s);continue}let a;try{a=so.readFileSync(sr__default.resolve(r.rootDir,i.fromFile),"utf-8");}catch(s){throw new Error(`Failed to read environment variable '${n}' from file '${i.fromFile}': ${s}`)}if(i.json)try{o[n]=JSON.parse(a);}catch(s){throw new Error(`Failed to parse environment variable '${n}' from file '${i.fromFile}' as JSON: ${s}`)}else o[n]=a;}return Object.keys(o).length>0&&I.debug(o,"Set environment variables with interpolation from project configuration"),o}function cSe(t){let{project:e,envFile:r,logger:o}=t,n={};if(!r)return n;let i=iSe.config({path:sr__default.resolve(e.rootDir,r),processEnv:n,logLevel:"error",quiet:true});if(i.error)throw new Ft(`Failed to load .env file: ${i.error.message}`,{cause:i.error});return o.debug("Set environment variables from .env file"),n}function Lu(t,e,r){let o=(e.config.environments??[]).find(c=>c.name===t);if(!o)throw new Ft(`Environment ${t} not found in local project configuration file`);let n={},i=lSe({envVariables:o.envVariables,project:e});Object.assign(n,i);let a=cSe({project:e,envFile:o.envFile,logger:r});return Object.assign(n,a),o.inheritFromShell&&(r.debug(process.env,"Inheriting environment variables from shell"),Object.assign(n,process.env)),{name:t,variables:n}}var wI=["node_modules","__pycache__",".npm",".yarn",".pnpm",".pnpm-store",".pnpm-state",".cache",".gradle",".pytest_cache",".mypy_cache",".ruff_cache",".tox",".nox","dist","bin",".next","out","build","coverage",".nyc_output",".terraform",".serverless",".aws-sam",".momentic-mcp",".vscode",".cursor",".idea",".windsurf",".claude",".codex",".git",".turbo",".env",".venv","venv","env","wheels"],mSe=wI.map(t=>`**/${t}`);function pSe(t){return t.map(e=>(e.endsWith("/")&&(e=e.slice(0,-1)),sr__default.join(e)))}async function ep(t,e){let r=await glob(t,{cwd:e.cwd,ignore:mSe.concat(e.ignore??[]),deep:e.maxDepth,onlyFiles:e.nodir,signal:e.signal});return pSe(r)}var sv=["**/*.test.yaml","**/*.module.yaml"],RI=C__default.string().refine(t=>/^[a-zA-Z0-9-]+$/.test(t)),lv=15;var Xl="momentic.config.yaml",MI="momentic.workspace.yaml",ESe=z.object({projects:z.string().array().describe("list of glob patterns to find project (momentic.config.yaml) files")}),TSe=z.union([z.string(),z.object({fromFile:z.string(),json:z.boolean().optional()})]),vSe=z.object({name:RI,baseUrl:z.string().optional().describe("Optional for mobile tests"),envFile:z.string().optional().describe("path to a file on disk to read environment variables from. can be relative to project root or absolute."),envVariables:z.record(z.string(),TSe).optional(),inheritFromShell:z.boolean().optional().describe("inherit all environment variables from the shell - might be noisy"),browser:As.optional().describe("NB: most things should use project-level configuration only")}),CSe=z.object({postSave:z.string().optional()}),ASe=z.union([z.boolean(),z.literal("on-fail")]).describe("Controls video recording for test runs. true records video for all tests, false disables video (default), 'on-fail' records video but removes it for passing tests."),wSe=z.object({name:RI,include:z.string().array().optional().describe("list of glob patterns that match momentic files (optional)"),exclude:z.string().array().optional().describe("opposite of include, takes precedence over include"),fileFormat:e1.optional().describe("file format version to use"),goldenFileDir:z.string().optional(),reporterDir:z.string().optional(),outputDir:z.string().optional(),recordVideo:ASe.optional(),retries:z.number().optional().describe("number of retries per test"),parallel:z.union([z.number(),z.literal("AUTO")]).optional().describe("degree of parallelism"),environments:z.array(vSe).optional(),gitMainBranch:z.string().optional().readonly(),gitProtectedBranches:z.string().array().optional().readonly(),ai:Ma.optional(),browser:As.optional(),emulator:EM.optional(),advanced:h_.optional(),displayRoot:z.string().optional().describe("relative path from project root to use as the Repository root"),hooks:CSe.optional()});function gK(t,e){let r;try{r=readFileSync(t,"utf-8");}catch(n){I.warn(`Could not read possible Momentic ${e} file at ${t}: ${j(n)}`);return}let o;try{if(o=Bg.parse(r),typeof o!="object"||o===null)throw new Error(`The ${e} file should parse as a map with key-value pairs, but is type ${typeof o} instead`)}catch(n){I.warn(`Possible Momentic ${e} file at ${t} does not parse as valid YAML: ${j(n)}`);return}return o}function SK(t,e){let r=[];for(let[o,n]of Object.entries(t)){let a=/^\d+$/.test(o)?`${e}[${o}]`:e?`${e}.${o}`:o;n!==null&&typeof n=="object"?r.push(...SK(n,a)):r.push(a);}return r}function xI(t){let e=gK(t,"project configuration");if(e===void 0)return;let r;try{r=wSe.parse(e);}catch(i){let a=i instanceof z.ZodError?`
|
|
206
206
|
${z.prettifyError(i)}`:`: ${j(i)}`;I.warn(`Project config at ${t} does not match the required schema${a}`);return}let o=deletedDiff(e,r),n=SK(o,"");return n.length>0&&I.warn(`Momentic config file at ${t} contains unrecognized keys: ${n.join(", ")}. These keys will be ignored.`),r}function RSe(t){let e=gK(t,"workspace configuration");if(e!==void 0)try{return ESe.parse(e)}catch(r){I.warn(`Possible Momentic workspace configuration file at ${t} does not adhere to the required schema: ${j(r)}`);return}}function _Se(){let t=[],e=cwd(),r=sr__default.parse(e).root,o=15,n=0;for(;n<o;){n++;let i=sr__default.basename(e);if(wI.includes(i))return I.warn(`Stopping search for Momentic projects since the current directory name (${i}) is likely a system artifact folder.`),t;for(let a of readdirSync(e))if(a.endsWith(Xl)){let s=sr__default.join(e,a),c=xI(s);c&&t.push({configFilePath:s,config:c,rootDir:dirname(s)});}if(t.length)return t;if(e=sr__default.dirname(e),e===r)break}return t}async function qn(t={}){let{configFilePath:e,nameFilter:r,skipExitOnError:o}=t,n=await xSe(e,o);if(r&&(n=n.filter(i=>i.config.name===r)),n.length>1)throw new Error(`Multiple valid projects were found in the same directory. Please use the '-c / --config' flag to disambiguate:
|
|
207
207
|
${n.map(i=>i.configFilePath)}`);if(n.length===0)throw new Error("No valid Momentic project file available.");return I.debug(`Found valid project configuration at ${n[0].configFilePath}`),n[0]}async function MSe(t){let e=RSe(t);if(!e||!e.projects||!e.projects.length)return;let r=e.projects.map(a=>(a.endsWith("/")||(a+="/"),`${a}*${Xl}`)),o=AbortSignal.timeout(2e3),n;try{n=await ep(r,{cwd:cwd(),maxDepth:lv,ignore:[],nodir:!0,signal:o});}catch(a){throw I.error({err:a},`Failed to list the available Momentic projects in the current directory. This usually indicates the 'include' or 'exclude' option in your ${MI} is misconfigured.`),a}let i=[];for(let a of n){let s=sr__default.join(cwd(),a),c=xI(s);c&&i.push({configFilePath:s,config:c,rootDir:dirname(s)});}return i}async function xSe(t,e){if(t){t=sr__default.resolve(t);let o=xI(t);return o?[{config:o,configFilePath:t,rootDir:sr__default.dirname(t)}]:(console.error(`No valid Momentic project file found at ${t}.`),e||process.exit(1),[])}if(existsSync(MI)){let o=await MSe(MI);if(o)return o}return _Se()}function Fu(t,e){let r=Bg.stringify(t);writeFileSync(e,r);}var vK=false,PSe=z.object({fileType:z.enum(ve)});async function vt(t,e=false){return AK({project:t,includeGlobs:t.config.include??sv,disableLogging:e})}async function CK(t,e=false){let r=t.config.include??["**/*.module.yaml"];return {mobileModules:(await AK({project:t,includeGlobs:r,disableLogging:e,filePathPredicate:n=>n.endsWith(".module.yaml")})).mobileModules}}async function AK({project:t,includeGlobs:e,disableLogging:r,filePathPredicate:o}){let n={project:t,tests:{},modules:{},mobileTests:{},mobileModules:{},duplicateEntities:{},metadataParseFailures:[]},i=t.config.exclude??[],a=AbortSignal.timeout(5e3),s;try{s=await ep(e,{cwd:t.rootDir,ignore:i,maxDepth:lv,nodir:!0,signal:a});}catch(c){throw I.error({err:c},"Failed to list all Momentic files in the current directory. This usually indicates the 'include' and 'exclude' globs are misconfigured in your momentic.config.yaml, or that your machine is severely resource constrained."),new Error("Listing Momentic files timed out after 5 seconds.",{cause:c})}for(let c of s){if(o&&!o(c))continue;let l=ISe(t.rootDir,c,n,r?pu:I);l&&(n.duplicateEntities[l.id]=l.paths);}return vK=true,n}function ISe(t,e,r,o){let n=sr__default.join(t,e),i=OSe(n,o);if(!i)return;let{entityJs:a,stats:s}=i,c=PSe.safeParse(a);if(c.success===false){o.warn(`Possible Momentic file at ${n} does not have a 'fileType', skipping: ${j(c.error)}`);return}let l=c.data.fileType,u=NSe(e,n,s);switch(l){case ve.TEST:try{return bK(a,l,r,u,n,o)}catch(d){o.warn(`Skipping file '${n}' because it is missing Momentic test metadata: ${j(d)}`);return}case ve.TEST_V2:try{return bK(a,l,r,u,n,o)}catch(d){cv({err:d,fullPath:n,fsAttributes:u,kind:"test",suffix:"test.yaml",resultsCollector:r,logger:o});return}case ve.MODULE:try{return yK(a,l,r,u,n,o)}catch(d){o.warn(`Skipping file '${n}' because it is missing Momentic module metadata: ${j(d)}`);return}case ve.MODULE_V2:try{return yK(a,l,r,u,n,o)}catch(d){cv({err:d,fullPath:n,fsAttributes:u,kind:"module",suffix:"module.yaml",resultsCollector:r,logger:o});return}case ve.MOBILE_TEST:try{return TK(a,l,r,u,n,o)}catch(d){o.warn(`Skipping file '${n}' because it is missing Momentic mobile test metadata: ${j(d)}`);return}case ve.MOBILE_TEST_V2:try{return TK(a,l,r,u,n,o)}catch(d){cv({err:d,fullPath:n,fsAttributes:u,kind:"test",suffix:"test.yaml",resultsCollector:r,logger:o});return}case ve.MOBILE_MODULE:try{return EK(a,l,r,u,n,o)}catch(d){o.warn(`Skipping file '${n}' because it is missing Momentic mobile module metadata: ${j(d)}`);return}case ve.MOBILE_MODULE_V2:try{return EK(a,l,r,u,n,o)}catch(d){cv({err:d,fullPath:n,fsAttributes:u,kind:"module",suffix:"module.yaml",resultsCollector:r,logger:o});return}default:{return}}}function OSe(t,e){try{let{parsed:r,stats:o}=wi(t);if(typeof r!="object"||r===null)throw new Error("The YAML document should parse as a map with key-value pairs");return {entityJs:r,stats:o}}catch(r){e.warn(`Could not parse possible Momentic file at ${t}, skipping: ${j(r)}`);return}}function cv({err:t,fullPath:e,fsAttributes:r,kind:o,suffix:n,resultsCollector:i,logger:a}){if(t instanceof z.ZodError){i.metadataParseFailures.push({fullPath:e,relativePath:r.relativePath,name:r.fileName.replace(`.${n}`,""),kind:o,issues:t.issues});return}a.warn(`Skipping file '${e}': failed to read Momentic v2 ${o} metadata: ${j(t)}`);}function NSe(t,e,r){return {relativePath:t,fullFilePath:e,platformSep:sr__default.sep,fullPathSegments:e.split(sr__default.sep),relativePathSegments:t.split(sr__default.sep),fileName:sr__default.basename(e),lastModified:r.mtime,createdAt:r.birthtime}}function bK(t,e,r,o,n,i){let a=o.fileName.replace(".test.yaml",""),s,c;e===ve.TEST_V2?(s=UM.parse(t),c=a):(s=sh.parse(t),c=s.name);let l;if(r.tests[s.id]){let u=r.tests[s.id].fullFilePath;l={id:s.id,paths:[u,n]};}return r.tests[s.id]={type:e,name:c,id:s.id,description:s.description??void 0,labels:s.labels,...o},l}function yK(t,e,r,o,n,i){let a,s,c,l=o.fileName.replace(".module.yaml","");if(e===ve.MODULE_V2){let d=Zy.parse(t);a=d.id,s=d.name??l,c=d.description;}else {let d=Aa.parse(t);a=d.moduleId,s=d.name,c=d.description;}let u;if(r.modules[a]){let d=r.modules[a].fullFilePath;u={id:a,paths:[d,n]};}return r.modules[a]={type:e,name:s,id:a,description:c??void 0,...o},!vK&&ji(s)!==l&&i.warn(`The module with ID ${a} has a name (${s}) that does not match its file name (${l}). We recommend renaming the module or the file to be consistent to avoid confusion and issues with module resolution.`),u}function EK(t,e,r,o,n,i){let a=o.fileName.replace(".module.yaml",""),s,c,l;if(e===ve.MOBILE_MODULE_V2){let d=oE.parse(t);s=d.id,c=d.description,l=d.name??a;}else {let d=Oa.parse(t);s=d.moduleId,c=d.description,l=a;}let u;if(r.mobileModules[s]){let d=r.mobileModules[s].fullFilePath;u={id:s,paths:[d,n]};}return r.mobileModules[s]={type:e,name:l,id:s,description:c??void 0,...o},u}function TK(t,e,r,o,n,i){let a=e===ve.MOBILE_TEST_V2?s$.parse(t):Rl.parse(t),s;if(r.mobileTests[a.id]){let l=r.mobileTests[a.id].fullFilePath;s={id:a.id,paths:[l,n]};}let c=o.fileName.replace(".test.yaml","");return r.mobileTests[a.id]={type:e,name:c,id:a.id,description:a.description??void 0,labels:a.labels,...o},s}var Dg="test-results";var wK=3e3,Nt=RK(),kSe=promisify(execFile);async function Ri(t){let{logger:e,operation:r,fn:o,context:n}=t,i=Date.now();try{return await o()}finally{let a=Date.now()-i;a>wK&&!process.env.CI&&e.warn({operation:r,durationMs:a,thresholdMs:wK,...n??{}},"[timing] slow git metadata operation");}}function Xa(t){if(t)try{let e=new Date(t);return isNaN(e.getTime())?void 0:e}catch{return}}async function FSe(t){let e=await Dt(t,Nt.raw(["config","--list"])),r={};if(!e)return r;for(let o of e.split(`
|
|
208
|
-
`)){let n=o.indexOf("=");if(n===-1)continue;let i=o.slice(0,n),a=o.slice(n+1).trim();r[i]=a;}return r}async function USe(t,e,r){try{let n=r["github.user"]||void 0;if(n)return n}catch{}let o;try{if(e?.startsWith("http://")||e?.startsWith("https://"))o=new URL(e).host;else if(e?.startsWith("git@")){let n=e.indexOf("@"),i=e.indexOf(":",n+1);n!==-1&&i!==-1&&(o=e.slice(n+1,i));}}catch{}if(o=o?.toLowerCase(),!!o&&e?.startsWith("git@")&&o.includes("github"))try{let{stdout:n,stderr:i}=await kSe("ssh",["-T","-o","BatchMode=yes",`git@${o}`],{timeout:5e3}),s=`${n??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}catch{return}}async function BSe(t,e,r){let o=e?.includes("github.com"),n=e?.includes("gitlab.com");try{if(o)return USe(t,e,r);if(n)return}catch{}}function Lg(t){if(t.startsWith("git@")){let e=t.split(":");if(e.length===2){let r=e[1].replace(".git","").split("/");if(r.length===2){let o=r[0],n=r[1];return `${o}/${n}`}}}else if(t.startsWith("http")||t.startsWith("https")){let r=new URL(t).pathname.split("/").filter(Boolean);if(r.length>=2){let o=r[0],n=r[1].replace(".git","");return `${o}/${n}`}}}function VSe(t){if(!(t instanceof Error))return false;let e=t.message;return e.includes("not a git repository")||e.includes("ENOENT")||e.includes("detected dubious ownership")}async function Dt(t,e){try{return (await e).trim()}catch(r){if(VSe(r))return;t.error({err:r},"Failed to run git command");return}}function zSe(){if(process.env.GITHUB_ACTION)return "GithubActions";if(process.env.GITLAB_CI)return "GitlabCI";if(process.env.CIRCLECI)return "CircleCI";if(process.env.BUILDKITE)return "Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return "AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return "GCPCloudBuild";if(process.env.BITRISE_BUILD_SLUG)return "Bitrise";if(process.env.MOMENTIC_GIT_OVERRIDE)return "Custom"}async function $Se(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`:void 0;return {ciProvider:"GithubActions",gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function jSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]);return {ciProvider:"GitlabCI",gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?Xa(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:r,gitCommitAuthorName:o,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function HSe(t){let[e,r,o,n]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),a=process.env.CIRCLE_REPOSITORY_URL?.trim()||void 0||r||void 0,s=process.env.CIRCLE_PROJECT_USERNAME?.trim(),c=process.env.CIRCLE_PROJECT_REPONAME?.trim(),u=(s&&c?`${s}/${c}`:void 0)??(a?Lg(a):void 0),d=a?.includes("github.com")??false,m=a?.includes("gitlab.com")??false;return {ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:a,gitCommitMessage:o,gitCommitAuthorName:n,githubRepository:d?u:void 0,gitlabProjectPath:m?u:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function GSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env.BUILDKITE_REPO,i=n?.includes("github.com"),a=n?.includes("gitlab.com"),s=n?Lg(n):void 0;return {ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function WSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env["Build.Repository.Uri"],i=n?.includes("github.com"),a=n?.includes("gitlab.com"),s=n?Lg(n):void 0;return {ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function qSe(t,e,r){let[o,n,i,a,s,c,l,u,d]=await Promise.all([Dt(t,Nt.revparse(["HEAD"])),Dt(t,Nt.revparse(["--short","HEAD"])),Dt(t,Nt.revparse(["--abbrev-ref","HEAD"])),Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"])),e?Dt(t,Nt.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),FSe(t)]),m=u||(e?await Dt(t,Nt.raw(["merge-base",e,"HEAD"])):void 0),p=m?await Dt(t,Nt.show(["--no-patch","--format=%ci",m])):void 0,f=a?.includes("github.com"),h=a?.includes("gitlab.com"),S=a?Lg(a):void 0,b=d["user.email"]||void 0,y=d["user.name"]||void 0,T=d["user.username"]||void 0,v=d["github.user"]||void 0,D=(r?.includeHostingUsername??true?await BSe(t,a,d):void 0)??T??v??void 0;return {ciProvider:"none",gitCommitSha:o,gitCommitShaShort:n,gitBranchName:i,gitOriginUrl:a,gitCommitTimestamp:s?Xa(s):void 0,gitCommitMessage:c,gitCommitAuthorName:l,gitLocalUsername:D,gitLocalEmail:b,gitLocalName:y,lastCommitOnMainSha:m,lastCommitOnMainTimestamp:p?Xa(p):void 0,githubRepository:f?S:void 0,gitlabProjectPath:h?S:void 0,pipelineId:void 0}}async function KSe(t){let[e,r]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),o=process.env.GIT_REPOSITORY_URL,n=o?.includes("github.com"),i=o?.includes("gitlab.com"),a=o?Lg(o):void 0;return {ciProvider:"Bitrise",gitCommitSha:process.env.BITRISE_GIT_COMMIT,gitCommitShaShort:process.env.BITRISE_GIT_COMMIT?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.BITRISE_GIT_BRANCH,gitOriginUrl:o,gitCommitMessage:process.env.BITRISE_GIT_MESSAGE,gitCommitAuthorName:r,githubRepository:n?a:void 0,gitlabProjectPath:i?a:void 0,pipelineId:`${process.env.BITRISE_APP_SLUG}:${process.env.BITRISE_BUILD_SLUG}`}}async function YSe(){let t=process.env._HEAD_REPO_URL;return {ciProvider:"GCPCloudBuild",gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:t?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:t?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}function XSe(){return {ciProvider:"Custom",gitCommitSha:process.env.GIT_COMMIT_SHA,gitCommitShaShort:process.env.GIT_COMMIT_SHA_SHORT??process.env.GIT_COMMIT_SHA?.slice(0,6),gitCommitTimestamp:Xa(process.env.GIT_COMMIT_TIMESTAMP),gitBranchName:process.env.GIT_BRANCH_NAME,gitOriginUrl:process.env.GIT_ORIGIN_URL,gitCommitAuthorName:process.env.GIT_COMMIT_AUTHOR_NAME,gitCommitMessage:process.env.GIT_COMMIT_MESSAGE,lastCommitOnMainSha:process.env.LAST_COMMIT_ON_MAIN_SHA,lastCommitOnMainTimestamp:Xa(process.env.LAST_COMMIT_ON_MAIN_TIMESTAMP),mergedGitBranchName:process.env.MERGED_GIT_BRANCH_NAME,githubRepository:process.env.GITHUB_REPOSITORY,gitlabProjectPath:process.env.GITLAB_PROJECT_PATH,gitLocalUsername:process.env.GIT_USERNAME,gitLocalEmail:process.env.GIT_EMAIL,gitLocalName:process.env.GIT_NAME}}async function JSe(t){let e=[...t.config.gitProtectedBranches??[]];return t.config.gitMainBranch&&e.push(t.config.gitMainBranch),{gitMainBranch:t.config.gitMainBranch,gitProtectedBranches:e}}async function kg(t,e,r){let o=zSe();if(!o)return qSe(t,e,r);switch(o){case "GithubActions":return $Se(t);case "GitlabCI":return jSe(t);case "CircleCI":return HSe(t);case "Buildkite":return GSe(t);case "AzureDevOps":return WSe(t);case "GCPCloudBuild":return YSe();case "Bitrise":return KSe(t);case "Custom":return XSe()}}async function ZSe(t,e,r,o){let n=o,i=o.gitCommitSha;if(!i)return n;let a=o.gitMainBranch;if(a&&(!n.lastCommitOnMainSha||!n.lastCommitOnMainTimestamp))try{let s=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getMergeBaseCommitFromGitlab",fn:()=>e.getMergeBaseCommitFromGitlab(r,a,i),context:{projectPath:r,mainBranch:a}});n={...n,lastCommitOnMainSha:s.sha,lastCommitOnMainTimestamp:s.committer.date};}catch(s){t.warn({err:s},"Failed to get merge base commit from Gitlab");}if(!n.gitCommitTimestamp||!n.gitCommitAuthorName||!n.gitCommitMessage||!n.gitCommitAuthorName)try{let s=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getCommitFromGitlab",fn:()=>e.getCommitFromGitlab(r,i),context:{projectPath:r,gitCommitSha:i}});s&&(n={...n,gitCommitTimestamp:n.gitCommitTimestamp??s.committer.date,gitCommitAuthorName:n.gitCommitAuthorName??s.author.name,gitCommitMessage:n.gitCommitMessage??s.message});}catch(s){t.warn({err:s},"Failed to get commit from Gitlab");}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!n.mergedGitBranchName){let s=o.gitBranchName;try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getMergedBranchFromGitlab",fn:()=>e.getMergedBranchFromGitlab(r,s,i),context:{projectPath:r,branchName:s,gitCommitSha:i}});c.mergedBranch&&(n={...n,mergedGitBranchName:c.mergedBranch});}catch(c){t.warn({err:c},"Failed to get merged branch from Gitlab");}}return n}async function QSe(t,e,r,o,n){let i=n,a=n.gitCommitSha;if(!a)return i;let s=n.gitMainBranch;if(s&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getMergeBaseCommitFromGithub",fn:()=>e.getMergeBaseCommitFromGithub(r,o,s,a),context:{owner:r,repo:o,mainBranch:s}});i={...i,lastCommitOnMainSha:c.sha,lastCommitOnMainTimestamp:c.committer.date};}catch(c){t.warn({err:c},"Failed to get merge base commit from GitHub");}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getCommitFromGithub",fn:()=>e.getCommitFromGithub(r,o,a),context:{owner:r,repo:o,gitCommitSha:a}});c&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??c.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??c.author.name,gitCommitMessage:i.gitCommitMessage??c.message});}catch(c){t.warn({err:c},"Failed to get commit from GitHub");}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!i.mergedGitBranchName){let c=n.gitBranchName;try{let l=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getMergedBranchFromGithub",fn:()=>e.getMergedBranchFromGithub(r,o,c,a),context:{owner:r,repo:o,branchName:c,gitCommitSha:a}});l.mergedBranch&&(i={...i,mergedGitBranchName:l.mergedBranch});}catch(l){t.warn({err:l},"Failed to get merged branch from GitHub");}}return i}async function ebe(t,e,r){try{if(r.githubRepository){let[o,n]=r.githubRepository.split("/");return await Ri({logger:t,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitHub",fn:()=>QSe(t,e,o,n,r),context:{githubRepository:r.githubRepository}})}else if(r.gitlabProjectPath){let o=r.gitlabProjectPath;return await Ri({logger:t,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitlab",fn:()=>ZSe(t,e,o,r),context:{gitlabProjectPath:o}})}}catch(o){t.warn({err:o},"Failed to get remote git metadata");}return r}async function tbe(t,e,r,o){let n={},i={gitMainBranch:r.config.gitMainBranch};return Ri({logger:t,operation:"getGitMetadata.total",fn:async()=>{let[a,s]=await Promise.all([Ri({logger:t,operation:"getGitMetadata.getConfiguredGitMetadata",fn:()=>JSe(r),context:{projectConfigPath:r.configFilePath}}),Ri({logger:t,operation:"getGitMetadata.getEnvironmentGitMetadata",fn:async()=>{let u=await kg(t,r.config.gitMainBranch,o);return i.ciProvider=u.ciProvider,u},context:i})]),c={...a,...s};n.gitBranchName=c.gitBranchName,n.githubRepository=c.githubRepository,n.gitlabProjectPath=c.gitlabProjectPath,(!c.lastCommitOnMainSha||!c.lastCommitOnMainTimestamp)&&c.gitBranchName===a.gitMainBranch&&(c.lastCommitOnMainSha=c.gitCommitSha,c.lastCommitOnMainTimestamp=c.gitCommitTimestamp);let l=await Ri({logger:t,operation:"getGitMetadata.getRemoteMetadataIfNeeded",fn:()=>ebe(t,e,c),context:{githubRepository:c.githubRepository,gitlabProjectPath:c.gitlabProjectPath,gitBranchName:c.gitBranchName}});return {...a,...s,...l}},context:n})}async function _K(t){try{let e=await RK(t).remote(["show","origin"]);return e?e.match(/HEAD branch: (.*)$/m)?.[1]?.trim():void 0}catch{return}}var II=new Map;async function rbe(t,e,r){let o,n;try{[o,n]=await Promise.all([Dt(t,Nt.raw(["symbolic-ref","--short","-q","HEAD"]).then(s=>s.trim())),Dt(t,Nt.revparse(["--verify","HEAD"]).then(s=>s.trim()))]);}catch{return}if(!o||!n)return;let i=`${e.configFilePath}:${e.config.gitMainBranch}:${e.config.gitProtectedBranches?.join(",")}`,a=`${r?.includeHostingUsername}`;return `${o}:${n}:${i}:${a}`}async function dr(t,e,r,o){let n=await rbe(t,r,o);if(n&&II.has(n))return t.debug("Using cached git metadata"),II.get(n);let i=await tbe(t,e,r,o);return n&&II.set(n,i),i}function ibe(t,e){let r=`${ji(e)}.module.yaml`,o=sr__default.join(sr__default.dirname(t),r);if(so.existsSync(o))throw new Error(`A conflicting file already exists at the following path: ${o}`);return so.renameSync(t,o),o}function Ja({content:t,schemaVersion:e,momenticFiles:r,project:o,forceSaveOnNoDiffs:n,forceFileFormat:i}){let a=r.mobileModules[t.moduleId]?.fullFilePath,s=r.mobileModules[t.moduleId]?.name;if(!a||!so.existsSync(a))throw new Error(`Tried to update mobile module ${t.moduleId} that could not be found on disk`);let{parsed:c}=wi(a),l=o.config.fileFormat==="v2";i!==void 0&&(l=i==="v2");let u=!!t.name&&t.name!==s,d={...c,...t,schemaVersion:e},m=Oa.parse(d),p=qi(t.platform).array().parse(t.steps),f=l?iv({metadata:{...m,moduleId:t.moduleId,name:t.name??s??""},steps:p,fileResolver:Nu({sourceFilePath:a,momenticFiles:{mobileModules:r.mobileModules}})}):oo({fileType:ve.MOBILE_MODULE,...m,steps:p}),h=diff(f,c);if(h&&Object.keys(h).length===0&&!n&&!u)return;so.writeFileSync(a,Bg.stringify(f),"utf-8");let S=u?ibe(a,t.name):void 0;Vs(S??a,o.config);}function xK({moduleId:t,patch:e,momenticFiles:r,project:o,logger:n}){let i=r.mobileModules[t]?.fullFilePath;if(!i)throw new Error(`Tried to update mobile module ${t} that could not be found on disk`);let a=Zl(i,n),s=Ql({module:a,moduleFilePath:i,momenticFiles:r}),c=Q_.parse({...s,...e}),l={moduleId:c.moduleId,platform:c.platform,name:e.name??s.name,description:c.description,enabled:c.enabled,parameters:c.parameters,steps:qi(c.platform).array().parse(c.steps)};Ja({content:l,schemaVersion:c.schemaVersion,momenticFiles:r,project:o});}async function Ug({name:t,description:e,enabled:r,platform:o,steps:n,folder:i,project:a,momenticFiles:s}){let c=ji(t),l=sr__default.join(i,`${c}.module.yaml`),u=Qm({projectConfig:a.config,momenticFiles:s,entityType:"mobile-module"}),{stepsToSave:{steps:d}}=await ho({platform:o,stepLists:{steps:n}}),m={schemaVersion:ty,platform:o,moduleId:u,description:e,enabled:r},p=a.config.fileFormat==="v2"?iv({metadata:{...m,moduleId:u,name:t},steps:d,fileResolver:Nu({sourceFilePath:l,momenticFiles:{mobileModules:s.mobileModules}})}):eM.parse({fileType:ve.MOBILE_MODULE,...m,steps:d});return so.writeFileSync(l,Bg.stringify(p),"utf-8"),Vs(l,a.config),{moduleId:u,platform:o,name:t,description:e||void 0,steps:n}}function Zl(t,e){let{parsed:r}=wi(t);if(Ig(r))try{return nE.parse(r)}catch(o){throw e.error({err:o,moduleFilePath:t,existingModule:r},`${t} does not parse as a valid V2 Momentic mobile module`),o}try{return eM.parse(r)}catch(o){throw e.error({err:o,moduleFilePath:t,existingModule:r},`${t} does not parse as a valid Momentic mobile module`),o}}function Ql({module:t,moduleFilePath:e,momenticFiles:r}){let o=sr__default.basename(e,".module.yaml");if(!Ig(t))return {...t,name:o};let{module:n}=nv({moduleV2:t,moduleName:o,fileResolver:Du({sourceFilePath:e,momenticFiles:r})});return n}async function Uu(t,e,r,o){let n=Zl(t.fullFilePath,r),i=Ql({module:n,moduleFilePath:t.fullFilePath,momenticFiles:e}),a=i.platform==="ANDROID"?o?.android:o?.ios,{resolvedSteps:s}=await OT({platform:i.platform,rawSteps:i.steps,resolvedModuleCache:a||{},onFetchModule:async l=>{let u=e.mobileModules[l]?.fullFilePath;if(!u)throw new Error(`Could not find mobile module with id ${l}`);let d=Zl(u,r);return Ql({module:d,moduleFilePath:u,momenticFiles:e})},logger:r,metadata:{id:i.moduleId,schemaVersion:i.schemaVersion}}),c=i.platform==="ANDROID"?{...i,platform:"ANDROID",name:t.name,description:i.description||void 0,steps:s}:{...i,platform:"IOS",name:t.name,description:i.description||void 0,steps:s};return a&&(a[t.id]=cloneDeep(c)),c}async function PK(t,e){let r={},o={};return await Promise.all(Object.values(t.mobileModules).map(async n=>{await Uu(n,t,e,{ios:r,android:o});})),[...Object.values(r),...Object.values(o)]}var tp=wy.array(),dv=C__default.discriminatedUnion("platform",[Uy.extend({beforeSteps:tp.optional(),steps:tp,afterSteps:tp.optional()}),By.extend({beforeSteps:tp.optional(),steps:tp,afterSteps:tp.optional()})]);function mv({name:t,description:e="",settings:r,folder:o,platform:n,project:i,momenticFiles:a}){try{ci(t);}catch(p){throw new Qr(`${p} when validating the test entity name`)}let c=`${ji(t)}.test.yaml`,l=sr__default.join(o,c);if(so.existsSync(l))throw new Error(`A test named '${t}' already exists at path '${l}'. Choose a different name.`);let u=Qm({projectConfig:i.config,momenticFiles:a,entityType:"mobile-test"}),d={fileType:ve.MOBILE_TEST,id:u,description:e,schemaVersion:eo,platform:n,settings:r,steps:[]},m=i.config.fileFormat==="v2"?Zm({metadata:d,stepLists:{steps:[]},fileResolver:Nu({sourceFilePath:l,momenticFiles:{mobileModules:a.mobileModules}})}):mV.parse(d);return so.writeFileSync(l,Bg.stringify(m),"utf-8"),{fullPath:l,testId:u}}function sbe(t){if(!so.existsSync(t))throw new Error(`Test file not found: ${t}`);let{parsed:e}=wi(t);if(Pg(e))return e;if(!e.steps||!Array.isArray(e.steps))throw new Error(`Test ${t} is missing steps`);return e}async function mr(t,e,r){let o=sbe(t),n,i;if(Pg(o)){let s;try{s=Il.parse(o);}catch(l){throw new Error(`Mobile test ${t} is missing metadata or has invalid metadata: ${j(l)}`,{cause:l})}n=Og({testV2:s});let c=await ov({testV2:s,platform:n.platform,fileResolver:Du({sourceFilePath:t,momenticFiles:{mobileModules:r.mobileModules}})});i={steps:c.stepLists.steps,beforeSteps:c.stepLists.beforeSteps,afterSteps:c.stepLists.afterSteps};}else {try{n=Rl.parse(o);}catch(s){throw new Error(`Mobile test ${t} is missing metadata or has invalid metadata: ${j(s)}`,{cause:s})}i={steps:o.steps,beforeSteps:o.beforeSteps,afterSteps:o.afterSteps};}let a={rawStepLists:i,logger:e,testMetadata:n,onFetchModule:async s=>{let c=r.mobileModules[s]?.fullFilePath;if(!c)throw new Error(`Mobile module ${s} not found`);let l=Zl(c,e);return Ql({module:l,moduleFilePath:c,momenticFiles:r})}};switch(n.platform){case "ANDROID":{let{resolvedStepLists:s}=await tI({...a,platform:n.platform});return {...n,steps:s.steps,...s.beforeSteps?.length&&{beforeSteps:s.beforeSteps},...s.afterSteps?.length&&{afterSteps:s.afterSteps}}}case "IOS":{let{resolvedStepLists:s}=await tI({...a,platform:n.platform});return {...n,steps:s.steps,...s.beforeSteps?.length&&{beforeSteps:s.beforeSteps},...s.afterSteps?.length&&{afterSteps:s.afterSteps}}}}}async function zs({platform:t,filePath:e,steps:r,beforeSteps:o,afterSteps:n,settings:i,labels:a,folder:s,project:c,momenticFiles:l,schemaVersion:u,forceFileFormat:d}){let m=sr__default.isAbsolute(e)?e:sr__default.join(s,e);if(!so.existsSync(m))throw new Error(`Test file not found: ${m}`);let{parsed:p}=wi(m),f=Pg(p),h,S;if(f?(S=Il.parse(p),h={...Og({testV2:S}),schemaVersion:u,fileType:ve.MOBILE_TEST,steps:[]}):h=dv.parse({...p,schemaVersion:u}),h.fileType!==ve.MOBILE_TEST)throw new Error(`File at '${m}' is not a mobile test (fileType=${h.fileType}).`);if(h.platform!==t)throw new Error(`Platform mismatch. Test at '${m}' is for platform ${h.platform}, but update is for platform ${t}.`);let b=r||o||n,y=b?await ho({platform:t,stepLists:{steps:r??[],beforeSteps:o,afterSteps:n}}):void 0,T=y?.moduleUpdates??[],v;f&&S&&!b&&(v={steps:S.steps??[],before:S.before,after:S.after});let w=c.config.fileFormat==="v2"||f;d!==void 0&&(w=d==="v2");for(let x of T)Ja({content:x,schemaVersion:eo,momenticFiles:l,project:c,forceFileFormat:d});if(w){let x={...h};a!==void 0&&(x.labels=a),i!==void 0&&(x.settings=i);let A={...x,steps:[]},B;if(b&&y){let O;y.stepsToSave.beforeSteps&&y.stepsToSave.beforeSteps.length>0&&(O=y.stepsToSave.beforeSteps);let z;y.stepsToSave.afterSteps&&y.stepsToSave.afterSteps.length>0&&(z=y.stepsToSave.afterSteps),B={steps:y.stepsToSave.steps,beforeSteps:O,afterSteps:z};let k=Nu({sourceFilePath:m,momenticFiles:{mobileModules:l.mobileModules}}),H=Zm({metadata:A,stepLists:B,fileResolver:k});so.writeFileSync(m,Bg.stringify(H),"utf-8");}else {let O=Zm({metadata:A,stepLists:{steps:[]},fileResolver:Nu({sourceFilePath:m,momenticFiles:{mobileModules:l.mobileModules}})}),z=OK({formatted:O,stepLists:v??{steps:[]}});so.writeFileSync(m,z,"utf-8");}Vs(m,c.config);return}let N={...h,steps:h.steps};if(r&&(N.steps=y?.stepsToSave.steps??[]),a!==void 0&&(N.labels=a),o){let x=y?.stepsToSave.beforeSteps;x&&x.length>0?N.beforeSteps=x:delete N.beforeSteps;}else h.beforeSteps&&h.beforeSteps.length>0&&(N.beforeSteps=h.beforeSteps);if(n){let x=y?.stepsToSave.afterSteps;x&&x.length>0?N.afterSteps=x:delete N.afterSteps;}else h.afterSteps&&h.afterSteps.length>0&&(N.afterSteps=h.afterSteps);i&&(N.settings=i);let D=Bg.stringify(dv.parse(N));so.writeFileSync(m,D,"utf-8"),Vs(m,c.config);}function IK(t,e,r){let o=sr__default.join(r.rootDir,t);if(!so.existsSync(o))throw new Ft(`Test not found at path '${t}' in project '${r.rootDir}'`);let{parsed:n}=wi(o),i=Pg(n),a=sr__default.basename(t,".test.yaml"),s,c;if(e.name&&e.name!==a){let u=`${ji(e.name)}.test.yaml`;if(s=sr__default.join(sr__default.dirname(t),u),c=sr__default.join(r.rootDir,s),so.existsSync(c))throw new Error(`Test with name '${e.name}' already exists at path '${c}'`)}let l=i?lbe({existingTestRaw:n,updates:e}):cbe({existingTestRaw:n,updates:e});return so.writeFileSync(o,l,"utf-8"),c&&c!==o?(so.renameSync(o,c),Vs(c,r.config)):Vs(o,r.config),{newRelativeTestPath:s}}function lbe({existingTestRaw:t,updates:e}){let r=Il.parse(t),o=Og({testV2:r}),n={...o,description:e.description??o.description,disabled:e.disabled??o.disabled,labels:e.labels??o.labels,settings:e.settings??o.settings,fileType:ve.MOBILE_TEST,steps:[]};return OK({formatted:Zm({metadata:n,stepLists:{steps:[]}}),stepLists:{before:r.before,steps:r.steps??[],after:r.after}})}function OK({formatted:t,stepLists:e}){let{steps:r,...o}=t,n=e.before;n&&n.length===0&&(n=void 0);let i=e.after;i&&i.length===0&&(i=void 0);let a=oo({...o,before:n,steps:e.steps,after:i});return Bg.stringify(a)}function cbe({existingTestRaw:t,updates:e}){let o={...dv.parse(t),...e};if(o.fileType!==ve.MOBILE_TEST)throw new Error(`Existing legacy mobile test has unexpected fileType=${o.fileType}.`);return Bg.stringify(dv.parse(o))}var NK=new Set([".DS_Store","__MACOSX"]),DK={status:(t,e)=>{if(t.status===e.status)return t.status;if(t.status==="FAILED"||e.status==="FAILED")return "FAILED";if(t.status==="CANCELLED"||e.status==="CANCELLED")return "CANCELLED";if(t.status==="RETRYING"||e.status==="RETRYING")return "RETRYING";if(t.status==="RUNNING"||e.status==="RUNNING")return "RUNNING";if(t.status==="PENDING"||e.status==="PENDING")return "PENDING";throw new Error(`Invalid run status merge: ${t.status} and ${e.status}`)},startedAt:(t,e)=>t.startedAt<e.startedAt?t.startedAt:e.startedAt,updatedAt:(t,e)=>t.updatedAt>e.updatedAt?t.updatedAt:e.updatedAt,finishedAt:(t,e)=>!t.finishedAt||!e.finishedAt?new Date:t.finishedAt>e.finishedAt?t.finishedAt:e.finishedAt,gitCommitTimestamp:(t,e)=>{if(!(!t&&!e)){if(!t.gitCommitTimestamp||!e.gitCommitTimestamp||t.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${t.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return t.gitCommitTimestamp}},pipelineId:(t,e)=>t.pipelineId===e.pipelineId?t.pipelineId:!t.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&t.pipelineId?t.pipelineId:t.startedAt<e.startedAt?e.pipelineId:t.pipelineId,labels:(t,e)=>{let r=new Set([...t.labels??[],...e.labels??[]]);return Array.from(r)},ai:(t,e)=>t.ai??e.ai,browser:(t,e)=>t.browser??e.browser};function dbe(t,e,r){if(DK[r]){let i=DK[r];return i(t,e)}let o=t[r],n=e[r];if(o!==n)throw new Error(`Metadata values for key "${r}" do not match: "${o}" vs "${n}"`);return o}var OI=class extends Error{constructor(e,r){let o=`${e} contains invalid Momentic results: ${r}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(o),this.name="InvalidMomenticResultsPathError";}};function LK(t,e){try{let r=sr__default.join(e,ro);return Em.parse(JSON.parse(so.readFileSync(r,"utf-8")))}catch{throw new OI(t,e)}}function kK(t,e,r){let o=randomUUID(),n=t.child({runGroupId:o});so.rmSync(e,{recursive:true,force:true});let i=so.readdirSync(r).filter(c=>!NK.has(c)).map(c=>sr__default.join(r,c));if(i.length===0)throw new Error(`No run groups found in results path: ${r}`);so.mkdirSync(e,{recursive:true});let a={...LK(r,i[0]),id:o};for(let c of i){let l=sr__default.join(c,on);if(!so.existsSync(l))continue;let u=LK(r,c);n.info({oldRunGroupId:u.id},"Merging run groups");for(let m in u){if(m==="id")continue;let p=m;a[p]=dbe(a,u,p);}let d=so.readdirSync(l);for(let m of d){if(NK.has(m))continue;let p=sr__default.join(l,m),f=sr__default.join(e,on,m);so.cpSync(p,f,{recursive:true});}}let s=sr__default.join(e,ro);so.writeFileSync(s,JSON.stringify(a,null,2));}var oe="v1",NI="mobile-cli",Bu="0.97.2";var mbe=9e4,pbe=3,fbe=1500,hbe=15e3,go=class extends Error{status;rawError;constructor(e,r,o,n={}){super(o,n),this.status=e,this.rawError=r;}},DI=class extends Ft{constructor(e,r={}){super(e,r),this.name="PlanLimitExceededError";}};async function gbe(t){return t.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var LI=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger;}getHeaders(){let e={"Content-Type":"application/json"};return (e[iE]=Bu),(e[f$]=NI),e}async sendRequest(e,r){let{retries:o=pbe,requestTimeoutMs:n=mbe,initialRetryDelayMs:i=fbe,maxRetryDelayMs:a=hbe,onFailedRequest:s}=r,c=o,l=o,u,d={path:e,baseUrl:this.baseUrl,method:r.method};for(;c>0;)try{return c--,await this.sendSingleRequestWithOTEL(e,r,n)}catch(m){u=m;try{s?.(u);}catch{}if(m instanceof go&&m.status>=400&&m.status<500)throw m.status===402?new DI(m.rawError,{cause:m}):m;if(m instanceof Error&&m.name==="AbortError"&&(u=new kl),c===0)throw u;let p=l-c,f=Math.min(i*Math.pow(2,p-1),a);await new Promise(h=>setTimeout(h,f));}throw this.logger.warn({...d,err:u},"Got fatal error response from Momentic server"),u}async sendSingleRequestWithOTEL(e,r,o){let n=Sbe(e);return Ji({name:`cli.api.${r.method.toLowerCase()}.${n}`,serviceName:"api-server",kind:"client",attributes:{"http.request.method":r.method,"url.path":n},fn:i=>this.sendSingleRequestHelper(e,r,o,a=>{i?.setAttribute("http.response.status_code",a);})})}async sendSingleRequestHelper(e,r,o,n){let i={path:e,baseUrl:this.baseUrl,method:r.method},a=new AbortController,s=setTimeout(()=>a.abort(),o),c=()=>a.abort();r.signal&&r.signal.addEventListener("abort",c,{once:true});let l=Date.now(),u={...this.getHeaders(),...r.extraHeaders};try{let d=await fetch(`${this.baseUrl}${e}`,{method:r.method,body:r.body?JSON.stringify(r.body):void 0,headers:u,signal:a.signal});if(n?.(d.status),!d.ok){let f=await gbe(d);throw new go(d.status,f,`Request to ${r.method} ${e} failed with status ${d.status}: ${f}`)}let m;if(d.status===204)m={};else if(r.responseType==="buffer"){let f=await d.arrayBuffer();m=Buffer.from(f);}else {let f=await d.text();try{m=JSON.parse(f);}catch{m=f;}}this.logger&&r.logResponse===!0&&m&&this.logger.debug({result:m,status:d.status,durationMs:Date.now()-l,...i},"Got response from Momentic server");let p=r.responseHeadersObject;return p&&d.headers.forEach((f,h)=>{p[h.toLowerCase()]=f;}),m}finally{clearTimeout(s),r.signal&&r.signal.removeEventListener("abort",c);}}};function Sbe(t){return (t.split("?")[0]??t).replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,":id")}var Za=class extends LI{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode;}getHeaders(){return {...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[p$]:this.mode??""}}};var d3="vercel.ai.error",bbe=Symbol.for(d3),FK,UK,zt=class m3 extends(UK=Error,FK=bbe,UK){constructor({name:e,message:r,cause:o}){super(r),this[FK]=true,this.name=e,this.cause=o;}static isInstance(e){return m3.hasMarker(e,d3)}static hasMarker(e,r){let o=Symbol.for(r);return e!=null&&typeof e=="object"&&o in e&&typeof e[o]=="boolean"&&e[o]===true}},p3="AI_APICallError",f3=`vercel.ai.error.${p3}`,ybe=Symbol.for(f3),BK,VK,Co=class extends(VK=zt,BK=ybe,VK){constructor({message:t,url:e,requestBodyValues:r,statusCode:o,responseHeaders:n,responseBody:i,cause:a,isRetryable:s=o!=null&&(o===408||o===409||o===429||o>=500),data:c}){super({name:p3,message:t,cause:a}),this[BK]=true,this.url=e,this.requestBodyValues=r,this.statusCode=o,this.responseHeaders=n,this.responseBody=i,this.isRetryable=s,this.data=c;}static isInstance(t){return zt.hasMarker(t,f3)}},h3="AI_EmptyResponseBodyError",g3=`vercel.ai.error.${h3}`,Ebe=Symbol.for(g3),zK,$K,S3=class extends($K=zt,zK=Ebe,$K){constructor({message:t="Empty response body"}={}){super({name:h3,message:t}),this[zK]=true;}static isInstance(t){return zt.hasMarker(t,g3)}};function b3(t){return t==null?"unknown error":typeof t=="string"?t:t instanceof Error?t.message:JSON.stringify(t)}var y3="AI_InvalidArgumentError",E3=`vercel.ai.error.${y3}`,Tbe=Symbol.for(E3),jK,HK,pv=class extends(HK=zt,jK=Tbe,HK){constructor({message:t,cause:e,argument:r}){super({name:y3,message:t,cause:e}),this[jK]=true,this.argument=r;}static isInstance(t){return zt.hasMarker(t,E3)}},T3="AI_InvalidPromptError",v3=`vercel.ai.error.${T3}`,vbe=Symbol.for(v3),GK,WK,C3=class extends(WK=zt,GK=vbe,WK){constructor({prompt:t,message:e,cause:r}){super({name:T3,message:`Invalid prompt: ${e}`,cause:r}),this[GK]=true,this.prompt=t;}static isInstance(t){return zt.hasMarker(t,v3)}},A3="AI_InvalidResponseDataError",w3=`vercel.ai.error.${A3}`,Cbe=Symbol.for(w3),qK,KK,fv=class extends(KK=zt,qK=Cbe,KK){constructor({data:t,message:e=`Invalid response data: ${JSON.stringify(t)}.`}){super({name:A3,message:e}),this[qK]=true,this.data=t;}static isInstance(t){return zt.hasMarker(t,w3)}},R3="AI_JSONParseError",_3=`vercel.ai.error.${R3}`,Abe=Symbol.for(_3),YK,XK,Vg=class extends(XK=zt,YK=Abe,XK){constructor({text:t,cause:e}){super({name:R3,message:`JSON parsing failed: Text: ${t}.
|
|
208
|
+
`)){let n=o.indexOf("=");if(n===-1)continue;let i=o.slice(0,n),a=o.slice(n+1).trim();r[i]=a;}return r}async function USe(t,e,r){try{let n=r["github.user"]||void 0;if(n)return n}catch{}let o;try{if(e?.startsWith("http://")||e?.startsWith("https://"))o=new URL(e).host;else if(e?.startsWith("git@")){let n=e.indexOf("@"),i=e.indexOf(":",n+1);n!==-1&&i!==-1&&(o=e.slice(n+1,i));}}catch{}if(o=o?.toLowerCase(),!!o&&e?.startsWith("git@")&&o.includes("github"))try{let{stdout:n,stderr:i}=await kSe("ssh",["-T","-o","BatchMode=yes",`git@${o}`],{timeout:5e3}),s=`${n??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}catch{return}}async function BSe(t,e,r){let o=e?.includes("github.com"),n=e?.includes("gitlab.com");try{if(o)return USe(t,e,r);if(n)return}catch{}}function Lg(t){if(t.startsWith("git@")){let e=t.split(":");if(e.length===2){let r=e[1].replace(".git","").split("/");if(r.length===2){let o=r[0],n=r[1];return `${o}/${n}`}}}else if(t.startsWith("http")||t.startsWith("https")){let r=new URL(t).pathname.split("/").filter(Boolean);if(r.length>=2){let o=r[0],n=r[1].replace(".git","");return `${o}/${n}`}}}function VSe(t){if(!(t instanceof Error))return false;let e=t.message;return e.includes("not a git repository")||e.includes("ENOENT")||e.includes("detected dubious ownership")}async function Dt(t,e){try{return (await e).trim()}catch(r){if(VSe(r))return;t.error({err:r},"Failed to run git command");return}}function zSe(){if(process.env.GITHUB_ACTION)return "GithubActions";if(process.env.GITLAB_CI)return "GitlabCI";if(process.env.CIRCLECI)return "CircleCI";if(process.env.BUILDKITE)return "Buildkite";if(process.env["System.CollectionUri"]?.includes("azure"))return "AzureDevOps";if(process.env.PROJECT_ID&&process.env.BUILD_ID)return "GCPCloudBuild";if(process.env.BITRISE_BUILD_SLUG)return "Bitrise";if(process.env.MOMENTIC_GIT_OVERRIDE)return "Custom"}async function $Se(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`:void 0;return {ciProvider:"GithubActions",gitCommitSha:process.env.GITHUB_SHA,gitCommitShaShort:process.env.GITHUB_SHA?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function jSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]);return {ciProvider:"GitlabCI",gitCommitSha:process.env.CI_COMMIT_SHA,gitCommitShaShort:process.env.CI_COMMIT_SHORT_SHA,gitCommitTimestamp:process.env.CI_COMMIT_TIMESTAMP?Xa(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:r,gitCommitAuthorName:o,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function HSe(t){let[e,r,o,n]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),a=process.env.CIRCLE_REPOSITORY_URL?.trim()||void 0||r||void 0,s=a?.includes("github.com")??false,c=a?.includes("gitlab.com")??false,l=a?Lg(a):void 0;return {ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:a,gitCommitMessage:o,gitCommitAuthorName:n,githubRepository:s?l:void 0,gitlabProjectPath:c?l:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function GSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env.BUILDKITE_REPO,i=n?.includes("github.com"),a=n?.includes("gitlab.com"),s=n?Lg(n):void 0;return {ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env.BUILDKITE_PIPELINE_ID}:${process.env.BUILDKITE_BUILD_ID}:${process.env.BUILDKITE_JOB_ID}`}}async function WSe(t){let[e,r,o]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),n=process.env["Build.Repository.Uri"],i=n?.includes("github.com"),a=n?.includes("gitlab.com"),s=n?Lg(n):void 0;return {ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:n,gitCommitMessage:r,gitCommitAuthorName:o,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function qSe(t,e,r){let[o,n,i,a,s,c,l,u,d]=await Promise.all([Dt(t,Nt.revparse(["HEAD"])),Dt(t,Nt.revparse(["--short","HEAD"])),Dt(t,Nt.revparse(["--abbrev-ref","HEAD"])),Dt(t,Nt.listRemote(["--get-url","origin"])),Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%B"])),Dt(t,Nt.show(["-s","--pretty=%an"])),e?Dt(t,Nt.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),FSe(t)]),m=u||(e?await Dt(t,Nt.raw(["merge-base",e,"HEAD"])):void 0),p=m?await Dt(t,Nt.show(["--no-patch","--format=%ci",m])):void 0,f=a?.includes("github.com"),h=a?.includes("gitlab.com"),S=a?Lg(a):void 0,b=d["user.email"]||void 0,y=d["user.name"]||void 0,T=d["user.username"]||void 0,v=d["github.user"]||void 0,D=(r?.includeHostingUsername??true?await BSe(t,a,d):void 0)??T??v??void 0;return {ciProvider:"none",gitCommitSha:o,gitCommitShaShort:n,gitBranchName:i,gitOriginUrl:a,gitCommitTimestamp:s?Xa(s):void 0,gitCommitMessage:c,gitCommitAuthorName:l,gitLocalUsername:D,gitLocalEmail:b,gitLocalName:y,lastCommitOnMainSha:m,lastCommitOnMainTimestamp:p?Xa(p):void 0,githubRepository:f?S:void 0,gitlabProjectPath:h?S:void 0,pipelineId:void 0}}async function KSe(t){let[e,r]=await Promise.all([Dt(t,Nt.show(["--no-patch","--format=%ci"])),Dt(t,Nt.show(["-s","--pretty=%an"]))]),o=process.env.GIT_REPOSITORY_URL,n=o?.includes("github.com"),i=o?.includes("gitlab.com"),a=o?Lg(o):void 0;return {ciProvider:"Bitrise",gitCommitSha:process.env.BITRISE_GIT_COMMIT,gitCommitShaShort:process.env.BITRISE_GIT_COMMIT?.slice(0,6),gitCommitTimestamp:e?Xa(e):void 0,gitBranchName:process.env.BITRISE_GIT_BRANCH,gitOriginUrl:o,gitCommitMessage:process.env.BITRISE_GIT_MESSAGE,gitCommitAuthorName:r,githubRepository:n?a:void 0,gitlabProjectPath:i?a:void 0,pipelineId:`${process.env.BITRISE_APP_SLUG}:${process.env.BITRISE_BUILD_SLUG}`}}async function YSe(){let t=process.env._HEAD_REPO_URL;return {ciProvider:"GCPCloudBuild",gitCommitSha:process.env.COMMIT_SHA,gitCommitShaShort:process.env.COMMIT_SHA?.slice(0,6),gitBranchName:process.env.BRANCH_NAME,gitOriginUrl:t?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:t?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}function XSe(){return {ciProvider:"Custom",gitCommitSha:process.env.GIT_COMMIT_SHA,gitCommitShaShort:process.env.GIT_COMMIT_SHA_SHORT??process.env.GIT_COMMIT_SHA?.slice(0,6),gitCommitTimestamp:Xa(process.env.GIT_COMMIT_TIMESTAMP),gitBranchName:process.env.GIT_BRANCH_NAME,gitOriginUrl:process.env.GIT_ORIGIN_URL,gitCommitAuthorName:process.env.GIT_COMMIT_AUTHOR_NAME,gitCommitMessage:process.env.GIT_COMMIT_MESSAGE,lastCommitOnMainSha:process.env.LAST_COMMIT_ON_MAIN_SHA,lastCommitOnMainTimestamp:Xa(process.env.LAST_COMMIT_ON_MAIN_TIMESTAMP),mergedGitBranchName:process.env.MERGED_GIT_BRANCH_NAME,githubRepository:process.env.GITHUB_REPOSITORY,gitlabProjectPath:process.env.GITLAB_PROJECT_PATH,gitLocalUsername:process.env.GIT_USERNAME,gitLocalEmail:process.env.GIT_EMAIL,gitLocalName:process.env.GIT_NAME}}async function JSe(t){let e=[...t.config.gitProtectedBranches??[]];return t.config.gitMainBranch&&e.push(t.config.gitMainBranch),{gitMainBranch:t.config.gitMainBranch,gitProtectedBranches:e}}async function kg(t,e,r){let o=zSe();if(!o)return qSe(t,e,r);switch(o){case "GithubActions":return $Se(t);case "GitlabCI":return jSe(t);case "CircleCI":return HSe(t);case "Buildkite":return GSe(t);case "AzureDevOps":return WSe(t);case "GCPCloudBuild":return YSe();case "Bitrise":return KSe(t);case "Custom":return XSe()}}async function ZSe(t,e,r,o){let n=o,i=o.gitCommitSha;if(!i)return n;let a=o.gitMainBranch;if(a&&(!n.lastCommitOnMainSha||!n.lastCommitOnMainTimestamp))try{let s=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getMergeBaseCommitFromGitlab",fn:()=>e.getMergeBaseCommitFromGitlab(r,a,i),context:{projectPath:r,mainBranch:a}});n={...n,lastCommitOnMainSha:s.sha,lastCommitOnMainTimestamp:s.committer.date};}catch(s){t.warn({err:s},"Failed to get merge base commit from Gitlab");}if(!n.gitCommitTimestamp||!n.gitCommitAuthorName||!n.gitCommitMessage||!n.gitCommitAuthorName)try{let s=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getCommitFromGitlab",fn:()=>e.getCommitFromGitlab(r,i),context:{projectPath:r,gitCommitSha:i}});s&&(n={...n,gitCommitTimestamp:n.gitCommitTimestamp??s.committer.date,gitCommitAuthorName:n.gitCommitAuthorName??s.author.name,gitCommitMessage:n.gitCommitMessage??s.message});}catch(s){t.warn({err:s},"Failed to get commit from Gitlab");}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!n.mergedGitBranchName){let s=o.gitBranchName;try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitlab.getMergedBranchFromGitlab",fn:()=>e.getMergedBranchFromGitlab(r,s,i),context:{projectPath:r,branchName:s,gitCommitSha:i}});c.mergedBranch&&(n={...n,mergedGitBranchName:c.mergedBranch});}catch(c){t.warn({err:c},"Failed to get merged branch from Gitlab");}}return n}async function QSe(t,e,r,o,n){let i=n,a=n.gitCommitSha;if(!a)return i;let s=n.gitMainBranch;if(s&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getMergeBaseCommitFromGithub",fn:()=>e.getMergeBaseCommitFromGithub(r,o,s,a),context:{owner:r,repo:o,mainBranch:s}});i={...i,lastCommitOnMainSha:c.sha,lastCommitOnMainTimestamp:c.committer.date};}catch(c){t.warn({err:c},"Failed to get merge base commit from GitHub");}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let c=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getCommitFromGithub",fn:()=>e.getCommitFromGithub(r,o,a),context:{owner:r,repo:o,gitCommitSha:a}});c&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??c.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??c.author.name,gitCommitMessage:i.gitCommitMessage??c.message});}catch(c){t.warn({err:c},"Failed to get commit from GitHub");}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!i.mergedGitBranchName){let c=n.gitBranchName;try{let l=await Ri({logger:t,operation:"getRemoteMetadataFromGitHub.getMergedBranchFromGithub",fn:()=>e.getMergedBranchFromGithub(r,o,c,a),context:{owner:r,repo:o,branchName:c,gitCommitSha:a}});l.mergedBranch&&(i={...i,mergedGitBranchName:l.mergedBranch});}catch(l){t.warn({err:l},"Failed to get merged branch from GitHub");}}return i}async function ebe(t,e,r){try{if(r.githubRepository){let[o,n]=r.githubRepository.split("/");return await Ri({logger:t,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitHub",fn:()=>QSe(t,e,o,n,r),context:{githubRepository:r.githubRepository}})}else if(r.gitlabProjectPath){let o=r.gitlabProjectPath;return await Ri({logger:t,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitlab",fn:()=>ZSe(t,e,o,r),context:{gitlabProjectPath:o}})}}catch(o){t.warn({err:o},"Failed to get remote git metadata");}return r}async function tbe(t,e,r,o){let n={},i={gitMainBranch:r.config.gitMainBranch};return Ri({logger:t,operation:"getGitMetadata.total",fn:async()=>{let[a,s]=await Promise.all([Ri({logger:t,operation:"getGitMetadata.getConfiguredGitMetadata",fn:()=>JSe(r),context:{projectConfigPath:r.configFilePath}}),Ri({logger:t,operation:"getGitMetadata.getEnvironmentGitMetadata",fn:async()=>{let u=await kg(t,r.config.gitMainBranch,o);return i.ciProvider=u.ciProvider,u},context:i})]),c={...a,...s};n.gitBranchName=c.gitBranchName,n.githubRepository=c.githubRepository,n.gitlabProjectPath=c.gitlabProjectPath,(!c.lastCommitOnMainSha||!c.lastCommitOnMainTimestamp)&&c.gitBranchName===a.gitMainBranch&&(c.lastCommitOnMainSha=c.gitCommitSha,c.lastCommitOnMainTimestamp=c.gitCommitTimestamp);let l=await Ri({logger:t,operation:"getGitMetadata.getRemoteMetadataIfNeeded",fn:()=>ebe(t,e,c),context:{githubRepository:c.githubRepository,gitlabProjectPath:c.gitlabProjectPath,gitBranchName:c.gitBranchName}});return {...a,...s,...l}},context:n})}async function _K(t){try{let e=await RK(t).remote(["show","origin"]);return e?e.match(/HEAD branch: (.*)$/m)?.[1]?.trim():void 0}catch{return}}var II=new Map;async function rbe(t,e,r){let o,n;try{[o,n]=await Promise.all([Dt(t,Nt.raw(["symbolic-ref","--short","-q","HEAD"]).then(s=>s.trim())),Dt(t,Nt.revparse(["--verify","HEAD"]).then(s=>s.trim()))]);}catch{return}if(!o||!n)return;let i=`${e.configFilePath}:${e.config.gitMainBranch}:${e.config.gitProtectedBranches?.join(",")}`,a=`${r?.includeHostingUsername}`;return `${o}:${n}:${i}:${a}`}async function dr(t,e,r,o){let n=await rbe(t,r,o);if(n&&II.has(n))return t.debug("Using cached git metadata"),II.get(n);let i=await tbe(t,e,r,o);return n&&II.set(n,i),i}function ibe(t,e){let r=`${ji(e)}.module.yaml`,o=sr__default.join(sr__default.dirname(t),r);if(so.existsSync(o))throw new Error(`A conflicting file already exists at the following path: ${o}`);return so.renameSync(t,o),o}function Ja({content:t,schemaVersion:e,momenticFiles:r,project:o,forceSaveOnNoDiffs:n,forceFileFormat:i}){let a=r.mobileModules[t.moduleId]?.fullFilePath,s=r.mobileModules[t.moduleId]?.name;if(!a||!so.existsSync(a))throw new Error(`Tried to update mobile module ${t.moduleId} that could not be found on disk`);let{parsed:c}=wi(a),l=o.config.fileFormat==="v2";i!==void 0&&(l=i==="v2");let u=!!t.name&&t.name!==s,d={...c,...t,schemaVersion:e},m=Oa.parse(d),p=qi(t.platform).array().parse(t.steps),f=l?iv({metadata:{...m,moduleId:t.moduleId,name:t.name??s??""},steps:p,fileResolver:Nu({sourceFilePath:a,momenticFiles:{mobileModules:r.mobileModules}})}):oo({fileType:ve.MOBILE_MODULE,...m,steps:p}),h=diff(f,c);if(h&&Object.keys(h).length===0&&!n&&!u)return;so.writeFileSync(a,Bg.stringify(f),"utf-8");let S=u?ibe(a,t.name):void 0;Vs(S??a,o.config);}function xK({moduleId:t,patch:e,momenticFiles:r,project:o,logger:n}){let i=r.mobileModules[t]?.fullFilePath;if(!i)throw new Error(`Tried to update mobile module ${t} that could not be found on disk`);let a=Zl(i,n),s=Ql({module:a,moduleFilePath:i,momenticFiles:r}),c=Q_.parse({...s,...e}),l={moduleId:c.moduleId,platform:c.platform,name:e.name??s.name,description:c.description,enabled:c.enabled,parameters:c.parameters,steps:qi(c.platform).array().parse(c.steps)};Ja({content:l,schemaVersion:c.schemaVersion,momenticFiles:r,project:o});}async function Ug({name:t,description:e,enabled:r,platform:o,steps:n,folder:i,project:a,momenticFiles:s}){let c=ji(t),l=sr__default.join(i,`${c}.module.yaml`),u=Qm({projectConfig:a.config,momenticFiles:s,entityType:"mobile-module"}),{stepsToSave:{steps:d}}=await ho({platform:o,stepLists:{steps:n}}),m={schemaVersion:ty,platform:o,moduleId:u,description:e,enabled:r},p=a.config.fileFormat==="v2"?iv({metadata:{...m,moduleId:u,name:t},steps:d,fileResolver:Nu({sourceFilePath:l,momenticFiles:{mobileModules:s.mobileModules}})}):eM.parse({fileType:ve.MOBILE_MODULE,...m,steps:d});return so.writeFileSync(l,Bg.stringify(p),"utf-8"),Vs(l,a.config),{moduleId:u,platform:o,name:t,description:e||void 0,steps:n}}function Zl(t,e){let{parsed:r}=wi(t);if(Ig(r))try{return nE.parse(r)}catch(o){throw e.error({err:o,moduleFilePath:t,existingModule:r},`${t} does not parse as a valid V2 Momentic mobile module`),o}try{return eM.parse(r)}catch(o){throw e.error({err:o,moduleFilePath:t,existingModule:r},`${t} does not parse as a valid Momentic mobile module`),o}}function Ql({module:t,moduleFilePath:e,momenticFiles:r}){let o=sr__default.basename(e,".module.yaml");if(!Ig(t))return {...t,name:o};let{module:n}=nv({moduleV2:t,moduleName:o,fileResolver:Du({sourceFilePath:e,momenticFiles:r})});return n}async function Uu(t,e,r,o){let n=Zl(t.fullFilePath,r),i=Ql({module:n,moduleFilePath:t.fullFilePath,momenticFiles:e}),a=i.platform==="ANDROID"?o?.android:o?.ios,{resolvedSteps:s}=await OT({platform:i.platform,rawSteps:i.steps,resolvedModuleCache:a||{},onFetchModule:async l=>{let u=e.mobileModules[l]?.fullFilePath;if(!u)throw new Error(`Could not find mobile module with id ${l}`);let d=Zl(u,r);return Ql({module:d,moduleFilePath:u,momenticFiles:e})},logger:r,metadata:{id:i.moduleId,schemaVersion:i.schemaVersion}}),c=i.platform==="ANDROID"?{...i,platform:"ANDROID",name:t.name,description:i.description||void 0,steps:s}:{...i,platform:"IOS",name:t.name,description:i.description||void 0,steps:s};return a&&(a[t.id]=cloneDeep(c)),c}async function PK(t,e){let r={},o={};return await Promise.all(Object.values(t.mobileModules).map(async n=>{await Uu(n,t,e,{ios:r,android:o});})),[...Object.values(r),...Object.values(o)]}var tp=wy.array(),dv=C__default.discriminatedUnion("platform",[Uy.extend({beforeSteps:tp.optional(),steps:tp,afterSteps:tp.optional()}),By.extend({beforeSteps:tp.optional(),steps:tp,afterSteps:tp.optional()})]);function mv({name:t,description:e="",settings:r,folder:o,platform:n,project:i,momenticFiles:a}){try{ci(t);}catch(p){throw new Qr(`${p} when validating the test entity name`)}let c=`${ji(t)}.test.yaml`,l=sr__default.join(o,c);if(so.existsSync(l))throw new Error(`A test named '${t}' already exists at path '${l}'. Choose a different name.`);let u=Qm({projectConfig:i.config,momenticFiles:a,entityType:"mobile-test"}),d={fileType:ve.MOBILE_TEST,id:u,description:e,schemaVersion:eo,platform:n,settings:r,steps:[]},m=i.config.fileFormat==="v2"?Zm({metadata:d,stepLists:{steps:[]},fileResolver:Nu({sourceFilePath:l,momenticFiles:{mobileModules:a.mobileModules}})}):mV.parse(d);return so.writeFileSync(l,Bg.stringify(m),"utf-8"),{fullPath:l,testId:u}}function sbe(t){if(!so.existsSync(t))throw new Error(`Test file not found: ${t}`);let{parsed:e}=wi(t);if(Pg(e))return e;if(!e.steps||!Array.isArray(e.steps))throw new Error(`Test ${t} is missing steps`);return e}async function mr(t,e,r){let o=sbe(t),n,i;if(Pg(o)){let s;try{s=Il.parse(o);}catch(l){throw new Error(`Mobile test ${t} is missing metadata or has invalid metadata: ${j(l)}`,{cause:l})}n=Og({testV2:s});let c=await ov({testV2:s,platform:n.platform,fileResolver:Du({sourceFilePath:t,momenticFiles:{mobileModules:r.mobileModules}})});i={steps:c.stepLists.steps,beforeSteps:c.stepLists.beforeSteps,afterSteps:c.stepLists.afterSteps};}else {try{n=Rl.parse(o);}catch(s){throw new Error(`Mobile test ${t} is missing metadata or has invalid metadata: ${j(s)}`,{cause:s})}i={steps:o.steps,beforeSteps:o.beforeSteps,afterSteps:o.afterSteps};}let a={rawStepLists:i,logger:e,testMetadata:n,onFetchModule:async s=>{let c=r.mobileModules[s]?.fullFilePath;if(!c)throw new Error(`Mobile module ${s} not found`);let l=Zl(c,e);return Ql({module:l,moduleFilePath:c,momenticFiles:r})}};switch(n.platform){case "ANDROID":{let{resolvedStepLists:s}=await tI({...a,platform:n.platform});return {...n,steps:s.steps,...s.beforeSteps?.length&&{beforeSteps:s.beforeSteps},...s.afterSteps?.length&&{afterSteps:s.afterSteps}}}case "IOS":{let{resolvedStepLists:s}=await tI({...a,platform:n.platform});return {...n,steps:s.steps,...s.beforeSteps?.length&&{beforeSteps:s.beforeSteps},...s.afterSteps?.length&&{afterSteps:s.afterSteps}}}}}async function zs({platform:t,filePath:e,steps:r,beforeSteps:o,afterSteps:n,settings:i,labels:a,folder:s,project:c,momenticFiles:l,schemaVersion:u,forceFileFormat:d}){let m=sr__default.isAbsolute(e)?e:sr__default.join(s,e);if(!so.existsSync(m))throw new Error(`Test file not found: ${m}`);let{parsed:p}=wi(m),f=Pg(p),h,S;if(f?(S=Il.parse(p),h={...Og({testV2:S}),schemaVersion:u,fileType:ve.MOBILE_TEST,steps:[]}):h=dv.parse({...p,schemaVersion:u}),h.fileType!==ve.MOBILE_TEST)throw new Error(`File at '${m}' is not a mobile test (fileType=${h.fileType}).`);if(h.platform!==t)throw new Error(`Platform mismatch. Test at '${m}' is for platform ${h.platform}, but update is for platform ${t}.`);let b=r||o||n,y=b?await ho({platform:t,stepLists:{steps:r??[],beforeSteps:o,afterSteps:n}}):void 0,T=y?.moduleUpdates??[],v;f&&S&&!b&&(v={steps:S.steps??[],before:S.before,after:S.after});let w=c.config.fileFormat==="v2"||f;d!==void 0&&(w=d==="v2");for(let x of T)Ja({content:x,schemaVersion:eo,momenticFiles:l,project:c,forceFileFormat:d});if(w){let x={...h};a!==void 0&&(x.labels=a),i!==void 0&&(x.settings=i);let A={...x,steps:[]},B;if(b&&y){let O;y.stepsToSave.beforeSteps&&y.stepsToSave.beforeSteps.length>0&&(O=y.stepsToSave.beforeSteps);let z;y.stepsToSave.afterSteps&&y.stepsToSave.afterSteps.length>0&&(z=y.stepsToSave.afterSteps),B={steps:y.stepsToSave.steps,beforeSteps:O,afterSteps:z};let k=Nu({sourceFilePath:m,momenticFiles:{mobileModules:l.mobileModules}}),H=Zm({metadata:A,stepLists:B,fileResolver:k});so.writeFileSync(m,Bg.stringify(H),"utf-8");}else {let O=Zm({metadata:A,stepLists:{steps:[]},fileResolver:Nu({sourceFilePath:m,momenticFiles:{mobileModules:l.mobileModules}})}),z=OK({formatted:O,stepLists:v??{steps:[]}});so.writeFileSync(m,z,"utf-8");}Vs(m,c.config);return}let N={...h,steps:h.steps};if(r&&(N.steps=y?.stepsToSave.steps??[]),a!==void 0&&(N.labels=a),o){let x=y?.stepsToSave.beforeSteps;x&&x.length>0?N.beforeSteps=x:delete N.beforeSteps;}else h.beforeSteps&&h.beforeSteps.length>0&&(N.beforeSteps=h.beforeSteps);if(n){let x=y?.stepsToSave.afterSteps;x&&x.length>0?N.afterSteps=x:delete N.afterSteps;}else h.afterSteps&&h.afterSteps.length>0&&(N.afterSteps=h.afterSteps);i&&(N.settings=i);let D=Bg.stringify(dv.parse(N));so.writeFileSync(m,D,"utf-8"),Vs(m,c.config);}function IK(t,e,r){let o=sr__default.join(r.rootDir,t);if(!so.existsSync(o))throw new Ft(`Test not found at path '${t}' in project '${r.rootDir}'`);let{parsed:n}=wi(o),i=Pg(n),a=sr__default.basename(t,".test.yaml"),s,c;if(e.name&&e.name!==a){let u=`${ji(e.name)}.test.yaml`;if(s=sr__default.join(sr__default.dirname(t),u),c=sr__default.join(r.rootDir,s),so.existsSync(c))throw new Error(`Test with name '${e.name}' already exists at path '${c}'`)}let l=i?lbe({existingTestRaw:n,updates:e}):cbe({existingTestRaw:n,updates:e});return so.writeFileSync(o,l,"utf-8"),c&&c!==o?(so.renameSync(o,c),Vs(c,r.config)):Vs(o,r.config),{newRelativeTestPath:s}}function lbe({existingTestRaw:t,updates:e}){let r=Il.parse(t),o=Og({testV2:r}),n={...o,description:e.description??o.description,disabled:e.disabled??o.disabled,labels:e.labels??o.labels,settings:e.settings??o.settings,fileType:ve.MOBILE_TEST,steps:[]};return OK({formatted:Zm({metadata:n,stepLists:{steps:[]}}),stepLists:{before:r.before,steps:r.steps??[],after:r.after}})}function OK({formatted:t,stepLists:e}){let{steps:r,...o}=t,n=e.before;n&&n.length===0&&(n=void 0);let i=e.after;i&&i.length===0&&(i=void 0);let a=oo({...o,before:n,steps:e.steps,after:i});return Bg.stringify(a)}function cbe({existingTestRaw:t,updates:e}){let o={...dv.parse(t),...e};if(o.fileType!==ve.MOBILE_TEST)throw new Error(`Existing legacy mobile test has unexpected fileType=${o.fileType}.`);return Bg.stringify(dv.parse(o))}var NK=new Set([".DS_Store","__MACOSX"]),DK={status:(t,e)=>{if(t.status===e.status)return t.status;if(t.status==="FAILED"||e.status==="FAILED")return "FAILED";if(t.status==="CANCELLED"||e.status==="CANCELLED")return "CANCELLED";if(t.status==="RETRYING"||e.status==="RETRYING")return "RETRYING";if(t.status==="RUNNING"||e.status==="RUNNING")return "RUNNING";if(t.status==="PENDING"||e.status==="PENDING")return "PENDING";throw new Error(`Invalid run status merge: ${t.status} and ${e.status}`)},startedAt:(t,e)=>t.startedAt<e.startedAt?t.startedAt:e.startedAt,updatedAt:(t,e)=>t.updatedAt>e.updatedAt?t.updatedAt:e.updatedAt,finishedAt:(t,e)=>!t.finishedAt||!e.finishedAt?new Date:t.finishedAt>e.finishedAt?t.finishedAt:e.finishedAt,gitCommitTimestamp:(t,e)=>{if(!(!t&&!e)){if(!t.gitCommitTimestamp||!e.gitCommitTimestamp||t.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${t.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return t.gitCommitTimestamp}},pipelineId:(t,e)=>t.pipelineId===e.pipelineId?t.pipelineId:!t.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&t.pipelineId?t.pipelineId:t.startedAt<e.startedAt?e.pipelineId:t.pipelineId,labels:(t,e)=>{let r=new Set([...t.labels??[],...e.labels??[]]);return Array.from(r)},ai:(t,e)=>t.ai??e.ai,browser:(t,e)=>t.browser??e.browser};function dbe(t,e,r){if(DK[r]){let i=DK[r];return i(t,e)}let o=t[r],n=e[r];if(o!==n)throw new Error(`Metadata values for key "${r}" do not match: "${o}" vs "${n}"`);return o}var OI=class extends Error{constructor(e,r){let o=`${e} contains invalid Momentic results: ${r}. Please ensure that the path points to a folder containing only valid results. If you passed \`--output-dir test-results/results-1\` to the \`run\` command, your results path for merging should be \`test-results\`.`;super(o),this.name="InvalidMomenticResultsPathError";}};function LK(t,e){try{let r=sr__default.join(e,ro);return Em.parse(JSON.parse(so.readFileSync(r,"utf-8")))}catch{throw new OI(t,e)}}function kK(t,e,r){let o=randomUUID(),n=t.child({runGroupId:o});so.rmSync(e,{recursive:true,force:true});let i=so.readdirSync(r).filter(c=>!NK.has(c)).map(c=>sr__default.join(r,c));if(i.length===0)throw new Error(`No run groups found in results path: ${r}`);so.mkdirSync(e,{recursive:true});let a={...LK(r,i[0]),id:o};for(let c of i){let l=sr__default.join(c,on);if(!so.existsSync(l))continue;let u=LK(r,c);n.info({oldRunGroupId:u.id},"Merging run groups");for(let m in u){if(m==="id")continue;let p=m;a[p]=dbe(a,u,p);}let d=so.readdirSync(l);for(let m of d){if(NK.has(m))continue;let p=sr__default.join(l,m),f=sr__default.join(e,on,m);so.cpSync(p,f,{recursive:true});}}let s=sr__default.join(e,ro);so.writeFileSync(s,JSON.stringify(a,null,2));}var oe="v1",NI="mobile-cli",Bu="0.97.3";var mbe=9e4,pbe=3,fbe=1500,hbe=15e3,go=class extends Error{status;rawError;constructor(e,r,o,n={}){super(o,n),this.status=e,this.rawError=r;}},DI=class extends Ft{constructor(e,r={}){super(e,r),this.name="PlanLimitExceededError";}};async function gbe(t){return t.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var LI=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger;}getHeaders(){let e={"Content-Type":"application/json"};return (e[iE]=Bu),(e[f$]=NI),e}async sendRequest(e,r){let{retries:o=pbe,requestTimeoutMs:n=mbe,initialRetryDelayMs:i=fbe,maxRetryDelayMs:a=hbe,onFailedRequest:s}=r,c=o,l=o,u,d={path:e,baseUrl:this.baseUrl,method:r.method};for(;c>0;)try{return c--,await this.sendSingleRequestWithOTEL(e,r,n)}catch(m){u=m;try{s?.(u);}catch{}if(m instanceof go&&m.status>=400&&m.status<500)throw m.status===402?new DI(m.rawError,{cause:m}):m;if(m instanceof Error&&m.name==="AbortError"&&(u=new kl),c===0)throw u;let p=l-c,f=Math.min(i*Math.pow(2,p-1),a);await new Promise(h=>setTimeout(h,f));}throw this.logger.warn({...d,err:u},"Got fatal error response from Momentic server"),u}async sendSingleRequestWithOTEL(e,r,o){let n=Sbe(e);return Ji({name:`cli.api.${r.method.toLowerCase()}.${n}`,serviceName:"api-server",kind:"client",attributes:{"http.request.method":r.method,"url.path":n},fn:i=>this.sendSingleRequestHelper(e,r,o,a=>{i?.setAttribute("http.response.status_code",a);})})}async sendSingleRequestHelper(e,r,o,n){let i={path:e,baseUrl:this.baseUrl,method:r.method},a=new AbortController,s=setTimeout(()=>a.abort(),o),c=()=>a.abort();r.signal&&r.signal.addEventListener("abort",c,{once:true});let l=Date.now(),u={...this.getHeaders(),...r.extraHeaders};try{let d=await fetch(`${this.baseUrl}${e}`,{method:r.method,body:r.body?JSON.stringify(r.body):void 0,headers:u,signal:a.signal});if(n?.(d.status),!d.ok){let f=await gbe(d);throw new go(d.status,f,`Request to ${r.method} ${e} failed with status ${d.status}: ${f}`)}let m;if(d.status===204)m={};else if(r.responseType==="buffer"){let f=await d.arrayBuffer();m=Buffer.from(f);}else {let f=await d.text();try{m=JSON.parse(f);}catch{m=f;}}this.logger&&r.logResponse===!0&&m&&this.logger.debug({result:m,status:d.status,durationMs:Date.now()-l,...i},"Got response from Momentic server");let p=r.responseHeadersObject;return p&&d.headers.forEach((f,h)=>{p[h.toLowerCase()]=f;}),m}finally{clearTimeout(s),r.signal&&r.signal.removeEventListener("abort",c);}}};function Sbe(t){return (t.split("?")[0]??t).replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,":id")}var Za=class extends LI{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode;}getHeaders(){return {...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[p$]:this.mode??""}}};var d3="vercel.ai.error",bbe=Symbol.for(d3),FK,UK,zt=class m3 extends(UK=Error,FK=bbe,UK){constructor({name:e,message:r,cause:o}){super(r),this[FK]=true,this.name=e,this.cause=o;}static isInstance(e){return m3.hasMarker(e,d3)}static hasMarker(e,r){let o=Symbol.for(r);return e!=null&&typeof e=="object"&&o in e&&typeof e[o]=="boolean"&&e[o]===true}},p3="AI_APICallError",f3=`vercel.ai.error.${p3}`,ybe=Symbol.for(f3),BK,VK,Co=class extends(VK=zt,BK=ybe,VK){constructor({message:t,url:e,requestBodyValues:r,statusCode:o,responseHeaders:n,responseBody:i,cause:a,isRetryable:s=o!=null&&(o===408||o===409||o===429||o>=500),data:c}){super({name:p3,message:t,cause:a}),this[BK]=true,this.url=e,this.requestBodyValues=r,this.statusCode=o,this.responseHeaders=n,this.responseBody=i,this.isRetryable=s,this.data=c;}static isInstance(t){return zt.hasMarker(t,f3)}},h3="AI_EmptyResponseBodyError",g3=`vercel.ai.error.${h3}`,Ebe=Symbol.for(g3),zK,$K,S3=class extends($K=zt,zK=Ebe,$K){constructor({message:t="Empty response body"}={}){super({name:h3,message:t}),this[zK]=true;}static isInstance(t){return zt.hasMarker(t,g3)}};function b3(t){return t==null?"unknown error":typeof t=="string"?t:t instanceof Error?t.message:JSON.stringify(t)}var y3="AI_InvalidArgumentError",E3=`vercel.ai.error.${y3}`,Tbe=Symbol.for(E3),jK,HK,pv=class extends(HK=zt,jK=Tbe,HK){constructor({message:t,cause:e,argument:r}){super({name:y3,message:t,cause:e}),this[jK]=true,this.argument=r;}static isInstance(t){return zt.hasMarker(t,E3)}},T3="AI_InvalidPromptError",v3=`vercel.ai.error.${T3}`,vbe=Symbol.for(v3),GK,WK,C3=class extends(WK=zt,GK=vbe,WK){constructor({prompt:t,message:e,cause:r}){super({name:T3,message:`Invalid prompt: ${e}`,cause:r}),this[GK]=true,this.prompt=t;}static isInstance(t){return zt.hasMarker(t,v3)}},A3="AI_InvalidResponseDataError",w3=`vercel.ai.error.${A3}`,Cbe=Symbol.for(w3),qK,KK,fv=class extends(KK=zt,qK=Cbe,KK){constructor({data:t,message:e=`Invalid response data: ${JSON.stringify(t)}.`}){super({name:A3,message:e}),this[qK]=true,this.data=t;}static isInstance(t){return zt.hasMarker(t,w3)}},R3="AI_JSONParseError",_3=`vercel.ai.error.${R3}`,Abe=Symbol.for(_3),YK,XK,Vg=class extends(XK=zt,YK=Abe,XK){constructor({text:t,cause:e}){super({name:R3,message:`JSON parsing failed: Text: ${t}.
|
|
209
209
|
Error message: ${b3(e)}`,cause:e}),this[YK]=true,this.text=t;}static isInstance(t){return zt.hasMarker(t,_3)}},M3="AI_LoadAPIKeyError",x3=`vercel.ai.error.${M3}`,wbe=Symbol.for(x3),JK,ZK,zg=class extends(ZK=zt,JK=wbe,ZK){constructor({message:t}){super({name:M3,message:t}),this[JK]=true;}static isInstance(t){return zt.hasMarker(t,x3)}},k3="AI_TooManyEmbeddingValuesForCallError",F3=`vercel.ai.error.${k3}`,xbe=Symbol.for(F3),i3,a3,U3=class extends(a3=zt,i3=xbe,a3){constructor(t){super({name:k3,message:`Too many values for a single embedding call. The ${t.provider} model "${t.modelId}" can only embed up to ${t.maxEmbeddingsPerCall} values per call, but ${t.values.length} values were provided.`}),this[i3]=true,this.provider=t.provider,this.modelId=t.modelId,this.maxEmbeddingsPerCall=t.maxEmbeddingsPerCall,this.values=t.values;}static isInstance(t){return zt.hasMarker(t,F3)}},B3="AI_TypeValidationError",V3=`vercel.ai.error.${B3}`,Pbe=Symbol.for(V3),s3,l3,rc=class kI extends(l3=zt,s3=Pbe,l3){constructor({value:e,cause:r,context:o}){let n="Type validation failed";if(o?.field&&(n+=` for ${o.field}`),o?.entityName||o?.entityId){n+=" (";let i=[];o.entityName&&i.push(o.entityName),o.entityId&&i.push(`id: "${o.entityId}"`),n+=i.join(", "),n+=")";}super({name:B3,message:`${n}: Value: ${JSON.stringify(e)}.
|
|
210
210
|
Error message: ${b3(r)}`,cause:r}),this[s3]=true,this.value=e,this.context=o;}static isInstance(e){return zt.hasMarker(e,V3)}static wrap({value:e,cause:r,context:o}){var n,i,a;return kI.isInstance(r)&&r.value===e&&((n=r.context)==null?void 0:n.field)===o?.field&&((i=r.context)==null?void 0:i.entityName)===o?.entityName&&((a=r.context)==null?void 0:a.entityId)===o?.entityId?r:new kI({value:e,cause:r,context:o})}},z3="AI_UnsupportedFunctionalityError",$3=`vercel.ai.error.${z3}`,Ibe=Symbol.for($3),c3,u3,An=class extends(u3=zt,c3=Ibe,u3){constructor({functionality:t,message:e=`'${t}' functionality not supported.`}){super({name:z3,message:e}),this[c3]=true,this.functionality=t;}static isInstance(t){return zt.hasMarker(t,$3)}};var hv=class extends Error{constructor(e,r){super(e),this.name="ParseError",this.type=r.type,this.field=r.field,this.value=r.value,this.line=r.line;}};function FI(t){}function j3(t){if(typeof t=="function")throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");let{onEvent:e=FI,onError:r=FI,onRetry:o=FI,onComment:n}=t,i="",a=true,s,c="",l="";function u(h){let S=a?h.replace(/^\xEF\xBB\xBF/,""):h,[b,y]=Obe(`${i}${S}`);for(let T of b)d(T);i=y,a=false;}function d(h){if(h===""){p();return}if(h.startsWith(":")){n&&n(h.slice(h.startsWith(": ")?2:1));return}let S=h.indexOf(":");if(S!==-1){let b=h.slice(0,S),y=h[S+1]===" "?2:1,T=h.slice(S+y);m(b,T,h);return}m(h,"",h);}function m(h,S,b){switch(h){case "event":l=S;break;case "data":c=`${c}${S}
|
|
211
211
|
`;break;case "id":s=S.includes("\0")?void 0:S;break;case "retry":/^\d+$/.test(S)?o(parseInt(S,10)):r(new hv(`Invalid \`retry\` value: "${S}"`,{type:"invalid-retry",value:S,line:b}));break;default:r(new hv(`Unknown field "${h.length>20?`${h.slice(0,20)}\u2026`:h}"`,{type:"unknown-field",field:h,value:S,line:b}));break}}function p(){c.length>0&&e({id:s,event:l||void 0,data:c.endsWith(`
|
|
@@ -241,7 +241,7 @@ ${o}
|
|
|
241
241
|
`);return Tve(c,{borderStyle:e.unicode?"round":"classic",borderColor:e.colorLevel>0?"yellow":void 0,padding:1,margin:{left:2},textAlignment:"center"})}var vve="https://registry.npmjs.org",Cve=z.object({versions:z.record(z.string(),z.unknown().optional()).optional()});async function d4({packageName:t,currentVersion:e}){let r=await Q(fetch(`${vve}/${t}`),{milliseconds:5e3});if(!r.ok)throw new Error(`Got error status code ${r.status} ${r.statusText}`);let o=await r.json(),n=Cve.parse(o).versions;if(!n)throw new Error("Failed to fetch npm registry data. Skipping version check.");let i=ip.major(e),a=e;for(let s of Object.keys(n))ip.valid(s)&&ip.prerelease(s)===null&&ip.major(s)===i&&ip.gt(s,a)&&(a=s);return a}function m4(t){return {checkCLIVersion:e=>Ave({...t,logger:e}),getLatestCLIVersion:()=>d4({packageName:t.packageName,currentVersion:t.currentVersion})}}async function Ave(t){let e=t.screen??an();if(!(process.env.NO_UPDATE_NOTIFIER||e.ci||!e.isTTY))try{let r=await d4({packageName:t.packageName,currentVersion:t.currentVersion});if(ip.eq(t.currentVersion,r))return;let o=u4({currentVersion:t.currentVersion,latestVersion:r,changelogUrl:t.changelogUrl,updateCommand:t.updateCommand},e);I.log(`
|
|
242
242
|
${o}
|
|
243
243
|
`);}catch(r){t.logger.warn({err:r},"Failed to check CLI version against npm");}}var ap=25;function p4(t){let e="v2";return {v2ProjectConfig:{...t.config,fileFormat:e},migratedFilePaths:[]}}function f4(t){let e="v1";return {legacyProjectConfig:{...t.config,fileFormat:e},migratedFilePaths:[]}}function gO({project:t,newProjectConfig:e,fileFormatLabel:r,migratedFilePaths:o}){t.config=e,Fu(t.config,t.configFilePath),o.push(t.configFilePath),I.info(`Updated ${t.configFilePath} to use ${r} file format`),e.hooks?.postSave&&(I.info(`Running post-save hook for ${o.length} migrated files`),lK([...new Set(o)],e));}async function sp(t,e,r){for(let o=0;o<t.length;o+=e)await Promise.all(t.slice(o,o+e).map(r));}function SO(t){return t.upgradedAgents.length>0||t.enabledUseMemory||t.enabledFailureRecovery}function wve(t){let e=t.ai??={},r=e.agentConfig??={},o=[];for(let[a,s]of Object.entries(Bd)){let c=r[a];c!==s&&(c?.startsWith(`${s}.`)||(r[a]=s,o.push({type:a,newValue:s})));}let n=e.useMemory!==true;n&&(e.useMemory=true);let i=e.failureRecovery!==true;return i&&(e.failureRecovery=true),{upgradedAgents:o,enabledUseMemory:n,enabledFailureRecovery:i}}async function h4({project:t,dryRun:e,migrate:r}){let o=t.config.fileFormat!=="v2",n=wve(t.config);return o?{fileFormatChanged:o,aiSettings:n,migration:await r()}:(!e&&SO(n)&&Fu(t.config,t.configFilePath),{fileFormatChanged:false,aiSettings:n,migration:bO()})}function bO(){return {migratedTestPaths:[],migratedModulePaths:[],alreadyV2TestCount:0,alreadyV2ModuleCount:0}}function yO({summary:t,fileFormatChanged:e,aiSettings:r,dryRun:o,testNoun:n="test",moduleNoun:i="module"}){let a=o?"Would migrate":"Migrated",s=xu(n,t.migratedTestPaths.length),c=xu(i,t.migratedModulePaths.length);I.info(`${a} ${t.migratedTestPaths.length} ${s} and ${t.migratedModulePaths.length} ${c} to v2.`),(t.alreadyV2TestCount>0||t.alreadyV2ModuleCount>0)&&I.dimmed(` Skipped ${t.alreadyV2TestCount} already-v2 ${xu(n,t.alreadyV2TestCount)} and ${t.alreadyV2ModuleCount} already-v2 ${xu(i,t.alreadyV2ModuleCount)}.`),e&&I.dimmed(" + fileFormat: v2");for(let l of r.upgradedAgents)I.dimmed(` + ai.agentConfig.${l.type}: ${l.newValue}`);r.enabledUseMemory&&I.dimmed(" + ai.useMemory: true"),r.enabledFailureRecovery&&I.dimmed(" + ai.failureRecovery: true");}var xve=C__default.string().url();async function Uv(t){if(xve.safeParse(t).success){let e=new AbortController,r=setTimeout(()=>e.abort(),1e4),o;try{o=await fetch(t,{signal:e.signal});}catch(i){throw new M("UserInfrastructureError",`Fetch failed or timed out for URL: ${t}`,{errOptions:{cause:i}})}finally{clearTimeout(r);}if(!o.ok)throw new M("UserInfrastructureError",`Failed to fetch file from URL: ${t}, status: ${o.status}`);let n=await o.arrayBuffer();return Buffer.from(n).toString("base64")}if(!existsSync(t))throw new M("UserInfrastructureError",`File does not exist at path: ${t}`);return readFileSync(t).toString("base64")}var g4=1e3,S4=5e6,Ive=5*1024*1024;function EO(t,e){for(let r=0;r<t.length;r++){let o=t[r];try{if(o.data){let{jsonString:n}=sV(JSON.stringify(o.data),1e3);o.data=JSON.parse(n);}}catch(n){e.error({err:n},"Failed to serialize individual result output data"),o.data=`Result output data could not be serialized: ${n}`;}switch(o.type){case "MOBILE_PRESET_STEP":b4(o);break;case "MOBILE_AI_ACTION_STEP":case "MOBILE_MODULE_STEP":EO(o.steps,e);break;case "MOBILE_CONDITIONAL_STEP":o.assertionResult&&b4(o.assertionResult),EO(o.steps,e);break;default:{throw new Error("If Typescript complains about the line below, you missed a case or break in the switch above")}}}}function b4(t){let e=t.command;"cache"in e&&e.cache&&(e.cache=void 0);}function y4(t,e){let r=JSON.stringify(t),o=r.replaceAll("\\u0000","");if(r.length!==o.length){let n=r.indexOf("\\u0000");e.warn({input:r.slice(Math.max(0,n-500),Math.min(r.length,n+500))},"Database content violation: stripped unicode character from input");}return o}function Bv(t,e,r){let o=cloneDeep(t);if(EO(o,r),o.length>g4)return r.error("Database content violation: results too long, truncating before insertion"),o.slice(0,g4);let n=y4(o,r);if(n.length>S4)for(r.error({serializedLength:n.length,resultsArrayLength:o.length},"Database content violation: results too large, truncating before insertion");n.length>S4;)o.pop(),n=y4(o,r);let{jsonString:i}=sV(n,Ive);try{return e.array().parse(JSON.parse(i))}catch(a){throw r.error({serialized:n,err:a},"Could not parse serialized results into JSON structure after processing"),a}}function cc(t,e,r=.01){let o=Buffer.from(t,"base64"),n=Buffer.from(e,"base64"),i=PNG.sync.read(o),a=PNG.sync.read(n);if(i.width!==a.width||i.height!==a.height)return 100;let s=i.width,c=i.height,l=Buffer.alloc(s*c*4);return Ove(i.data,a.data,l,s,c,{threshold:r})/(s*c)*100}var v4=1e4,C4=2e4,kve=250,Fve=5e3,Uve=[/dbug Appium Creating hash file directory/];function Bve(t){return Uve.some(e=>e.test(t))}var Vve=createRequire(import.meta.url),zve=Vve.resolve("appium/build/lib/main.js");function $ve(t){let e=(t??"").toLowerCase();return {deviceOffline:e.includes("device offline"),instrumentationCrashed:e.includes("instrumentation process has been unexpectedly terminated"),uiAutomatorCrashed:e.includes("uiautomator2")&&(e.includes("instrumentation")||e.includes("not running")||e.includes("socket hang up"))}}async function TO(t){try{let e=await fetch(`http://localhost:${t}/status`,{method:"GET",signal:AbortSignal.timeout(Fve)}),r=await e.text();return {ok:!0,statusCode:e.status,body:r}}catch(e){return {ok:false,error:j(e)}}}async function jve({appiumPort:t,child:e}){let r=Date.now();for(;Date.now()-r<C4;){if(e.exitCode!==null)throw new Error(`Appium subprocess exited before becoming ready with exit code ${e.exitCode}`);if((await TO(t)).ok)return;await new Promise(n=>setTimeout(n,kve));}throw new Error(`Timed out waiting for Appium to become ready after ${C4}ms`)}async function A4({child:t,logger:e}){t.exitCode!==null||t.killed||(t.kill("SIGTERM"),await Q(new Promise(r=>{t.once("exit",()=>r());}),{milliseconds:v4,fallback:()=>{e.warn({timeoutMs:v4},"Appium subprocess close timed out; sending SIGKILL"),t.kill("SIGKILL");}}));}function w4(t,e,r,o){let n=createInterface({input:t,terminal:false}),i=[],a=c=>{let l=$ve(c);o.deviceOffline||=l.deviceOffline,o.instrumentationCrashed||=l.instrumentationCrashed,o.uiAutomatorCrashed||=l.uiAutomatorCrashed;},s=()=>{if(i.length===0)return;let c=i.join(`
|
|
244
|
-
`);a(c),e[r]({appium:true,logLine:c},"Appium log"),i.length=0;};n.on("line",c=>{if(!c.trim()||Bve(c))return;let l;try{l=JSON.parse(c);}catch{}l!==void 0?(s(),a(c),e[r]({appium:true,parsed:l},"Appium log")):(!/^\s/.test(c)&&i.length>0&&s(),i.push(c));}),n.on("close",s);}async function vO({logger:t,logLevel:e,appiumPort:r}){let o=Date.now(),n=spawn(process.execPath,[zve,"--address","127.0.0.1","--port",`${r}`,"--relaxed-security","--log-format","json","--log-level",e],{stdio:["ignore","pipe","pipe"],env:process.env}),i={deviceOffline:false,instrumentationCrashed:false,uiAutomatorCrashed:false};n.stdout&&w4(n.stdout,t,"info",i),n.stderr&&w4(n.stderr,t,"warn",i);try{await jve({appiumPort:r,child:n});}catch(a){throw await A4({child:n,logger:t}),a}return t.info({duration:Date.now()-o},"Started Appium server"),{close:()=>A4({child:n,logger:t}),appiumLogHints:i}}function _4(t){let e=j(t);return e.includes("/session")&&(e.toLowerCase().includes("timeout")||e.toLowerCase().includes("socket hang up"))}function Vv(t){return t instanceof Error?t.message.includes("Could not find a driver for automationName")||t.message.includes("Multiple drivers claim support for the same automationName"):false}async function Zve(t,e){let r=new Hve(e);return await r.start(),Xve.createInterface({input:r}).on("line",n=>{t.info({wdio:true,logLine:n},"WebdriverIO log");}),()=>r.quit()}async function Qve(t){let e=sr__default.join(tmpdir(),"momentic","wdio",randomUUID());mkdirSync(e,{recursive:true});let r=new Set,o=[],n=watch(e,async(i,a)=>{if(i!=="rename"||!a||r.has(a))return;r.add(a);let s=sr__default.join(e,a.toString());if(!existsSync(s)){r.delete(a);return}try{let c=await Zve(t,s);o.push(c);}catch(c){r.delete(a),t.warn({err:c,fileName:a},"Failed to start forwarding logs from new WDIO log file");}});return {stop:async()=>{n.close(),await Promise.all(o.map(i=>i().catch(a=>{t.warn({err:a},"Failed to stop forwarding logs from WDIO log file");})));},logDir:e}}async function M4({logger:t,callbacks:e,logLevel:r,wdioOpts:o}){let{onStatusUpdate:n,onFailure:i}=e,a=Math.floor(Math.random()*1e4)+4e4,s=await Hl(a,"appium"),{close:c,appiumLogHints:l}=await vO({logger:t,logLevel:r,appiumPort:s}),u=async()=>{try{await c();}catch(p){t.warn({err:p},"Failed to close Appium server");}},{logDir:d,stop:m}=await Qve(t);for(let p=1;p<=2;p++)try{p>1&&n("Retrying Appium session creation...");let f=Date.now(),h=await remote({connectionRetryTimeout:3e4,connectionRetryCount:0,...o,outputDir:d,hostname:"localhost",port:s,path:"/",protocol:"http",logLevel:r});return t.info({duration:Date.now()-f},"Created Wdio driver"),{driver:h,appiumServerClose:async()=>{await m(),await c();}}}catch(f){let h,S;try{let b=i?await i({err:f,attempt:p,appiumPort:s,appiumLogHints:l}):{shouldRetry:!1,recover:void 0};h=b.shouldRetry,S=b.recover;}catch(b){throw await m(),await u(),b}if(!h||p>=2)throw await m(),await u(),f;if(S)try{await S();}catch(b){t.warn({err:b},"Recovery failed before Appium restart");}await u(),{close:c,appiumLogHints:l}=await vO({logger:t,logLevel:r,appiumPort:s});}throw new Error("createWdioDriverWithRecovery: unexpected state")}function x4(t,e){let r=new Map;e.on("command",o=>{r.set(o.command,Date.now());}),e.on("result",o=>{let n=r.get(o.command);if(!n)return;let i=Date.now()-n;o.result instanceof Error?t.warn({err:o.result,command:o.command,args:o.body,durationMs:i},"Appium cmd failed"):i>1e4&&t.warn({command:o.command,args:o.body,durationMs:i},"Appium cmd took very long"),r.delete(o.command);});}var P4=1e4,eCe=15e3,tCe=15e3;function I4(t,e,r,o){let{onHeartbeatFailure:n,onHeartbeatRestored:i}=o||{},a=0,s=false,c,l,u=[];t.on("command",m=>{u.push(m.command);}),t.on("result",m=>{m.result instanceof Error||(l=Date.now());});async function d(){let m=eCe,p=Date.now()-(l??0);if(p>P4)try{await Q(e(),{milliseconds:tCe}),a>0&&(r.info("Driver heartbeat restored"),i?.()),a=0;}catch(f){a++;let h=f instanceof Error?f.message:`${f}`;if(r.warn({attempt:a,error:h,recentCommands:u},"Driver heartbeat failed"),a===3){let S="The driver appears unresponsive, indicating a possible emulator failure";r.error({err:f},S),I.error(S),n?.();}}else a>0&&(r.info("Driver heartbeat restored"),i?.()),a=0,m-=p;u=[],s||(c=setTimeout(()=>void d(),Math.max(m,P4)));}return d(),()=>{s=true,clearTimeout(c);}}async function lp(t,e,r,o){let{maxAttempts:n=3,signal:i,slowThresholdMs:a=3e3,initialBackoffMs:s=3e3,backoffMultiplier:c=2,attemptTimeoutMs:l=1e4,operationName:u}=r,d;for(let m=0;m<n;m++){i?.throwIfAborted();let p=o?.reconnectingPromise?.();if(p){t.info("Waiting for reconnect to finish before attempt");try{await p;}catch(h){t.error({err:h},"Error while waiting for reconnect");}}else n>1&&m===n-1&&o?.tryReconnect&&(t.info({attempt:m+1,maxAttempts:n},`Attempting reconnect before final attempt ${m+1}`),await o.tryReconnect(t));let f=Date.now();try{let h=await Q(e(),{milliseconds:l,signal:i,message:`${u} timed out after ${l}ms`}),S=Date.now()-f;return S>a&&t.warn({durationMs:S},`${u} took very long`),h}catch(h){if(i?.throwIfAborted(),d=h,m===n-1)throw t.error({err:h,attempt:m+1,maxAttempts:n},`${u} failed on final attempt`),h;if(!rCe(h))throw t.error({err:h,attempt:m+1,maxAttempts:n},`${u} failed and does not look retryable`),h;let S=Math.min(1e4,s*Math.pow(c,m));t.warn({err:h,attempt:m+1,maxAttempts:n,backoffMs:S},`${u} failed, sleeping ${S}ms for recovery`),await ce(S,i);}}throw d}function rCe(t){return t instanceof Error?["socket hang up","read ECONNRESET","timeout","timed out","UND_ERR_HEADERS_TIMEOUT"].some(r=>t.message.includes(r)):false}var oCe="NATIVE_APP",uc=class t{currentContext;driver;appiumClose;stopHeartbeat;initializationParams;reconnectingPromise;async close(){try{this.stopHeartbeat();}catch{}try{await this.appiumClose();}catch{}}startHeartbeat(e,r){return I4(this.driver,()=>this.healthcheck(),e,{...r,onHeartbeatFailure:()=>{r.onHeartbeatFailure?.(),this.reconnect(e).catch(o=>{e.error({err:o},"Failed to reconnect after heartbeat failure");});}})}constructor({logger:e,driver:r,appiumClose:o,callbacks:n,initializationParams:i}){this.initializationParams=i,this.driver=r,this.appiumClose=o,this.stopHeartbeat=this.startHeartbeat(e,n);}static async connectAppium(e){let{logger:r}=e,{driver:o,appiumServerClose:n}=await M4(e);return x4(r,o),{...e,driver:o,appiumClose:n,initializationParams:e}}async executeInNativeContext(e,r,o){return this.executeInContext(e,oCe,r,o)}async reconnect(e){if(e.info("Attempting to reconnect to Appium"),this.reconnectingPromise)return this.reconnectingPromise;this.reconnectingPromise=(async()=>{try{await this.close();}catch(i){e.error({err:i},"Error while closing Appium during reconnect");}this.initializationParams.callbacks.restartWda&&await this.initializationParams.callbacks.restartWda(e);let{driver:r,appiumClose:o,callbacks:n}=await t.connectAppium(this.initializationParams);this.currentContext=void 0,this.driver=r,this.appiumClose=o,this.stopHeartbeat=this.startHeartbeat(e,n);})();try{await this.reconnectingPromise;}finally{this.reconnectingPromise=void 0;}}async executeInContext(e,r,o,n){return lp(e,async()=>(this.currentContext!==r&&(e.info({from:this.currentContext,to:r},"Switching Appium context"),this.currentContext=void 0,await this.driver.switchContext(r),this.currentContext=r),await o(this.driver)),n,{reconnectingPromise:()=>this.reconnectingPromise,tryReconnect:async a=>{await this.reconnect(a);}})}};function cp({containerBounds:t,viewport:e,defaultThresholdPercent:r}){let o=e.width*e.height;if(o<=0)return r;let n=O4({start:t.left,size:t.width,maxSize:e.width}),i=O4({start:t.top,size:t.height,maxSize:e.height});if(n<=0||i<=0)return r;let a=Math.min(n*i/o,1);return r*a}function zv({currentPixelDelta:t,baseDirection:e,correctionDirection:r,correctionPixels:o}){let n=Math.abs(t),i;r===e?i=n+o:i=Math.max(0,n-o);let a;return t===0?a=e==="down"?1:-1:a=Math.sign(t),a*i}function dc({containerBounds:t,containerInsetRatio:e}){let r=t.height*e;return t.height-2*r}function $v({viewportTop:t,viewportBottom:e,elementHeight:r,targetTopRatio:o}){let n=Math.max(1,e-t),i=t+n*o,a=Math.max(t,e-r);return Math.max(t,Math.min(i,a))}function O4({start:t,size:e,maxSize:r}){let o=t+e;return Math.max(0,Math.min(o,r)-Math.max(t,0))}function N4(t){return t?.position?{...t,position:void 0}:t}function nCe(t){return t?.map(e=>({...e,requirements:N4(e.requirements)}))}function jv(t){return {...t,requirements:N4(t.requirements),requiredRelatedElements:nCe(t.requiredRelatedElements)}}function Hv(t){let{tracer:e,span:r,screenshot:o,emulatorState:n,logger:i}=t;if(e.storeTraceAsset)try{let a=randomUUID$1();e.storeTraceAsset({snapshotId:a,data:Buffer.from(o,"base64"),extension:"png"}),r.screenshotSnapshotId=a;let s=randomUUID$1();e.storeTraceAsset({snapshotId:s,data:Buffer.from(n),extension:"xml"}),r.emulatorStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}function Gv(t,e){return e.length*(t+50)+4e3}var iCe=["WebSocket was closed before the connection was","Intentional disconnect"];function Kg(t){return t instanceof Error&&iCe.some(e=>t.message.includes(e))}var CO=false,L4;try{let t=await import('@sentry/node');t.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",dist:"production",release:"mobile-cli-0.97.2",tracesSampleRate:0,sendDefaultPii:!0,beforeSend(e,r){return IW(r?.originalException)||OW(r?.originalException)||Jb(r?.originalException,Ft)||Kg(r?.originalException)?null:e}}),WG(t.captureException),L4=e=>{if(!e){t.setUser(null);return}t.setUser({id:e.userId,organizationId:e.orgId,...e.email&&{email:e.email}});},CO=!0;}catch{}var k4=t=>L4?.(t);var aCe="https://api.momentic.ai";function F4(t){let e=process.env.MOMENTIC_API_KEY??Pv();if(!e)return;let r=(process.env.MOMENTIC_SERVER??Iv()??aCe).replace(/\/+$/,"");return new pr({apiKey:e,baseUrl:r,logger:t})}function U4({apiClient:t,logger:e}){let r=Router();return r.get("/:id",async(o,n)=>{let{id:i}=o.params;if(!i){n.status(400).json({error:"Missing screenshot ID"});return}if(!t){n.status(401).json({error:"Missing Momentic API key"});return}try{let{data:a,contentType:s}=await t.fetchOnDemandScreenshot(i);n.setHeader("Content-Type",s),n.send(a);}catch(a){e.error({err:a,screenshotId:i},"Failed to proxy on-demand screenshot"),n.status(502).json({error:"Failed to fetch screenshot"});}}),r}function B4(t){let e=Router(),r=sr__default.join(t,on);return e.get("/",async(o,n)=>{try{let i=uCe(t);if(!i){n.status(404).json({error:"No run group found"});return}if(!so.existsSync(r)){n.status(404).json({error:"No runs found for run group"});return}let a=dCe(r,i),s={...i,id:i.id??"local-run-group",createdAt:i.startedAt,runs:a};n.status(200).json(s);}catch(i){n.status(500).json({error:`Error loading run group: ${i.message}`});}}),e}function uCe(t){let e=sr__default.join(t,ro);if(!so.existsSync(e))return I.error("Run group metadata file not found"),null;try{let r=so.readFileSync(e,"utf-8");return Em.parse(JSON.parse(r))}catch(r){return I.error({err:r},"Error reading run group metadata"),null}}function dCe(t,e){let r=so.readdirSync(t).filter(n=>n.endsWith(".zip")).sort((n,i)=>{let a=so.statSync(sr__default.join(t,n));return so.statSync(sr__default.join(t,i)).mtime.getTime()-a.mtime.getTime()}),o=[];for(let n of r){let i=sr__default.join(t,n),a=n.replace(/\.zip$/i,"");o.push(mCe(i,a,e));}return o}function mCe(t,e,r){let o=new GY(t),n=o.getEntry(ro);if(!n)throw new Error(`No entry found for file ${t}/${ro}`);try{let i=n.getData().toString("utf-8"),a=JSON.parse(i),s=s2.parse(a),c=fCe(o,t);return Eq(s,e,{runGroupMetadata:r,runAttempts:c,organizationId:"local"})}catch(i){throw I.error({err:i,zipPath:t},`Error parsing ${ro} for run`),new Error(`Error parsing ${ro} for run ${t}`,{cause:i})}}var pCe=/^attempts\/(\d+)\/metadata\.json$/;function fCe(t,e){let r=[];for(let n of t.getEntries()){let i=pCe.exec(n.entryName);!i||!i[1]||r.push({index:parseInt(i[1],10),entry:n});}r.sort((n,i)=>n.index-i.index);let o=[];for(let{entry:n}of r){let i=hCe(n,e);!i||!i.id||o.push({id:i.id,status:i.status,startedAt:i.startedAt,finishedAt:i.finishedAt??null});}return o}function hCe(t,e){try{let r=t.getData().toString("utf-8");return i2.parse(JSON.parse(r))}catch(r){return I.warn({err:r,zipPath:e,entryName:t.entryName},"Skipping attempt metadata that failed to parse"),null}}function z4(t){let e=Router(),r=sr__default.join(t,on);return e.get("/:filename",(o,n)=>{let i=o.params.filename;if(!i||!i.endsWith(".zip")){n.status(404).send("Not found");return}let a=sr__default.join(r,i),s=sr__default.resolve(a),c=sr__default.resolve(r);if(!s.startsWith(c)){n.status(403).send("Forbidden");return}if(!so.existsSync(a)){n.status(404).send("File not found");return}try{n.setHeader("Content-Type","application/zip"),n.setHeader("Content-Disposition",`attachment; filename="${i}"`);let l=so.readFileSync(a);n.send(l);}catch(l){n.status(500).send(`Error reading file: ${l.message}`);}}),e}function $4(t){let e=Router();return e.get("*",(r,o)=>{let n=r.path==="/"?sr__default.join(t,"index.html"):sr__default.join(t,r.path),i=sr__default.resolve(n),a=sr__default.resolve(t);if(!i.startsWith(a)){o.status(403).send("Forbidden");return}if(!so.existsSync(n)&&(n=sr__default.join(t,"index.html"),!so.existsSync(n))){o.status(404).send("File not found");return}try{let s=sr__default.extname(n).toLowerCase(),c=mu[s]||"application/octet-stream";o.setHeader("Content-Type",c);let l=so.readFileSync(n);o.send(l);}catch(s){o.status(500).send(`Error reading file: ${s.message}`);}}),e}async function j4(t,e,r,o){Vm(t);let n=r??await Hl($y,"local-run-viewer-server"),i=Qre();i.use((s,c,l)=>{c.setHeader("Access-Control-Allow-Origin","*"),c.setHeader("Cache-Control","no-cache"),l();});let a=F4(t);return i.use("/api/runs",z4(e)),i.use("/api/run-group",B4(e)),i.use("/api/on-demand-screenshots",U4({apiClient:a,logger:t})),o&&i.use("/",$4(o)),new Promise((s,c)=>{let l=i.listen(n,()=>{let u=`http://localhost:${n}`;_u(async()=>{await l.close();}),s({port:n,url:u});});l.on("error",u=>{c(u);});})}async function RO(t){let{logger:e,staticDir:r,resultsPath:o,runId:n,port:i}=t,a=sr__default.resolve(o),s=sr__default.join(a,on),c;if(n){c=`${n.replace(/\.zip$/i,"")}.zip`;let u=sr__default.join(s,c);if(!so.existsSync(u)){let d=[];if(so.existsSync(s))for(let m of so.readdirSync(s))m.endsWith(".zip")&&d.push(m.replace(/\.zip$/i,""));I.error(`Run not found: ${c} in ${s}`),d.length>0&&I.error(`Available runs: ${d.join(", ")}`),process.exit(1);}}so.existsSync(r)||(I.error(`Static frontend files not found at ${r}. Please ensure the CLI is properly built.`),process.exit(1));try{let u=(await j4(e,a,i,r)).url;I.info(`Run viewer running at ${u}`);let d=new URL(u);c&&d.searchParams.set("zipUrl",`${u}/api/runs/${c}`),await nhe(d.toString());}catch(l){I.error(`Failed to start run viewer: ${l.message}`),process.exit(1);}}function vCe(){let t=process.env.ANDROID_HOME;if(!t)return "adb";let e=process.platform==="win32"?"adb.exe":"adb";return sr__default.join(t,"platform-tools",e)}async function Dr(t,e){let{timeoutMs:r=5e3,serial:o,throwOnError:n=false,encoding:i="utf8"}=e,a=vCe(),s=o?["-s",o,...t]:t;return await new Promise((c,l)=>{execFile$1(a,s,{encoding:i,timeout:r,maxBuffer:1024*1024*20},(u,d)=>{if(u){if(n){l(u);return}c(void 0);return}c(d);});})}var Kv=class t extends uc{get capabilities(){return this.driver.capabilities}get sessionId(){return this.driver.sessionId}get sessionOptions(){let{hostname:e,port:r,protocol:o}=this.driver.options;return {hostname:e,port:r,protocol:o}}static async init(e){let r=await uc.connectAppium(e);return new t(r)}async healthcheck(){await this.driver.execute("mobile: shell",{command:"echo",args:["ping"]});}};var _O=12e4,MCe=6e4,Yv=6,xCe=1e3;async function H4(t){let{apiClient:e,logger:r,creationOpts:o,onStatusUpdate:n,logLevel:i,orgId:a,sessionId:s,onConnectionStateChange:c}=t,{token:l,webRtcUrl:u,adbUrl:d,apiUrl:m,name:p,apkDownloadUrl:f,region:h,playwrightServerUrl:S}=await e.createAndroidEmulator({...o,hostname:hostname(),sessionId:s}),b;try{execSync("adb --version"),b="adb";}catch{if(process.env.ANDROID_HOME)b=sr__default.join(process.env.ANDROID_HOME,"platform-tools","adb");else throw new M("UserInfrastructureError","The ADB binary was not found in PATH and ANDROID_HOME is not set either")}r.info({creationOpts:o,emulatorName:p,apkToInstall:o.apkToInstall,region:h,apkDownloadUrl:f,sessionId:s,playwrightServerUrl:S},"Android instance creation ok");let y=await _t.recordDuration({fn:async()=>await createInstanceClient$1({adbUrl:d,apiUrl:m,token:l,logLevel:i,adbPath:b}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:android",`orgId:${a}`],timeoutMs:MCe}),T;c&&(T=y.onConnectionStateChange(c));let v=["https://storage.googleapis.com/mobile-drivers/appium-uiautomator2-server-v9.11.1.apk","https://storage.googleapis.com/mobile-drivers/appium-uiautomator2-server-debug-androidTest-v9.11.1.apk","https://storage.googleapis.com/mobile-drivers/settings_apk-debug-v7.0.22.apk"];f&&v.push(f);let w=o.apkToInstall?.channel,N=o.apkToInstall?.tag;n(`Installing APK${w?` with channel ${w}`:""}${N?` and tag ${N}`:""}`),await _t.recordDuration({fn:async()=>{await Promise.all(v.map(B=>PCe({client:y,url:B,logger:r,emulatorName:p})));},name:"test_event_duration",tags:["name:limbar-asset-upload",`orgId:${a}`]}),n("Starting ADB tunnel");let D=await _t.recordDuration({fn:async()=>await y.startAdbTunnel(),name:"test_event_duration",tags:["name:limbar-tunnel-connect",`orgId:${a}`]}),x=()=>{T?.(),D.close(),y.disconnect();},A;return S&&(n("Opening Playwright connection"),A=await _t.recordDuration({fn:async()=>{let B=await _android.connect(S,{timeout:3e4});return r.info("Playwright connection opened"),B},name:"test_event_duration",tags:["name:playwright-device-connect",`orgId:${a}`]})),{adbPort:D.address.port,close:x,limbarToken:l,limbarUrl:u,limbarRegion:h,limbarOsVersion:o.osVersion,emulatorName:p,playwrightDevice:A,limbarClient:y}}async function PCe(t){let{client:e,url:r,logger:o,emulatorName:n}=t,i;for(let a=1;a<=Yv;a++)try{await Q(e.sendAsset(r,_O),{milliseconds:_O,message:`Timed out after ${_O}ms sending asset to emulator ${n}: ${r}`});return}catch(s){if(i=s,a===Yv)break;let c=xCe*2**(a-1);o.warn({url:r,err:s,emulatorName:n,attempt:a,maxAttempts:Yv,backoffMs:c},"Failed to send asset to Limbar client; retrying after backoff"),await ce(c);}throw o.error({url:r,err:i,emulatorName:n,maxAttempts:Yv},"Failed to send asset to Limbar client (no more retries)"),new M("UserConfigurationError",`Failed to send asset to emulator ${n}: ${i}`)}var ICe=["If you see 'device offline' in ADB output, the emulator likely reset or crashed. Please start a new editor session by refreshing the page.","If Appium /status does not respond, the Appium server may not have started correctly. Please inspect the log output above for errors."];function G4(t,e){if(!t||!e)return;let r=t.split(/\r?\n/).map(o=>o.trim()).filter(o=>o.length>0);for(let o of r){if(o.startsWith("List of devices attached")||!o.startsWith(e))continue;let i=o.split(/\s+/)[1]?.toLowerCase();return i==="device"?"device":i==="offline"?"offline":i==="unauthorized"?"unauthorized":"unknown"}}function OCe(t){return t&&(/^\d{1,3}(\.\d{1,3}){3}:\d+$/.test(t)||/^localhost:\d+$/.test(t))?t:null}async function NCe(t){return {adbSerial:t,devices:await Dr(["devices","-l"],{timeoutMs:2500}),state:t?await Dr(["get-state"],{serial:t,timeoutMs:5e3}):void 0,bootCompleted:t?await Dr(["shell","getprop","sys.boot_completed"],{serial:t,timeoutMs:5e3}):void 0}}async function DCe({logger:t,adbSerial:e,adbSnapshot:r,appiumLogHints:o,transportMode:n}){let i=G4(r.devices,e);if(!(i==="offline"||o.deviceOffline||o.instrumentationCrashed||o.uiAutomatorCrashed))return;let s=n==="tunneled"?OCe(e):void 0;if(t.warn({adbSerial:e,deviceState:i,appiumLogHints:o,transportMode:n},"Attempting best-effort recovery of Android transport"),n==="tunneled"&&s?(await Dr(["start-server"],{timeoutMs:5e3}),await ce(500),await Dr(["disconnect",s],{timeoutMs:5e3}),await ce(500),await Dr(["connect",s],{timeoutMs:5e3}),await ce(500)):(await Dr(["kill-server"],{timeoutMs:5e3}),await ce(500),await Dr(["start-server"],{timeoutMs:5e3}),await ce(500),await Dr(["reconnect","offline"],{timeoutMs:5e3}),await ce(500)),e){let c=await Dr(["get-state"],{serial:e,timeoutMs:5e3});typeof c=="string"&&c.trim()==="device"&&(await Dr(["shell","pm","clear","io.appium.uiautomator2.server"],{serial:e,timeoutMs:5e3}),await Dr(["shell","pm","clear","io.appium.uiautomator2.server.test"],{serial:e,timeoutMs:5e3}));}}function W4({logger:t,onStatusUpdate:e,adbSerial:r,transportMode:o}){return async({err:n,attempt:i,appiumPort:a,appiumLogHints:s})=>{let c=n instanceof M?n:new M("UserInfrastructureError",j(n),{errOptions:{cause:n}}),l=await TO(a),u=await NCe(r),d=G4(u.devices,r);t.error({err:n,appiumPort:a,appiumStatus:l,adbSnapshot:u,adbDeviceState:d,appiumLogHints:s},"Failed to create Appium WebDriver session"),e(`Appium session creation failed: ${j(n)}`);let m=i===1&&(_4(n)||Vv(n)||d==="offline"||s.instrumentationCrashed||s.deviceOffline);if(!m)throw I.error(`Failed to create Appium WebDriver session. Troubleshooting:
|
|
244
|
+
`);a(c),e[r]({appium:true,logLine:c},"Appium log"),i.length=0;};n.on("line",c=>{if(!c.trim()||Bve(c))return;let l;try{l=JSON.parse(c);}catch{}l!==void 0?(s(),a(c),e[r]({appium:true,parsed:l},"Appium log")):(!/^\s/.test(c)&&i.length>0&&s(),i.push(c));}),n.on("close",s);}async function vO({logger:t,logLevel:e,appiumPort:r}){let o=Date.now(),n=spawn(process.execPath,[zve,"--address","127.0.0.1","--port",`${r}`,"--relaxed-security","--log-format","json","--log-level",e],{stdio:["ignore","pipe","pipe"],env:process.env}),i={deviceOffline:false,instrumentationCrashed:false,uiAutomatorCrashed:false};n.stdout&&w4(n.stdout,t,"info",i),n.stderr&&w4(n.stderr,t,"warn",i);try{await jve({appiumPort:r,child:n});}catch(a){throw await A4({child:n,logger:t}),a}return t.info({duration:Date.now()-o},"Started Appium server"),{close:()=>A4({child:n,logger:t}),appiumLogHints:i}}function _4(t){let e=j(t);return e.includes("/session")&&(e.toLowerCase().includes("timeout")||e.toLowerCase().includes("socket hang up"))}function Vv(t){return t instanceof Error?t.message.includes("Could not find a driver for automationName")||t.message.includes("Multiple drivers claim support for the same automationName"):false}async function Zve(t,e){let r=new Hve(e);return await r.start(),Xve.createInterface({input:r}).on("line",n=>{t.info({wdio:true,logLine:n},"WebdriverIO log");}),()=>r.quit()}async function Qve(t){let e=sr__default.join(tmpdir(),"momentic","wdio",randomUUID());mkdirSync(e,{recursive:true});let r=new Set,o=[],n=watch(e,async(i,a)=>{if(i!=="rename"||!a||r.has(a))return;r.add(a);let s=sr__default.join(e,a.toString());if(!existsSync(s)){r.delete(a);return}try{let c=await Zve(t,s);o.push(c);}catch(c){r.delete(a),t.warn({err:c,fileName:a},"Failed to start forwarding logs from new WDIO log file");}});return {stop:async()=>{n.close(),await Promise.all(o.map(i=>i().catch(a=>{t.warn({err:a},"Failed to stop forwarding logs from WDIO log file");})));},logDir:e}}async function M4({logger:t,callbacks:e,logLevel:r,wdioOpts:o}){let{onStatusUpdate:n,onFailure:i}=e,a=Math.floor(Math.random()*1e4)+4e4,s=await Hl(a,"appium"),{close:c,appiumLogHints:l}=await vO({logger:t,logLevel:r,appiumPort:s}),u=async()=>{try{await c();}catch(p){t.warn({err:p},"Failed to close Appium server");}},{logDir:d,stop:m}=await Qve(t);for(let p=1;p<=2;p++)try{p>1&&n("Retrying Appium session creation...");let f=Date.now(),h=await remote({connectionRetryTimeout:3e4,connectionRetryCount:0,...o,outputDir:d,hostname:"localhost",port:s,path:"/",protocol:"http",logLevel:r});return t.info({duration:Date.now()-f},"Created Wdio driver"),{driver:h,appiumServerClose:async()=>{await m(),await c();}}}catch(f){let h,S;try{let b=i?await i({err:f,attempt:p,appiumPort:s,appiumLogHints:l}):{shouldRetry:!1,recover:void 0};h=b.shouldRetry,S=b.recover;}catch(b){throw await m(),await u(),b}if(!h||p>=2)throw await m(),await u(),f;if(S)try{await S();}catch(b){t.warn({err:b},"Recovery failed before Appium restart");}await u(),{close:c,appiumLogHints:l}=await vO({logger:t,logLevel:r,appiumPort:s});}throw new Error("createWdioDriverWithRecovery: unexpected state")}function x4(t,e){let r=new Map;e.on("command",o=>{r.set(o.command,Date.now());}),e.on("result",o=>{let n=r.get(o.command);if(!n)return;let i=Date.now()-n;o.result instanceof Error?t.warn({err:o.result,command:o.command,args:o.body,durationMs:i},"Appium cmd failed"):i>1e4&&t.warn({command:o.command,args:o.body,durationMs:i},"Appium cmd took very long"),r.delete(o.command);});}var P4=1e4,eCe=15e3,tCe=15e3;function I4(t,e,r,o){let{onHeartbeatFailure:n,onHeartbeatRestored:i}=o||{},a=0,s=false,c,l,u=[];t.on("command",m=>{u.push(m.command);}),t.on("result",m=>{m.result instanceof Error||(l=Date.now());});async function d(){let m=eCe,p=Date.now()-(l??0);if(p>P4)try{await Q(e(),{milliseconds:tCe}),a>0&&(r.info("Driver heartbeat restored"),i?.()),a=0;}catch(f){a++;let h=f instanceof Error?f.message:`${f}`;if(r.warn({attempt:a,error:h,recentCommands:u},"Driver heartbeat failed"),a===3){let S="The driver appears unresponsive, indicating a possible emulator failure";r.error({err:f},S),I.error(S),n?.();}}else a>0&&(r.info("Driver heartbeat restored"),i?.()),a=0,m-=p;u=[],s||(c=setTimeout(()=>void d(),Math.max(m,P4)));}return d(),()=>{s=true,clearTimeout(c);}}async function lp(t,e,r,o){let{maxAttempts:n=3,signal:i,slowThresholdMs:a=3e3,initialBackoffMs:s=3e3,backoffMultiplier:c=2,attemptTimeoutMs:l=1e4,operationName:u}=r,d;for(let m=0;m<n;m++){i?.throwIfAborted();let p=o?.reconnectingPromise?.();if(p){t.info("Waiting for reconnect to finish before attempt");try{await p;}catch(h){t.error({err:h},"Error while waiting for reconnect");}}else n>1&&m===n-1&&o?.tryReconnect&&(t.info({attempt:m+1,maxAttempts:n},`Attempting reconnect before final attempt ${m+1}`),await o.tryReconnect(t));let f=Date.now();try{let h=await Q(e(),{milliseconds:l,signal:i,message:`${u} timed out after ${l}ms`}),S=Date.now()-f;return S>a&&t.warn({durationMs:S},`${u} took very long`),h}catch(h){if(i?.throwIfAborted(),d=h,m===n-1)throw t.error({err:h,attempt:m+1,maxAttempts:n},`${u} failed on final attempt`),h;if(!rCe(h))throw t.error({err:h,attempt:m+1,maxAttempts:n},`${u} failed and does not look retryable`),h;let S=Math.min(1e4,s*Math.pow(c,m));t.warn({err:h,attempt:m+1,maxAttempts:n,backoffMs:S},`${u} failed, sleeping ${S}ms for recovery`),await ce(S,i);}}throw d}function rCe(t){return t instanceof Error?["socket hang up","read ECONNRESET","timeout","timed out","UND_ERR_HEADERS_TIMEOUT"].some(r=>t.message.includes(r)):false}var oCe="NATIVE_APP",uc=class t{currentContext;driver;appiumClose;stopHeartbeat;initializationParams;reconnectingPromise;async close(){try{this.stopHeartbeat();}catch{}try{await this.appiumClose();}catch{}}startHeartbeat(e,r){return I4(this.driver,()=>this.healthcheck(),e,{...r,onHeartbeatFailure:()=>{r.onHeartbeatFailure?.(),this.reconnect(e).catch(o=>{e.error({err:o},"Failed to reconnect after heartbeat failure");});}})}constructor({logger:e,driver:r,appiumClose:o,callbacks:n,initializationParams:i}){this.initializationParams=i,this.driver=r,this.appiumClose=o,this.stopHeartbeat=this.startHeartbeat(e,n);}static async connectAppium(e){let{logger:r}=e,{driver:o,appiumServerClose:n}=await M4(e);return x4(r,o),{...e,driver:o,appiumClose:n,initializationParams:e}}async executeInNativeContext(e,r,o){return this.executeInContext(e,oCe,r,o)}async reconnect(e){if(e.info("Attempting to reconnect to Appium"),this.reconnectingPromise)return this.reconnectingPromise;this.reconnectingPromise=(async()=>{try{await this.close();}catch(i){e.error({err:i},"Error while closing Appium during reconnect");}this.initializationParams.callbacks.restartWda&&await this.initializationParams.callbacks.restartWda(e);let{driver:r,appiumClose:o,callbacks:n}=await t.connectAppium(this.initializationParams);this.currentContext=void 0,this.driver=r,this.appiumClose=o,this.stopHeartbeat=this.startHeartbeat(e,n);})();try{await this.reconnectingPromise;}finally{this.reconnectingPromise=void 0;}}async executeInContext(e,r,o,n){return lp(e,async()=>(this.currentContext!==r&&(e.info({from:this.currentContext,to:r},"Switching Appium context"),this.currentContext=void 0,await this.driver.switchContext(r),this.currentContext=r),await o(this.driver)),n,{reconnectingPromise:()=>this.reconnectingPromise,tryReconnect:async a=>{await this.reconnect(a);}})}};function cp({containerBounds:t,viewport:e,defaultThresholdPercent:r}){let o=e.width*e.height;if(o<=0)return r;let n=O4({start:t.left,size:t.width,maxSize:e.width}),i=O4({start:t.top,size:t.height,maxSize:e.height});if(n<=0||i<=0)return r;let a=Math.min(n*i/o,1);return r*a}function zv({currentPixelDelta:t,baseDirection:e,correctionDirection:r,correctionPixels:o}){let n=Math.abs(t),i;r===e?i=n+o:i=Math.max(0,n-o);let a;return t===0?a=e==="down"?1:-1:a=Math.sign(t),a*i}function dc({containerBounds:t,containerInsetRatio:e}){let r=t.height*e;return t.height-2*r}function $v({viewportTop:t,viewportBottom:e,elementHeight:r,targetTopRatio:o}){let n=Math.max(1,e-t),i=t+n*o,a=Math.max(t,e-r);return Math.max(t,Math.min(i,a))}function O4({start:t,size:e,maxSize:r}){let o=t+e;return Math.max(0,Math.min(o,r)-Math.max(t,0))}function N4(t){return t?.position?{...t,position:void 0}:t}function nCe(t){return t?.map(e=>({...e,requirements:N4(e.requirements)}))}function jv(t){return {...t,requirements:N4(t.requirements),requiredRelatedElements:nCe(t.requiredRelatedElements)}}function Hv(t){let{tracer:e,span:r,screenshot:o,emulatorState:n,logger:i}=t;if(e.storeTraceAsset)try{let a=randomUUID$1();e.storeTraceAsset({snapshotId:a,data:Buffer.from(o,"base64"),extension:"png"}),r.screenshotSnapshotId=a;let s=randomUUID$1();e.storeTraceAsset({snapshotId:s,data:Buffer.from(n),extension:"xml"}),r.emulatorStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}function Gv(t,e){return e.length*(t+50)+4e3}var iCe=["WebSocket was closed before the connection was","Intentional disconnect"];function Kg(t){return t instanceof Error&&iCe.some(e=>t.message.includes(e))}var CO=false,L4;try{let t=await import('@sentry/node');t.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",dist:"production",release:"mobile-cli-0.97.3",tracesSampleRate:0,sendDefaultPii:!0,beforeSend(e,r){return IW(r?.originalException)||OW(r?.originalException)||Jb(r?.originalException,Ft)||Kg(r?.originalException)?null:e}}),WG(t.captureException),L4=e=>{if(!e){t.setUser(null);return}t.setUser({id:e.userId,organizationId:e.orgId,...e.email&&{email:e.email}});},CO=!0;}catch{}var k4=t=>L4?.(t);var aCe="https://api.momentic.ai";function F4(t){let e=process.env.MOMENTIC_API_KEY??Pv();if(!e)return;let r=(process.env.MOMENTIC_SERVER??Iv()??aCe).replace(/\/+$/,"");return new pr({apiKey:e,baseUrl:r,logger:t})}function U4({apiClient:t,logger:e}){let r=Router();return r.get("/:id",async(o,n)=>{let{id:i}=o.params;if(!i){n.status(400).json({error:"Missing screenshot ID"});return}if(!t){n.status(401).json({error:"Missing Momentic API key"});return}try{let{data:a,contentType:s}=await t.fetchOnDemandScreenshot(i);n.setHeader("Content-Type",s),n.send(a);}catch(a){e.error({err:a,screenshotId:i},"Failed to proxy on-demand screenshot"),n.status(502).json({error:"Failed to fetch screenshot"});}}),r}function B4(t){let e=Router(),r=sr__default.join(t,on);return e.get("/",async(o,n)=>{try{let i=uCe(t);if(!i){n.status(404).json({error:"No run group found"});return}if(!so.existsSync(r)){n.status(404).json({error:"No runs found for run group"});return}let a=dCe(r,i),s={...i,id:i.id??"local-run-group",createdAt:i.startedAt,runs:a};n.status(200).json(s);}catch(i){n.status(500).json({error:`Error loading run group: ${i.message}`});}}),e}function uCe(t){let e=sr__default.join(t,ro);if(!so.existsSync(e))return I.error("Run group metadata file not found"),null;try{let r=so.readFileSync(e,"utf-8");return Em.parse(JSON.parse(r))}catch(r){return I.error({err:r},"Error reading run group metadata"),null}}function dCe(t,e){let r=so.readdirSync(t).filter(n=>n.endsWith(".zip")).sort((n,i)=>{let a=so.statSync(sr__default.join(t,n));return so.statSync(sr__default.join(t,i)).mtime.getTime()-a.mtime.getTime()}),o=[];for(let n of r){let i=sr__default.join(t,n),a=n.replace(/\.zip$/i,"");o.push(mCe(i,a,e));}return o}function mCe(t,e,r){let o=new GY(t),n=o.getEntry(ro);if(!n)throw new Error(`No entry found for file ${t}/${ro}`);try{let i=n.getData().toString("utf-8"),a=JSON.parse(i),s=s2.parse(a),c=fCe(o,t);return Eq(s,e,{runGroupMetadata:r,runAttempts:c,organizationId:"local"})}catch(i){throw I.error({err:i,zipPath:t},`Error parsing ${ro} for run`),new Error(`Error parsing ${ro} for run ${t}`,{cause:i})}}var pCe=/^attempts\/(\d+)\/metadata\.json$/;function fCe(t,e){let r=[];for(let n of t.getEntries()){let i=pCe.exec(n.entryName);!i||!i[1]||r.push({index:parseInt(i[1],10),entry:n});}r.sort((n,i)=>n.index-i.index);let o=[];for(let{entry:n}of r){let i=hCe(n,e);!i||!i.id||o.push({id:i.id,status:i.status,startedAt:i.startedAt,finishedAt:i.finishedAt??null});}return o}function hCe(t,e){try{let r=t.getData().toString("utf-8");return i2.parse(JSON.parse(r))}catch(r){return I.warn({err:r,zipPath:e,entryName:t.entryName},"Skipping attempt metadata that failed to parse"),null}}function z4(t){let e=Router(),r=sr__default.join(t,on);return e.get("/:filename",(o,n)=>{let i=o.params.filename;if(!i||!i.endsWith(".zip")){n.status(404).send("Not found");return}let a=sr__default.join(r,i),s=sr__default.resolve(a),c=sr__default.resolve(r);if(!s.startsWith(c)){n.status(403).send("Forbidden");return}if(!so.existsSync(a)){n.status(404).send("File not found");return}try{n.setHeader("Content-Type","application/zip"),n.setHeader("Content-Disposition",`attachment; filename="${i}"`);let l=so.readFileSync(a);n.send(l);}catch(l){n.status(500).send(`Error reading file: ${l.message}`);}}),e}function $4(t){let e=Router();return e.get("*",(r,o)=>{let n=r.path==="/"?sr__default.join(t,"index.html"):sr__default.join(t,r.path),i=sr__default.resolve(n),a=sr__default.resolve(t);if(!i.startsWith(a)){o.status(403).send("Forbidden");return}if(!so.existsSync(n)&&(n=sr__default.join(t,"index.html"),!so.existsSync(n))){o.status(404).send("File not found");return}try{let s=sr__default.extname(n).toLowerCase(),c=mu[s]||"application/octet-stream";o.setHeader("Content-Type",c);let l=so.readFileSync(n);o.send(l);}catch(s){o.status(500).send(`Error reading file: ${s.message}`);}}),e}async function j4(t,e,r,o){Vm(t);let n=r??await Hl($y,"local-run-viewer-server"),i=Qre();i.use((s,c,l)=>{c.setHeader("Access-Control-Allow-Origin","*"),c.setHeader("Cache-Control","no-cache"),l();});let a=F4(t);return i.use("/api/runs",z4(e)),i.use("/api/run-group",B4(e)),i.use("/api/on-demand-screenshots",U4({apiClient:a,logger:t})),o&&i.use("/",$4(o)),new Promise((s,c)=>{let l=i.listen(n,()=>{let u=`http://localhost:${n}`;_u(async()=>{await l.close();}),s({port:n,url:u});});l.on("error",u=>{c(u);});})}async function RO(t){let{logger:e,staticDir:r,resultsPath:o,runId:n,port:i}=t,a=sr__default.resolve(o),s=sr__default.join(a,on),c;if(n){c=`${n.replace(/\.zip$/i,"")}.zip`;let u=sr__default.join(s,c);if(!so.existsSync(u)){let d=[];if(so.existsSync(s))for(let m of so.readdirSync(s))m.endsWith(".zip")&&d.push(m.replace(/\.zip$/i,""));I.error(`Run not found: ${c} in ${s}`),d.length>0&&I.error(`Available runs: ${d.join(", ")}`),process.exit(1);}}so.existsSync(r)||(I.error(`Static frontend files not found at ${r}. Please ensure the CLI is properly built.`),process.exit(1));try{let u=(await j4(e,a,i,r)).url;I.info(`Run viewer running at ${u}`);let d=new URL(u);c&&d.searchParams.set("zipUrl",`${u}/api/runs/${c}`),await nhe(d.toString());}catch(l){I.error(`Failed to start run viewer: ${l.message}`),process.exit(1);}}function vCe(){let t=process.env.ANDROID_HOME;if(!t)return "adb";let e=process.platform==="win32"?"adb.exe":"adb";return sr__default.join(t,"platform-tools",e)}async function Dr(t,e){let{timeoutMs:r=5e3,serial:o,throwOnError:n=false,encoding:i="utf8"}=e,a=vCe(),s=o?["-s",o,...t]:t;return await new Promise((c,l)=>{execFile$1(a,s,{encoding:i,timeout:r,maxBuffer:1024*1024*20},(u,d)=>{if(u){if(n){l(u);return}c(void 0);return}c(d);});})}var Kv=class t extends uc{get capabilities(){return this.driver.capabilities}get sessionId(){return this.driver.sessionId}get sessionOptions(){let{hostname:e,port:r,protocol:o}=this.driver.options;return {hostname:e,port:r,protocol:o}}static async init(e){let r=await uc.connectAppium(e);return new t(r)}async healthcheck(){await this.driver.execute("mobile: shell",{command:"echo",args:["ping"]});}};var _O=12e4,MCe=6e4,Yv=6,xCe=1e3;async function H4(t){let{apiClient:e,logger:r,creationOpts:o,onStatusUpdate:n,logLevel:i,orgId:a,sessionId:s,onConnectionStateChange:c}=t,{token:l,webRtcUrl:u,adbUrl:d,apiUrl:m,name:p,apkDownloadUrl:f,region:h,playwrightServerUrl:S}=await e.createAndroidEmulator({...o,hostname:hostname(),sessionId:s}),b;try{execSync("adb --version"),b="adb";}catch{if(process.env.ANDROID_HOME)b=sr__default.join(process.env.ANDROID_HOME,"platform-tools","adb");else throw new M("UserInfrastructureError","The ADB binary was not found in PATH and ANDROID_HOME is not set either")}r.info({creationOpts:o,emulatorName:p,apkToInstall:o.apkToInstall,region:h,apkDownloadUrl:f,sessionId:s,playwrightServerUrl:S},"Android instance creation ok");let y=await _t.recordDuration({fn:async()=>await createInstanceClient$1({adbUrl:d,apiUrl:m,token:l,logLevel:i,adbPath:b}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:android",`orgId:${a}`],timeoutMs:MCe}),T;c&&(T=y.onConnectionStateChange(c));let v=["https://storage.googleapis.com/mobile-drivers/appium-uiautomator2-server-v9.11.1.apk","https://storage.googleapis.com/mobile-drivers/appium-uiautomator2-server-debug-androidTest-v9.11.1.apk","https://storage.googleapis.com/mobile-drivers/settings_apk-debug-v7.0.22.apk"];f&&v.push(f);let w=o.apkToInstall?.channel,N=o.apkToInstall?.tag;n(`Installing APK${w?` with channel ${w}`:""}${N?` and tag ${N}`:""}`),await _t.recordDuration({fn:async()=>{await Promise.all(v.map(B=>PCe({client:y,url:B,logger:r,emulatorName:p})));},name:"test_event_duration",tags:["name:limbar-asset-upload",`orgId:${a}`]}),n("Starting ADB tunnel");let D=await _t.recordDuration({fn:async()=>await y.startAdbTunnel(),name:"test_event_duration",tags:["name:limbar-tunnel-connect",`orgId:${a}`]}),x=()=>{T?.(),D.close(),y.disconnect();},A;return S&&(n("Opening Playwright connection"),A=await _t.recordDuration({fn:async()=>{let B=await _android.connect(S,{timeout:3e4});return r.info("Playwright connection opened"),B},name:"test_event_duration",tags:["name:playwright-device-connect",`orgId:${a}`]})),{adbPort:D.address.port,close:x,limbarToken:l,limbarUrl:u,limbarRegion:h,limbarOsVersion:o.osVersion,emulatorName:p,playwrightDevice:A,limbarClient:y}}async function PCe(t){let{client:e,url:r,logger:o,emulatorName:n}=t,i;for(let a=1;a<=Yv;a++)try{await Q(e.sendAsset(r,_O),{milliseconds:_O,message:`Timed out after ${_O}ms sending asset to emulator ${n}: ${r}`});return}catch(s){if(i=s,a===Yv)break;let c=xCe*2**(a-1);o.warn({url:r,err:s,emulatorName:n,attempt:a,maxAttempts:Yv,backoffMs:c},"Failed to send asset to Limbar client; retrying after backoff"),await ce(c);}throw o.error({url:r,err:i,emulatorName:n,maxAttempts:Yv},"Failed to send asset to Limbar client (no more retries)"),new M("UserConfigurationError",`Failed to send asset to emulator ${n}: ${i}`)}var ICe=["If you see 'device offline' in ADB output, the emulator likely reset or crashed. Please start a new editor session by refreshing the page.","If Appium /status does not respond, the Appium server may not have started correctly. Please inspect the log output above for errors."];function G4(t,e){if(!t||!e)return;let r=t.split(/\r?\n/).map(o=>o.trim()).filter(o=>o.length>0);for(let o of r){if(o.startsWith("List of devices attached")||!o.startsWith(e))continue;let i=o.split(/\s+/)[1]?.toLowerCase();return i==="device"?"device":i==="offline"?"offline":i==="unauthorized"?"unauthorized":"unknown"}}function OCe(t){return t&&(/^\d{1,3}(\.\d{1,3}){3}:\d+$/.test(t)||/^localhost:\d+$/.test(t))?t:null}async function NCe(t){return {adbSerial:t,devices:await Dr(["devices","-l"],{timeoutMs:2500}),state:t?await Dr(["get-state"],{serial:t,timeoutMs:5e3}):void 0,bootCompleted:t?await Dr(["shell","getprop","sys.boot_completed"],{serial:t,timeoutMs:5e3}):void 0}}async function DCe({logger:t,adbSerial:e,adbSnapshot:r,appiumLogHints:o,transportMode:n}){let i=G4(r.devices,e);if(!(i==="offline"||o.deviceOffline||o.instrumentationCrashed||o.uiAutomatorCrashed))return;let s=n==="tunneled"?OCe(e):void 0;if(t.warn({adbSerial:e,deviceState:i,appiumLogHints:o,transportMode:n},"Attempting best-effort recovery of Android transport"),n==="tunneled"&&s?(await Dr(["start-server"],{timeoutMs:5e3}),await ce(500),await Dr(["disconnect",s],{timeoutMs:5e3}),await ce(500),await Dr(["connect",s],{timeoutMs:5e3}),await ce(500)):(await Dr(["kill-server"],{timeoutMs:5e3}),await ce(500),await Dr(["start-server"],{timeoutMs:5e3}),await ce(500),await Dr(["reconnect","offline"],{timeoutMs:5e3}),await ce(500)),e){let c=await Dr(["get-state"],{serial:e,timeoutMs:5e3});typeof c=="string"&&c.trim()==="device"&&(await Dr(["shell","pm","clear","io.appium.uiautomator2.server"],{serial:e,timeoutMs:5e3}),await Dr(["shell","pm","clear","io.appium.uiautomator2.server.test"],{serial:e,timeoutMs:5e3}));}}function W4({logger:t,onStatusUpdate:e,adbSerial:r,transportMode:o}){return async({err:n,attempt:i,appiumPort:a,appiumLogHints:s})=>{let c=n instanceof M?n:new M("UserInfrastructureError",j(n),{errOptions:{cause:n}}),l=await TO(a),u=await NCe(r),d=G4(u.devices,r);t.error({err:n,appiumPort:a,appiumStatus:l,adbSnapshot:u,adbDeviceState:d,appiumLogHints:s},"Failed to create Appium WebDriver session"),e(`Appium session creation failed: ${j(n)}`);let m=i===1&&(_4(n)||Vv(n)||d==="offline"||s.instrumentationCrashed||s.deviceOffline);if(!m)throw I.error(`Failed to create Appium WebDriver session. Troubleshooting:
|
|
245
245
|
- ${ICe.join(`
|
|
246
246
|
- `)}`),c;return {shouldRetry:m,recover:()=>DCe({logger:t,adbSerial:r,adbSnapshot:u,appiumLogHints:s,transportMode:o})}}}var q4=5e3;async function mp({callbacks:t,creationOpts:e,apiClient:r,logger:o,driverLogLevel:n,socket:i,orgId:a,sessionId:s}){let c=Date.now();o.info("Starting android driver creation");let l=[],u,d;if("avdId"in e)d=e;else {d=await H4({apiClient:r,logger:o,creationOpts:e,onStatusUpdate:t.onStatusUpdate,orgId:a,sessionId:s,onConnectionStateChange:t.onLimbarConnectionStateChange});let f=d.emulatorName,h=d.close;u=async()=>r.deleteAndroidEmulator(f),l.push(h),o=o.child({emulatorName:f}),(async()=>{try{let[S,b]=await Promise.allSettled([Fm("limserver-1.limrun.net"),Fm("125.253.92.199")]);o.info({limserver:S.status==="fulfilled"?S.value:S.reason,ip125:b.status==="fulfilled"?b.value:b.reason},"Limbar network diagnostics");}catch(S){o.warn({err:S},"Failed to run network diagnostics");}})();}let m=async()=>{let f=l.toReversed();u&&(f.push(u),u=void 0);let h=f.map(S=>Promise.resolve(S()).catch(b=>{AT(b)||o.warn({err:b},"Error running cleanup task");}));try{await Q(Promise.allSettled(h),{milliseconds:q4,message:`Android driver cleanup timed out after ${q4}ms`});}catch(S){o.warn({err:S},"Android driver cleanup timed out");}},p=async()=>{if(i&&!i.connected)throw await m(),new M("UserInfrastructureError","Client disconnected before Appium driver could be started, cleaning up...")};await p();try{let f=await UCe({logger:o,driverLogLevel:n,emulatorStart:c,emulatorCreationParams:d,apiClient:r,callbacks:t,creationOpts:e,orgId:a,sessionId:s}),h=f.driver;return l.push(f.appiumClose),await p(),{...d,...f,driver:h,cleanup:m}}catch(f){throw await m(),new M("UserInfrastructureError",`Failed to start Appium driver: ${f.message}`)}}async function UCe({logger:t,driverLogLevel:e="error",emulatorCreationParams:r,callbacks:o,creationOpts:n}){let i=[],{adbPort:a,emulatorName:s}=r,c,l="tunneled";if(!a){l="local";let f=0;for(;f<10;){let h=5555+Math.floor(Math.random()*30);if(h%2!==0&&(h=Math.min(h+1,5584)),await yT(h)&&await yT(h+1)){c=h,a=h+1;break}f+=1;}if(!a)throw new M("UserInfrastructureError",`Failed to find an available ADB port after ${f} attempts`)}s||(s=`emulator-${c}`,o.onStatusUpdate("Killing existing emulators..."),await K4(t),i.push(()=>K4(t)),o.onStatusUpdate("Starting new emulator..."));let u={platformName:"Android","appium:automationName":"UiAutomator2","appium:deviceName":"Android","appium:udid":`127.0.0.1:${a}`,"appium:adbExecTimeout":3e4,"appium:newCommandTimeout":3600,"appium:skipDeviceInitialization":true,"appium:skipServerInstallation":true,"appium:androidInstallTimeout":6e4,"appium:autoWebview":false,"appium:autoWebviewTimeout":0,"appium:clearDeviceLogsOnStart":true,"appium:ensureWebviewsHavePages":true,"appium:noReset":true,"appium:fullReset":false,"appium:dontStopAppOnReset":true,"appium:shouldTerminateApp":false,"appium:forceAppLaunch":false,"appium:skipUnlock":true},d={capabilities:u,connectionRetryTimeout:3e4,connectionRetryCount:3};if("avdId"in r){u["appium:avd"]=r.avdId,u["appium:avdLaunchTimeout"]=18e4,u["appium:avdReadyTimeout"]=18e4,u["appium:skipDeviceInitialization"]=false,u["appium:skipServerInstallation"]=false,u["appium:udid"]=void 0;let f=BCe();u["appium:avdArgs"]=`-port ${c} -memory ${f} -no-snapshot-save -no-boot-anim -noaudio`,d.connectionRetryTimeout=12e4,d.connectionRetryCount=3;}let m=du in r?s:`127.0.0.1:${a}`,p=await Kv.init({logger:t,callbacks:{...o,onFailure:W4({logger:t,onStatusUpdate:o.onStatusUpdate,adbSerial:m,transportMode:l})},logLevel:e,wdioOpts:d});try{if("avdId"in n){let b=n.apkFilePath?.trim();if(b){let y=sr__default.resolve(b);if(!so.existsSync(y))throw new M("UserConfigurationError",`APK not found at path: ${y}`);o.onStatusUpdate("Installing local APK...");let T=Date.now();try{await p.executeInNativeContext(t,v=>v.installApp(y),{operationName:"installApp"}),t.info({apkFilePath:y,installDurationMs:Date.now()-T},"Installed local APK");}catch(v){throw t.error({err:v,apkFilePath:y},"Failed to install local APK"),new M("UserConfigurationError",`Failed to install APK from ${y}: ${v.message}`)}}}let[f,h]=await Promise.all([Dr(["shell","wm","size"],{serial:m,timeoutMs:5e3}),Dr(["shell","wm","density"],{serial:m,timeoutMs:5e3}),p.executeInNativeContext(t,b=>b.updateSettings({enableMultiWindows:!0,waitForIdleTimeout:250,simpleBoundsCalculation:!0}),{operationName:"updateSettings"})]);return t.info({capabilities:u,emulatorName:s,viewport:{size:f?.trim(),density:h?.trim()}},"Started Appium driver"),{driver:p,appiumClose:async()=>{await p.close(),await Promise.all(i.map(b=>b()));},emulatorName:s,adbPort:a}}catch(f){throw t.error({err:f},"Failed to initialize emulator"),await p.close(),f}}async function K4(t){let o=(await Dr(["devices"],{timeoutMs:5e3})??"").split(`
|
|
247
247
|
`).map(n=>n.trim().split(/\s+/)[0]).filter(n=>!!n?.startsWith("emulator-"));await Promise.all(o.map(async n=>{t.info({emulatorName:n},"Killing emulator");let i=await Dr(["emu","kill"],{serial:n,timeoutMs:5e3});i&&t.warn({emulatorName:n,killResult:i},"Failed to kill emulator, continuing...");}));}function BCe(){let t=Math.floor(totalmem()/1024/1024),e=Math.floor(t/4);return Math.max(2048,Math.min(4096,Math.floor(e/256)*256))}var $Ce="If you do not have Java installed, please download the JDK 24 from https://www.oracle.com/java/technologies/downloads/, move it to your home directory, and then set the JAVA_HOME environment variable in your shell profile to the JDK path.",jCe="If you do not have Android Studio installed, please download it first from https://developer.android.com/studio and then follow all setup instructions in the Android Studio app.",HCe="Follow the instructions at https://developer.android.com/tools/variables to set the ANDROID_HOME environment variable.",J4="On Mac OS, the SDK is typically installed at /Users/<username>/Library/Android/sdk.",Z4="On Windows, the SDK is typically installed at C:\\Users\\<username>\\AppData\\Local\\Android\\Sdk.";function GCe(){if(!process.env.JAVA_HOME)I.warn("JAVA_HOME is not set. Some Appium drivers and Android tools may not work as expected.");else {process.platform==="darwin"&&/\.jdk\/?$/.test(process.env.JAVA_HOME)&&I.warn("JAVA_HOME appears to point at a *.jdk bundle, which is incorrect. The correct path should be formatted like '<bundle>/Contents/Home'.");let e=((r,o)=>join(r,"bin",process.platform==="win32"?`${o}.exe`:o))(process.env.JAVA_HOME,"java");existsSync(e)||I.warn(`JAVA_HOME does not appear to point to a valid Java installation: expected the 'java' binary to exist at ${e}`);}try{execSync("java --version",{stdio:"pipe",encoding:"utf-8"})||(I.error(`Could not find a Java installation. ${$Ce}`),process.exit(1));}catch(t){I.error(`Got error while checking if the Java JDK is installed: ${t}`),process.exit(1);}}function WCe(){process.env.ANDROID_HOME||(I.error(`The ANDROID_HOME environment variable is not set. ${HCe} ${platform()==="darwin"?J4:Z4}`),process.exit(1));}function qCe(){let t=process.env.ANDROID_HOME?`${process.env.ANDROID_HOME}/platform-tools/adb`:"adb";try{execSync(`${t} version`,{stdio:"pipe",encoding:"utf-8"})||(I.error(`Could not find the Android Debug Bridge (ADB) tool locally. This tool is included with Android Studio. ${jCe} Finally, ensure that the 'adb' command is available in your shell. ${platform()==="darwin"?J4:Z4}`),process.exit(1));}catch(e){I.error(`Got error while checking if ADB is installed: ${e}`),process.exit(1);}}function Q4(){GCe(),WCe(),qCe();}var ZCe=100,QCe=2500,e5=4e3,eAe="\u2026",tAe=1e3;async function Xv({driver:t,onLogs:e,logFilePath:r}){await t.execute("mobile: startLogsBroadcast");let o=r?so.createWriteStream(r,{flags:"a"}):void 0,n=[],i=()=>{n.length===0||!o||(o.write(n.join(`
|
|
@@ -5430,7 +5430,7 @@ ${t}`;case "ELEMENT_CHECK":return `${a6}
|
|
|
5430
5430
|
${t}`;default:return t}}async function Ii({frameConfig:t,action:e,browser:r}){let o=r.getActiveFrameConfig();t?r.setActiveFrameConfig(t):o?.type==="auto"&&r.setActiveFrameConfig(void 0);try{return await e()}finally{r.setActiveFrameConfig(o);}}var GRe=["NAVIGATE","NEW_TAB","CLOSE_TAB","TAB","REFRESH","WAIT_FOR_URL"];async function c6({beforeUrl:t,beforePages:e,browser:r,command:o,logger:n}){if(GRe.includes(o.type))return;await Lr().startAsyncSpan("AUTO_FOLLOW_NEW_TABS",async a=>{let l=("cache"in o&&o.cache&&"target"in o.cache?o.cache.target:void 0)?.nodeOnlySerializedHtml?.includes("<a")??false?300:3e3,u=Date.now(),d=0;for(n.info({command:o.type,beforePages:e,beforeUrl:t,timeout:l},"Checking for new tabs to auto-follow");d===0||Date.now()-u<l;){await ce(250),d++;let m=(await r.getOpenPages()).map(f=>f.url),p=r.url();if(m.length!==e.length)for(let f=m.length-1;f>=e.length;f--){let h=m[f];if(ql(h,n)&&h!==t&&h!==p){n.info({beforePages:e,afterPages:m,beforeUrl:t},"Auto-following new tab after preset action"),await r.switchToPage({type:"INDEX",index:String(f)}),a.result={followed:true};return}}}a.result={followed:false};});}async function Sc(t,e={}){let r=await t.getBrowserState(e);return {serializedTree:r.serialize(e.serializationOpts),tree:r}}var u6=t=>!!t&&Ed(t),d6=t=>{let{cache:e,description:r,disableSecondaryCacheResolution:o,logger:n}=t,i=e,a=false,s;return i&&o&&i.targetSource==="HEURISTIC_HEALED"&&(a=true,s="Heuristic healed cache incompatible",i=void 0),i?.inputDescription&&!s6(r,i.inputDescription)&&(n.warn({old:i.inputDescription,new:r},"Target cache was generated with a different description, clearing it automatically"),a=true,s="Description changed",i=void 0),{cache:i,cacheBustedBeforeAction:a,cacheBustReason:s}};var p6={minChunkTokenCount:1e4,acceptableChunkTokenCount:25e3,maxChunkTokenCount:5e4,maxLineLength:4e3},m6=/<(\S+) id="(\d+)".*?>/g,WRe=/(<\/(\S+)>)|(<(\S+).*?\/>)/g,f6=["h1","h2","section","footer","nav","aside","form","label","dialog"],qRe=[...f6,"span","div","h3"],KRe=["table","select","form","ul","ol","menu","pre","code","dialog"],YRe=["table","form","dialog","nav","section","ul","select"];function h6(t){return XRe(t)}function XRe({logger:t,serializedTree:e,options:r}){let{minChunkTokenCount:o,acceptableChunkTokenCount:n,maxChunkTokenCount:i,maxLineLength:a}=r,s=[],c=e.split(`
|
|
5431
5431
|
`),l=0,u=[],d=0,m=[],p=[],f=false;for(;l<c.length;){f&&(s.push({ids:m,content:u.join(`
|
|
5432
5432
|
`),tokenLength:d}),u=[],d=0,m=p.length?[p[p.length-1].id]:[],f=false);let h=c[l],S=It(h);d+=S,h.length>a&&(h=h.slice(0,a));let T=Array.from(h.matchAll(m6)).map(H=>H&&H.length>=3?{tagName:H[1],id:H[2]}:void 0).filter(H=>!!H),w=Array.from(h.matchAll(WRe)).map(H=>H&&(H[2]||H[4])).filter(H=>!!H);w.reverse();let N=h.replace(/ id="[0-9]+"/g,"");u.push(N);for(let H of T)m.push(H.id),p.push(H);for(let H of w){let ne=p[p.length-1];ne&&ne.tagName===H&&p.pop();}let D=p.some(H=>KRe.includes(H.tagName)),x=c[l+1]??"",A=It(x),O=Array.from(x.matchAll(m6)).map(H=>H&&H.length>2?H[1]:void 0).filter(H=>!!H),z=O.some(H=>f6.includes(H)),k=O.some(H=>qRe.includes(H));d+A>=i&&(f=true),d>=o&&(z&&!D||w.some(H=>YRe.includes(H)))&&(f=true),d>=n&&k&&!D&&(f=true),l++;}return u.length&&s.push({ids:m,content:u.join(`
|
|
5433
|
-
`),tokenLength:d}),s.forEach((h,S)=>{let b=h.ids[0],y=h.ids[h.ids.length-1];t.debug({tokenLength:h.tokenLength,minId:b,maxId:y},`Chunk for page filtering (index ${S+1}/${s.length})`);}),{chunks:s}}var g6=5e6,ZRe=15e4;async function Ku(t){let{fixtures:e}=t,{logger:r}=e,o=t.tree,n=t.serializedTree,i=It(n);if(i>g6)throw new M("UserConfigurationError",`Page accessibility tree is too large for AI page filtering (${i} tokens). Maximum supported size is ${g6} tokens.`);if(i>ZRe){let a=h6({serializedTree:n,options:p6,logger:r}),s=randomUUID();o=await QRe({...t,chunks:a.chunks,callId:s}),n=o.serialize();let c=It(n);r.info({oldTokens:i,newTokens:c,langfuseCallId:s},"Filtered page using AI chunk ranking");}return n}async function QRe({type:t,callId:e,chunks:r,description:o,fixtures:n,tree:i}){let{generator:a,signal:s,logger:c}=n,l=await a.rankChunksWithAi({chunks:r,description:o,type:t,softTokenLimit:3e4,mediumTokenLimit:6e4,hardTokenLimit:18e4,callId:e},{abortSignal:s,logger:c,loggerTags:Ie(c)}),u=[];return r.forEach((m,p)=>{l.indices.includes(p)&&(u=u.concat(m.ids));}),i.pruneUsingRelevantIds(new Set(u))}async function bN(t,e){if(!t.description)throw new M("UserConfigurationError","Cannot locate element with empty description");return Ii({action:async()=>t_e(t,e),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:e.browser,logger:t.logger})}async function t_e(t,e){let{disableCache:r,testContext:o,filterByViewport:n,skipWait:i,source:a,memory:s,logger:c,allowNotActionableNodesOverride:l,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,skipSavingVisualAttributes:m,isAutoHeal:p,cacheBustReason:f,acceptElementMovedError:h}=t,{orgId:S,browser:b,localCodeEvalTools:y,generator:T,abortSignal:v}=e,w=t.description,N=Lr(),D=t.useMemory&&!r;o&&(w=await Gs({orgId:S,s:w,context:o,localTools:y,signal:v,logger:c})),a&&(w=l6(w,a));let{serializedTree:x,tree:A}=await N.startAsyncSpan("GET_PAGE_STATE",async()=>Sc(b,{allowNotActionableNodesOverride:l,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,filterByViewport:n,abortSignal:v,skipWait:i,logger:c}),{}),B=await N.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let K,ee=Date.now(),V;for(;!K&&Date.now()-ee<3e3;){v.throwIfAborted();try{K=await b.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(le){V=le;}}if(!K)throw new M("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${V?.message}`);return K}),O=x,z=false,H=`data:image/jpeg;base64,${B.toString("base64")}`;O=await Ku({type:"locator",description:w,screenshot:H,serializedTree:x,tree:A,fixtures:{generator:T,signal:v,logger:c,orgId:S}}),O!==x&&(z=true);let ne=await N.startAsyncSpan("AI_LOCATOR_CALL",async K=>{p&&(K.attributes.isAutoHeal=true),f&&(K.attributes.cacheBustReason=f);let ee=await T.getElementLocation({browserState:O,goal:w,screenshot:H,source:a,memory:D?s:void 0},{disableCache:r,abortSignal:v,logger:c,loggerTags:Ie(c),useMemory:D,cacheBustReason:f});if(K.result=ee,N.storeTraceAsset){let V=randomUUID();N.storeTraceAsset({snapshotId:V,data:B}),K.screenshotSnapshotId=V;}return ee});if(c.debug({usedRag:z,result:ne},"Got locator result"),!(ne.id>0))throw new va(`Could not find any relevant element: ${ne.thoughts}`,ne.updatedMemory?{type:"GCS_TRACES",traces:ne.updatedMemory}:void 0);let{resolution:$,target:F,frameConfig:U}=await N.startAsyncSpan("TARGET_RESOLUTION",async K=>{let ee=await b.createTargetFromA11yId({id:ne.id,requirements:ne.requirements,additionalElements:ne.additionalElements,description:w,targetSource:"AI",logger:c,skipSavingVisualAttributes:m,acceptElementMovedError:h});return K.result={serializedElement:ee.target.nodeOnlySerializedHtml??"Unknown HTML element"},ee});if($.a11yNode?.properties?.hidden&&$.a11yNode?.properties?.hidden!=="false")throw new M("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${$.displayString}`);return D&&(ne.updatedMemory?F.memory={type:"GCS_TRACES",traces:ne.updatedMemory}:s&&(F.memory=s)),{thoughts:ne.thoughts,target:F,resolution:$,frameConfig:U,screenshot:H}}var r_e=15;async function gC({command:t,logger:e,fixtures:r,useMemory:o,maxRetries:n=r_e,recoveryHint:i}){if(!t.assertion.trim())throw new M("ActionFailureError","Assertion command is missing the assertion content");let a=T_.optional().catch(void 0).parse(t.source);t.source&&!a&&e.warn(`Invalid source ${t.source} for AI assertion, ignoring...`);let s=Lr();return s.startAsyncSpan("AI_ASSERTION_CALL",async c=>{let{browser:l}=r,u=t.timeout?t.timeout*1e3:l.smartWaitingTimeout,d=bq(u,n-1),m=0,p=Date.now(),f=p+u,h=p,S,b,y;try{await Ii({action:()=>l.clearHighlights(),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:l,logger:e});}catch(w){e.warn({err:w},"Failed to clear highlights before AI check, continuing...");}for(;m<n;){r.abortSignal.throwIfAborted();let w=Date.now();if(m>0){if(w>=f)break;let x=f-w,A=h-w,B=Math.min(A,x);B>0&&await ce(B,r.abortSignal);}let N=Date.now();if(m>0&&N>=f)break;let D=false;try{if(S=await Ii({action:async()=>{let A=await b6(l,e,r.abortSignal);return b&&b.serializedTree===A.serializedTree&&b.screenshotBuff.equals(A.screenshotBuff)?(D=!0,S):(b=A,y6({command:t,state:A,fixtures:r,useMemory:o,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:m,logger:e,source:a,recoveryHint:i}))},frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,logger:e,browser:l}),S?.success){S?.updatedMemory&&gg(t,S.updatedMemory,e);break}else throw S?.thoughts?new M("AssertionFailureError",S.thoughts):new M("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(x){r.abortSignal.throwIfAborted(),y=x instanceof Error?x:new Error(`${x}`),D?e.info(`AI check attempt ${m} failed (re-used previous result)`):e.info({err:x},`AI check assert attempt ${m} failed, retrying...`);}finally{m++,h=N+d;}}if(!S?.success){let w=f-Date.now();w>0&&await ce(w,r.abortSignal);}if(!S?.success)try{S=await Ii({action:async()=>y6({command:t,state:await b6(l,e,r.abortSignal),fixtures:r,useMemory:o,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:m,logger:e,recoveryHint:i}),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,logger:e,browser:l});}catch(w){r.abortSignal.throwIfAborted(),y=w instanceof Error?w:new Error(`${w}`);}finally{m++;}S?.updatedMemory&&gg(t,S.updatedMemory,e);let T=S?.afterScreenshotOverride;if(T&&s.storeTraceAsset){let w=randomUUID();s.storeTraceAsset({snapshotId:w,data:T}),c.screenshotSnapshotId=w;}let v=S?.elementScreenshotOverride;if(v&&s.storeTraceAsset){let w=randomUUID();s.storeTraceAsset({snapshotId:w,data:v}),c.elementScreenshotSnapshotId=w;}if(!S?.success){c.result={thoughts:y?.message??"AI check failed after all attempts",result:false};let w=`AI check still failing after ${m} attempts.`;throw y&&(w+=` Latest result: ${y.message}`),new M("AssertionFailureError",w)}return c.result={thoughts:S.thoughts,result:true},{...S,succeedImmediately:false,urlAfterCommand:l.url()}})}async function b6(t,e,r){await t.waitForPageLoad({signal:r});let[o,n]=await Promise.all([Sc(t,{abortSignal:r,skipWait:true,skipWaitForPageLoad:true,logger:e}),t.screenshot({retries:1,respectActiveFrame:true})]);return {...o,screenshotBuff:n}}async function y6({command:t,state:e,fixtures:r,useConsensus:o,useMemory:n,highlightElementsOnFailure:i,attemptNumber:a,source:s,logger:c,recoveryHint:l}){let {browser:u,generator:d,abortSignal:m}=r,{serializedTree:f,tree:h}=e,S=e.screenshotBuff,b=S.toString("base64"),y=u.url(),T=t.contextChoice??"MULTIMODAL",v=f;T!=="VISION_ONLY"&&(v=await Ku({type:"assertion",serializedTree:f,tree:h,description:t.assertion,screenshot:b,fixtures:{generator:d,signal:m,logger:c,orgId:r.orgId}}),v);let w={goal:t.assertion,url:y,memory:n?t.cache?.memory:void 0,browserState:v,screenshot:b,contextChoice:T,source:s,recoveryHint:l},D=await(T==="VISION_ONLY"?(A,B)=>d.getVisualAssertionResult(A,B):(A,B)=>d.getAssertionResult(A,B))(w,{useConsensus:o,attemptNumber:a,useMemory:n,disableCache:!!t.disableCache,abortSignal:m,logger:c,loggerTags:Ie(c)}),x;if((D.result||i)&&D.relevantElements?.length){D.relevantElements.map(A=>u.getSerializedFormFromA11yId(A)).filter(A=>!!A);try{let A=D.relevantElements[0],{resolution:B}=await u.createTargetFromA11yId({id:A,description:null,targetSource:"AI",skipSaveToCache:!0});x=await u.screenshot({locator:B.locator,clearHighlights:!0,respectActiveFrame:!0});}catch(A){c.debug({err:A},"Failed to capture element screenshot for trace, continuing...");}await o_e(D.relevantElements,u,c);}return {success:D.result,thoughts:D.thoughts,afterScreenshotOverride:S,elementScreenshotOverride:x,updatedMemory:n?D.updatedMemory:void 0}}async function o_e(t,e,r){let o=Date.now();for(let n of t){if(Date.now()-o>2e3){r.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await Q(e.highlightA11yId(n),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}});}catch(i){r.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}async function T6(t){let{command:e,logger:r,fixtures:o,disableCache:n}=t,{browser:i,generator:a,abortSignal:s}=o;if(!e.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(e.schema){let d=ym(e.schema);if(d)throw new M("UserConfigurationError",d)}let c=await i.getCondensedHtml(),l=await i.screenshot({retries:2}),u=Lr();try{return await u.startAsyncSpan("AI_EXTRACTION_CALL",async d=>{let m=await a.getTextExtraction({goal:e.goal,browserState:c,returnSchema:e.schema,screenshot:`data:image/jpeg;base64,${l.toString("base64")}`},{disableCache:n,abortSignal:s,loggerTags:Ie(r)});if(d.result=m,n_e({tracer:u,span:d,screenshot:l,htmlState:c,logger:r}),m.result==="NOT_FOUND")throw new M("ActionFailureError","No relevant data found for extraction goal on this page");if(m.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",m.thoughts);return {thoughts:m.thoughts||void 0,data:m.result,succeedImmediately:!1,urlAfterCommand:i.url()}})}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}}function n_e(t){let{tracer:e,span:r,screenshot:o,htmlState:n,logger:i}=t;if(e.storeTraceAsset)try{let a=randomUUID();e.storeTraceAsset({snapshotId:a,data:o}),r.screenshotSnapshotId=a;let s=randomUUID();e.storeTraceAsset({snapshotId:s,data:Buffer.from(n),extension:"html"}),r.browserStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}async function v6(t,e){let{logger:r}=t,{abortSignal:o,browser:n}=e,i=Date.now();try{await i_e(i,t,e);}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||o.aborted)return;r.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=n.smartWaitingTimeout-(Date.now()-i);s>0&&await ce(s,o);}finally{r.debug({durationMs:Date.now()-i},"AI smart waiting complete");}}async function i_e(t,e,r){let{abortSignal:o,browser:n}=r;if(n.smartWaitingTimeout<3e3){await ce(n.smartWaitingTimeout,o);return}if(!e.description)throw new M("UserConfigurationError","Cannot locate element with empty description");await Q(a_e(t,e,r),{milliseconds:n.smartWaitingTimeout});}async function a_e(t,e,r){let{logger:o,iframeUrl:n}=e,{browser:i}=r;for(;Date.now()-t<i.smartWaitingTimeout;)if(await Ii({action:async()=>s_e(e,r),frameConfig:n?{type:"url",url:n}:void 0,browser:i,logger:o}))return}async function s_e(t,e){let{testContext:r,logger:o}=t,{browser:n,abortSignal:i,localCodeEvalTools:a,orgId:s,generator:c}=e,l=t.description;r&&(l=await Gs({orgId:s,s:l,context:r,localTools:a,signal:i,logger:o})),i.throwIfAborted();let u;try{u=await n.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(f){throw new M("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${f instanceof Error?f.message:f}`)}let m=`data:image/jpeg;base64,${u.toString("base64")}`;i.throwIfAborted();let p=await c.getSmartWaitingDecision({description:l,screenshot:m},{abortSignal:i,loggerTags:Ie(o)});return o.debug({result:p},"Got smart waiting result"),p.isPageReady}async function w6(t){return Lr().startAsyncSpan("ELEMENT_ASSERTION",async r=>l_e(t,r),{name:"Element check"})}async function l_e(t,e){let{command:r,timeoutMs:o,fixtures:n,disableCache:i}=t,{abortSignal:a}=n,s=()=>kR(r.cache)?r.cache:void 0,c=s(),l=!i&&!!c?.target&&Ed(c.target),u=cloneDeep(c),d=(y=false)=>{if(c=s(),!!c)if(y){let T=QW(u,c);c.target=T.target,c.updatedAt=T.updatedAt;}else {if(!u){c=void 0;return}c.target=u.target,c.updatedAt=u.updatedAt;}},m=Date.now(),p=0,f,h=500,S=false;for(;p<2||Date.now()-m<o;){p++,p>1&&await ce(h,a),a?.throwIfAborted(),c=s();let y=p===1,{result:T,elementWasFound:v}=await C6({cacheToUse:c,skipAISmartWaiting:!y,useAIIfCacheFails:!l,params:t});if(f=T,S=S||v,T.success)break;d(),h=Math.min(h*1.25,1e4);}if(!f)throw new M("InternalPlatformError",`Failed to evaluate manual element assertion in ${o}ms.`);if(a?.throwIfAborted(),!f.success){let y=s(),T=y?.target?.memory?{target:{id:-1,memory:y.target.memory}}:void 0,{result:v,elementWasFound:w}=await C6({cacheToUse:T,skipAISmartWaiting:true,useAIIfCacheFails:true,params:t});f=v,S=S||w,f.success||d(true);}let b=s();return f.success&&b?.target&&!S&&(b.target=ZP(b.target),b.updatedAt=new Date),e.result={success:f.success,message:f.err?.message},f}async function C6({cacheToUse:t,skipAISmartWaiting:e,useAIIfCacheFails:r,params:o}){let{command:n,disableCache:i,fixtures:a,tracer:s,targetingWrapper:c}=o,{logger:l}=a;if(n.target&&!dl(n.target))throw new Error("Element assertion with x/y is not supported yet");let u=$m(n.assertion),d=c_e(n.assertion),m,p=false,f=cloneDeep(t);try{let{elementInteractedDisplayString:h,result:S,thoughts:b}=await c({tracer:s,command:n,target:n.target,cache:f?.target,action:async y=>u_e(y.locator,o),options:{...n,allowNotActionableNodesOverride:d,allowIneligibleTagRedirect:d,showZeroOpacityElementsOverride:!0,disableCache:i,memory:f?.target?.memory,disableGlobalLocatorRedirect:!0,source:Zf(n),skipAISmartWaiting:e,targetName:"target"},retriesWithAI:r?1:0});return m={success:S.success,data:S.data,err:S.err,elementInteractedDisplayString:h,thoughts:b},p=!0,S.success||(l.warn({aiThoughts:b,elementString:h,err:S.err},"Element check found an element but failed"),m={...S,thoughts:b}),{result:m,elementWasFound:p}}catch(h){if(u)return m={success:true,thoughts:`The element described does not exist on the page: ${h.message}`,err:void 0,data:void 0},{result:m,elementWasFound:p};if(!(h instanceof M)||h.reason!="ActionFailureError")throw h;return m={success:false,err:h,data:void 0,thoughts:void 0},l.warn({err:h},"Element check did not find an element and failed"),{result:m,elementWasFound:p}}}function c_e(t){return !(t.type==="ELEMENT_EXISTENCE"&&t.condition==="VISIBLE"&&!t.negated)}async function u_e(t,{command:e,fixtures:r}){return await r.browser.highlight(t),await d_e(t,e.assertion)}async function d_e(t,e){let r=true,o,n;switch(e.type){case "ELEMENT_CONTENT":{let a=await t.textContent()??"";if(n={elementTextContent:Cr(a,500,true)},!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,o=new M("AssertionFailureError",`The content ${s} '${e.value}': ${a}`);}break}case "ELEMENT_ATTRIBUTE":{n={elementOuterHtml:Cr(await t.evaluate(s=>s.cloneNode(false).outerHTML),500,true)};let a=null;try{a=await t.getAttribute(e.attr,{timeout:3e3});}catch(s){o=new M("AssertionFailureError",j(s)),r=false;break}if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,e.operation==="EXISTS"?o=new M("AssertionFailureError",`The attribute ${e.attr} ${s}`):o=new M("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`);}break}case "ELEMENT_EXISTENCE":{switch(e.condition){case "VISIBLE":{r=await t.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return true}return false},Zr*1e3);break}case "EDITABLE":{r=await t.isEditable({timeout:Zr*1e3});break}case "EXISTS":{r=true;break}case "ENABLED":{r=await t.isEnabled({timeout:Zr*1e3});break}case "FOCUSED":{r=await t.evaluate(s=>s===document.activeElement);break}default:return (s=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(r=e.negated?!r:r,!r){let a=fo(e);o=new M("AssertionFailureError",`The element ${a}`);}break}case "ELEMENT_NAME":{let a=await t.evaluate(s=>s.tagName);if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:true})){let s=fo(e);r=false,o=new M("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`);}break}case "ELEMENT_STYLE":{let a=await t.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,e.operation==="EXISTS"?o=new M("AssertionFailureError",`The style property ${e.property} ${s}`):o=new M("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`);}break}default:return (a=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}return {thoughts:void 0,success:r,data:n,err:o}}function R6(t){return t.type==="ELEMENT_EXISTENCE"&&t.negated&&t.condition==="EXISTS"}async function nS(t,e){let r=await t.screenshot(e),o=await Jimp.fromBuffer(r);return {buffer:r,width:Math.ceil(o.bitmap.width??0),height:Math.ceil(o.bitmap.height??0)}}async function M6({tracer:t,command:e,disableCache:r,browser:o,targetingWrapper:n,logger:i,screenshotStorage:a}){if(e.target&&!dl(e.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForStability({logger:i});let s={clearHighlights:true,hideCaret:true},c;e.target?.elementDescriptor?c=(await n({tracer:t,command:e,target:e.target,cache:e.cache?.target,action:async B=>nS(o,{locator:B.locator,...s}),options:{...e,disableCache:r,disableGlobalLocatorRedirect:true,memory:e.cache?.target?.memory,targetName:"target"}})).result:c=await nS(o,s);let l=await a.prepareGoldenScreenshotForComparison(i,e,c);if((c.height!==l.height||c.width!==l.width)&&i.warn({currHeight:c.height,currWidth:c.width,savedHeight:l.height,savedWidth:l.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(c.height-l.height)>10||Math.abs(c.width-l.width)>10){let A=`${c.width}x${c.height}`,B=`${l.width}x${l.height}`;return {fail:true,thoughts:`Current screenshot (${A}) does not match saved screenshot dimensions (${B}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:c.buffer,succeedImmediately:false,urlAfterCommand:o.url()}}let u=await Jimp.fromBuffer(c.buffer),d={width:c.width,height:c.height},m=await Jimp.fromBuffer(l.buffer),p={width:l.width,height:l.height},f,h=d.width*d.height,S=p.width*p.height,b=Math.abs(d.height-p.height),y=Math.abs(d.width-p.width);if(h>S){let A=u.cover({w:p.width,h:p.height});c.buffer=await A.getBuffer("image/jpeg"),f="current",c.width=p.width,c.height=p.height;}else if(S>h){let A=m.cover({w:d.width,h:d.height});l.buffer=await A.getBuffer("image/jpeg"),f="saved";}let T={data:Buffer.alloc(c.width*c.height*4),width:c.width,height:c.height},v=e.threshold??.1,N=Ove(yN.decode(l.buffer).data,yN.decode(c.buffer).data,T.data,c.width,c.height,{threshold:v,diffColorAlt:[0,255,0]})/(c.width*c.height)*100,D=N>v*100,x=`Visual diff of ${N.toFixed(2)}% detected, which is ${D?"over":"under"} the threshold of ${v*100}%.`;if(f&&(x+=` The ${f} screenshot was cropped since it was taller by ${b} pixels and wider by ${y} pixels.`),D)throw new M("ActionFailureError",x);return {fail:D,thoughts:x,beforeScreenshotOverride:c.buffer,afterScreenshotOverride:yN.encode(T,75).data,succeedImmediately:false,urlAfterCommand:o.url()}}var f_e=3e4;function h_e(t){if(!t.body)return {};switch(t.body.type){case "json":return {content:t.body.content,contentType:"application/json"};case "form-urlencoded":{let e=new URLSearchParams;return Object.entries(t.body.content).forEach(([r,o])=>{e.append(r,o);}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function Tp({command:t,logger:e,baseUrl:r,fetchImplementation:o=fetch}){let n=t.timeout??f_e/1e3,i=Object.fromEntries(Object.entries(t.headers||{}).filter(([f,h])=>f&&h)),a=new URLSearchParams;Object.entries(t.params||{}).filter(([f,h])=>f&&h).forEach(([f,h])=>{a.append(f,h);});let s=a.toString(),c;if(Hm(t.url)&&(c=t.url),r&&Gm(t.url,r)&&(c=new URL(t.url,r).toString()),!c)throw new M("ActionFailureError",`Invalid URL: ${t.url}`);let l=c;e.info({url:l,searchParams:s,headers:i,body:t.body,method:t.method},"Making HTTP request");let d=await Q((async()=>{let f=s?`${l}?${s}`:l;try{let h=h_e(t),S=new Headers(i);return h.contentType&&!S.has("Content-Type")&&S.set("Content-Type",h.contentType),await o(f,{headers:S,method:t.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:n*1e3,fallback:()=>{throw new M("ActionFailureError",`Fetch request timed out after ${n} seconds`)}});if(!d.ok){let f;try{f=await d.text();}catch(h){f=`Failed to read response body: ${h}`;}throw new M("ActionFailureError",`Fetch request failed with status ${d.status}: ${f}`)}let m={};d.headers.forEach((f,h)=>{m[h]=f;});let p={status:d.status,headers:m,request:{url:d.url,method:t.method,headers:i}};if(t.body?.type==="json"&&t.body.content)try{p.request.json=JSON.parse(t.body.content);}catch{}if(d.headers.get("content-type")?.includes("json"))try{p.json=await d.json();}catch{}else d.headers.get("content-type")?.includes("text")&&(p.text=await d.text());return p}var g_e=5e3;async function I6({timeout:t=Zr,...e}){let r=Date.now(),o=t*1e3,n=o+1e4,i,a=0,s=500;for(;a-r<o;){if(Date.now()-r>n){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await x6(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await ce(s,e.signal),s=Math.min(Math.floor(s*1.5),g_e);else return i}return i=await x6(e),i}async function x6(t){return Lr().startAsyncSpan("PAGE_ASSERTION",async r=>{let o=await EN(t);return r.result={success:o.success,message:o.err?.message},o},{name:"Page check"})}async function EN({assertion:t,browser:e,autoExpandIframes:r}){switch(t.type){case "CONTENT":case "CONTENT":{let n,i=false,a;try{let s;if(r){let c=await e.evaluateFunctionInAllFrames(P6,{value:t.value,negated:!!t.negated,returnHtml:!1});i=t.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml;}else ({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(P6,{value:t.value,negated:!!t.negated,returnHtml:!0},"checking page content"));if(!i){let c=t.negated?ks.CONTAINS:Fs.CONTAINS;a=new M("AssertionFailureError",`The page ${c} '${t.value}'.`),n=s;}}catch(s){a=new M("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`);}return {success:i,err:a,data:i||!n?void 0:{pageContent:n}}}default:return (n=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}}function P6({value:t,negated:e,returnHtml:r}){let o=document.body.innerHTML,n=o.includes(t)===!e;return o.length>1e4&&(o=o.slice(0,1e4)+"...TRUNCATED"),{evaluation:n,pageHtml:!n&&r?o:void 0}}var S_e=3e4;async function O6({command:t,logger:e,baseUrl:r,fetchImplementation:o=fetch}){let n=t.timeout??S_e/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(t.headers||{}).filter(([d,m])=>d&&m));a["Content-Type"]="application/json";let s;if(Hm(t.url)&&(s=t.url),r&&Gm(t.url,r)&&(s=new URL(t.url,r).toString()),!s)throw new M("ActionFailureError",`Invalid URL: ${t.url}`);let l=await Q((async()=>{try{return await o(s,{headers:a,method:"POST",body:JSON.stringify({query:t.query,variables:t.variables?JSON.parse(t.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:n*1e3});if(!l)throw new M("ActionFailureError",`GraphQL request timed out after ${n} seconds`);if(!l.ok){let d,m=await l.text();try{d=JSON.parse(m);}catch{throw new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${m}`)}throw d?.errors?.length&&d?.errors[0]?.message?new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${m}`)}let u={};return l.headers.forEach((d,m)=>{u[m]=d;}),{status:l.status,headers:u,json:await l.json()}}var SC=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;executionOptionsStack=[];recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:r,logger:o,storage:n,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=n,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=r,this.logger=o;}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal);}setClosed(){this.executeAbortController.abort();}throwIfClosed(){this.executeAbortController.signal.throwIfAborted();}get closed(){return this.executeAbortController.signal.aborted}async withExecutionOptions(e,r){this.executionOptionsStack.push(e);try{return await r()}finally{this.executionOptionsStack.pop();}}getCurrentExecutionOptions(){return this.executionOptionsStack[this.executionOptionsStack.length-1]??{}}async evaluateAiAction({goal:e,startingScreenshot:r,history:o,disableCache:n,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([Sc(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:true,skipWaitForPageLoad:true,logger:s}),this.browser.screenshot({retries:1,clearHighlights:true})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await Ku({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),m={url:this.browser.url(),browserState:d,startingScreenshot:r,history:o,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(m,{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:{...Ie(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:r,history:o,actionHint:n,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([Sc(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:true,skipWaitForPageLoad:true,logger:a}),this.browser.screenshot({retries:1,clearHighlights:true})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,m=await Ku({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),p={url:c,browserState:m,startingScreenshot:r,history:o,goal:e,actionHint:n,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(p,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...Ie(a)},langfuseSessionId:s})}catch(f){throw new M("InternalWebAgentError",`Error generating command: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}}async getBrowserState(e){return Sc(this.browser,e)}async locateElement(e){return await bN(e,this.getControllerFixtures())}async locateElementWithSelector(e,r){return Ii({action:async()=>{let o=await this.browser.resolveHardcodedCssSelector({selector:e,timeoutMs:2e3,logger:this.logger});return {thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:o}},frameConfig:r?{type:"url",url:r}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(){return {browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??true}async wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:o,descriptions:n,caches:i,action:a,options:s,retriesWithAI:c=1}){let l=[];for(let u=0;u<n.length;u++){let d=n[u],m=await this.wrapElementTargetingCommand({tracer:e,command:r,target:d,cache:i[u],action:async p=>p,options:{...s,targetName:o[u]}});l.push(m);}try{let u=await a(...l.map(p=>p.result)),d=p=>p==="fromTarget"?"From Target":p==="toTarget"?"To Target":"Target",m=l.map((p,f)=>p.thoughts?`${d(o[f])}: ${p.thoughts}`:void 0).filter(p=>!!p).join(" -------------- ")||void 0;return {result:u,elementInteractedDisplayStrings:l.map(p=>p.elementInteractedDisplayString),thoughts:m}}catch(u){if(this.throwIfClosed(),c>0)return this.logger.warn({err:u},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:o,descriptions:n,caches:n.map(()=>{}),action:a,options:s,retriesWithAI:c-1});throw new M("ActionFailureError",u.message,{errOptions:{cause:u}})}}async wrapHardcodedCssTargetingCommandHelper({target:e,action:r,options:o,command:n}){let i=this.logger.child({commandId:n.id}),{targetName:a}=o;if(e.type!=="description")throw new M("ActionFailureError","Cannot use selector with non-description target");let s,c=Date.now(),l=Date.now();for(;Date.now()-l<this.browser.smartWaitingTimeout;){c=Date.now();try{let u=await this.browser.resolveHardcodedCssSelector({selector:e.elementDescriptor,targetName:a,logger:i});return {result:await r({locator:u.locator,originalElementLocationResult:void 0,serverSideBoundingBox:null}),elementInteractedDisplayString:u.displayString}}catch(u){if(u.name==="AbortError")throw u;s=u,i.warn({err:u},"Failed to action on hardcoded css selector"),Date.now()-c<500&&await ce(500);}}throw s}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:r,disableGlobalLocatorRedirect:o,logger:n}=e,i=Lr(),a=!o&&this.browser.userBrowserSettings.globalLocatorRedirect!==false;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(r.locator);});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async c=>{let{targetingResult:l,metadata:u}=await this.browser.performTargetRedirection(r,n);if(c.result=u,u.outcome==="redirected to new element"&&l&&i.storeTraceAsset&&!this.browser.userBrowserSettings.disableBrowserMonitoring){let d=randomUUID();(async()=>{try{let m=await this.browser.screenshot({locator:l.locator,clearHighlights:!0,boundingBoxOverride:l.serverSideBoundingBox??void 0});i.storeTraceAsset?.({snapshotId:d,data:m});}catch(m){n.debug({err:m},"Failed to capture element screenshot for redirect trace");}})(),c.elementScreenshotSnapshotId=d;}return l})),s||(s={locator:r.locator,serverSideBoundingBox:await r.locator.boundingBox({timeout:Oe}),originalElementLocationResult:r.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{cache:r,options:o,logger:n}=e,a=await Lr().startAsyncSpan("CACHE_RESOLUTION",async c=>{c.targetSource=r.targetSource;try{let l=await this.browser.resolveTarget(r,{allowNotActionableNodesOverride:o.allowNotActionableNodesOverride,logger:n,signal:this.executeAbortController.signal,...o.resolveTargetOptions,acceptElementMovedError:o.force});c.attributes.targetDisplayString=l.displayString,c.attributes.decisions=l.decisions;let u=l.decisions.find(d=>d.matched);return u&&(c.resolutionMethod=u.type),l}catch(l){throw l instanceof we&&(c.cacheMissReason=l.cacheMissReason,c.attributes.decisions=l.decisions),l}}),s=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:a,disableGlobalLocatorRedirect:o.disableGlobalLocatorRedirect,logger:n});return o.force||await a.revalidator?.(),{resolutionResult:a,finalTarget:s}}async wrapElementTargetingCommand(e){return await Ii({action:()=>this.wrapElementTargetingCommandHelper(e),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper(e){let{tracer:r,target:o,action:n,options:i,command:a,finalAttempt:s=false,originalCache:c=e.cache}=e,{retriesWithAI:l=1}=e,{disableCache:u,useSelector:d,targetName:m}=i,p=Lr(),f=this.logger.child({commandId:a.id}),h=this.shouldUseMemory(),S=cloneDeep(e.cache);if((!S||u)&&!qk(o))throw new M("ActionFailureError","Cannot target element with no cached data or element descriptor");if(d)return this.wrapHardcodedCssTargetingCommandHelper(e);let b=false,y;u&&(f.info("Cache explicitly disabled for this step"),b=true,y="Cache explicitly disabled",S=void 0);let T=d6({cache:S,description:o.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:f});S=T.cache,b=b||T.cacheBustedBeforeAction,!y&&T.cacheBustReason&&(y=T.cacheBustReason);let v=true;if(!u6(S))return l--,v=false,this.executeTargetingCommandWithAI({tracer:p,stepTracer:r,target:o,options:i,command:a,action:n,originalCache:c,logger:f,useMemory:h,cacheBustedBeforeAction:b,cacheBustReason:y});try{let{resolutionResult:w,finalTarget:N}=await this.resolveCachedTargetForAction({cache:S,options:i,logger:f}),D=await n(N);if(_t.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.97.2"]),xT({cmd:a,key:m,newTarget:S,logger:f,updatedWithAI:!1}),v){let x=w.decisions.filter(A=>A.matched);if(x.length!==1)f.warn({decisions:w.decisions},"Expected exactly 1 matching method for element location, got more or less");else {let A=x[0].type;r.recordTargetAutoHeal({healType:A});}}return {result:D,elementInteractedDisplayString:w.displayString}}catch(w){this.throwIfClosed();let N=XR(w);if(N&&!s)return f.warn({err:w},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({tracer:r,command:a,target:o,action:n,cache:c,originalCache:c,retriesWithAI:l,finalAttempt:true,options:i});if(w instanceof M&&!N)throw f.warn({err:w},"Failed to execute command with target (fatal)"),w;if(l>0&&o){f.info({err:w},"Failed to execute action with cached target, retrying with AI"),_t.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.97.2",`missReason:${w instanceof we?w.cacheMissReason:"unknown"}`]);let D;S.memory&&Kk(S.memory)&&(D=S.memory);let x=w instanceof we&&w.cacheMissReason==="failing-ldist";return this.wrapElementTargetingCommandHelper({tracer:r,command:a,target:o,cache:void 0,action:n,originalCache:c,retriesWithAI:l,finalAttempt:true,options:{...i,memory:D,targetHealingInProgress:true},skipInitialLocateWait:x})}throw new M("ActionFailureError",`Failed to execute interactive command: ${w instanceof Error?w.message:`${w}`}`,{errOptions:{cause:w}})}}async executeTargetingCommandWithAI(e){let{tracer:r,stepTracer:o,target:n,options:i,command:a,action:s,originalCache:c,logger:l,useMemory:u,cacheBustedBeforeAction:d,cacheBustReason:m,skipInitialLocateWait:p}=e;l.info({description:n.elementDescriptor,targetHealingInProgress:i.targetHealingInProgress,cacheBustedBeforeAction:d,memory:i.memory,useMemory:u},"Prompting AI for an updated element location");let f=false;(d||!c)&&!this.getCurrentExecutionOptions().skipAISmartWaiting&&!i.skipAISmartWaiting?(await r.startAsyncSpan("SMART_WAITING",async()=>await v6({description:n.elementDescriptor,iframeUrl:i.iframeUrl,source:i.source,logger:l,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride},this.getControllerFixtures())),f=true):(d||!c)&&(i.skipAISmartWaiting?l.debug("Skipping AI smart waiting for this targeting attempt"):l.debug("Skipping AI smart waiting due to controller execution options"));let h=2;for(let S=1;S<=h;S++){let b=false,y=this.browser.getActiveFrameConfig(),T=i.force||S>1;try{let v;try{v=await bN({description:n.elementDescriptor,disableCache:!!i.disableCache,iframeUrl:i.iframeUrl,source:i.source,useMemory:u,memory:u?i.memory:void 0,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride,allowIneligibleTagRedirect:i.allowIneligibleTagRedirect,showZeroOpacityElementsOverride:i.showZeroOpacityElementsOverride,logger:l,skipWait:f||p,isAutoHeal:!!i.targetHealingInProgress,cacheBustReason:m,acceptElementMovedError:T},this.getControllerFixtures());}catch(D){if(D instanceof va&&D.updatedLocatorMemory){let x={id:-1,...c,memory:D.updatedLocatorMemory};xT({cmd:a,key:i.targetName,newTarget:x,logger:l,updatedWithAI:!0});}throw D}v.frameConfig&&(this.browser.setActiveFrameConfig(v.frameConfig),b=!0);let w=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:v.resolution,disableGlobalLocatorRedirect:i.disableGlobalLocatorRedirect,logger:l}),N=await s(w);return xT({cmd:a,key:i.targetName,newTarget:v.target,logger:l,updatedWithAI:!0}),i.targetHealingInProgress&&(o.recordTargetAutoHeal({healType:"AI"}),v.target.targetSource="AI_HEALED",v.target.targetUpdateTime=new Date().toUTCString(),v.target.targetUpdateLoggerTags=Ie(l)),{result:N,elementInteractedDisplayString:v.resolution.displayString,thoughts:v.thoughts}}catch(v){if(b&&this.browser.setActiveFrameConfig(y),this.throwIfClosed(),S<h&&XR(v)){l.warn({err:v,aiAttempt:S},"Encountered retryable AI targeting error; retrying with AI once");continue}throw v instanceof M?v:new M("ActionFailureError",v.message)}}throw new M("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return nS(this.browser,e)}async executePresetCommand(e,r,o,n,i){this.options?.slowMoMs&&await ce(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(r,o);}catch(l){throw this.throwIfClosed(),new M("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,r,o,n,i);return this.options?.autoFollowNewTabs&&await c6({beforeUrl:s,command:r,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{gp(r,c);}}createCallbacksForBrowser(e){return {createIsolatedFolder:()=>XO(e)}}async traceBrowserInteraction(e,r,o){return Lr().startAsyncSpan("BROWSER_INTERACTION",async i=>r(i),{name:e,...o})}async resolveCommandTemplateStrings(e,r){return hp({obj:e,context:r,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,r,o,n,i){n=n||"disableCache"in r&&!!r.disableCache;let a=this.logger.child({commandId:r.id});switch(r.type){case "SUCCESS":{let s=r.condition;return s?.assertion.trim()?gC({command:s,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:a,recoveryHint:i}):{succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "AI_ASSERTION":{if(!r.assertion.trim())throw new M("ActionFailureError","Missing assertion");if(r.timeout&&r.timeout>1800)throw new M("AssertionFailureError",`AI check timeout of ${r.timeout} exceeds the maximum allowed value of 30 minutes.`);return gC({command:r,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:a,recoveryHint:i})}case "AI_EXTRACT":return T6({command:r,logger:a,fixtures:this.getControllerFixtures(),disableCache:n});case "NAVIGATE":if(!Hm(r.url)&&!Gm(r.url,this.browser.baseUrl))throw new M("ActionFailureError",`Invalid URL provided to navigate command: ${r.url}`);await this.traceBrowserInteraction("Navigate",()=>this.browser.navigate({url:r.url,loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0}));break;case "DIALOG":this.browser.registerDialogHandler(r.action);break;case "CAPTCHA":throw new M("UserConfigurationError","Captcha solving is no longer available on Momentic");case "GO_BACK":await this.traceBrowserInteraction("Go back",()=>this.browser.goBack());break;case "GO_FORWARD":await this.traceBrowserInteraction("Go forward",()=>this.browser.goForward());break;case "SCROLL_LEFT":case "SCROLL_RIGHT":case "SCROLL_DOWN":case "SCROLL_UP":{let s,c;if(r.target&&ya(r.target)){let d=Kt(r.target.pixels);await this.browser.hoverUsingVisualCoordinates(d);}else if(r.target&&r.target.elementDescriptor.trim()){let{elementInteractedDisplayString:d,thoughts:m}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:p=>this.browser.hover(p),options:{...r,targetName:"target",disableGlobalLocatorRedirect:true,disableCache:n}});s=d,c=m;}let l=this.browser.getViewport()?.height??hl.height,u=this.browser.getViewport()?.width??hl.width;switch(r.type){case "SCROLL_UP":await this.traceBrowserInteraction("Scroll up",()=>this.browser.scrollVertical(-(r.deltaY??l)));break;case "SCROLL_DOWN":await this.traceBrowserInteraction("Scroll down",()=>this.browser.scrollVertical(r.deltaY??l));break;case "SCROLL_LEFT":await this.traceBrowserInteraction("Scroll left",()=>this.browser.scrollHorizontal(-(r.deltaX??u)));break;case "SCROLL_RIGHT":await this.traceBrowserInteraction("Scroll right",()=>this.browser.scrollHorizontal(r.deltaX??u));break}return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "WAIT_FOR_URL":{if(r.timeout&&r.timeout>1800)throw new M("UserConfigurationError",`Wait for URL timeout of ${r.timeout} exceeds the maximum allowed value of 30 minutes.`);let s=r.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:s},{timeout:r.timeout?r.timeout*1e3:void 0,negated:r.negated,caseInsensitive:r.caseInsensitive});break}case "WAIT":{if(r.delay>1800)throw new M("UserConfigurationError",`Wait timeout of ${r.delay} seconds exceeds the maximum allowed value of 30 minutes`);let s=r.delay*1e3;await ce(s,this.executeAbortController.signal);break}case "REFRESH":await this.traceBrowserInteraction("Refresh",()=>this.browser.refresh({loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0}));break;case "CLICK":{if(ya(r.target)){let m=Kt(r.target.pixels),p={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0};await this.traceBrowserInteraction("Click",()=>this.browser.clickUsingVisualCoordinates(m,p),{coordinates:m});break}let s=this.browser.url(),{elementInteractedDisplayString:c,result:l,thoughts:u}=await this.wrapElementTargetingCommand({tracer:e,target:r.target,command:r,cache:r.cache?.target,action:m=>this.traceBrowserInteraction("Click",async p=>{let f={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0},h=await this.browser.click(m,this.createCallbacksForBrowser(this.orgId),f);return h.coordinates&&(p.coordinates=h.coordinates),h},{selector:m.locator.toString()}),options:{...r,targetName:"target",disableCache:n}}),d={urlAfterCommand:this.browser.url(),succeedImmediately:false,elementInteracted:c,thoughts:u,data:l.downloadedFile?{downloadedFile:l.downloadedFile}:void 0};return VT(s,d.urlAfterCommand)&&(d.succeedImmediately=true,d.succeedImmediatelyReason="URL changed"),d}case "COPY":return await this.browser.copy(r.value),{succeedImmediately:false,data:r.value,urlAfterCommand:this.browser.url()};case "PASTE":{await this.browser.paste();break}case "DRAG":{if(ya(r.fromTarget)&&ya(r.toTarget)){let l=Kt(r.fromTarget.pixels),u=Kt(r.toTarget.pixels);await this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDropUsingVisualCoordinates(l,u,{hoverDurationMs:r.hoverSeconds?r.hoverSeconds*1e3:void 0}),{coordinates:l});break}if(ya(r.fromTarget)||ya(r.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:s,thoughts:c}=await this.wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:["fromTarget","toTarget"],descriptions:[r.fromTarget,r.toTarget],caches:[r.cache?.fromTarget,r.cache?.toTarget],action:(l,u)=>this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDrop(l,u,{hoverDurationMs:r.hoverSeconds?r.hoverSeconds*1e3:void 0,steps:r.steps})),options:{...r,disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s[0],thoughts:c}}case "MOUSE_DRAG":{let s=parseInt(r.deltaX),c=parseInt(r.deltaY),l=r.steps??5;if(isNaN(s)||isNaN(c))throw new M("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${r.deltaX}, ${r.deltaY})`);if(r.target&&ya(r.target)){let m=Kt(r.target.pixels);await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDragUsingVisualCoordinates({deltaX:s,deltaY:c,steps:l,fromTarget:m}),{coordinates:m});break}let u,d;if(r.target?.elementDescriptor){let{elementInteractedDisplayString:m,thoughts:p}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:async f=>this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(s,c,l,f.locator,{force:r.force})),options:{...r,targetName:"target",disableCache:n}});u=m,d=p;}else await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(s,c,l,void 0,{force:r.force}));return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:u,thoughts:d}}case "SELECT_OPTION":{if(!dl(r.target))throw new Error("Select with x/y is not supported yet");let s=r.target.elementDescriptor,c=r.choice,{elementInteractedDisplayString:l,thoughts:u}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:{type:"description",elementDescriptor:s},cache:r.cache?.target,action:d=>this.traceBrowserInteraction("Select option",()=>this.browser.selectOption(d,c,r.force),{value:c.type==="LABEL"?c.label:c.type==="VALUE"?c.value:c.index}),options:{...r,targetName:"target",disableCache:n,source:Zf(r)}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:u}}case "TAB":{let s={loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0,retry:true};await this.browser.switchToPage(r.action,s);break}case "NEW_TAB":await this.browser.createNewTab(r.url,{loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0});break;case "CLOSE_TAB":await this.browser.closePage(r.action,{retry:true});break;case "COOKIE":{if(!r.value)break;let s=await this.browser.setCookie(r.value);a.debug({results:s},"Set cookies");break}case "LOCAL_STORAGE":if(!r.value||!r.key)break;await this.browser.setLocalStorage(r.key,r.value);break;case "JAVASCRIPT":{let s;try{r.environment==="BROWSER"?(s=await this.browser.evaluateCodeInPage({code:r.code,fragment:r.fragment??!1,context:o.toObjectCopy(),timeoutMs:r.timeout?r.timeout*1e3:void 0}),a.info({result:s},"Executed JavaScript in browser")):s=await _i({orgId:this.orgId,code:r.code,fragment:!!r.fragment,context:o,timeoutMs:r.timeout?r.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async c=>{if(!this.options?.scratchPadId){a.warn({updates:c},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:c,logger:a});}}});}catch(c){throw this.throwIfClosed(),new M("ActionFailureError",c instanceof Error?c.message:`${c}`,{errOptions:{cause:c}})}try{JSON.stringify(s);}catch(c){throw new M("ActionFailureError",`Return value is not serializable: ${c instanceof Error?c.message:`${c}`}`,{errOptions:{cause:c}})}return {urlAfterCommand:this.browser.url(),succeedImmediately:false,data:s}}case "TYPE":{if(r.target&&ya(r.target)){let p=Kt(r.target.pixels),f={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0};await this.browser.clickUsingVisualCoordinates(p,f),await this.traceBrowserInteraction("Type",()=>this.browser.type(r.value,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter},true),{value:r.value});break}let s=this.browser.url(),c,l,u=cloneDeep(r.target),d=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(u){let{elementInteractedDisplayString:p,thoughts:f}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:u,cache:r.cache?.target,action:h=>this.traceBrowserInteraction("Type",()=>this.browser.typeIntoTarget(r.value,h,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter,relativePosition:r.relativePosition}),{value:r.value,selector:h.locator.toString()}),options:{...r,targetName:"target",disableCache:n,disableGlobalLocatorRedirect:!d,source:Zf(r)}});c=p,l=f;}else await this.traceBrowserInteraction("Type",()=>this.browser.type(r.value,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter},true),{value:r.value});let m={urlAfterCommand:this.browser.url(),succeedImmediately:false,elementInteracted:c,thoughts:l};return VT(s,m.urlAfterCommand)&&(m.succeedImmediately=true,m.succeedImmediatelyReason="URL changed"),m}case "HOVER":{if(ya(r.target)){let l=Kt(r.target.pixels);await this.traceBrowserInteraction("Hover",()=>this.browser.hoverUsingVisualCoordinates(l),{coordinates:l});break}let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:l=>this.traceBrowserInteraction("Hover",()=>this.browser.hover(l,{relativePosition:r.relativePosition?Kt(r.relativePosition):void 0}),{selector:l.locator.toString()}),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "FOCUS":{if(!dl(r.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:l=>this.browser.focus(l),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "BLUR":{if(r.target&&!dl(r.target))throw new Error("Blur with x/y is not supported yet");if(!r.target||!r.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:false,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,target:r.target,command:r,cache:r.cache?.target,action:l=>this.browser.blur(l),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "PRESS":{let s=this.browser.url();await this.traceBrowserInteraction("Press key",()=>this.browser.press(r.value,{repeat:r.repeat,convertMeta:r.convertMeta??true,delayMs:r.delayMs}),{value:r.value});let c={urlAfterCommand:this.browser.url(),succeedImmediately:false};return VT(s,c.urlAfterCommand)&&(c.succeedImmediately=true,c.succeedImmediatelyReason="URL changed"),c}case "KEY_DOWN":return await this.browser.keyDown(r.value,{convertMeta:r.convertMeta??true}),{urlAfterCommand:this.browser.url(),succeedImmediately:false};case "KEY_UP":return await this.browser.keyUp(r.value,{convertMeta:r.convertMeta??true}),{urlAfterCommand:this.browser.url(),succeedImmediately:false};case "REQUEST":{let s=new CookieJar,c=y_e(fetch,s),l;try{l=new URL(r.url).hostname;}catch{}let u=await Tp({command:r,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:c});return {data:wd.parse({...u,cookies:em(s,l)}),succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "GRAPHQL_REQUEST":return {data:await O6({command:r,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:false,urlAfterCommand:this.browser.url()};case "VISUAL_DIFF":return M6({tracer:e,command:r,disableCache:n,browser:this.browser,logger:a,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:s=>this.wrapElementTargetingCommand(s)});case "FILE_UPLOAD":{let s,c;if(r.fileSource.type==="URL"?(c=r.fileSource.url,s=await X5({uri:r.fileSource.url,logger:a,orgId:this.orgId})):r.fileSource.type==="USER_FILE"&&(c=r.fileSource.name,s=await this.uploadedFileStorage?.getFileForUpload(r.fileSource.name,this.orgId)),!s)throw new M("UserConfigurationError",`Attempted to use non-existent file for upload step: ${c}`);await this.browser.setFileChooserHandler({...s,filename:r.filename});break}case "AUTH_SAVE":{let s=await this.browser.saveAuthState();if(r.storageState&&mI(r.storageState)){let c=sr__default.resolve(r.storageState);so.mkdirSync(sr__default.dirname(c),{recursive:true}),so.writeFileSync(c,`${JSON.stringify(s,null,2)}
|
|
5433
|
+
`),tokenLength:d}),s.forEach((h,S)=>{let b=h.ids[0],y=h.ids[h.ids.length-1];t.debug({tokenLength:h.tokenLength,minId:b,maxId:y},`Chunk for page filtering (index ${S+1}/${s.length})`);}),{chunks:s}}var g6=5e6,ZRe=15e4;async function Ku(t){let{fixtures:e}=t,{logger:r}=e,o=t.tree,n=t.serializedTree,i=It(n);if(i>g6)throw new M("UserConfigurationError",`Page accessibility tree is too large for AI page filtering (${i} tokens). Maximum supported size is ${g6} tokens.`);if(i>ZRe){let a=h6({serializedTree:n,options:p6,logger:r}),s=randomUUID();o=await QRe({...t,chunks:a.chunks,callId:s}),n=o.serialize();let c=It(n);r.info({oldTokens:i,newTokens:c,langfuseCallId:s},"Filtered page using AI chunk ranking");}return n}async function QRe({type:t,callId:e,chunks:r,description:o,fixtures:n,tree:i}){let{generator:a,signal:s,logger:c}=n,l=await a.rankChunksWithAi({chunks:r,description:o,type:t,softTokenLimit:3e4,mediumTokenLimit:6e4,hardTokenLimit:18e4,callId:e},{abortSignal:s,logger:c,loggerTags:Ie(c)}),u=[];return r.forEach((m,p)=>{l.indices.includes(p)&&(u=u.concat(m.ids));}),i.pruneUsingRelevantIds(new Set(u))}async function bN(t,e){if(!t.description)throw new M("UserConfigurationError","Cannot locate element with empty description");return Ii({action:async()=>t_e(t,e),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:e.browser,logger:t.logger})}async function t_e(t,e){let{disableCache:r,testContext:o,filterByViewport:n,skipWait:i,source:a,memory:s,logger:c,allowNotActionableNodesOverride:l,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,skipSavingVisualAttributes:m,isAutoHeal:p,cacheBustReason:f,acceptElementMovedError:h}=t,{orgId:S,browser:b,localCodeEvalTools:y,generator:T,abortSignal:v}=e,w=t.description,N=Lr(),D=t.useMemory&&!r;o&&(w=await Gs({orgId:S,s:w,context:o,localTools:y,signal:v,logger:c})),a&&(w=l6(w,a));let{serializedTree:x,tree:A}=await N.startAsyncSpan("GET_PAGE_STATE",async()=>Sc(b,{allowNotActionableNodesOverride:l,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,filterByViewport:n,abortSignal:v,skipWait:i,logger:c}),{}),B=await N.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let K,ee=Date.now(),V;for(;!K&&Date.now()-ee<3e3;){v.throwIfAborted();try{K=await b.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(le){V=le;}}if(!K)throw new M("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${V?.message}`);return K}),O=x,z=false,H=`data:image/jpeg;base64,${B.toString("base64")}`;O=await Ku({type:"locator",description:w,screenshot:H,serializedTree:x,tree:A,fixtures:{generator:T,signal:v,logger:c,orgId:S}}),O!==x&&(z=true);let ne=await N.startAsyncSpan("AI_LOCATOR_CALL",async K=>{p&&(K.attributes.isAutoHeal=true),f&&(K.attributes.cacheBustReason=f);let ee=await T.getElementLocation({browserState:O,goal:w,screenshot:H,source:a,memory:D?s:void 0},{disableCache:r,abortSignal:v,logger:c,loggerTags:Ie(c),useMemory:D,cacheBustReason:f});if(K.result=ee,N.storeTraceAsset){let V=randomUUID();N.storeTraceAsset({snapshotId:V,data:B}),K.screenshotSnapshotId=V;}return ee});if(c.debug({usedRag:z,result:ne},"Got locator result"),!(ne.id>0))throw new va(`Could not find any relevant element: ${ne.thoughts}`,ne.updatedMemory?{type:"GCS_TRACES",traces:ne.updatedMemory}:void 0);let{resolution:$,target:F,frameConfig:U}=await N.startAsyncSpan("TARGET_RESOLUTION",async K=>{let ee=await b.createTargetFromA11yId({id:ne.id,requirements:ne.requirements,additionalElements:ne.additionalElements,description:w,targetSource:"AI",logger:c,skipSavingVisualAttributes:m,acceptElementMovedError:h});return K.result={serializedElement:ee.target.nodeOnlySerializedHtml??"Unknown HTML element"},ee});if($.a11yNode?.properties?.hidden&&$.a11yNode?.properties?.hidden!=="false")throw new M("ActionFailureError",`Momentic's AI found a relevant element to interact with, but it is explicitly marked with an 'aria-hidden' attribute. Please remove this attribute or adjust the element description to locate a different element. Element chosen: ${$.displayString}`);return D&&(ne.updatedMemory?F.memory={type:"GCS_TRACES",traces:ne.updatedMemory}:s&&(F.memory=s)),{thoughts:ne.thoughts,target:F,resolution:$,frameConfig:U,screenshot:H}}var r_e=15;async function gC({command:t,logger:e,fixtures:r,useMemory:o,maxRetries:n=r_e,recoveryHint:i}){if(!t.assertion.trim())throw new M("ActionFailureError","Assertion command is missing the assertion content");let a=T_.optional().catch(void 0).parse(t.source);t.source&&!a&&e.warn(`Invalid source ${t.source} for AI assertion, ignoring...`);let s=Lr();return s.startAsyncSpan("AI_ASSERTION_CALL",async c=>{let{browser:l}=r,u=t.timeout?t.timeout*1e3:l.smartWaitingTimeout,d=bq(u,n-1),m=0,p=Date.now(),f=p+u,h=p,S,b,y;try{await Ii({action:()=>l.clearHighlights(),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:l,logger:e});}catch(w){e.warn({err:w},"Failed to clear highlights before AI check, continuing...");}for(;m<n;){r.abortSignal.throwIfAborted();let w=Date.now();if(m>0){if(w>=f)break;let x=f-w,A=h-w,B=Math.min(A,x);B>0&&await ce(B,r.abortSignal);}let N=Date.now();if(m>0&&N>=f)break;let D=false;try{if(S=await Ii({action:async()=>{let A=await b6(l,e,r.abortSignal);return b&&b.serializedTree===A.serializedTree&&b.screenshotBuff.equals(A.screenshotBuff)?(D=!0,S):(b=A,y6({command:t,state:A,fixtures:r,useMemory:o,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:m,logger:e,source:a,recoveryHint:i}))},frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,logger:e,browser:l}),S?.success){S?.updatedMemory&&gg(t,S.updatedMemory,e);break}else throw S?.thoughts?new M("AssertionFailureError",S.thoughts):new M("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(x){r.abortSignal.throwIfAborted(),y=x instanceof Error?x:new Error(`${x}`),D?e.info(`AI check attempt ${m} failed (re-used previous result)`):e.info({err:x},`AI check assert attempt ${m} failed, retrying...`);}finally{m++,h=N+d;}}if(!S?.success){let w=f-Date.now();w>0&&await ce(w,r.abortSignal);}if(!S?.success)try{S=await Ii({action:async()=>y6({command:t,state:await b6(l,e,r.abortSignal),fixtures:r,useMemory:o,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:m,logger:e,recoveryHint:i}),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,logger:e,browser:l});}catch(w){r.abortSignal.throwIfAborted(),y=w instanceof Error?w:new Error(`${w}`);}finally{m++;}S?.updatedMemory&&gg(t,S.updatedMemory,e);let T=S?.afterScreenshotOverride;if(T&&s.storeTraceAsset){let w=randomUUID();s.storeTraceAsset({snapshotId:w,data:T}),c.screenshotSnapshotId=w;}let v=S?.elementScreenshotOverride;if(v&&s.storeTraceAsset){let w=randomUUID();s.storeTraceAsset({snapshotId:w,data:v}),c.elementScreenshotSnapshotId=w;}if(!S?.success){c.result={thoughts:y?.message??"AI check failed after all attempts",result:false};let w=`AI check still failing after ${m} attempts.`;throw y&&(w+=` Latest result: ${y.message}`),new M("AssertionFailureError",w)}return c.result={thoughts:S.thoughts,result:true},{...S,succeedImmediately:false,urlAfterCommand:l.url()}})}async function b6(t,e,r){await t.waitForPageLoad({signal:r});let[o,n]=await Promise.all([Sc(t,{abortSignal:r,skipWait:true,skipWaitForPageLoad:true,logger:e}),t.screenshot({retries:1,respectActiveFrame:true})]);return {...o,screenshotBuff:n}}async function y6({command:t,state:e,fixtures:r,useConsensus:o,useMemory:n,highlightElementsOnFailure:i,attemptNumber:a,source:s,logger:c,recoveryHint:l}){let {browser:u,generator:d,abortSignal:m}=r,{serializedTree:f,tree:h}=e,S=e.screenshotBuff,b=S.toString("base64"),y=u.url(),T=t.contextChoice??"MULTIMODAL",v=f;T!=="VISION_ONLY"&&(v=await Ku({type:"assertion",serializedTree:f,tree:h,description:t.assertion,screenshot:b,fixtures:{generator:d,signal:m,logger:c,orgId:r.orgId}}),v);let w={goal:t.assertion,url:y,memory:n?t.cache?.memory:void 0,browserState:v,screenshot:b,contextChoice:T,source:s,recoveryHint:l},D=await(T==="VISION_ONLY"?(A,B)=>d.getVisualAssertionResult(A,B):(A,B)=>d.getAssertionResult(A,B))(w,{useConsensus:o,attemptNumber:a,useMemory:n,disableCache:!!t.disableCache,abortSignal:m,logger:c,loggerTags:Ie(c)}),x;if((D.result||i)&&D.relevantElements?.length){D.relevantElements.map(A=>u.getSerializedFormFromA11yId(A)).filter(A=>!!A);try{let A=D.relevantElements[0],{resolution:B}=await u.createTargetFromA11yId({id:A,description:null,targetSource:"AI",skipSaveToCache:!0});x=await u.screenshot({locator:B.locator,clearHighlights:!0,respectActiveFrame:!0});}catch(A){c.debug({err:A},"Failed to capture element screenshot for trace, continuing...");}await o_e(D.relevantElements,u,c);}return {success:D.result,thoughts:D.thoughts,afterScreenshotOverride:S,elementScreenshotOverride:x,updatedMemory:n?D.updatedMemory:void 0}}async function o_e(t,e,r){let o=Date.now();for(let n of t){if(Date.now()-o>2e3){r.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await Q(e.highlightA11yId(n),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}});}catch(i){r.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}async function T6(t){let{command:e,logger:r,fixtures:o,disableCache:n}=t,{browser:i,generator:a,abortSignal:s}=o;if(!e.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(e.schema){let d=ym(e.schema);if(d)throw new M("UserConfigurationError",d)}let c=await i.getCondensedHtml(),l=await i.screenshot({retries:2}),u=Lr();try{return await u.startAsyncSpan("AI_EXTRACTION_CALL",async d=>{let m=await a.getTextExtraction({goal:e.goal,browserState:c,returnSchema:e.schema,screenshot:`data:image/jpeg;base64,${l.toString("base64")}`},{disableCache:n,abortSignal:s,loggerTags:Ie(r)});if(d.result=m,n_e({tracer:u,span:d,screenshot:l,htmlState:c,logger:r}),m.result==="NOT_FOUND")throw new M("ActionFailureError","No relevant data found for extraction goal on this page");if(m.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",m.thoughts);return {thoughts:m.thoughts||void 0,data:m.result,succeedImmediately:!1,urlAfterCommand:i.url()}})}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step in the browser instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}}function n_e(t){let{tracer:e,span:r,screenshot:o,htmlState:n,logger:i}=t;if(e.storeTraceAsset)try{let a=randomUUID();e.storeTraceAsset({snapshotId:a,data:o}),r.screenshotSnapshotId=a;let s=randomUUID();e.storeTraceAsset({snapshotId:s,data:Buffer.from(n),extension:"html"}),r.browserStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}async function v6(t,e){let{logger:r}=t,{abortSignal:o,browser:n}=e,i=Date.now();try{await i_e(i,t,e);}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||o.aborted)return;r.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=n.smartWaitingTimeout-(Date.now()-i);s>0&&await ce(s,o);}finally{r.debug({durationMs:Date.now()-i},"AI smart waiting complete");}}async function i_e(t,e,r){let{abortSignal:o,browser:n}=r;if(n.smartWaitingTimeout<3e3){await ce(n.smartWaitingTimeout,o);return}if(!e.description)throw new M("UserConfigurationError","Cannot locate element with empty description");await Q(a_e(t,e,r),{milliseconds:n.smartWaitingTimeout});}async function a_e(t,e,r){let{logger:o,iframeUrl:n}=e,{browser:i}=r;for(;Date.now()-t<i.smartWaitingTimeout;)if(await Ii({action:async()=>s_e(e,r),frameConfig:n?{type:"url",url:n}:void 0,browser:i,logger:o}))return}async function s_e(t,e){let{testContext:r,logger:o}=t,{browser:n,abortSignal:i,localCodeEvalTools:a,orgId:s,generator:c}=e,l=t.description;r&&(l=await Gs({orgId:s,s:l,context:r,localTools:a,signal:i,logger:o})),i.throwIfAborted();let u;try{u=await n.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(f){throw new M("ActionFailureError",`Failed to take screenshot of page to perform smart waiting. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${f instanceof Error?f.message:f}`)}let m=`data:image/jpeg;base64,${u.toString("base64")}`;i.throwIfAborted();let p=await c.getSmartWaitingDecision({description:l,screenshot:m},{abortSignal:i,loggerTags:Ie(o)});return o.debug({result:p},"Got smart waiting result"),p.isPageReady}async function w6(t){return Lr().startAsyncSpan("ELEMENT_ASSERTION",async r=>l_e(t,r),{name:"Element check"})}async function l_e(t,e){let{command:r,timeoutMs:o,fixtures:n,disableCache:i}=t,{abortSignal:a}=n,s=()=>kR(r.cache)?r.cache:void 0,c=s(),l=!i&&!!c?.target&&Ed(c.target),u=cloneDeep(c),d=(y=false)=>{if(c=s(),!!c)if(y){let T=QW(u,c);c.target=T.target,c.updatedAt=T.updatedAt;}else {if(!u){c=void 0;return}c.target=u.target,c.updatedAt=u.updatedAt;}},m=Date.now(),p=0,f,h=500,S=false;for(;p<2||Date.now()-m<o;){p++,p>1&&await ce(h,a),a?.throwIfAborted(),c=s();let y=p===1,{result:T,elementWasFound:v}=await C6({cacheToUse:c,skipAISmartWaiting:!y,useAIIfCacheFails:!l,params:t});if(f=T,S=S||v,T.success)break;d(),h=Math.min(h*1.25,1e4);}if(!f)throw new M("InternalPlatformError",`Failed to evaluate manual element assertion in ${o}ms.`);if(a?.throwIfAborted(),!f.success){let y=s(),T=y?.target?.memory?{target:{id:-1,memory:y.target.memory}}:void 0,{result:v,elementWasFound:w}=await C6({cacheToUse:T,skipAISmartWaiting:true,useAIIfCacheFails:true,params:t});f=v,S=S||w,f.success||d(true);}let b=s();return f.success&&b?.target&&!S&&(b.target=ZP(b.target),b.updatedAt=new Date),e.result={success:f.success,message:f.err?.message},f}async function C6({cacheToUse:t,skipAISmartWaiting:e,useAIIfCacheFails:r,params:o}){let{command:n,disableCache:i,fixtures:a,tracer:s,targetingWrapper:c}=o,{logger:l}=a;if(n.target&&!dl(n.target))throw new Error("Element assertion with x/y is not supported yet");let u=$m(n.assertion),d=c_e(n.assertion),m,p=false,f=cloneDeep(t);try{let{elementInteractedDisplayString:h,result:S,thoughts:b}=await c({tracer:s,command:n,target:n.target,cache:f?.target,action:async y=>u_e(y.locator,o),options:{...n,allowNotActionableNodesOverride:d,allowIneligibleTagRedirect:d,showZeroOpacityElementsOverride:!0,disableCache:i,memory:f?.target?.memory,disableGlobalLocatorRedirect:!0,source:Zf(n),skipAISmartWaiting:e,targetName:"target"},retriesWithAI:r?1:0});return m={success:S.success,data:S.data,err:S.err,elementInteractedDisplayString:h,thoughts:b},p=!0,S.success||(l.warn({aiThoughts:b,elementString:h,err:S.err},"Element check found an element but failed"),m={...S,thoughts:b}),{result:m,elementWasFound:p}}catch(h){if(u)return m={success:true,thoughts:`The element described does not exist on the page: ${h.message}`,err:void 0,data:void 0},{result:m,elementWasFound:p};if(!(h instanceof M)||h.reason!="ActionFailureError")throw h;return m={success:false,err:h,data:void 0,thoughts:void 0},l.warn({err:h},"Element check did not find an element and failed"),{result:m,elementWasFound:p}}}function c_e(t){return !(t.type==="ELEMENT_EXISTENCE"&&t.condition==="VISIBLE"&&!t.negated)}async function u_e(t,{command:e,fixtures:r}){return await r.browser.highlight(t),await d_e(t,e.assertion)}async function d_e(t,e){let r=true,o,n;switch(e.type){case "ELEMENT_CONTENT":{let a=await t.textContent()??"";if(n={elementTextContent:Cr(a,500,true)},!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,o=new M("AssertionFailureError",`The content ${s} '${e.value}': ${a}`);}break}case "ELEMENT_ATTRIBUTE":{n={elementOuterHtml:Cr(await t.evaluate(s=>s.cloneNode(false).outerHTML),500,true)};let a=null;try{a=await t.getAttribute(e.attr,{timeout:3e3});}catch(s){o=new M("AssertionFailureError",j(s)),r=false;break}if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,e.operation==="EXISTS"?o=new M("AssertionFailureError",`The attribute ${e.attr} ${s}`):o=new M("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`);}break}case "ELEMENT_EXISTENCE":{switch(e.condition){case "VISIBLE":{r=await t.evaluate(async(s,c)=>{let l=Date.now();for(;Date.now()-l<c;){await new Promise(d=>setTimeout(d,250));let u=s.getBoundingClientRect();if(!(u.width===0||u.height===0)&&window.getComputedStyle(s).visibility!=="hidden"&&window.getComputedStyle(s).display!=="none")return true}return false},Zr*1e3);break}case "EDITABLE":{r=await t.isEditable({timeout:Zr*1e3});break}case "EXISTS":{r=true;break}case "ENABLED":{r=await t.isEnabled({timeout:Zr*1e3});break}case "FOCUSED":{r=await t.evaluate(s=>s===document.activeElement);break}default:return (s=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})(e.condition)}if(r=e.negated?!r:r,!r){let a=fo(e);o=new M("AssertionFailureError",`The element ${a}`);}break}case "ELEMENT_NAME":{let a=await t.evaluate(s=>s.tagName);if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:true})){let s=fo(e);r=false,o=new M("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`);}break}case "ELEMENT_STYLE":{let a=await t.evaluate((s,c)=>window.getComputedStyle(s).getPropertyValue(c),e.property);if(!sn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let s=fo(e);r=false,e.operation==="EXISTS"?o=new M("AssertionFailureError",`The style property ${e.property} ${s}`):o=new M("AssertionFailureError",`The style property ${e.property} ${s} '${e.value}': ${a}`);}break}default:return (a=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}return {thoughts:void 0,success:r,data:n,err:o}}function R6(t){return t.type==="ELEMENT_EXISTENCE"&&t.negated&&t.condition==="EXISTS"}async function nS(t,e){let r=await t.screenshot(e),o=await Jimp.fromBuffer(r);return {buffer:r,width:Math.ceil(o.bitmap.width??0),height:Math.ceil(o.bitmap.height??0)}}async function M6({tracer:t,command:e,disableCache:r,browser:o,targetingWrapper:n,logger:i,screenshotStorage:a}){if(e.target&&!dl(e.target))throw new Error("Visual Diff with x/y is not supported yet");await o.waitForStability({logger:i});let s={clearHighlights:true,hideCaret:true},c;e.target?.elementDescriptor?c=(await n({tracer:t,command:e,target:e.target,cache:e.cache?.target,action:async B=>nS(o,{locator:B.locator,...s}),options:{...e,disableCache:r,disableGlobalLocatorRedirect:true,memory:e.cache?.target?.memory,targetName:"target"}})).result:c=await nS(o,s);let l=await a.prepareGoldenScreenshotForComparison(i,e,c);if((c.height!==l.height||c.width!==l.width)&&i.warn({currHeight:c.height,currWidth:c.width,savedHeight:l.height,savedWidth:l.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(c.height-l.height)>10||Math.abs(c.width-l.width)>10){let A=`${c.width}x${c.height}`,B=`${l.width}x${l.height}`;return {fail:true,thoughts:`Current screenshot (${A}) does not match saved screenshot dimensions (${B}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:c.buffer,succeedImmediately:false,urlAfterCommand:o.url()}}let u=await Jimp.fromBuffer(c.buffer),d={width:c.width,height:c.height},m=await Jimp.fromBuffer(l.buffer),p={width:l.width,height:l.height},f,h=d.width*d.height,S=p.width*p.height,b=Math.abs(d.height-p.height),y=Math.abs(d.width-p.width);if(h>S){let A=u.cover({w:p.width,h:p.height});c.buffer=await A.getBuffer("image/jpeg"),f="current",c.width=p.width,c.height=p.height;}else if(S>h){let A=m.cover({w:d.width,h:d.height});l.buffer=await A.getBuffer("image/jpeg"),f="saved";}let T={data:Buffer.alloc(c.width*c.height*4),width:c.width,height:c.height},v=e.threshold??.1,N=Ove(yN.decode(l.buffer).data,yN.decode(c.buffer).data,T.data,c.width,c.height,{threshold:v,diffColorAlt:[0,255,0]})/(c.width*c.height)*100,D=N>v*100,x=`Visual diff of ${N.toFixed(2)}% detected, which is ${D?"over":"under"} the threshold of ${v*100}%.`;if(f&&(x+=` The ${f} screenshot was cropped since it was taller by ${b} pixels and wider by ${y} pixels.`),D)throw new M("ActionFailureError",x);return {fail:D,thoughts:x,beforeScreenshotOverride:c.buffer,afterScreenshotOverride:yN.encode(T,75).data,succeedImmediately:false,urlAfterCommand:o.url()}}var f_e=3e4;function h_e(t){if(!t.body)return {};switch(t.body.type){case "json":return {content:t.body.content,contentType:"application/json"};case "form-urlencoded":{let e=new URLSearchParams;return Object.entries(t.body.content).forEach(([r,o])=>{e.append(r,o);}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function Tp({command:t,logger:e,baseUrl:r,fetchImplementation:o=fetch}){let n=t.timeout??f_e/1e3,i=Object.fromEntries(Object.entries(t.headers||{}).filter(([f,h])=>f&&h)),a=new URLSearchParams;Object.entries(t.params||{}).filter(([f,h])=>f&&h).forEach(([f,h])=>{a.append(f,h);});let s=a.toString(),c;if(Hm(t.url)&&(c=t.url),r&&Gm(t.url,r)&&(c=new URL(t.url,r).toString()),!c)throw new M("ActionFailureError",`Invalid URL: ${t.url}`);let l=c;e.info({url:l,searchParams:s,headers:i,body:t.body,method:t.method},"Making HTTP request");let d=await Q((async()=>{let f=s?`${l}?${s}`:l;try{let h=h_e(t),S=new Headers(i);return h.contentType&&!S.has("Content-Type")&&S.set("Content-Type",h.contentType),await o(f,{headers:S,method:t.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:n*1e3,fallback:()=>{throw new M("ActionFailureError",`Fetch request timed out after ${n} seconds`)}});if(!d.ok){let f;try{f=await d.text();}catch(h){f=`Failed to read response body: ${h}`;}throw new M("ActionFailureError",`Fetch request failed with status ${d.status}: ${f}`)}let m={};d.headers.forEach((f,h)=>{m[h]=f;});let p={status:d.status,headers:m,request:{url:d.url,method:t.method,headers:i}};if(t.body?.type==="json"&&t.body.content)try{p.request.json=JSON.parse(t.body.content);}catch{}if(d.headers.get("content-type")?.includes("json"))try{p.json=await d.json();}catch{}else d.headers.get("content-type")?.includes("text")&&(p.text=await d.text());return p}var g_e=5e3;async function I6({timeout:t=Zr,...e}){let r=Date.now(),o=t*1e3,n=o+1e4,i,a=0,s=500;for(;a-r<o;){if(Date.now()-r>n){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let c=Date.now();i=await x6(e),a=Date.now();let l=a-c;if(l>1e3&&e.logger.warn({pageAssertDuration:l},"Page assertion took longer than expected"),!i.success)await ce(s,e.signal),s=Math.min(Math.floor(s*1.5),g_e);else return i}return i=await x6(e),i}async function x6(t){return Lr().startAsyncSpan("PAGE_ASSERTION",async r=>{let o=await EN(t);return r.result={success:o.success,message:o.err?.message},o},{name:"Page check"})}async function EN({assertion:t,browser:e,autoExpandIframes:r}){switch(t.type){case "CONTENT":case "CONTENT":{let n,i=false,a;try{let s;if(r){let c=await e.evaluateFunctionInAllFrames(P6,{value:t.value,negated:!!t.negated,returnHtml:!1});i=t.negated?c.every(l=>l.evaluation):c.some(l=>l.evaluation),s=c.find(l=>l.pageHtml)?.pageHtml;}else ({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(P6,{value:t.value,negated:!!t.negated,returnHtml:!0},"checking page content"));if(!i){let c=t.negated?ks.CONTAINS:Fs.CONTAINS;a=new M("AssertionFailureError",`The page ${c} '${t.value}'.`),n=s;}}catch(s){a=new M("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`);}return {success:i,err:a,data:i||!n?void 0:{pageContent:n}}}default:return (n=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}}function P6({value:t,negated:e,returnHtml:r}){let o=document.body.innerHTML,n=o.includes(t)===!e;return o.length>1e4&&(o=o.slice(0,1e4)+"...TRUNCATED"),{evaluation:n,pageHtml:!n&&r?o:void 0}}var S_e=3e4;async function O6({command:t,logger:e,baseUrl:r,fetchImplementation:o=fetch}){let n=t.timeout??S_e/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(t.headers||{}).filter(([d,m])=>d&&m));a["Content-Type"]="application/json";let s;if(Hm(t.url)&&(s=t.url),r&&Gm(t.url,r)&&(s=new URL(t.url,r).toString()),!s)throw new M("ActionFailureError",`Invalid URL: ${t.url}`);let l=await Q((async()=>{try{return await o(s,{headers:a,method:"POST",body:JSON.stringify({query:t.query,variables:t.variables?JSON.parse(t.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:n*1e3});if(!l)throw new M("ActionFailureError",`GraphQL request timed out after ${n} seconds`);if(!l.ok){let d,m=await l.text();try{d=JSON.parse(m);}catch{throw new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${m}`)}throw d?.errors?.length&&d?.errors[0]?.message?new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${d.errors[0].message}`):new M("ActionFailureError",`GraphQL request failed with status ${l.status}: ${m}`)}let u={};return l.headers.forEach((d,m)=>{u[m]=d;}),{status:l.status,headers:u,json:await l.json()}}var SC=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;executionOptionsStack=[];recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:r,logger:o,storage:n,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:c,options:l}){this.orgId=i,this.options=l,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=n,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=c,this.localCodeEvalTools=a,this.generator=r,this.logger=o;}setOpen(){this.executeAbortController=new AbortController,this.browser.registerAbortSignal(this.executeAbortController.signal);}setClosed(){this.executeAbortController.abort();}throwIfClosed(){this.executeAbortController.signal.throwIfAborted();}get closed(){return this.executeAbortController.signal.aborted}async withExecutionOptions(e,r){this.executionOptionsStack.push(e);try{return await r()}finally{this.executionOptionsStack.pop();}}getCurrentExecutionOptions(){return this.executionOptionsStack[this.executionOptionsStack.length-1]??{}}async evaluateAiAction({goal:e,startingScreenshot:r,history:o,disableCache:n,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[c,l]=await Promise.all([Sc(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:true,skipWaitForPageLoad:true,logger:s}),this.browser.screenshot({retries:1,clearHighlights:true})]),u=`data:image/jpeg;base64,${l.toString("base64")}`,d=await Ku({type:"ai-action",description:e,screenshot:u,serializedTree:c.serializedTree,tree:c.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),m={url:this.browser.url(),browserState:d,startingScreenshot:r,history:o,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(m,{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:{...Ie(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:r,history:o,actionHint:n,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let c=this.browser.url(),[l,u]=await Promise.all([Sc(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:true,skipWaitForPageLoad:true,logger:a}),this.browser.screenshot({retries:1,clearHighlights:true})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,m=await Ku({type:"ai-action",description:e,screenshot:d,serializedTree:l.serializedTree,tree:l.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),p={url:c,browserState:m,startingScreenshot:r,history:o,goal:e,actionHint:n,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(p,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...Ie(a)},langfuseSessionId:s})}catch(f){throw new M("InternalWebAgentError",`Error generating command: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}}async getBrowserState(e){return Sc(this.browser,e)}async locateElement(e){return await bN(e,this.getControllerFixtures())}async locateElementWithSelector(e,r){return Ii({action:async()=>{let o=await this.browser.resolveHardcodedCssSelector({selector:e,timeoutMs:2e3,logger:this.logger});return {thoughts:"Located element with selector",target:{id:-1,selector:e,targetSource:"USER_CSS_SELECTOR",targetUpdateTime:new Date().toUTCString()},resolution:o}},frameConfig:r?{type:"url",url:r}:void 0,browser:this.browser,logger:this.logger})}getControllerFixtures(){return {browser:this.browser,generator:this.generator,logger:this.logger,orgId:this.orgId,storage:this.storage,localCodeEvalTools:this.localCodeEvalTools,abortSignal:this.executeAbortController.signal}}shouldUseMemory(){return this.options?.useMemory??true}async wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:o,descriptions:n,caches:i,action:a,options:s,retriesWithAI:c=1}){let l=[];for(let u=0;u<n.length;u++){let d=n[u],m=await this.wrapElementTargetingCommand({tracer:e,command:r,target:d,cache:i[u],action:async p=>p,options:{...s,targetName:o[u]}});l.push(m);}try{let u=await a(...l.map(p=>p.result)),d=p=>p==="fromTarget"?"From Target":p==="toTarget"?"To Target":"Target",m=l.map((p,f)=>p.thoughts?`${d(o[f])}: ${p.thoughts}`:void 0).filter(p=>!!p).join(" -------------- ")||void 0;return {result:u,elementInteractedDisplayStrings:l.map(p=>p.elementInteractedDisplayString),thoughts:m}}catch(u){if(this.throwIfClosed(),c>0)return this.logger.warn({err:u},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:o,descriptions:n,caches:n.map(()=>{}),action:a,options:s,retriesWithAI:c-1});throw new M("ActionFailureError",u.message,{errOptions:{cause:u}})}}async wrapHardcodedCssTargetingCommandHelper({target:e,action:r,options:o,command:n}){let i=this.logger.child({commandId:n.id}),{targetName:a}=o;if(e.type!=="description")throw new M("ActionFailureError","Cannot use selector with non-description target");let s,c=Date.now(),l=Date.now();for(;Date.now()-l<this.browser.smartWaitingTimeout;){c=Date.now();try{let u=await this.browser.resolveHardcodedCssSelector({selector:e.elementDescriptor,targetName:a,logger:i});return {result:await r({locator:u.locator,originalElementLocationResult:void 0,serverSideBoundingBox:null}),elementInteractedDisplayString:u.displayString}}catch(u){if(u.name==="AbortError")throw u;s=u,i.warn({err:u},"Failed to action on hardcoded css selector"),Date.now()-c<500&&await ce(500);}}throw s}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:r,disableGlobalLocatorRedirect:o,logger:n}=e,i=Lr(),a=!o&&this.browser.userBrowserSettings.globalLocatorRedirect!==false;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(r.locator);});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async c=>{let{targetingResult:l,metadata:u}=await this.browser.performTargetRedirection(r,n);if(c.result=u,u.outcome==="redirected to new element"&&l&&i.storeTraceAsset&&!this.browser.userBrowserSettings.disableBrowserMonitoring){let d=randomUUID();(async()=>{try{let m=await this.browser.screenshot({locator:l.locator,clearHighlights:!0,boundingBoxOverride:l.serverSideBoundingBox??void 0});i.storeTraceAsset?.({snapshotId:d,data:m});}catch(m){n.debug({err:m},"Failed to capture element screenshot for redirect trace");}})(),c.elementScreenshotSnapshotId=d;}return l})),s||(s={locator:r.locator,serverSideBoundingBox:await r.locator.boundingBox({timeout:Oe}),originalElementLocationResult:r.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{cache:r,options:o,logger:n}=e,a=await Lr().startAsyncSpan("CACHE_RESOLUTION",async c=>{c.targetSource=r.targetSource;try{let l=await this.browser.resolveTarget(r,{allowNotActionableNodesOverride:o.allowNotActionableNodesOverride,logger:n,signal:this.executeAbortController.signal,...o.resolveTargetOptions,acceptElementMovedError:o.force});c.attributes.targetDisplayString=l.displayString,c.attributes.decisions=l.decisions;let u=l.decisions.find(d=>d.matched);return u&&(c.resolutionMethod=u.type),l}catch(l){throw l instanceof we&&(c.cacheMissReason=l.cacheMissReason,c.attributes.decisions=l.decisions),l}}),s=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:a,disableGlobalLocatorRedirect:o.disableGlobalLocatorRedirect,logger:n});return o.force||await a.revalidator?.(),{resolutionResult:a,finalTarget:s}}async wrapElementTargetingCommand(e){return await Ii({action:()=>this.wrapElementTargetingCommandHelper(e),frameConfig:e.options.iframeUrl?{type:"url",url:e.options.iframeUrl}:void 0,browser:this.browser,logger:this.logger})}async wrapElementTargetingCommandHelper(e){let{tracer:r,target:o,action:n,options:i,command:a,finalAttempt:s=false,originalCache:c=e.cache}=e,{retriesWithAI:l=1}=e,{disableCache:u,useSelector:d,targetName:m}=i,p=Lr(),f=this.logger.child({commandId:a.id}),h=this.shouldUseMemory(),S=cloneDeep(e.cache);if((!S||u)&&!qk(o))throw new M("ActionFailureError","Cannot target element with no cached data or element descriptor");if(d)return this.wrapHardcodedCssTargetingCommandHelper(e);let b=false,y;u&&(f.info("Cache explicitly disabled for this step"),b=true,y="Cache explicitly disabled",S=void 0);let T=d6({cache:S,description:o.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:f});S=T.cache,b=b||T.cacheBustedBeforeAction,!y&&T.cacheBustReason&&(y=T.cacheBustReason);let v=true;if(!u6(S))return l--,v=false,this.executeTargetingCommandWithAI({tracer:p,stepTracer:r,target:o,options:i,command:a,action:n,originalCache:c,logger:f,useMemory:h,cacheBustedBeforeAction:b,cacheBustReason:y});try{let{resolutionResult:w,finalTarget:N}=await this.resolveCachedTargetForAction({cache:S,options:i,logger:f}),D=await n(N);if(_t.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.97.3"]),xT({cmd:a,key:m,newTarget:S,logger:f,updatedWithAI:!1}),v){let x=w.decisions.filter(A=>A.matched);if(x.length!==1)f.warn({decisions:w.decisions},"Expected exactly 1 matching method for element location, got more or less");else {let A=x[0].type;r.recordTargetAutoHeal({healType:A});}}return {result:D,elementInteractedDisplayString:w.displayString}}catch(w){this.throwIfClosed();let N=XR(w);if(N&&!s)return f.warn({err:w},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({tracer:r,command:a,target:o,action:n,cache:c,originalCache:c,retriesWithAI:l,finalAttempt:true,options:i});if(w instanceof M&&!N)throw f.warn({err:w},"Failed to execute command with target (fatal)"),w;if(l>0&&o){f.info({err:w},"Failed to execute action with cached target, retrying with AI"),_t.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!S.requirements}`,`hasAdditionalElements:${!!S.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.97.3",`missReason:${w instanceof we?w.cacheMissReason:"unknown"}`]);let D;S.memory&&Kk(S.memory)&&(D=S.memory);let x=w instanceof we&&w.cacheMissReason==="failing-ldist";return this.wrapElementTargetingCommandHelper({tracer:r,command:a,target:o,cache:void 0,action:n,originalCache:c,retriesWithAI:l,finalAttempt:true,options:{...i,memory:D,targetHealingInProgress:true},skipInitialLocateWait:x})}throw new M("ActionFailureError",`Failed to execute interactive command: ${w instanceof Error?w.message:`${w}`}`,{errOptions:{cause:w}})}}async executeTargetingCommandWithAI(e){let{tracer:r,stepTracer:o,target:n,options:i,command:a,action:s,originalCache:c,logger:l,useMemory:u,cacheBustedBeforeAction:d,cacheBustReason:m,skipInitialLocateWait:p}=e;l.info({description:n.elementDescriptor,targetHealingInProgress:i.targetHealingInProgress,cacheBustedBeforeAction:d,memory:i.memory,useMemory:u},"Prompting AI for an updated element location");let f=false;(d||!c)&&!this.getCurrentExecutionOptions().skipAISmartWaiting&&!i.skipAISmartWaiting?(await r.startAsyncSpan("SMART_WAITING",async()=>await v6({description:n.elementDescriptor,iframeUrl:i.iframeUrl,source:i.source,logger:l,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride},this.getControllerFixtures())),f=true):(d||!c)&&(i.skipAISmartWaiting?l.debug("Skipping AI smart waiting for this targeting attempt"):l.debug("Skipping AI smart waiting due to controller execution options"));let h=2;for(let S=1;S<=h;S++){let b=false,y=this.browser.getActiveFrameConfig(),T=i.force||S>1;try{let v;try{v=await bN({description:n.elementDescriptor,disableCache:!!i.disableCache,iframeUrl:i.iframeUrl,source:i.source,useMemory:u,memory:u?i.memory:void 0,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride,allowIneligibleTagRedirect:i.allowIneligibleTagRedirect,showZeroOpacityElementsOverride:i.showZeroOpacityElementsOverride,logger:l,skipWait:f||p,isAutoHeal:!!i.targetHealingInProgress,cacheBustReason:m,acceptElementMovedError:T},this.getControllerFixtures());}catch(D){if(D instanceof va&&D.updatedLocatorMemory){let x={id:-1,...c,memory:D.updatedLocatorMemory};xT({cmd:a,key:i.targetName,newTarget:x,logger:l,updatedWithAI:!0});}throw D}v.frameConfig&&(this.browser.setActiveFrameConfig(v.frameConfig),b=!0);let w=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:v.resolution,disableGlobalLocatorRedirect:i.disableGlobalLocatorRedirect,logger:l}),N=await s(w);return xT({cmd:a,key:i.targetName,newTarget:v.target,logger:l,updatedWithAI:!0}),i.targetHealingInProgress&&(o.recordTargetAutoHeal({healType:"AI"}),v.target.targetSource="AI_HEALED",v.target.targetUpdateTime=new Date().toUTCString(),v.target.targetUpdateLoggerTags=Ie(l)),{result:N,elementInteractedDisplayString:v.resolution.displayString,thoughts:v.thoughts}}catch(v){if(b&&this.browser.setActiveFrameConfig(y),this.throwIfClosed(),S<h&&XR(v)){l.warn({err:v,aiAttempt:S},"Encountered retryable AI targeting error; retrying with AI once");continue}throw v instanceof M?v:new M("ActionFailureError",v.message)}}throw new M("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return nS(this.browser,e)}async executePresetCommand(e,r,o,n,i){this.options?.slowMoMs&&await ce(this.options.slowMoMs);let a=await this.browser.getOpenPages(),s=this.browser.url(),c;try{c=await this.resolveCommandTemplateStrings(r,o);}catch(l){throw this.throwIfClosed(),new M("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,r,o,n,i);return this.options?.autoFollowNewTabs&&await c6({beforeUrl:s,command:r,beforePages:a.map(u=>u.url),browser:this.browser,logger:this.logger}),l}catch(l){throw l.name!=="AbortError"&&this.logger.error({err:l},"Error thrown in action controller"),l}finally{gp(r,c);}}createCallbacksForBrowser(e){return {createIsolatedFolder:()=>XO(e)}}async traceBrowserInteraction(e,r,o){return Lr().startAsyncSpan("BROWSER_INTERACTION",async i=>r(i),{name:e,...o})}async resolveCommandTemplateStrings(e,r){return hp({obj:e,context:r,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,r,o,n,i){n=n||"disableCache"in r&&!!r.disableCache;let a=this.logger.child({commandId:r.id});switch(r.type){case "SUCCESS":{let s=r.condition;return s?.assertion.trim()?gC({command:s,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:a,recoveryHint:i}):{succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "AI_ASSERTION":{if(!r.assertion.trim())throw new M("ActionFailureError","Missing assertion");if(r.timeout&&r.timeout>1800)throw new M("AssertionFailureError",`AI check timeout of ${r.timeout} exceeds the maximum allowed value of 30 minutes.`);return gC({command:r,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:a,recoveryHint:i})}case "AI_EXTRACT":return T6({command:r,logger:a,fixtures:this.getControllerFixtures(),disableCache:n});case "NAVIGATE":if(!Hm(r.url)&&!Gm(r.url,this.browser.baseUrl))throw new M("ActionFailureError",`Invalid URL provided to navigate command: ${r.url}`);await this.traceBrowserInteraction("Navigate",()=>this.browser.navigate({url:r.url,loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0}));break;case "DIALOG":this.browser.registerDialogHandler(r.action);break;case "CAPTCHA":throw new M("UserConfigurationError","Captcha solving is no longer available on Momentic");case "GO_BACK":await this.traceBrowserInteraction("Go back",()=>this.browser.goBack());break;case "GO_FORWARD":await this.traceBrowserInteraction("Go forward",()=>this.browser.goForward());break;case "SCROLL_LEFT":case "SCROLL_RIGHT":case "SCROLL_DOWN":case "SCROLL_UP":{let s,c;if(r.target&&ya(r.target)){let d=Kt(r.target.pixels);await this.browser.hoverUsingVisualCoordinates(d);}else if(r.target&&r.target.elementDescriptor.trim()){let{elementInteractedDisplayString:d,thoughts:m}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:p=>this.browser.hover(p),options:{...r,targetName:"target",disableGlobalLocatorRedirect:true,disableCache:n}});s=d,c=m;}let l=this.browser.getViewport()?.height??hl.height,u=this.browser.getViewport()?.width??hl.width;switch(r.type){case "SCROLL_UP":await this.traceBrowserInteraction("Scroll up",()=>this.browser.scrollVertical(-(r.deltaY??l)));break;case "SCROLL_DOWN":await this.traceBrowserInteraction("Scroll down",()=>this.browser.scrollVertical(r.deltaY??l));break;case "SCROLL_LEFT":await this.traceBrowserInteraction("Scroll left",()=>this.browser.scrollHorizontal(-(r.deltaX??u)));break;case "SCROLL_RIGHT":await this.traceBrowserInteraction("Scroll right",()=>this.browser.scrollHorizontal(r.deltaX??u));break}return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "WAIT_FOR_URL":{if(r.timeout&&r.timeout>1800)throw new M("UserConfigurationError",`Wait for URL timeout of ${r.timeout} exceeds the maximum allowed value of 30 minutes.`);let s=r.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:s},{timeout:r.timeout?r.timeout*1e3:void 0,negated:r.negated,caseInsensitive:r.caseInsensitive});break}case "WAIT":{if(r.delay>1800)throw new M("UserConfigurationError",`Wait timeout of ${r.delay} seconds exceeds the maximum allowed value of 30 minutes`);let s=r.delay*1e3;await ce(s,this.executeAbortController.signal);break}case "REFRESH":await this.traceBrowserInteraction("Refresh",()=>this.browser.refresh({loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0}));break;case "CLICK":{if(ya(r.target)){let m=Kt(r.target.pixels),p={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0};await this.traceBrowserInteraction("Click",()=>this.browser.clickUsingVisualCoordinates(m,p),{coordinates:m});break}let s=this.browser.url(),{elementInteractedDisplayString:c,result:l,thoughts:u}=await this.wrapElementTargetingCommand({tracer:e,target:r.target,command:r,cache:r.cache?.target,action:m=>this.traceBrowserInteraction("Click",async p=>{let f={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0},h=await this.browser.click(m,this.createCallbacksForBrowser(this.orgId),f);return h.coordinates&&(p.coordinates=h.coordinates),h},{selector:m.locator.toString()}),options:{...r,targetName:"target",disableCache:n}}),d={urlAfterCommand:this.browser.url(),succeedImmediately:false,elementInteracted:c,thoughts:u,data:l.downloadedFile?{downloadedFile:l.downloadedFile}:void 0};return VT(s,d.urlAfterCommand)&&(d.succeedImmediately=true,d.succeedImmediatelyReason="URL changed"),d}case "COPY":return await this.browser.copy(r.value),{succeedImmediately:false,data:r.value,urlAfterCommand:this.browser.url()};case "PASTE":{await this.browser.paste();break}case "DRAG":{if(ya(r.fromTarget)&&ya(r.toTarget)){let l=Kt(r.fromTarget.pixels),u=Kt(r.toTarget.pixels);await this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDropUsingVisualCoordinates(l,u,{hoverDurationMs:r.hoverSeconds?r.hoverSeconds*1e3:void 0}),{coordinates:l});break}if(ya(r.fromTarget)||ya(r.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:s,thoughts:c}=await this.wrapMultiElementTargetingCommand({tracer:e,command:r,targetNames:["fromTarget","toTarget"],descriptions:[r.fromTarget,r.toTarget],caches:[r.cache?.fromTarget,r.cache?.toTarget],action:(l,u)=>this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDrop(l,u,{hoverDurationMs:r.hoverSeconds?r.hoverSeconds*1e3:void 0,steps:r.steps})),options:{...r,disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s[0],thoughts:c}}case "MOUSE_DRAG":{let s=parseInt(r.deltaX),c=parseInt(r.deltaY),l=r.steps??5;if(isNaN(s)||isNaN(c))throw new M("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${r.deltaX}, ${r.deltaY})`);if(r.target&&ya(r.target)){let m=Kt(r.target.pixels);await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDragUsingVisualCoordinates({deltaX:s,deltaY:c,steps:l,fromTarget:m}),{coordinates:m});break}let u,d;if(r.target?.elementDescriptor){let{elementInteractedDisplayString:m,thoughts:p}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:async f=>this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(s,c,l,f.locator,{force:r.force})),options:{...r,targetName:"target",disableCache:n}});u=m,d=p;}else await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(s,c,l,void 0,{force:r.force}));return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:u,thoughts:d}}case "SELECT_OPTION":{if(!dl(r.target))throw new Error("Select with x/y is not supported yet");let s=r.target.elementDescriptor,c=r.choice,{elementInteractedDisplayString:l,thoughts:u}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:{type:"description",elementDescriptor:s},cache:r.cache?.target,action:d=>this.traceBrowserInteraction("Select option",()=>this.browser.selectOption(d,c,r.force),{value:c.type==="LABEL"?c.label:c.type==="VALUE"?c.value:c.index}),options:{...r,targetName:"target",disableCache:n,source:Zf(r)}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:u}}case "TAB":{let s={loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0,retry:true};await this.browser.switchToPage(r.action,s);break}case "NEW_TAB":await this.browser.createNewTab(r.url,{loadTimeoutMs:r.loadTimeout?r.loadTimeout*1e3:void 0});break;case "CLOSE_TAB":await this.browser.closePage(r.action,{retry:true});break;case "COOKIE":{if(!r.value)break;let s=await this.browser.setCookie(r.value);a.debug({results:s},"Set cookies");break}case "LOCAL_STORAGE":if(!r.value||!r.key)break;await this.browser.setLocalStorage(r.key,r.value);break;case "JAVASCRIPT":{let s;try{r.environment==="BROWSER"?(s=await this.browser.evaluateCodeInPage({code:r.code,fragment:r.fragment??!1,context:o.toObjectCopy(),timeoutMs:r.timeout?r.timeout*1e3:void 0}),a.info({result:s},"Executed JavaScript in browser")):s=await _i({orgId:this.orgId,code:r.code,fragment:!!r.fragment,context:o,timeoutMs:r.timeout?r.timeout*1e3:void 0,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async c=>{if(!this.options?.scratchPadId){a.warn({updates:c},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:c,logger:a});}}});}catch(c){throw this.throwIfClosed(),new M("ActionFailureError",c instanceof Error?c.message:`${c}`,{errOptions:{cause:c}})}try{JSON.stringify(s);}catch(c){throw new M("ActionFailureError",`Return value is not serializable: ${c instanceof Error?c.message:`${c}`}`,{errOptions:{cause:c}})}return {urlAfterCommand:this.browser.url(),succeedImmediately:false,data:s}}case "TYPE":{if(r.target&&ya(r.target)){let p=Kt(r.target.pixels),f={...r,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0};await this.browser.clickUsingVisualCoordinates(p,f),await this.traceBrowserInteraction("Type",()=>this.browser.type(r.value,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter},true),{value:r.value});break}let s=this.browser.url(),c,l,u=cloneDeep(r.target),d=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(u){let{elementInteractedDisplayString:p,thoughts:f}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:u,cache:r.cache?.target,action:h=>this.traceBrowserInteraction("Type",()=>this.browser.typeIntoTarget(r.value,h,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter,relativePosition:r.relativePosition}),{value:r.value,selector:h.locator.toString()}),options:{...r,targetName:"target",disableCache:n,disableGlobalLocatorRedirect:!d,source:Zf(r)}});c=p,l=f;}else await this.traceBrowserInteraction("Type",()=>this.browser.type(r.value,{force:r.force,clearContent:r.clearContent,forceClearContent:r.forceClearContent,delay:r.delay,pressEnter:r.pressEnter},true),{value:r.value});let m={urlAfterCommand:this.browser.url(),succeedImmediately:false,elementInteracted:c,thoughts:l};return VT(s,m.urlAfterCommand)&&(m.succeedImmediately=true,m.succeedImmediatelyReason="URL changed"),m}case "HOVER":{if(ya(r.target)){let l=Kt(r.target.pixels);await this.traceBrowserInteraction("Hover",()=>this.browser.hoverUsingVisualCoordinates(l),{coordinates:l});break}let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:l=>this.traceBrowserInteraction("Hover",()=>this.browser.hover(l,{relativePosition:r.relativePosition?Kt(r.relativePosition):void 0}),{selector:l.locator.toString()}),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "FOCUS":{if(!dl(r.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:r,target:r.target,cache:r.cache?.target,action:l=>this.browser.focus(l),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "BLUR":{if(r.target&&!dl(r.target))throw new Error("Blur with x/y is not supported yet");if(!r.target||!r.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:false,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:s,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,target:r.target,command:r,cache:r.cache?.target,action:l=>this.browser.blur(l),options:{...r,targetName:"target",disableCache:n}});return {succeedImmediately:false,urlAfterCommand:this.browser.url(),elementInteracted:s,thoughts:c}}case "PRESS":{let s=this.browser.url();await this.traceBrowserInteraction("Press key",()=>this.browser.press(r.value,{repeat:r.repeat,convertMeta:r.convertMeta??true,delayMs:r.delayMs}),{value:r.value});let c={urlAfterCommand:this.browser.url(),succeedImmediately:false};return VT(s,c.urlAfterCommand)&&(c.succeedImmediately=true,c.succeedImmediatelyReason="URL changed"),c}case "KEY_DOWN":return await this.browser.keyDown(r.value,{convertMeta:r.convertMeta??true}),{urlAfterCommand:this.browser.url(),succeedImmediately:false};case "KEY_UP":return await this.browser.keyUp(r.value,{convertMeta:r.convertMeta??true}),{urlAfterCommand:this.browser.url(),succeedImmediately:false};case "REQUEST":{let s=new CookieJar,c=y_e(fetch,s),l;try{l=new URL(r.url).hostname;}catch{}let u=await Tp({command:r,baseUrl:this.browser.baseUrl,logger:a,fetchImplementation:c});return {data:wd.parse({...u,cookies:em(s,l)}),succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "GRAPHQL_REQUEST":return {data:await O6({command:r,baseUrl:this.browser.baseUrl,logger:a}),succeedImmediately:false,urlAfterCommand:this.browser.url()};case "VISUAL_DIFF":return M6({tracer:e,command:r,disableCache:n,browser:this.browser,logger:a,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:s=>this.wrapElementTargetingCommand(s)});case "FILE_UPLOAD":{let s,c;if(r.fileSource.type==="URL"?(c=r.fileSource.url,s=await X5({uri:r.fileSource.url,logger:a,orgId:this.orgId})):r.fileSource.type==="USER_FILE"&&(c=r.fileSource.name,s=await this.uploadedFileStorage?.getFileForUpload(r.fileSource.name,this.orgId)),!s)throw new M("UserConfigurationError",`Attempted to use non-existent file for upload step: ${c}`);await this.browser.setFileChooserHandler({...s,filename:r.filename});break}case "AUTH_SAVE":{let s=await this.browser.saveAuthState();if(r.storageState&&mI(r.storageState)){let c=sr__default.resolve(r.storageState);so.mkdirSync(sr__default.dirname(c),{recursive:true}),so.writeFileSync(c,`${JSON.stringify(s,null,2)}
|
|
5434
5434
|
`,"utf8");}return {data:s,succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "AUTH_LOAD":{let s;if(mI(r.storageState))try{s=JSON.parse(so.readFileSync(sr__default.resolve(r.storageState),"utf8"));}catch(l){throw new M("UserConfigurationError",`Failed to read auth state from '${r.storageState}': ${j(l)}`,{errOptions:{cause:l}})}else if(!r.storageState.trim())s=void 0;else if(s=await _i({orgId:this.orgId,code:r.storageState,fragment:false,context:o,logger:a,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof s!="object")throw new M("ActionFailureError",`Credentials must evaluate to an object (received ${typeof s} instead)`);let c;try{c=GB.optional().parse(s);}catch(l){throw new M("ActionFailureError",`Credentials provided do not follow the required format: ${l}`)}await this.browser.loadAuthState(c);break}case "ELEMENT_CHECK":{let s=(r.timeout??Zr)*1e3,c=this.generator.getAgentConfig()?.assertion;if(R6(r.assertion)&&!r.useSelector&&r.target.type==="description"&&c&&c!=="v1"){let u={id:r.id,type:"AI_ASSERTION",assertion:`There is no element on the page closely matches the following description. If the description has single quotes, remember that requires an exact text substring match. Description: ${r.target.elementDescriptor}`,iframeUrl:r.iframeUrl,timeout:r.timeout,source:"NEGATED_CHECK",cache:r.cache&&"memory"in r.cache?{memory:r.cache?.memory}:void 0};try{let d=await gC({command:u,logger:a,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory()});return {succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${d.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:d.afterScreenshotOverride}}finally{u.cache?.memory&&gg(r,u.cache?.memory.traces,a);}}let l=await w6({command:r,tracer:e,timeoutMs:s,targetingWrapper:u=>this.wrapElementTargetingCommand(u),fixtures:this.getControllerFixtures(),disableCache:n});return {fail:!l.success,data:l.data,elementInteracted:l.elementInteractedDisplayString,thoughts:l.err?.message??l.thoughts??`Element assertion ${l.success?"succeeded":"failed"}.`,succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "PAGE_CHECK":{let s=await Ii({action:async()=>I6({assertion:r.assertion,browser:this.browser,logger:a,timeout:r.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:this.browser,logger:a});return {fail:!s.success,data:s.data,thoughts:s.success?"Page assertion passed.":s.err?.message??`Page assertion still failing after ${r.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:false}}case "REGISTER_REQUEST_LISTENER":{let s=new hc(r.requestMatcher),c=this.browser.registerRequestListener(s);return this.registeredListeners[r.key]=c.then(async l=>await eN(l)).catch(l=>{a.error({err:l},"Failed to get request listener response");}),{succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "AWAIT_LISTENER":{let s=this.registeredListeners[r.key];if(!s)throw new M("ActionFailureError",`No listener registered with key: ${r.key}`);let c=r.timeout??10;return {data:await Q(s,{milliseconds:c*1e3,message:`Request listener timed out after ${c} seconds`}),succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "RECORD_REQUESTS":{let s=new hc(r.requestMatcher);return this.recordedRequests[r.key]={},this.browser.registerRequestRecorder(r.key,{matches:c=>s.matches({url:c.request.url,method:c.request.method}),onRequestStart:(c,l)=>{this.recordedRequests[r.key][c]=aC(l);},onRequestComplete:(c,l)=>{this.recordedRequests[r.key]?.[c]&&(this.recordedRequests[r.key][c]=aC(l));}}),{succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "GET_RECORDED_REQUESTS":{let s=this.recordedRequests[r.key];if(!s)throw new M("ActionFailureError",`No recorder registered with key: ${r.key}`);return delete this.recordedRequests[r.key],{data:Object.values(s),succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "SET_HEADER":{let s;return r.requestMatcher&&(s=new hc(r.requestMatcher)),this.browser.setHeader(r.name,r.value,s),{succeedImmediately:false,urlAfterCommand:this.browser.url()}}case "MOCK_ROUTE":return {data:{key:this.browser.registerMock(r.key,new hc(r.requestMatcher),async(c,l)=>{let u=await _i({orgId:this.orgId,code:r.responseGenerator,fragment:false,context:o,timeoutMs:void 0,logger:a,localTools:this.localCodeEvalTools,mock:{request:c,response:l},disallowVariableUpdates:true,responseSerialization:"RESPONSE"}),d=TV.parse(u);return new Response(d.body,{status:d.status,headers:d.headers})},r.fetchOriginalResponse??false)},succeedImmediately:false,urlAfterCommand:this.browser.url()};case "REMOVE_ROUTE_MOCK":return this.browser.removeMock(r.key),{succeedImmediately:false,urlAfterCommand:this.browser.url()};case "OFFLINE_MODE":return await this.browser.setOfflineMode(r.enable),{succeedImmediately:false,urlAfterCommand:this.browser.url()};default:return (c=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}return {succeedImmediately:false,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:r,disableCache:o,screenshot:n}){return (await this.generator.getReverseMappedDescription({browserState:e,target:r,screenshot:n},{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:Ie(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights();}async startRecordMode({params:e,abortController:r,isClickToRecord:o}){this.recordAbortController=r;let n=new mC({signal:r.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,n,o),n}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:true,abortSignal:this.executeAbortController.signal,loggerTags:Ie(this.logger)})}async getFailureRecoveryPlan(e,r){return this.generator.getFailureRecoveryPlan(e,{disableCache:true,abortSignal:this.executeAbortController.signal,loggerTags:Ie(r??this.logger)})}};function ft({text:t,section:e}){if(!e)return [{type:"text",text:t}];let r=`### ${e}`;return t.length===0?[{type:"text",text:r}]:[{type:"text",text:`${r}
|
|
5435
5435
|
${t}`}]}function AN({base64Data:t,mediaType:e,section:r}){return r?[{type:"text",text:`### ${r}`},{type:"media",data:t,mediaType:e}]:[{type:"media",data:t,mediaType:e}]}function iS(t){if(t.length===0)throw new Qr("No content parts provided to construct the tool response content.");return {type:"content",value:t}}function D6({projectRoot:t,filePath:e,pathLabel:r="path"}){if(!e||!sr__default.isAbsolute(e))return e;let o=sr__default.relative(t,e);if(o.startsWith("..")||sr__default.isAbsolute(o))throw new Error(`Error: ${r} "${e}" must be inside project root "${t}".`);return o}function L6(t){return t.map(e=>{switch(e.type){case "text":return e;case "media":return {type:"image",data:e.data,mimeType:e.mediaType};default:return (o=>{throw new Error("Unhandled content part")})()}})}var wN="We are scrolling the device in search of the element described below. Return -1 unless there is a strong match clearly visible in the current viewport. Description:";function bC(t){return `${wN} ${t}`}function bc(t,e){if(t===e)return true;let r=o=>o.startsWith(wN)?o.slice(wN.length).trim():o;return r(t)===r(e)}var T_e=[400,401,403,404,408,409,413,429,498,500,502,503,504],v_e=["overloaded","service unavailable","bad gateway","too many requests","toomanyrequests","internal server error","gateway timeout","rate_limit","ratelimit","rate limit","wrong-key","unexpected","capacity","timeout","terminated","other side closed","connection closed","upstream_closed","server_error","websocket unavailable","you can retry your request","429","500","502","503","504"];function k6(t){if(t&&typeof t=="object"&&"statusCode"in t){let r=t.statusCode;if(typeof r=="number"&&(T_e.includes(r)||r>500))return true}let e=F6(t).toLowerCase();return v_e.some(r=>e.includes(r))}function F6(t){if(t instanceof Error){let e="cause"in t?t.cause:void 0,r="code"in t&&typeof t.code=="string"?t.code:"";return `${t.name} ${t.message} ${r} ${F6(e)}`}if(typeof t=="string")return t;if(t&&typeof t=="object")try{return JSON.stringify(t)}catch{return ""}return ""}function B6(t){return new RN(t)}var RN=class{specificationVersion="v3";settings;retryAfterOutput;models;constructor(e){if(this.settings=e,this.models=[...e.models],this.retryAfterOutput=e.retryAfterOutput??true,this.models.length===0)throw new Error("No models available in settings")}get supportedUrls(){return this.currentModel.supportedUrls}get modelId(){return this.currentModel.modelId}get provider(){return this.currentModel.provider}doGenerate(e){return this.retry(()=>this.currentModel.doGenerate(e))}doStream(e){return this.retry(async()=>{let r=await this.currentModel.doStream(e);return {...r,stream:this.createRetryingStream({stream:r.stream,options:e})}})}get currentModel(){let e=this.models[0];if(!e)throw new Error("No model available at current fallback index");return e}moveCurrentModelToBack(){let e=this.models.shift();e&&this.models.push(e);}shouldRetry(e){return this.settings.shouldRetryThisError?this.settings.shouldRetryThisError(e):k6(e)}async notifyError(e){await this.settings.onError?.(e,this.modelId);}async retry(e){let r=this.models.length;for(let o=0;o<r;o++)try{return await e()}catch(n){if(!this.shouldRetry(n)||(await this.notifyError(n),this.moveCurrentModelToBack(),o===r-1))throw n}throw new Error("No models available in settings")}createRetryingStream(e){let{stream:r,options:o}=e,n={hasStreamedAny:false,hasEmittedClientExecutedToolCall:false,remainingFallbackAttempts:this.models.length-1};return new ReadableStream({start:async i=>{let a;try{a=r.getReader(),await this.pipeStreamToController({reader:a,controller:i,retryState:n}),i.close();}catch(s){await this.retryStreamAfterError({error:s,options:o,controller:i,retryState:n});}finally{U6(a);}}})}async pipeStreamToController(e){let{reader:r,controller:o,retryState:n}=e,i=await r.read();for(;!i.done;){let a=i.value;if(n&&a.type==="error"&&this.shouldRetry(a.error))throw a.error;o.enqueue(a),n&&(n.hasStreamedAny||=a.type!=="stream-start",a.type==="tool-call"&&a.providerExecuted!==true&&(n.hasEmittedClientExecutedToolCall=true)),i=await r.read();}}async retryStreamAfterError(e){let{error:r,options:o,controller:n,retryState:i}=e;if(!this.shouldRetry(r)){n.error(r);return}if(await this.notifyError(r),i.hasEmittedClientExecutedToolCall||i.hasStreamedAny&&!this.retryAfterOutput||i.remainingFallbackAttempts<=0){n.error(r);return}this.moveCurrentModelToBack(),i.remainingFallbackAttempts-=1;let a;try{a=(await this.currentModel.doStream(o)).stream.getReader(),await this.pipeStreamToController({reader:a,controller:n,retryState:i}),n.close();}catch(s){await this.retryStreamAfterError({error:s,options:o,controller:n,retryState:i});}finally{U6(a);}}};function U6(t){try{t?.releaseLock();}catch{}}var A_e=new Set(["itemId","reasoningEncryptedContent"]);function V6({model:t,logger:e,logMessage:r}){return wrapLanguageModel({model:t,middleware:{specificationVersion:"v3",transformParams:async({params:n})=>{let{messages:i,wasPruned:a}=w_e(n.prompt);return a&&e.info({messageCount:i.length,fallbackModel:t.modelId},r),{...n,prompt:i}}}})}function w_e(t){let e=false,r=[];for(let o of t){let{message:n,wasPruned:i}=R_e(o);e=e||i,n&&r.push(n);}return {messages:r,wasPruned:e}}function R_e(t){let e=z6(t.providerOptions),r=e.wasPruned;switch(t.role){case "system":return {message:{...t,providerOptions:e.providerOptions},wasPruned:r};case "assistant":{let o=[];for(let i of t.content){if(i.type==="reasoning"){r=true;continue}o.push(i);}let n=_N(o);return r=r||n.wasPruned,n.parts.length===0?{message:void 0,wasPruned:true}:{message:{...t,content:n.parts,providerOptions:e.providerOptions},wasPruned:r}}case "user":{let o=_N(t.content);return r=r||o.wasPruned,{message:{...t,content:o.parts,providerOptions:e.providerOptions},wasPruned:r}}case "tool":{let o=_N(t.content);return r=r||o.wasPruned,{message:{...t,content:o.parts,providerOptions:e.providerOptions},wasPruned:r}}}}function z6(t){if(!t)return {providerOptions:t,wasPruned:false};let e=false,r={};for(let[o,n]of Object.entries(t)){let i={};for(let[a,s]of Object.entries(n)){if(A_e.has(a)){e=true;continue}s!==void 0&&(i[a]=s);}Object.keys(i).length>0&&(r[o]=i);}return {providerOptions:Object.keys(r).length>0?r:void 0,wasPruned:e}}function _N(t){let e=false;return {parts:t.map(r=>{let o=__e(r);return e=e||o.wasPruned,o.part}),wasPruned:e}}function __e(t){let e=z6(t.providerOptions);return e.wasPruned?{part:{...t,providerOptions:e.providerOptions},wasPruned:true}:{part:t,wasPruned:false}}var aS="openai-websocket",$6={cacheControl:{type:"ephemeral"}};function j6(t){if(!t||typeof t!="object"||!("modelId"in t))return false;let e=t.modelId;return typeof e=="string"&&e.startsWith(`${aS}/`)}function G6(){let t=new Map;return {get(e){return t.get(e)},set(e,r){t.set(e,r);}}}var O_e=G6();function yC(t){let{providerFallback:e,prepareStep:r,onChunk:o,streamTelemetry:n,...i}=t,a=q6(e);return streamText({...i,prepareStep:F_e(r),onChunk:N_e({logger:e.logger,onChunk:o,telemetry:n}),model:a})}async function W6(t){let{providerFallback:e,...r}=t,o={...e,websocketFirst:void 0},n=q6(o),i=streamObject({...r,model:n,output:"object"});return await consumeStream({stream:i.fullStream,onError(a){throw a}}),i.object}function N_e(t){let{logger:e,onChunk:r,telemetry:o}=t;if(!o)return r;let n=new Map;return async i=>{D_e({logger:e,buffers:n,telemetry:o,chunk:i.chunk}),await r?.(i);}}function D_e(t){let{logger:e,buffers:r,telemetry:o,chunk:n}=t;if(n.type==="text-delta"&&o.textDeltas){H6({logger:e,buffers:r,telemetry:o,chunk:n});return}if(n.type==="reasoning-delta"&&o.reasoningDeltas){H6({logger:e,buffers:r,telemetry:o,chunk:n});return}if(n.type==="text-end"||n.type==="reasoning-end"){xN({logger:e,buffers:r,telemetry:o,id:n.id,kind:n.type==="text-end"?"text-delta":"reasoning-delta",flushReason:"end"});return}(n.type==="finish"||n.type==="abort"||n.type==="error")&&k_e({logger:e,buffers:r,telemetry:o,flushReason:n.type});}function H6(t){let{logger:e,buffers:r,telemetry:o,chunk:n}=t,i=`${n.type}:${n.id}`,s=r.get(i)??{id:n.id,kind:n.type,text:"",deltaCount:0,timer:void 0};s.timer&&clearTimeout(s.timer),s.text+=n.text,s.deltaCount+=1,s.timer=setTimeout(()=>{xN({logger:e,buffers:r,telemetry:o,id:n.id,kind:n.type,flushReason:"debounce"});},o.debounceMs??2e3),L_e(s.timer),r.set(i,s);}function L_e(t){if(typeof t!="object"||t===null||!("unref"in t))return;let e=t.unref;typeof e=="function"&&e.call(t);}function xN(t){let{logger:e,buffers:r,telemetry:o,id:n,kind:i,flushReason:a}=t,s=`${i}:${n}`,c=r.get(s);if(!c)return;c.timer&&clearTimeout(c.timer),r.delete(s);let l=o.maxLoggedChars,u=typeof l=="number"&&c.text.length>l?c.text.slice(0,l):c.text;e.info({...o.attributes,chunkId:c.id,chunkType:c.kind,deltaCount:c.deltaCount,flushReason:a,text:u,textLength:c.text.length,truncated:u.length!==c.text.length},`streamText ${i}`);}function k_e(t){let{logger:e,buffers:r,telemetry:o,flushReason:n}=t;for(let i of Array.from(r.values()))xN({logger:e,buffers:r,telemetry:o,id:i.id,kind:i.kind,flushReason:n});}function F_e(t){if(t)return e=>{if(!j6(e.model))return t(e)}}function q6(t){let e=t.scopeKey,r=e?t.state??O_e:G6(),o=U_e({...t,scopeKey:e,state:r});if(o.length===0)throw new Error("No streamText fallback providers configured");return B6({models:o.map(n=>n.model),retryAfterOutput:true,onError:async(n,i)=>{let a=o.find(s=>s.model.modelId===i)?.id??i;t.logger.warn({err:n,modelId:i,providerId:a},"streamText provider failed, trying next fallback"),await t.onError?.({error:Zb(n),failedProviderId:a,failedModelId:i});}})}function U_e(t){let e=t.scopeKey?t.state.get(t.scopeKey):void 0;if(t.websocketFirst?.enabled&&(!e||e===t.websocketFirst.provider.id))return [MN({candidate:t.websocketFirst.provider,config:t,pruneProviderState:false}),...t.providers.map(i=>MN({candidate:i,config:t,pruneProviderState:true}))];let r=e?t.providers.findIndex(i=>i.id===e):-1,o=r>=0?r:0;return [...t.providers.slice(o),...t.providers.slice(0,o)].map((i,a)=>MN({candidate:i,config:t,pruneProviderState:a>0}))}function MN(t){let{candidate:e,config:r,pruneProviderState:o}=t,n=B_e({model:e.model,providerId:e.id,scopeKey:r.scopeKey,state:r.state});return o&&(n=V6({model:n,logger:r.logger,logMessage:"Stripped provider-local state from streamText fallback step"})),{...e,model:n}}function B_e(t){let{model:e,providerId:r,scopeKey:o,state:n}=t;return wrapLanguageModel({model:e,middleware:{specificationVersion:"v3",overrideModelId:()=>`${r}/${e.modelId}`,wrapGenerate:async({doGenerate:i})=>{let a=await i();return o&&n.set(o,r),a},wrapStream:async({doStream:i})=>{let a=await i();return {...a,stream:V_e({stream:a.stream,providerId:r,scopeKey:o,state:n})}}}})}function V_e(t){let{stream:e,providerId:r,scopeKey:o,state:n}=t,i=false,a,s=false;return new ReadableStream({async start(c){a=e.getReader();try{for(;;){let{done:l,value:u}=await a.read();if(l)break;!i&&u.type!=="stream-start"&&u.type!=="error"&&(i=!0,o&&n.set(o,r)),c.enqueue(u);}s||c.close();}catch(l){s||c.error(l);}finally{a.releaseLock(),a=void 0;}},cancel(c){return s=true,a?.cancel(c)}})}async function z_e(t){let{agentConfig:e,streamResponseMessages:r,userMessage:o,...n}=t,i={role:"user",content:o};return W6({...n,providerFallback:e.providerFallback,system:e.system,providerOptions:e.providerOptions,messages:[...e.messages??[],...r,i]})}async function sS({validate:t,maxAttempts:e,logger:r,...o}){let n;for(let i=1;i<=e;i++){o.abortSignal?.throwIfAborted();try{let a=await z_e(o);return await t(a),a}catch(a){if(o.abortSignal?.aborted||(n=a,i===e))throw a;r.warn({err:a,attempt:i,nextAttempt:i+1},"Failed to validate generated object to repair missing submission tool call, retrying");}}throw n}var K6=500;function PN(t){return !t||typeof t!="object"||!("type"in t)||t.type!=="content"||!("value"in t)||!Array.isArray(t.value)?t:{type:t.type,value:t.value.map(e=>{if(!e||typeof e!="object"||!("type"in e))return e;if(e.type==="text"&&"text"in e){let r=typeof e.text=="string"?e.text:"";return {type:e.type,textLength:r.length,preview:r.slice(0,K6),truncated:r.length>K6}}if(e.type==="media"&&"data"in e){let r=typeof e.data=="string"?e.data:"";return {type:e.type,dataLength:r.length,mediaType:"mediaType"in e?e.mediaType:void 0}}return e})}}var Y6=z.looseObject({type:z.literal("tool-call"),toolCallId:z.string(),toolName:z.string(),input:z.unknown().optional()}),EC=z.object({type:z.literal("content"),value:z.array(z.discriminatedUnion("type",[z.object({type:z.literal("text"),text:z.string()}),z.object({type:z.literal("media"),data:z.string(),mediaType:z.string()})]))}),$_e=z.discriminatedUnion("type",[z.object({type:z.literal("text"),value:z.string()}),z.object({type:z.literal("json"),value:z.unknown().optional()}),z.object({type:z.literal("error-text"),value:z.string()}),z.object({type:z.literal("error-json"),value:z.unknown().optional()}),EC]),X6=z.looseObject({type:z.literal("tool-result"),toolCallId:z.string(),toolName:z.string(),output:$_e}),J6=z.looseObject({text:z.string()});var Z6=2,j_e=1600,H_e=.3,Yu="[trimmed: omitted due to context budget]",t8="[screenshot truncated]",r8="[browser state truncated]",o8={_momenticTrimmed:true,summary:Yu},n8={type:"text",value:Yu},G_e=z.object({type:z.literal("text"),value:z.literal(Yu)}),W_e=["reasoning","tool-result","image","tool-call","text"];function i8(t){let{messages:e,phase1:r,phase2:o,logger:n}=t,i=q_e(e,r.toolResultPruningRules??[],{trimReasoning:r.trimReasoning??false});if(typeof r.numScreenshots=="number"&&(i=K_e(i,r.numScreenshots)),typeof r.numBrowserStates=="number"&&r.browserStateMarkers&&r.browserStateMarkers.length>0&&(i=Q_e(i,r.numBrowserStates,r.browserStateMarkers)),!o)return i;let a=It(i);return a<=o.tokensThreshold||(n.info({totalTokens:a,threshold:o.tokensThreshold,target:o.targetTokens,messageCount:i.length,breakdown:e8(i)},"Phase 2 triggered \u2014 token breakdown before compaction"),i=gMe(i,o.targetTokens,n),n.info({totalTokens:It(i),messageCount:i.length,breakdown:e8(i)},"Phase 2 complete \u2014 token breakdown after compaction")),i}function q_e(t,e,r){let o=t;r.trimReasoning&&(o=o.map((n,i)=>n.role!=="assistant"?n:mMe(n,i===t.length-1)));for(let n of e)o=nMe(o,n);return o}function K_e(t,e){let r={count:e},o=[...t];for(let n=o.length-1;n>=0;n--)o[n]=Y_e(o[n],r);return o}function Y_e(t,e){if(t.role==="user"){if(typeof t.content=="string")return t;let r=X_e(t.content,e);return {...t,content:r}}if(t.role==="tool"){let r=J_e(t.content,e);return {...t,content:r}}return t}function X_e(t,e){let r=[...t];for(let o=r.length-1;o>=0;o--)if(r[o].type==="image"){if(e.count>0){e.count--;continue}r[o]={type:"text",text:t8};}return r}function J_e(t,e){let r=[...t];for(let o=r.length-1;o>=0;o--){let n=r[o];if(n.type!=="tool-result")continue;let i=EC.safeParse(n.output);if(!i.success)continue;let a=Z_e(i.data.value,e);a!==i.data.value&&(r[o]={...n,output:{...i.data,value:a}});}return r}function Z_e(t,e){let r=[...t],o=false;for(let n=r.length-1;n>=0;n--)if(r[n].type==="media"){if(e.count>0){e.count--;continue}r[n]={type:"text",text:t8},o=true;}return o?r:t}function Q_e(t,e,r){let o={count:e},n=[...t];for(let i=n.length-1;i>=0;i--)n[i]=eMe(n[i],o,r);return n}function eMe(t,e,r){if(t.role==="user"){if(typeof t.content=="string")return t;let o=tMe(t.content,e,r);return {...t,content:o}}if(t.role==="tool"){let o=rMe(t.content,e,r);return {...t,content:o}}return t}function tMe(t,e,r){let o=[...t];for(let n=o.length-1;n>=0;n--){let i=o[n];if(!(i.type!=="text"||!a8(i.text,r))){if(e.count>0){e.count--;continue}o[n]={type:"text",text:r8};}}return o}function rMe(t,e,r){let o=[...t];for(let n=o.length-1;n>=0;n--){let i=o[n];if(i.type!=="tool-result")continue;let a=EC.safeParse(i.output);if(!a.success)continue;let s=oMe(a.data.value,e,r);s!==a.data.value&&(o[n]={...i,output:{...a.data,value:s}});}return o}function oMe(t,e,r){let o=[...t],n=false;for(let i=o.length-1;i>=0;i--){let a=o[i];if(!(a.type!=="text"||!a8(a.text,r))){if(e.count>0){e.count--;continue}o[i]={type:"text",text:r8},n=true;}}return n?o:t}function a8(t,e){for(let r of e)if(t.includes(r))return true;return false}function nMe(t,e){let r=new Set;for(let o of t.slice(-e.keepLastMessages))if(typeof o.content!="string")for(let n of o.content)iMe(n)&&e.tools.includes(n.toolName)&&r.add(n.toolCallId);return t.map((o,n)=>n>=t.length-e.keepLastMessages?o:hMe(o,e,r))}function TC(t){return Y6.safeParse(t).success}function NN(t){return X6.safeParse(t).success}function iMe(t){return TC(t)||NN(t)}function aMe(t){return J6.safeParse(t).success}function s8(t){return !t||typeof t!="object"||Array.isArray(t)?false:t._momenticTrimmed===true}function l8(t){return G_e.safeParse(t).success}function ON(t){return t.text===Yu?{part:t,trimmedTokens:0}:{part:{...t,text:Yu},trimmedTokens:It(t.text)}}function sMe(t){return t.input===void 0||s8(t.input)?{part:t,trimmedTokens:0}:{part:{...t,input:o8},trimmedTokens:It(t.input)}}function c8(t){return t.output===void 0||l8(t.output)?{part:t,trimmedTokens:0}:{part:{...t,output:n8},trimmedTokens:It(t.output)}}function lMe(t,e,r){let o=0,n=[];for(let i of t){if(o>=e){n.push(i);continue}switch(i.role){case "assistant":{let a=cMe(i,e-o,r);o+=a.trimmedTokens,n.push(a.message);continue}case "tool":{let a=dMe(i,e-o,r);o+=a.trimmedTokens,n.push(a.message);continue}case "user":{let a=uMe(i,e-o,r);o+=a.trimmedTokens,n.push(a.message);continue}default:n.push(i);}}return {messages:n,trimmedTokens:o}}function cMe(t,e,r){if(typeof t.content=="string")return {message:t,trimmedTokens:0};let o=[],n=0;for(let i of t.content){if(n>=e){o.push(i);continue}if(r==="image"){o.push(i);continue}if(r==="reasoning"){if(i.type!=="reasoning"){o.push(i);continue}let s=ON(i);n+=s.trimmedTokens,o.push(s.part);continue}if(r==="text"){if(i.type!=="text"){o.push(i);continue}let s=ON(i);n+=s.trimmedTokens,o.push(s.part);continue}if(r==="tool-call"){if(!TC(i)){o.push(i);continue}let s=sMe(i);n+=s.trimmedTokens,o.push(s.part);continue}if(!NN(i)){o.push(i);continue}let a=c8(i);n+=a.trimmedTokens,o.push(a.part);}return {message:{...t,content:o},trimmedTokens:n}}function uMe(t,e,r){if(typeof t.content=="string")return {message:t,trimmedTokens:0};let o=[],n=0;for(let i of t.content){if(n>=e){o.push(i);continue}if(r==="image"){if(i.type!=="image"){o.push(i);continue}n+=j_e;continue}if(r!=="text"||!aMe(i)){o.push(i);continue}let a=ON(i);n+=a.trimmedTokens,o.push(a.part);}return {message:{...t,content:o},trimmedTokens:n}}function dMe(t,e,r){if(r!=="tool-result")return {message:t,trimmedTokens:0};let o=[],n=0;for(let i of t.content){if(i.type==="tool-approval-response"){o.push(i);continue}if(n>=e){o.push(i);continue}let a=c8(i);n+=a.trimmedTokens,o.push(a.part);}return {message:{...t,content:o},trimmedTokens:n}}function mMe(t,e){return e||typeof t.content=="string"?t:{...t,content:t.content.map(r=>r.type!=="reasoning"||r.text===Yu?r:{...r,text:Yu})}}function pMe(t,e,r){return !e.tools.includes(t.toolName)||r.has(t.toolCallId)||t.input===void 0||s8(t.input)?t:{...t,input:o8}}function u8(t,e,r){return !e.tools.includes(t.toolName)||r.has(t.toolCallId)||t.output===void 0||l8(t.output)?t:{...t,output:n8}}function fMe(t,e,r){return TC(t)?pMe(t,e,r):NN(t)?u8(t,e,r):t}function hMe(t,e,r){return t.role==="assistant"&&typeof t.content!="string"?{...t,content:t.content.map(o=>fMe(o,e,r))}:t.role==="tool"?{...t,content:t.content.map(o=>o.type==="tool-approval-response"?o:u8(o,e,r))}:t}function lS(t,e,r){let o=[...t];for(let n of W_e){let i=It(o);if(i<=e)break;let a=i-e,s=lMe(o,a,n);o=s.messages,s.trimmedTokens>0&&r.debug({contentType:n,trimmedTokens:s.trimmedTokens,newTokenCount:It(o)},"Trimmed content");}return o}function d8(t){return t.role!=="assistant"||typeof t.content=="string"?false:t.content.some(e=>TC(e))}function Q6(t){if(t.length===0)return;let e=t[0];if(d8(e)){t.shift(),t.length>0&&t[0].role==="tool"&&t.shift();return}t.shift();}function e8(t){let e={};for(let r of t)if(r.role==="system")e.system=(e.system??0)+It(r);else if(r.role==="user")e.user=(e.user??0)+It(r);else if(r.role==="assistant")if(typeof r.content=="string")e.assistant_text=(e.assistant_text??0)+It(r);else for(let o of r.content)if(o.type==="tool-call"){let n=`tool_call:${o.toolName}`;e[n]=(e[n]??0)+It(o);}else e.assistant_text=(e.assistant_text??0)+It(o);else if(r.role==="tool"){for(let o of r.content)if(o.type==="tool-result"){let n=`tool_result:${o.toolName}`;e[n]=(e[n]??0)+It(o);}}return e}function gMe(t,e,r){let o=It(t);if(o<=e||t.length<=1)return t;let n=t[0],i=[],a=[];if(t.length>Z6+1){let u=t.length-Z6;u>1&&t[u]?.role==="tool"&&d8(t[u-1])&&u++,i=t.slice(1,u),a=t.slice(u);}else a=t.slice(1);if(i.length>0){i=lS(i,e,r);let u=[n,...i,...a];if(o=It(u),o<=e)return u}let s=It(i),c=s/e;if(c<H_e){if(a.length>1){let u=a[a.length-1],d=[...i,...a.slice(0,-1)],m=lS(d,e,r),p=[n,...m,u];if(o=It(p),o<=e)return p;let f=lS([...m,u],e,r),h=[n,...f];if(o=It(h),o<=e)return h}else if(a.length===1){let u=[...i,...a],d=lS(u,e,r),m=[n,...d];if(o=It(m),o<=e)return m}}else for(r.debug({headBudgetRatio:c,middleMsgTokens:s,targetTokens:e},"Middle exceeds 30% budget, removing messages");i.length>0;){Q6(i);let u=[n,...i,...a];if(o=It(u),o<=e)return u}a=lS(a,e,r);let l=[n,...i,...a];if(o=It(l),o<=e)return l;for(;a.length>0;)if(Q6(a),l=[n,...i,...a],o=It(l),o<=e)return l;return o>e&&r.warn({targetTokens:e,finalTokenCount:o,remainingMessages:l.length},"Unable to meet token target after all pruning phases"),l}var DN=5e3,m8=2e4;function h8(t){let{tool:e,name:r,spanName:o,attributes:n}=t,i=e.execute;return i?{...e,execute:async(a,s)=>Ji({name:o,attributes:{"momentic.tool_name":r,...n},fn:async c=>{c?.setAttribute("momentic.tool_input",p8(a));let l=await i(a,s);return c?.setAttribute("momentic.tool_output",p8(PN(l))),l}})}:e}function p8(t){let e=Wl({json:t,maxJsonStringSize:DN});return typeof e=="string"?e:Pl(e)??""}function vC(t){let{tool:e,name:r,logger:o,logPrefix:n,agentName:i}=t,a=t.getResultForLogging??PN,s=e.execute;return s?{...e,strict:e.strict??false,execute:async(c,l)=>LN({logger:o,toolName:r,logPrefix:n,agentName:i,input:c,execute:async()=>s(c,l),getResultForLogging:a})}:{...e,strict:e.strict??false}}async function LN(t){let{logger:e,toolName:r,logPrefix:o="",agentName:n,input:i}=t,a=t.getResultForLogging??(l=>l),s=Date.now(),c=f8({logger:e,toolName:r,agentName:n,value:i,label:"input"});e.info({...n!=null&&{agentName:n},...c!==void 0&&{inputTokenCount:c},params:Wl({json:i,maxJsonStringSize:DN}),toolName:r},`${o}Tool invoked: ${r}`);try{let l=await t.execute(),u=f8({logger:e,toolName:r,agentName:n,value:l,label:"output"}),d=a(l);return u!==void 0&&u>m8&&e.warn({...n!=null&&{agentName:n},largeToolOutputWarningThresholdTokens:m8,outputTokenCount:u,toolName:r},`${o}Tool output is large: ${r}`),e.info({...n!=null&&{agentName:n},duration:Date.now()-s,...u!==void 0&&{outputTokenCount:u},response:Wl({json:d,maxJsonStringSize:DN}),toolName:r},`${o}Tool completed: ${r}`),l}catch(l){throw e.error({...n!=null&&{agentName:n},duration:Date.now()-s,err:l,toolName:r},`${o}Tool failed: ${r}`),l}}function f8(t){let{logger:e,toolName:r,agentName:o,value:n,label:i}=t;try{return It(n)}catch(a){e.warn({...o!=null&&{agentName:o},err:a,toolName:r},`Failed to calculate tool ${i} token count`);return}}var g8=".momentic-mcp",vMe=30*24*60*60*1e3;function FN(t){return t?sr__default.join(t,g8):sr__default.resolve(g8)}function as(t){let e=FN(t);mkdirSync(e,{recursive:true});}function CMe(){return `${Date.now()}`}function ss({rootDir:t,entity:e,ext:r}){return sr__default.join(FN(t),`${e}-${CMe()}.${r}`)}function AMe(t){let e=sr__default.relative(process.cwd(),t);return e.startsWith(".")?e:`./${e}`}function aa({filePath:t,title:e}){return `- [${e}](${AMe(t)})`}var uS="All relative paths/links returned by a tool are relative to the server's `cwd`. Use the advertised `cwd` to resolve relative paths, use `projectRootAbsolutePath` to find the project-local `.momentic-mcp` artifacts, and use `projectConfigAbsolutePath` for the active `momentic.config.yaml`.";function S8({projectRootAbsolutePath:t,projectConfigAbsolutePath:e,cwd:r}){return [uS,"",`- **projectRootAbsolutePath**: \`${t}\``,`- **projectConfigAbsolutePath**: \`${e}\``,`- **cwd**: \`${r}\``].join(`
|
|
5436
5436
|
`)}async function b8({projectRootAbsolutePath:t,projectConfigAbsolutePath:e,cwd:r,stepSchema:o,stepSchemaTitle:n,supportsFileOutput:i}){let a="Step Authoring Guide",s="Read this Step Authoring Guide to understand momentic step input shapes. It explains the CLI-style step arguments accepted by the MCP tools and includes the project context.",c=[s,"","## Project context","",S8({projectRootAbsolutePath:t,projectConfigAbsolutePath:e,cwd:r}),"",`## ${n}`,"",o].join(`
|
|
@@ -5576,19 +5576,19 @@ ${s}`}]}async function T8({rootDir:t,cutoffTime:e}){let r=await readdir(t,{withF
|
|
|
5576
5576
|
`),section:"Diffs For Recovery"})),u}return u.push(...ft({text:["",d].join(`
|
|
5577
5577
|
`),section:"Diffs For Recovery"})),u}function EQ({moduleName:t,existingModuleNames:e,parameterNames:r,defaultParameters:o,parameterEnums:n,moduleInputs:i,testPath:a,startIndex:s,endIndex:c,availableSteps:l,containsNestedModuleStep:u}){if(e.includes(t))throw new Error(`Error: module with the name "${t}" already exists. Please use a different name.`);let d=r??[],m=[...Object.keys(o??{}),...Object.keys(n??{})];for(let b of m)if(!d.includes(b)){let y=d.length?d.join(", "):"none";throw new Error(`Error: Parameter metadata "${b}" is not defined in parameters. Available parameters: ${y}`)}let p=new Set(d);for(let b of Object.keys(i??{}))if(!p.has(b)){let y=p.size?Array.from(p).join(", "):"none";throw new Error(`Error: Module input "${b}" is not defined in parameters. Available parameters: ${y}`)}let f=s??0,h=c??f+1;if(c!==void 0&&s===void 0)throw new Error("Error: startIndex is required when endIndex is provided for extraction.");if(s===void 0)return {stepsToExtract:[],startIndex:f,endIndex:h};if(!a)throw new Error("Error: testPath is required when extracting steps from the test.");if(!l)throw new Error("Error: resolved steps are required to validate module extraction.");if(f<0||f>=l.length)throw new Error(`Error: startIndex ${f} is out of bounds. Test has ${l.length} steps.`);if(h<=f||h>l.length)throw new Error(`Error: endIndex ${h} is out of bounds. Must be between ${f+1} and ${l.length}.`);let S=l.slice(f,h);for(let b of S)if(u(b))throw new Error("Error: Modules cannot be nested. Please select steps that do not include module references.");return {stepsToExtract:S,startIndex:f,endIndex:h}}var Ake=new Set(["android.webkit.webview","com.facebook.react.views.webview.reactwebview","com.tencent.smtt.sdk.webview","com.tencent.smtt.sdk.x5webview","org.xwalk.core.xwalkview","com.uc.webview.export.webview"]);function wke(t){let e=t.toLowerCase();return e.endsWith("webview")||Ake.has(e)}function ub(t){return !!(wke(t.tagName)||t.getAttribute("package")==="com.android.chrome"&&t.getAttribute("content-desc")==="Web View"&&TQ(t.tagName.toLowerCase()).startsWith("frame"))}function TQ(t){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let r of e)if(t.startsWith(r))return t.substring(r.length);return t}var Rke=new Set(["index","package","a11y-important","screen-reader-focusabl"]),_ke=new Set(["selected","checked","checkable","clickable","enabled","focusable","focused","long-clickable","password","scrollable","selected","showing-hint","context-clickable","multiline","text-entry-key","heading","dismissable","screen-reader-focusable","content-invalid","a11y-focused"]),Mke=new Set(["text","hint"]),xke=new Set(["live-region","drawing-order"]),Pke=new Set(["displayed","enabled"]);function Ike(t,e){let r={};for(let[o,n]of Object.entries(e))Rke.has(o)||o==="class"&&t===n||o==="focusable"&&n==="true"&&e.clickable==="true"||_ke.has(o)&&n==="false"||Mke.has(o)&&n===""||Pke.has(o)&&n==="true"||xke.has(o)&&n==="0"||o!=="id"&&(r[o]=n);return r}function vQ(t,e,r){let{prunedDocument:o,idToElement:n,prunedIdToElement:i,idCounter:a,opts:s}=t,c=a.value++;r.setAttribute("id",String(c));let l={};for(let m of e.attributes){let p=m.name,f=m.value;f!=null&&(l[p]=String(f));}let u=Ike(e.tagName,l);for(let[m,p]of Object.entries(u))r.setAttribute(m,p);if(n.set(c,e),i.set(c,r),ub(e)){let m=s?.injectedWebviewContent??"";if(s?.removeWebviewContent){for(;r.firstChild;)r.removeChild(r.firstChild);return}else if(!s?.disableMomenticAccessibilityTree&&m.trim().length>0){for(;r.firstChild;)r.removeChild(r.firstChild);m.trim().length>0&&r.appendChild(o.createCDATASection(`
|
|
5578
5578
|
${m}
|
|
5579
|
-
`));return}}let d=Array.from(e.childNodes??[]);for(let m of d){let p=m.nodeType;if(p===3){let f=m.nodeValue;f&&f.trim().length>0&&r.appendChild(o.createTextNode(f));continue}if(p===1){let f=m;if(!Dke(f,s?.viewportBounds))continue;let h=o.createElement(TQ(f.tagName));vQ(t,f,h),r.appendChild(h);}}}function Oke(t,e,r,o){let n=t.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:n,idToElement:r,prunedIdToElement:i,idCounter:{value:0},opts:o},s=n.documentElement;vQ(a,e,s);let c=new XMLSerializer().serializeToString(n);return {prunedDocument:n,prunedIdToElement:i,xml:c}}async function CQ(t,e,r){let o=new DOMParser,n=o.parseFromString(t,"text/xml"),i=new Map,a=n.documentElement;if(!a)throw new M("InternalWebAgentError","No root element found in XML");if(a.tagName!=="hierarchy")throw new M("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:s,prunedIdToElement:c,xml:l}=Oke(o,a,i,r),u=l;try{u=await Tke.format(l,{parser:"xml",plugins:[Eke],printWidth:120,tabWidth:1,singleAttributePerLine:!1});}catch(d){e.warn({err:d},"Failed to format XML");}return {xml:u,originalXml:t,document:n,idToElement:i,prunedDocument:s,prunedIdToElement:c}}function Nke(t){let e=[],r=t;for(;r;){let o=r.tagName,n=r.parentElement,i=1;if(n){let a=Array.from(n.children).filter(s=>s.tagName===o);for(let s=0;s<a.length;s++)if(a[s]===r){i=s+1;break}}e.unshift(`${o}[${i}]`),r=n;}return `/${e.join("/")}`}function tw(t,e){let r=t.idToElement.get(e);if(r)return Nke(r)}function p0(t,e){let r=t.idToElement.get(e);if(!r)return;let o=r.cloneNode(true);for(let n of Array.from(o.children)){let i=n;for(let a of Array.from(i.children))i.removeChild(a);}return o.outerHTML}function cd(t){if(!t.hasAttribute("bounds"))return;let e=t.getAttribute("bounds");if(!e)return;let r=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(r){let o=parseInt(r[1],10),n=parseInt(r[2],10),i=parseInt(r[3],10),a=parseInt(r[4],10);if(Number.isFinite(o)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(a))return [o,n,i,a]}}function Dke(t,e){if(!e)return true;let r=cd(t);if(!r||r.length<4)return true;let o=r[0],n=r[1],i=r[2],a=r[3];return !(i<=e.left||o>=e.right||a<=e.top||n>=e.bottom)}function AQ(t,e){if(t&&!(!e||e.length===0))return Object.fromEntries(e.map(r=>[r,t.getAttribute(r)]).filter(([,r])=>r!==null))}function RQ({requirements:t,element:e}){let r;if((t?.positionSpecificity||t?.shapeSpecificity)&&(r=cd(e),!r))throw new M("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:t?.textRequired&&fp(e)||void 0,requiredAttributes:AQ(e,t?.attributesRequired),requiredBounds:t?.boundsRequired,position:t?.positionSpecificity?{x1:r[0],y1:r[1],x2:r[2],y2:r[3],tolerance:t?.positionSpecificity}:void 0,shape:t?.shapeSpecificity?{width:r[2]-r[0],height:r[3]-r[1],tolerance:t?.shapeSpecificity}:void 0}}function MQ({aiResponse:t,description:e,emulatorState:r,memory:o,useMemory:n}){let i=r.graph.idToElement.get(t.id);if(!i)throw new M("InternalWebAgentError",`Could not find node with id: ${t.id}`);let a=cd(i);if(!a)throw new M("InternalWebAgentError",`Node ${t.id} has no bounding box: ${i.outerHTML}`);let s=tw(r.graph,t.id)??"",c=p0(r.graph,t.id)??"",l=RQ({requirements:t.requirements,element:i}),u=[];t.additionalElements&&(u=t.additionalElements.map(({id:m,requirements:p})=>{let f=r.graph.idToElement.get(m);if(!f)return;let h=tw(r.graph,m);return h?{xPath:h,requirements:RQ({requirements:p,element:f})}:void 0}).filter(m=>!!m));let d;if(ub(i)&&t.inWebview!==false?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:c,requirements:l,requiredRelatedElements:u},n)if(t.updatedMemory){let m={type:"GCS_TRACES",traces:t.updatedMemory};d.memory=m;}else o&&(d.memory=o);return {target:d,resolvedNode:i}}function xQ(t){return t?.type==="WEBVIEW"?t.browserCache?.memory:void 0}function Lke(t,e){let r=e.x2-e.x1,o=(e.x1+e.x2)/2,n=(t[0]+t[2])/2;if(!rs(e.tolerance,o,n,Math.min(1,r)))return false;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(t[1]+t[3])/2;return rs(e.tolerance,a,s,Math.min(1,i))}function kke(t,e){return rs(e.tolerance,e.width,t[2]-t[0],Math.min(1,e.width))?rs(e.tolerance,e.height,t[3]-t[1],Math.min(1,e.height)):false}var _Q=(t,e,r)=>{if(!e)return;let{requiredAttributes:o,requiredText:n,requiredBounds:i,position:a,shape:s}=e;if(n!==void 0&&n.length>0){let c=fp(t);if(c!==n)throw new we(`Resolved element text mismatch: expected ${n}, got ${c}`)}if(o)for(let[c,l]of Object.entries(o)){let u=t.getAttribute(c)??void 0;if(u!==l)throw new we(`Attribute ${c} mismatch: expected ${l}, got ${u}`)}if(i&&r&&!r.targetBounds.every((l,u)=>l===r.newElementBounds[u]))throw new we(`Bounds changed from [${r.targetBounds.join(",")} ] to [${r.newElementBounds.join(",")} ]`);if(a&&r&&!Lke(r.newElementBounds,a))throw new we(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(r.newElementBounds)}`);if(s&&r&&!kke(r.newElementBounds,s))throw new we(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(r.newElementBounds)}`)};async function Kp(t){let{target:e,domState:r}=t,{graph:o}=r,{document:n}=o,i=ue();if(e.type==="WEBVIEW")return Fke(e,t);if(!e.xPath)throw new M("ActionFailureError","Native element cache has no XPath");let a=wQ.evaluateXPathToFirstNode(e.xPath,n,null,null);if(!a)throw new we(`Could not resolve cached target via XPath: ${e.xPath}`);if(e.requiredRelatedElements){let m=e.requiredRelatedElements;i.startSection("Validate related elements are similar enough to past runs",()=>{for(let p of m){let f=wQ.evaluateXPathToFirstNode(p.xPath,n);if(!f)throw new we(`Required related element not found for XPath: ${p.xPath}`);_Q(f,p.requirements);}});}let s=cd(a);if(!s)throw new we("Resolved native element has no bounding box");if(!e.bounds)throw new we("Native element cache has no bounds");_Q(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let c;for(let[m,p]of o.idToElement.entries())if(p===a){c=m;break}let l=e.elementOnlySerializedXml,u=e.xPath;return c!==void 0&&(l=p0(o,c)??l,u=tw(o,c)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:l,xPath:u}}}async function Fke(t,e){let{stateManager:r,logger:o,signal:n}=e,i=ue(),a=await r.getActiveWebview();if(!a||!a.browserController)throw o.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new we("No browser controller is attached to the requested webview");let s=a.browserController;if(!t.browserCache)throw o.error({target:t},"resolveTargetCacheInWebView: No browser target available on cache"),new we("No browser target available on cache");let c=t.browserCache,{finalTarget:l}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({cache:c,options:{resolveTargetOptions:{logger:o,signal:n,skipWaitForPageLoad:true,skipSavingVisualAttributes:true}},logger:o}));return {resolvedTarget:{...t,controller:a.browserController,browserTarget:l}}}function ud(t){let{command:e,cacheKey:r="cache",targetName:o="target",updatedCache:n}=t;Da(e)&&(e[r]={...e[r],[o]:jd.parse(n)},t.updatedWithAI&&(e[r].updatedAt=new Date,e[r].updatedAtLoggerTags=Ie(t.logger)));}function Dc(t){if(t.type==="WEBVIEW")return {type:"WEBVIEW",resolvedDescription:t.resolvedDescription,xPath:t.xPath,browserCache:t.browserCache,memory:t.memory};let{resolvedNode:e,...r}=t;return {...r}}var Qn=.15,Bke=500,Rr=class{driver;generator;stateManager;logger;fixtures;aborter;orgId;aiSettings;options;constructor(e){this.stateManager=e.stateManager,this.generator=e.generator,this.driver=e.driver,this.logger=e.logger,this.fixtures=e.fixtures,this.aborter=e.aborter,this.orgId=e.orgId,this.aiSettings=e.aiSettings,this.options=e.options;}shouldUseMemoryForCommand(e){return this.aiSettings?.useMemory&&!e?.disableCache}async findElement({description:e,tracer:r,skipFetchingFullWebviewContent:o=false,removeWebviewContent:n=false,useMemory:i=false,memory:a,webviewMemory:s,metadata:c,cacheBustReason:l}){let u=this.logger.child({...c}),d=await r.startAsyncSection("Get emulator state",async()=>{let b=await this.stateManager.getCurrentScreenshotPngString();return {emulatorState:await this.stateManager.getDomState({skipFetchingFullWebviewContent:o,removeWebviewContent:n}),screenshot:b}}),m;try{m=await r.startAsyncSpan("AI_LOCATOR_CALL",async b=>{l&&(b.attributes.cacheBustReason=l);let y=await this.generator.getAndroidElementLocation({description:e,screenXml:d.emulatorState.graph.xml,screenshot:d.screenshot,source:c?.source==="SCROLL_TO"?"SCROLL_TO":void 0,memory:i?a:void 0},{logger:u,loggerTags:Ie(u),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return b.result=y,y});}catch(b){throw this.throwIfAborted(),u.error({err:b},"Failed to locate element"),new M("InternalWebAgentError",`Failed to locate element: ${b instanceof Error?b.message:b}`,{errOptions:{cause:b}})}if(m.id===-1){let b=m.updatedMemory?{type:"GCS_TRACES",traces:m.updatedMemory}:void 0;return {success:false,thoughts:m.thoughts??"No matching element found",updatedLocatorMemory:b}}let{target:p,resolvedNode:f}=MQ({aiResponse:m,description:e,emulatorState:d.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:true,resolvedTarget:{...p,resolvedNode:f},thoughts:m.thoughts};let{browserLocateResult:h,browserController:S}=await r.startWebviewTrace(async()=>{let b=await this.stateManager.getActiveWebview();if(!b||!b.browserController)throw new M("InternalWebAgentError","No browser controller is attached to the requested webview");return {browserLocateResult:await b.browserController.locateElement({description:e,disableCache:false,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:true,skipSavingVisualAttributes:true}),browserController:b.browserController}});return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:h.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:true,resolvedTarget:{...p,controller:S,browserTarget:{...h.resolution,serverSideBoundingBox:await h.resolution.locator.boundingBox({timeout:5e3})},browserCache:h.target},thoughts:h.thoughts}}async targetingActionWithAILocator(e){let{action:r,command:o,description:n,tracer:i,cacheKey:a,targetName:s,cache:c,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:d,cacheBustReason:m}=e,p=await this.findElement({description:n,tracer:i,skipFetchingFullWebviewContent:l,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(o),memory:c?.memory,webviewMemory:xQ(c),metadata:d,cacheBustReason:m});if(!p.success){if(p.updatedLocatorMemory&&c){let b={...c,memory:p.updatedLocatorMemory};ud({command:o,cacheKey:a,targetName:s,updatedCache:b,updatedWithAI:true,logger:this.logger});}throw new M("NoMatchingElementError",p.thoughts??"No matching element found")}let f=p.thoughts,{result:h,resolvedTarget:S}=await this.executeActionWithWebviewReconstructRetry({action:r,resolvedTarget:p.resolvedTarget,reason:"webview target closed during AI-located action"});return ud({command:o,cacheKey:a,targetName:s,updatedCache:Dc(S),updatedWithAI:true,logger:this.logger}),{result:h,thoughts:f}}async wrapTargetingAction(e){let{action:r,description:o,command:n,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:c,skipFetchingFullWebviewContent:l=false,removeWebviewContent:u=false}=e,d,m={commandId:n.id};if(i==="cache"&&"cache"in n&&n.cache){let T=n.cache;a==="target"&&"target"in T?d=T.target:a==="fromTarget"&&"fromTarget"in T?d=T.fromTarget:a==="toTarget"&&"toTarget"in T&&(d=T.toTarget);}let p=false,f,h=cloneDeep(d);if(n.disableCache&&(this.logger.debug({command:n},"Cache explicitly disabled for command"),p=true,f="Cache explicitly disabled",h=void 0),s&&(p=true,f=f??"Cache invalidated after resolution",h=void 0),h&&!bc(h?.resolvedDescription??"",o)&&(this.logger.info({description:o,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=true,f="Description mismatch",h=void 0),!h)return this.logger.info({description:o,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:r,command:n,description:o,tracer:c,cacheKey:i,targetName:a,cache:d,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m,cacheBustReason:f});let S=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,b=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,y;try{this.options?.emulator?.waitForStability&&await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let{resolvedTarget:T}=await c.startAsyncSpan("CACHE_RESOLUTION",async N=>{let D=Date.now(),x;for(;Date.now()-D<3e3;){y=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let A;try{A=(await Kp({target:h,domState:y,stateManager:this.stateManager,logger:this.logger})).resolvedTarget;}catch(z){if(x=z,z instanceof we){this.logger.warn({err:z},"Failed to resolve target cache, retrying"),await Wa(500,this.aborter.controller?.signal);continue}throw this.logger.error({err:z},"Failed to resolve target cache"),z}let B=Dc(A),O=diff(h,B);return O&&Object.keys(O).length>0&&this.logger.info({cacheDiffs:O},"Successfully resolved target with cache"),N.attributes.serializedElement=A.type==="WEBVIEW"?A.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":A.elementOnlySerializedXml??"Unknown element",{resolvedTarget:A,updatedCache:B}}throw x}),{result:v,resolvedTarget:w}=await this.executeActionWithWebviewReconstructRetry({action:r,resolvedTarget:T,reason:"webview target closed during cached action"});return ud({command:n,cacheKey:i,targetName:a,updatedCache:Dc(w),updatedWithAI:!1,logger:this.logger}),_t.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${S}`,`hasAdditionalElements:${b}`,`orgId:${this.orgId}`,"cliVersion:0.97.2"]),{result:v,thoughts:"Successfully executed preset action with cache"}}catch(T){if(this.throwIfAborted(),T instanceof M&&T.reason!=="InternalWebAgentError")throw this.logger.error({err:T},"Failed to execute action with target cache (fatal)"),T;return _t.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${S}`,`hasAdditionalElements:${b}`,`orgId:${this.orgId}`,"cliVersion:0.97.2"]),this.logger.warn({err:T},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:r,command:n,description:o,tracer:c,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m})}}async executeActionWithWebviewReconstructRetry(e){let{action:r,resolvedTarget:o,reason:n}=e;try{return {result:await r(o),resolvedTarget:o}}catch(i){if(this.throwIfAborted(),o.type!=="WEBVIEW"||!this.errorLooksLikeClosedWebviewTarget(i)||(this.logger.warn({err:i},"Webview target appears closed or crashed during action, reconstructing browser and retrying once"),!(await this.stateManager.reconstructActiveWebviewBrowser(n))?.browserController))throw i;let s=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true}),{resolvedTarget:c}=await Kp({target:Dc(o),domState:s,stateManager:this.stateManager,logger:this.logger,signal:this.abortSignal});return {result:await r(c),resolvedTarget:c}}}errorLooksLikeClosedWebviewTarget(e){let r=j(e);return ["Target closed","Target crashed","Page crashed","Target page, context or browser has been closed","Session closed. Most likely the page has been closed"].some(o=>r.includes(o))}constructPerformerParams(){return {stateManager:this.stateManager,generator:this.generator,driver:this.driver,logger:this.logger,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,aiSettings:this.aiSettings,options:this.options}}getBoundsFromNativeCache(e){if(!e.bounds)throw new M("ActionFailureError","Native element cache has no bounds");let[r,o,n,i]=e.bounds;if(r===void 0||o===void 0||n===void 0||i===void 0)throw new M("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return {left:r,top:o,width:n-r,height:i-o}}calculateSwipeCoordinates({containerBounds:e,direction:r,desiredDelta:o}){let n=e.left+e.width/2,i=e.top+e.height/2;if(r==="up"||r==="down"){let a=e.height*Qn,s=e.top+a,c=e.top+e.height-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u,m=r==="down"?c-d/2:s+d/2;return {startX:n,startY:m,actualDelta:u}}else {let a=e.width*Qn,s=e.left+a,c=e.left+e.width-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u;return {startX:r==="right"?c-d/2:s+d/2,startY:i,actualDelta:u}}}invertDirection(e){if(e==="up")return "down";if(e==="down")return "up";if(e==="left")return "right";if(e==="right")return "left";throw new Error(`Unreachable code: ${e}`)}async performRawSwipe({startX:e,startY:r,deltaPixels:o,direction:n,durationMs:i=300}){let a=Math.abs(o),s=e,c=r;n==="up"||n==="down"?c=n==="up"?r-a:r+a:s=n==="left"?e-a:e+a,await this.driver.executeInNativeContext(this.logger,async l=>{await l.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:r},{type:"pointerDown",button:0},{type:"pause",duration:250},{type:"pointerMove",duration:i,x:s,y:c},{type:"pause",duration:500},{type:"pointerUp",button:0}]}]),await l.releaseActions();},{operationName:"performRawSwipe"}),await ce(Bke,this.abortSignal);}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}get abortSignal(){return this.aborter.controller?.signal}get aiSettingsCopy(){return cloneDeep(this.aiSettings)}get optionsCopy(){return cloneDeep(this.options)}};function Lc(t){if(t.type==="WEBVIEW"){let a=t.browserTarget.serverSideBoundingBox;return a?{left:a.x,top:a.y,width:a.width,height:a.height}:void 0}let{bounds:e}=t;if(!e)return;let[r,o,n,i]=e;if(!(r===void 0||o===void 0||n===void 0||i===void 0))return {left:r,top:o,width:n-r,height:i-o}}function OQ(t){return "iterations"in t}function $ke(t){let e={relativePosition:t.relativePosition?Kt(t.relativePosition):void 0};if(t.iterations!==void 0&&(!Number.isInteger(t.iterations)||t.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(t.tapDelayMs!==void 0&&(!Number.isInteger(t.tapDelayMs)||t.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(t.iterations&&t.iterations>1&&t.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(t.tapDelayMs!==void 0&&(!t.iterations||t.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(t.longPress){if(t.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return {...e,longPress:true,longPressDurationMs:t.longPressDurationMs}}return t.iterations!==void 0?{...e,iterations:t.iterations,tapDelayMs:t.tapDelayMs}:e}var Yp=class extends Rr{async tapOnNativeCoordinates(e){let r=e.x,o=e.y;if(this.logger.info({x:r,y:o},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeInNativeContext(this.logger,n=>n.executeScript("mobile: longClickGesture",[{x:r,y:o,duration:e.longPressDurationMs??2e3}]),{operationName:"longPress"});if(OQ(e)){let n=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.executeInNativeContext(this.logger,a=>a.tap({x:r,y:o}),{operationName:"tap"}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,n));return}await this.driver.executeInNativeContext(this.logger,n=>n.tap({x:r,y:o}),{operationName:"tap"});}async tapOnNativeTarget(e,r){let[o,n,i,a]=e.bounds,s=i-o,c=a-n,l=r?.relativePosition?.x??s/2,u=r?.relativePosition?.y??c/2;l=Math.max(0,Math.min(l,s)),u=Math.max(0,Math.min(u,c));let d=o+l,m=n+u;return await this.tapOnNativeCoordinates({x:d,y:m,...r}),{x:d,y:m}}async tapOnWebviewTarget(e,r){let{controller:o}=e,n,i=1;return r&&OQ(r)?(n=r.tapDelayMs,i=r.iterations):r&&"longPress"in r&&(n=r.longPressDurationMs),(await o.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),c=sr__default.join(tmpdir(),"momentic","downloads"),l=sr__default.join(c,this.orgId,s);return mkdirSync(l,{recursive:true}),l}},{delayMs:n,relativePosition:r?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:r}){return await ue().startAsyncSpan("EMULATOR_INTERACTION",async n=>{if(n.attributes.options=r,"type"in e&&e.type==="NATIVE"){let i=await this.tapOnNativeTarget(e,r);n.attributes.point=i,n.targetBounds=Lc(e);}else {n.withinWebview=true;let i=await this.tapOnWebviewTarget(e,r);n.attributes.point=i,n.targetBounds=Lc(e);}},{name:"Tap on target"})}async executeTap({command:e}){let r=ue(),o=$ke(e);if(e.target.type==="coordinates"||e.target.type==="absolute_percent"){let a=await this.driver.executeInNativeContext(this.logger,l=>l.getWindowSize(),{operationName:"getTapWindowSize"}),s,c;return e.target.type==="coordinates"?(s=e.target.xPercent*a.width,c=e.target.yPercent*a.height):(s=e.target.x/100*a.width,c=e.target.y/100*a.height),await r.startAsyncSpan("EMULATOR_INTERACTION",async l=>{await this.tapOnNativeCoordinates({...o,x:s,y:c}),l.attributes.point={x:s,y:c};},{name:`Tap at coordinates ${s}, ${c}`}),{success:true,message:`Tapped at ${s}, ${c}`}}let n=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:r,action:a=>this.tapOnTarget({target:a,options:o}),description:n});return {success:true,message:i}}};var kc=class extends Rr{async doPress({keycode:e,longPress:r}){await ue().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeInNativeContext(this.logger,n=>n.executeScript("mobile: pressKey",[{keycode:e,isLongPress:r}]),{operationName:"pressKey"}),{name:"Send key events to emulator"});}};var dd=25,NQ=150,ow=class extends Rr{async doType(e){let r=ue();if(!e.target){if(e.clearContent)throw new M("UserConfigurationError","Clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(e),{success:true,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:r,action:async n=>{"type"in n&&n.type==="NATIVE"?await this.doNativeType(e,n):await this.doWebviewType(e,n);},description:e.target.description});return {success:true,message:o}}async doWebviewType(e,r){await ue().startAsyncSpan("EMULATOR_INTERACTION",async n=>{n.withinWebview=true;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??dd};n.attributes.options=i;let{controller:a,browserTarget:s}=r;await a.browser.typeIntoTarget(e.text,s,i);},{name:"Typing within web view"});}async doNativeType(e,r){e.clearContent?(await this.tapNativeTargetForType(r,{longPress:true}),await this.clearContent()):await this.tapNativeTargetForType(r),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e);}async tapNativeTargetForType(e,r){let o=ue(),n=new Yp(this.constructPerformerParams());await o.startAsyncSpan("EMULATOR_INTERACTION",async i=>{i.attributes.options=r??{};let a=await n.tapOnNativeTarget(e,r);i.attributes.point=a,i.targetBounds=Lc(e);},{name:"Tap on target"});}async sendKeys(e){let r=ue(),o=e.keyPressDelayMs??dd;await r.startAsyncSection("Waiting for system keyboard to open",async(n,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.executeInNativeContext(this.logger,l=>l.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;let c=Date.now()-s;c<500&&await new Promise(l=>setTimeout(l,500-c));}i.attributes.timedOut=true;}),await r.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{o!==dd&&await this.driver.executeInNativeContext(this.logger,async i=>i.updateSettings({keyInjectionDelay:o}),{operationName:"updateKeyInjectionDelay"});let n=[];for(let i=0;i<e.text.length;i+=NQ)n.push(e.text.slice(i,i+NQ));for(let i of n)await this.driver.executeInNativeContext(this.logger,async a=>a.keys(i),{operationName:"typeWithCustomKeyDelay",attemptTimeoutMs:Gv(o,i),maxAttempts:1});}finally{o!==dd&&await this.driver.executeInNativeContext(this.logger,async n=>n.updateSettings({keyInjectionDelay:dd}),{operationName:"updateKeyInjectionDelay"});}},{name:`Typing with a ${o}ms delay`});}async clearContent(){let e=ue();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper());}catch(r){this.logger.warn({err:r},"Failed to find select all button, continuing...");}}async clearContentHelper(){await this.driver.executeInNativeContext(this.logger,async r=>{let o=r.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await o.waitForExist({timeout:750}),await o.click();},{operationName:"selectAllText",maxAttempts:1}),await new kc(this.constructPerformerParams()).doPress({keycode:67});}};var DQ=.8,jke=C__default.object({navigationBar:C__default.object({visible:C__default.boolean(),x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()}),statusBar:C__default.object({visible:C__default.boolean(),x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()})});function g0(t,e){t.attributes.scrollableElementType=e.type,t.attributes.scrollableElementDisplay=Ms(e),e.type==="CUSTOM"&&(t.attributes.scrollableElementDescription=e.target.description);}var Xp=class extends Rr{async getHardcodedScrollableElementBounds(e,r){let o;switch(e.type){case "SCREEN":o=this.getContainerBoundsFromViewport(r);break;case "OPEN_APP":try{let n=jke.parse(await this.driver.executeInNativeContext(this.logger,i=>i.executeScript("mobile: getSystemBars",[]),{operationName:"getSystemBars"}));o=this.getContainerBoundsFromViewport(r),n.navigationBar.visible&&(o.height=Math.max(1,o.height-n.navigationBar.height)),n.statusBar.visible&&(o.top+=n.statusBar.height,o.height=Math.max(1,o.height-n.statusBar.height));}catch(n){this.logger.warn({err:n},"Failed to get system bars, using hardcoded bounds"),o=this.getContainerBoundsFromViewport(r);}break;case "OPEN_WEBVIEW":{let n=await this.stateManager.getActiveWebviewNodes();if(n.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),n=await this.stateManager.getActiveWebviewNodes()),n.length===0)throw new Error("No active webviews found");if(n.length>1){let a=n.map(s=>({id:s.id,ele:s.originalElement.outerHTML,bounds:s.bounds}));throw new Error(`Multiple active webviews found. Momentic currently only supports a single active webview at a time. Discovered nodes: ${JSON.stringify(a)}`)}let i=n[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");o=this.getContainerBoundsFromBounds(i);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return o}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:Math.max(1,e.width),height:Math.max(1,e.height)}}getContainerBoundsFromBounds(e){let r=e[0],o=e[1],n=e[2],i=e[3],a=n-r,s=i-o;return {left:r,top:o,width:Math.max(1,a),height:Math.max(1,s)}}async executeSwipe(e){let r=ue(),o=Ms(e.scrollableElement);if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:i,startY:a,deltaPixels:s}=e.scrollableElement;return await r.startAsyncSpan("EMULATOR_INTERACTION",async c=>{g0(c,e.scrollableElement),c.attributes.startX=i,c.attributes.startY=a,c.attributes.deltaPixels=s,c.attributes.direction=e.direction,await this.performRawSwipe({startX:i,startY:a,deltaPixels:s,direction:e.direction,durationMs:e.durationMs});},{name:`Swipe ${e.direction} in ${o}`}),{success:true,message:"Successfully executed swipe action"}}if(e.scrollableElement.type!=="CUSTOM"){let i=await this.driver.executeInNativeContext(this.logger,s=>s.getWindowRect(),{operationName:"getSwipeViewportRect"}),a=await this.getHardcodedScrollableElementBounds(e.scrollableElement,i);return await r.startAsyncSpan("EMULATOR_INTERACTION",async s=>{g0(s,e.scrollableElement),await this.swipeByAbsoluteCoordinates({span:s,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:a,relativePosition:e.relativePosition?Kt(e.relativePosition):void 0});},{name:`Swipe ${e.direction} in ${o}`}),{success:true,message:"Successfully executed swipe action"}}let{thoughts:n}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async i=>ue().startAsyncSpan("EMULATOR_INTERACTION",async s=>(g0(s,e.scrollableElement),"type"in i&&i.type==="NATIVE"?this.scrollInNativeContainer({span:s,cmd:e,target:i}):(s.withinWebview=true,this.swipeInWebview({span:s,cmd:e,target:i}))),{name:`Swipe ${e.direction} in ${o}`}),tracer:r});return {success:true,message:n}}async scrollInNativeContainer({span:e,cmd:r,target:o}){if(!o.bounds||o.bounds.length<4)throw new M("ActionFailureError","Native container cache has no bounds");let n=o.bounds,i=n[2]-n[0],a=n[3]-n[1];await this.swipeByAbsoluteCoordinates({span:e,direction:r.direction,percent:r.viewportPercent,durationMs:r.durationMs,containerBounds:{left:n[0],top:n[1],width:Math.max(1,i),height:Math.max(1,a)},relativePosition:r.relativePosition?Kt(r.relativePosition):void 0});}async swipeInWebview({span:e,cmd:r,target:o}){let{controller:n,browserTarget:i}=o;if(!n.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=r.direction==="down"||r.direction==="up",c=await i.locator.boundingBox();if(!c)throw new Error("Failed to get bounds for webview container");let l=Math.floor(c.width*Qn),u=Math.floor(c.height*Qn),d=Math.max(1,c.width-l*2),m=Math.max(1,c.height-u*2),p,f;if(r.relativePosition){let b=Kt(r.relativePosition);p=c.x+b.x,f=c.y+b.y;}else p=c.x+c.width/2,f=c.y+c.height/2;let h={x:p,y:f},S=(s?m:d)*(r.viewportPercent??DQ)*(s?r.direction==="down"?1:-1:r.direction==="right"?1:-1);e.attributes.startPoint=h,e.attributes.scrollPixelAmount=S,await n.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:S,deltaY:s?S:0,steps:10,dragDurationMs:r.durationMs,fromTarget:h});}async swipeByAbsoluteCoordinates({span:e,direction:r,percent:o=DQ,durationMs:n=500,containerBounds:i,relativePosition:a}){e.attributes.containerBounds=i;let s=i.width*Qn,c=i.height*Qn,l,u;if(r==="up"||r==="down"?(l=(i.height-2*c)*o,u=Math.floor(l/(n/1e3))):(l=(i.width-2*s)*o,u=Math.floor(l/(n/1e3))),e.attributes.pixelDelta=l,e.attributes.pixelsPerSecond=u,a){let d=i.left+a.x,m=i.top+a.y;await this.performRawSwipe({startX:d,startY:m,deltaPixels:l,direction:r,durationMs:n});}else {let d=i.width*Qn,m=i.height*Qn,p={left:i.left+d,top:i.top+m,width:Math.max(1,i.width-2*d),height:Math.max(1,i.height-2*m)};await this.driver.executeInNativeContext(this.logger,f=>f.executeScript("mobile: swipeGesture",[{...p,direction:r,percent:o,speed:u}]),{operationName:"swipeGesture"});}}};var Hke=20,S0=.9,Jp=.5,b0=.2;var nw=class extends Xp{async executeScrollTo(e){let r=e.target.description,o=e.scrollStepPercent??S0,n=await this.tryUseCachedScrollPosition(e,r);return n||this.searchForElement({cmd:e,description:r,scrollStepPercent:o})}async resolveContainer({scrollableElement:e,containerCache:r,aiMetadata:o}){let n=await this.driver.executeInNativeContext(this.logger,u=>u.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(e.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:n.width,height:n.height},diffThresholdPercent:Jp};if(e.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(e,n),diffThresholdPercent:Jp};let i=ue(),a=e.target.description;if(r){let u=this.getBoundsFromNativeCache(r);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:r,diffThresholdPercent:cp({containerBounds:u,viewport:n,defaultThresholdPercent:Jp})}}let s=await this.findElement({description:a,tracer:i,metadata:o});if(!s.success)throw new M("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:c}=s;if(c.type!=="NATIVE")throw new Error(`ActionFailureError: Custom scroll container "${a}" resolved to a webview element. Custom containers must be native elements.`);let l=this.getBoundsFromNativeCache(c);return this.logger.info({bounds:l},"Got container bounds from AI"),{bounds:l,cache:c,diffThresholdPercent:cp({containerBounds:l,viewport:n,defaultThresholdPercent:Jp})}}async tryUseCachedScrollPosition(e,r){let o=e.cache?.target;return o?o.type==="WEBVIEW"?this.tryUseWebviewCache(e,r):o.scrollDetails?this.tryUseNativeScrollCache(e,r,o):null:null}async tryUseWebviewCache(e,r){let o=ue();try{let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:o,description:r,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i);}});return {success:!0,message:n}}catch(n){return this.logger.warn({err:n},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,r,o){let n=o.scrollDetails,i=ue(),a=e.scrollStepPercent??S0;if(n.pixelDelta===0)return this.logger.info("Skipping cached scroll-position replay because it would not move the viewport"),null;let s=n.scrollableElement.type==="CUSTOM"?n.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:n.scrollableElement,containerCache:s,direction:n.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let l=await this.tryFindElement({cmd:e,description:r,tracer:i,scrollDetails:n,useAIIfCacheFails:!0});if(l)return l;this.logger.info("Element not found at cached position, undoing scroll");}catch(l){this.logger.warn({err:l},"Error finding element at cached position, will undo scroll");}let c=n.direction==="down"?"up":"down";return this.logger.info({pixelDelta:n.pixelDelta,originalDirection:n.direction,undoDirection:c,scrollableElementType:n.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:n.scrollableElement,containerCache:s,direction:c,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:n,useAIIfCacheFails:i=true}){let a,s,c=false,l=n,u=y0(e.cache?.target);if(u&&u.resolvedDescription!==void 0&&bc(u.resolvedDescription,r)&&!e.disableCache){let p=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true,removeWebviewContent:true});try{let{resolvedTarget:f}=await Kp({target:u,domState:p,stateManager:this.stateManager,logger:this.logger});a=f,c=!0,s="Successfully resolved scroll to target with cache.",this.logger.info("Successfully resolved scroll to target from cache");}catch(f){this.logger.warn({err:f},"Failed to resolve target from cache");}}if(a&&c&&a.type==="NATIVE"&&n){let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:n});l=p.scrollDetails,p.resolvedTarget?a=p.resolvedTarget:(a=void 0,c=false);}if(!a&&!i)return null;if(!a)try{let p=bC(r),f=await this.findElement({description:p,tracer:o,metadata:{commandId:e.id,source:"SCROLL_TO"}});if(!f.success)return null;a=f.resolvedTarget,s=f.thoughts;}catch(p){if(p instanceof M&&p.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:p},"Failed to find scroll-to target with AI"),p}if(a&&!c&&a.type==="NATIVE"&&n)try{let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:n});l=p.scrollDetails,p.resolvedTarget&&(a=p.resolvedTarget);}catch(p){this.logger.warn({err:p},"Failed to reposition AI-resolved scroll-to target for stable cache generation");}if(a.type==="WEBVIEW"){await this.scrollWebviewTargetIntoView(a);let p=y0(Dc(a));return ud({command:e,updatedCache:p,updatedWithAI:!c,logger:this.logger}),{success:true,message:s}}let m=Dc(a);if(m.type!=="NATIVE")throw new Error("Expected native target cache for scroll-to");return ud({command:e,updatedCache:y0({...m,scrollDetails:l}),updatedWithAI:!c,logger:this.logger}),{success:true,message:s}}async correctNativeTargetIntoView({cmd:e,resolvedTarget:r,scrollDetails:o}){let n=await this.getCorrectiveScrollForTarget({resolvedTarget:r});if(!n)return {resolvedTarget:r,scrollDetails:o};this.logger.info({bounds:r.bounds,correction:n},"Repositioning scroll-to target to the preferred viewport anchor");let i=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0,a=await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:o.scrollableElement,containerCache:i,direction:n.direction,scrollStepPercent:e.scrollStepPercent??S0,aiMetadata:{commandId:e.id},useVisualDiff:true});if(a===0)return this.logger.info({bounds:r.bounds,correction:n},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:r,scrollDetails:o};let s={...o,pixelDelta:zv({currentPixelDelta:o.pixelDelta,baseDirection:o.direction,correctionDirection:n.direction,correctionPixels:a})},c=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true,removeWebviewContent:true}),l;try{({resolvedTarget:l}=await Kp({target:r,domState:c,stateManager:this.stateManager,logger:this.logger}));}catch(d){return this.logger.warn({err:d},"Failed to re-resolve scroll-to target after corrective scroll"),{scrollDetails:s}}if(l.type!=="NATIVE")return {scrollDetails:s};let u=await this.getCorrectiveScrollForTarget({resolvedTarget:l});return u?(this.logger.warn({bounds:l.bounds,correction:u},"Corrective scroll still did not bring the scroll-to target into the preferred viewport anchor"),{resolvedTarget:l,scrollDetails:s}):{resolvedTarget:l,scrollDetails:s}}async searchForElement({cmd:e,description:r,scrollStepPercent:o}){let n=ue(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch({cmd:e,description:r,tracer:n,scrollStepPercent:o,resolvedContainer:i})}async scrollAndSearch({cmd:e,description:r,tracer:o,scrollStepPercent:n,resolvedContainer:i}){let a=0,s=i.bounds,c=i.diffThresholdPercent,l=e.scrollableElement.type==="CUSTOM_COORDINATES"?e.scrollableElement:void 0,u;l?u=Math.abs(l.deltaPixels):u=this.calculateSwipeCoordinates({containerBounds:s,direction:e.direction,desiredDelta:dc({containerBounds:s,containerInsetRatio:Qn})*n}).actualDelta;let d=true,m=e.maxScrollAttempts??Hke;for(let h=0;h<m;h++){this.throwIfAborted();let S=this.buildScrollDetails(e,a,i.cache),b=await this.tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:S});if(b)return b;if(!d)throw new Error(`ActionFailureError: Could not find element "${r}" after scrolling to the end`);this.logger.debug({attempt:h,cumulativePixelDelta:a},"Element not found, scrolling further"),d=await this.scrollByPage({direction:e.direction,containerBounds:s,scrollStepPercent:n,diffThresholdPercent:c,rawCoordinates:l}),a+=e.direction==="down"?u:-u;}let p=this.buildScrollDetails(e,a,i.cache),f=await this.tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:p});if(f)return f;throw new Error(`ActionFailureError: Could not find element "${r}" after ${m} scroll attempts`)}buildScrollDetails(e,r,o){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:r,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:o},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:r,browserTarget:o}=e;await r.browser.hover(o);}async scrollByPage({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n,rawCoordinates:i}){return ue().startAsyncSpan("EMULATOR_INTERACTION",async s=>(s.attributes.containerBounds=r,s.attributes.direction=e,(await this.executeScrollGesture({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n,rawCoordinates:i})).canScrollMore),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:r,containerCache:o,direction:n,scrollStepPercent:i,aiMetadata:a,useVisualDiff:s=false}){if(e===0)return 0;let c=ue(),l,u=Jp,d,m,p;if(r.type==="CUSTOM_COORDINATES")d=r.startX,m=r.startY,p=r.deltaPixels;else {l=await this.resolveContainer({scrollableElement:r,containerCache:o,aiMetadata:a});let h=l.bounds;u=l.diffThresholdPercent;let S=dc({containerBounds:h,containerInsetRatio:Qn})*i,b=this.calculateSwipeCoordinates({containerBounds:h,direction:n,desiredDelta:S});d=b.startX,m=b.startY,p=b.actualDelta;}let f=Math.ceil(Math.abs(e)/p);return this.logger.debug({pixelDelta:e,direction:n,scrollableElementType:r.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),c.startAsyncSpan("EMULATOR_INTERACTION",async h=>{h.attributes.pixelDelta=e,h.attributes.numScrolls=f,h.attributes.maxScrollPerStep=p,h.attributes.startX=d,h.attributes.startY=m;let S=this.invertDirection(n),b=0;for(let y=0;y<f;y++){this.throwIfAborted();let T=Math.abs(e)-b,v=Math.min(p,T);if(s){let w=await this.executeScrollGesture({direction:n,containerBounds:l?.bounds,scrollStepPercent:i,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:v}});if(w.didScroll&&(b+=v),!w.canScrollMore)break}else await this.performRawSwipe({startX:d,startY:m,deltaPixels:v,direction:S}),b+=v;}return h.attributes.appliedPixels=b,b},{name:`Scroll ${n} by ${Math.abs(e)}px`})}async executeScrollGesture({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n=Jp,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,c,l;if(i)s=i.startX,c=i.startY,l=i.deltaPixels;else {if(!r)throw new Error("Expected container bounds for scroll gesture");let f=dc({containerBounds:r,containerInsetRatio:Qn})*o,h=this.calculateSwipeCoordinates({containerBounds:r,direction:e,desiredDelta:f});s=h.startX,c=h.startY,l=h.actualDelta;}await this.performRawSwipe({startX:s,startY:c,deltaPixels:l,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=cc(a,u),m=d>n,p=d>n;return this.logger.debug({diffPercent:d,didScroll:m,diffThresholdPercent:n,canScrollMore:p,direction:e,actualDelta:l,rawCoordinates:i},"Scroll gesture visual diff result"),{didScroll:m,canScrollMore:p}}async getCorrectiveScrollForTarget({resolvedTarget:e}){let r=e.bounds;if(!r||r.length<4)return;let o=await this.stateManager.getViewportBounds(),n=Math.max(1,o.bottom-o.top),i=r[1],a=r[3],s=$v({viewportTop:o.top,viewportBottom:o.bottom,elementHeight:a-r[1],targetTopRatio:b0}),c=o.top+n*b0,l=o.bottom-n*b0,u=i>=o.top&&a<=o.bottom,d=i<c||a>l,m=e.resolvedNode.getAttribute("displayed")!=="false"&&e.resolvedNode.getAttribute("visible")!=="false",p=s-i;if(!(u&&m&&!d)){if(p>0)return {direction:"up",pixelDelta:p};if(p<0)return {direction:"down",pixelDelta:Math.abs(p)}}}};function y0(t){return !t||t.type!=="NATIVE"?t:jv(t)}var iw=class extends Rr{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:true,message:"Installed APK."}}async installApkFromUri(e){let r=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${sr__default.resolve(r.localPath)}`),this.logger.info({uri:e,localPath:r.localPath},"Installed APK on device");}finally{r.cleanup();}}async resolveUriToLocalApk(e){try{let r=new URL(e);if(r.protocol==="file:"){let o=r.href.slice(7),n;if(so.existsSync(o))n=o;else if(so.existsSync(sr__default.join("/",o)))n=sr__default.join("/",o);else throw new M("UserConfigurationError",`APK not found at path: ${o}`);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}if(r.protocol==="http:"||r.protocol==="https:"){let o=await this.fetchWithTimeout(r);if(!o.ok)throw new M("UserInfrastructureError",`Failed to download APK from ${e} (status ${o.status})`);let n=await o.arrayBuffer(),i=Buffer.from(n),a=await this.writeBufferToTempFile(i,r.pathname);return {localPath:a,cleanup:()=>{try{so.unlinkSync(a);}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file");}}}}throw new M("UserConfigurationError",`Unsupported URI scheme for APK installation: ${r.protocol}`)}catch(r){if(r instanceof TypeError){let o=sr__default.resolve(e);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}throw r}}assertFileExists(e){try{so.accessSync(e);}catch{throw new M("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let r=AbortSignal.timeout(9e4);return await fetch(e,{signal:r})}async writeBufferToTempFile(e,r){let o=sr__default.extname(r)||".apk",n=sr__default.join(tmpdir(),`momentic-apk-${randomUUID()}${o}`);return so.writeFileSync(n,e),n}};async function LQ({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,abortSignal:a}){let s=ue();if(!t.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(t.schema){let u=ym(t.schema);if(u)throw new M("UserConfigurationError",u)}let c="",l="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{c=await n(),l=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await r.getAndroidTextExtraction({goal:t.goal,emulatorState:c,returnSchema:t.schema,screenshot:`data:image/png;base64,${l}`},{disableCache:!!t.disableCache,abortSignal:a,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["android-text-extraction"]});if(u.result=d,Hv({tracer:s,span:u,screenshot:l,emulatorState:c,logger:e}),d.result==="NOT_FOUND")return {success:!1,message:"No relevant data found for extraction goal on this page"};if(d.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}})}var aw=class extends Rr{async dragNative(e,r,o){let{left:n,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:c,top:l,width:u,height:d}=this.getBoundsFromNativeCache(r),m=n+a/2,p=i+s/2,f=c+u/2,h=l+d/2,S=o?.hoverDuration??500,b=o?.dragDuration??1e3;await this.driver.executeInNativeContext(this.logger,async y=>{await y.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:m,y:p},{type:"pointerDown",button:0},{type:"pause",duration:S},{type:"pointerMove",duration:b,x:f,y:h},{type:"pointerUp",button:0}]}]),await y.releaseActions();},{operationName:"dragAndDrop"});}async dragWebview(e,r,o){let{controller:n}=e;if(e.controller!==r.controller)throw new M("UserConfigurationError","Cannot drag and drop between different webviews");let i=o?.dragDuration??1e3,a=o?.hoverDuration??1e3,s;o?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await n.browser.dragAndDrop(e.browserTarget,r.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i});}async executeDragAndDrop({command:e}){let r=ue();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new M("UserConfigurationError","Drag and drop only supports description targets for now");let o=e.fromTarget.description,{result:n,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:r,description:o,cacheKey:"cache",targetName:"fromTarget",action:async l=>l}),a=e.toTarget.description,{result:s,thoughts:c}=await this.wrapTargetingAction({command:e,tracer:r,description:a,cacheKey:"cache",targetName:"toTarget",action:async l=>l});if(n.type!==s.type)throw new M("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${n.type}, To=${s.type}`);return await r.startAsyncSpan("EMULATOR_INTERACTION",async l=>{n.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(n,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):n.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(l.withinWebview=true,await this.dragWebview(n,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}));},{name:"Drag and drop"}),{success:true,message:`${i}
|
|
5579
|
+
`));return}}let d=Array.from(e.childNodes??[]);for(let m of d){let p=m.nodeType;if(p===3){let f=m.nodeValue;f&&f.trim().length>0&&r.appendChild(o.createTextNode(f));continue}if(p===1){let f=m;if(!Dke(f,s?.viewportBounds))continue;let h=o.createElement(TQ(f.tagName));vQ(t,f,h),r.appendChild(h);}}}function Oke(t,e,r,o){let n=t.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:n,idToElement:r,prunedIdToElement:i,idCounter:{value:0},opts:o},s=n.documentElement;vQ(a,e,s);let c=new XMLSerializer().serializeToString(n);return {prunedDocument:n,prunedIdToElement:i,xml:c}}async function CQ(t,e,r){let o=new DOMParser,n=o.parseFromString(t,"text/xml"),i=new Map,a=n.documentElement;if(!a)throw new M("InternalWebAgentError","No root element found in XML");if(a.tagName!=="hierarchy")throw new M("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:s,prunedIdToElement:c,xml:l}=Oke(o,a,i,r),u=l;try{u=await Tke.format(l,{parser:"xml",plugins:[Eke],printWidth:120,tabWidth:1,singleAttributePerLine:!1});}catch(d){e.warn({err:d},"Failed to format XML");}return {xml:u,originalXml:t,document:n,idToElement:i,prunedDocument:s,prunedIdToElement:c}}function Nke(t){let e=[],r=t;for(;r;){let o=r.tagName,n=r.parentElement,i=1;if(n){let a=Array.from(n.children).filter(s=>s.tagName===o);for(let s=0;s<a.length;s++)if(a[s]===r){i=s+1;break}}e.unshift(`${o}[${i}]`),r=n;}return `/${e.join("/")}`}function tw(t,e){let r=t.idToElement.get(e);if(r)return Nke(r)}function p0(t,e){let r=t.idToElement.get(e);if(!r)return;let o=r.cloneNode(true);for(let n of Array.from(o.children)){let i=n;for(let a of Array.from(i.children))i.removeChild(a);}return o.outerHTML}function cd(t){if(!t.hasAttribute("bounds"))return;let e=t.getAttribute("bounds");if(!e)return;let r=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(r){let o=parseInt(r[1],10),n=parseInt(r[2],10),i=parseInt(r[3],10),a=parseInt(r[4],10);if(Number.isFinite(o)&&Number.isFinite(n)&&Number.isFinite(i)&&Number.isFinite(a))return [o,n,i,a]}}function Dke(t,e){if(!e)return true;let r=cd(t);if(!r||r.length<4)return true;let o=r[0],n=r[1],i=r[2],a=r[3];return !(i<=e.left||o>=e.right||a<=e.top||n>=e.bottom)}function AQ(t,e){if(t&&!(!e||e.length===0))return Object.fromEntries(e.map(r=>[r,t.getAttribute(r)]).filter(([,r])=>r!==null))}function RQ({requirements:t,element:e}){let r;if((t?.positionSpecificity||t?.shapeSpecificity)&&(r=cd(e),!r))throw new M("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:t?.textRequired&&fp(e)||void 0,requiredAttributes:AQ(e,t?.attributesRequired),requiredBounds:t?.boundsRequired,position:t?.positionSpecificity?{x1:r[0],y1:r[1],x2:r[2],y2:r[3],tolerance:t?.positionSpecificity}:void 0,shape:t?.shapeSpecificity?{width:r[2]-r[0],height:r[3]-r[1],tolerance:t?.shapeSpecificity}:void 0}}function MQ({aiResponse:t,description:e,emulatorState:r,memory:o,useMemory:n}){let i=r.graph.idToElement.get(t.id);if(!i)throw new M("InternalWebAgentError",`Could not find node with id: ${t.id}`);let a=cd(i);if(!a)throw new M("InternalWebAgentError",`Node ${t.id} has no bounding box: ${i.outerHTML}`);let s=tw(r.graph,t.id)??"",c=p0(r.graph,t.id)??"",l=RQ({requirements:t.requirements,element:i}),u=[];t.additionalElements&&(u=t.additionalElements.map(({id:m,requirements:p})=>{let f=r.graph.idToElement.get(m);if(!f)return;let h=tw(r.graph,m);return h?{xPath:h,requirements:RQ({requirements:p,element:f})}:void 0}).filter(m=>!!m));let d;if(ub(i)&&t.inWebview!==false?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:c,requirements:l,requiredRelatedElements:u},n)if(t.updatedMemory){let m={type:"GCS_TRACES",traces:t.updatedMemory};d.memory=m;}else o&&(d.memory=o);return {target:d,resolvedNode:i}}function xQ(t){return t?.type==="WEBVIEW"?t.browserCache?.memory:void 0}function Lke(t,e){let r=e.x2-e.x1,o=(e.x1+e.x2)/2,n=(t[0]+t[2])/2;if(!rs(e.tolerance,o,n,Math.min(1,r)))return false;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(t[1]+t[3])/2;return rs(e.tolerance,a,s,Math.min(1,i))}function kke(t,e){return rs(e.tolerance,e.width,t[2]-t[0],Math.min(1,e.width))?rs(e.tolerance,e.height,t[3]-t[1],Math.min(1,e.height)):false}var _Q=(t,e,r)=>{if(!e)return;let{requiredAttributes:o,requiredText:n,requiredBounds:i,position:a,shape:s}=e;if(n!==void 0&&n.length>0){let c=fp(t);if(c!==n)throw new we(`Resolved element text mismatch: expected ${n}, got ${c}`)}if(o)for(let[c,l]of Object.entries(o)){let u=t.getAttribute(c)??void 0;if(u!==l)throw new we(`Attribute ${c} mismatch: expected ${l}, got ${u}`)}if(i&&r&&!r.targetBounds.every((l,u)=>l===r.newElementBounds[u]))throw new we(`Bounds changed from [${r.targetBounds.join(",")} ] to [${r.newElementBounds.join(",")} ]`);if(a&&r&&!Lke(r.newElementBounds,a))throw new we(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(r.newElementBounds)}`);if(s&&r&&!kke(r.newElementBounds,s))throw new we(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(r.newElementBounds)}`)};async function Kp(t){let{target:e,domState:r}=t,{graph:o}=r,{document:n}=o,i=ue();if(e.type==="WEBVIEW")return Fke(e,t);if(!e.xPath)throw new M("ActionFailureError","Native element cache has no XPath");let a=wQ.evaluateXPathToFirstNode(e.xPath,n,null,null);if(!a)throw new we(`Could not resolve cached target via XPath: ${e.xPath}`);if(e.requiredRelatedElements){let m=e.requiredRelatedElements;i.startSection("Validate related elements are similar enough to past runs",()=>{for(let p of m){let f=wQ.evaluateXPathToFirstNode(p.xPath,n);if(!f)throw new we(`Required related element not found for XPath: ${p.xPath}`);_Q(f,p.requirements);}});}let s=cd(a);if(!s)throw new we("Resolved native element has no bounding box");if(!e.bounds)throw new we("Native element cache has no bounds");_Q(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let c;for(let[m,p]of o.idToElement.entries())if(p===a){c=m;break}let l=e.elementOnlySerializedXml,u=e.xPath;return c!==void 0&&(l=p0(o,c)??l,u=tw(o,c)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:l,xPath:u}}}async function Fke(t,e){let{stateManager:r,logger:o,signal:n}=e,i=ue(),a=await r.getActiveWebview();if(!a||!a.browserController)throw o.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new we("No browser controller is attached to the requested webview");let s=a.browserController;if(!t.browserCache)throw o.error({target:t},"resolveTargetCacheInWebView: No browser target available on cache"),new we("No browser target available on cache");let c=t.browserCache,{finalTarget:l}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({cache:c,options:{resolveTargetOptions:{logger:o,signal:n,skipWaitForPageLoad:true,skipSavingVisualAttributes:true}},logger:o}));return {resolvedTarget:{...t,controller:a.browserController,browserTarget:l}}}function ud(t){let{command:e,cacheKey:r="cache",targetName:o="target",updatedCache:n}=t;Da(e)&&(e[r]={...e[r],[o]:jd.parse(n)},t.updatedWithAI&&(e[r].updatedAt=new Date,e[r].updatedAtLoggerTags=Ie(t.logger)));}function Dc(t){if(t.type==="WEBVIEW")return {type:"WEBVIEW",resolvedDescription:t.resolvedDescription,xPath:t.xPath,browserCache:t.browserCache,memory:t.memory};let{resolvedNode:e,...r}=t;return {...r}}var Qn=.15,Bke=500,Rr=class{driver;generator;stateManager;logger;fixtures;aborter;orgId;aiSettings;options;constructor(e){this.stateManager=e.stateManager,this.generator=e.generator,this.driver=e.driver,this.logger=e.logger,this.fixtures=e.fixtures,this.aborter=e.aborter,this.orgId=e.orgId,this.aiSettings=e.aiSettings,this.options=e.options;}shouldUseMemoryForCommand(e){return this.aiSettings?.useMemory&&!e?.disableCache}async findElement({description:e,tracer:r,skipFetchingFullWebviewContent:o=false,removeWebviewContent:n=false,useMemory:i=false,memory:a,webviewMemory:s,metadata:c,cacheBustReason:l}){let u=this.logger.child({...c}),d=await r.startAsyncSection("Get emulator state",async()=>{let b=await this.stateManager.getCurrentScreenshotPngString();return {emulatorState:await this.stateManager.getDomState({skipFetchingFullWebviewContent:o,removeWebviewContent:n}),screenshot:b}}),m;try{m=await r.startAsyncSpan("AI_LOCATOR_CALL",async b=>{l&&(b.attributes.cacheBustReason=l);let y=await this.generator.getAndroidElementLocation({description:e,screenXml:d.emulatorState.graph.xml,screenshot:d.screenshot,source:c?.source==="SCROLL_TO"?"SCROLL_TO":void 0,memory:i?a:void 0},{logger:u,loggerTags:Ie(u),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return b.result=y,y});}catch(b){throw this.throwIfAborted(),u.error({err:b},"Failed to locate element"),new M("InternalWebAgentError",`Failed to locate element: ${b instanceof Error?b.message:b}`,{errOptions:{cause:b}})}if(m.id===-1){let b=m.updatedMemory?{type:"GCS_TRACES",traces:m.updatedMemory}:void 0;return {success:false,thoughts:m.thoughts??"No matching element found",updatedLocatorMemory:b}}let{target:p,resolvedNode:f}=MQ({aiResponse:m,description:e,emulatorState:d.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:true,resolvedTarget:{...p,resolvedNode:f},thoughts:m.thoughts};let{browserLocateResult:h,browserController:S}=await r.startWebviewTrace(async()=>{let b=await this.stateManager.getActiveWebview();if(!b||!b.browserController)throw new M("InternalWebAgentError","No browser controller is attached to the requested webview");return {browserLocateResult:await b.browserController.locateElement({description:e,disableCache:false,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:true,skipSavingVisualAttributes:true}),browserController:b.browserController}});return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:h.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:true,resolvedTarget:{...p,controller:S,browserTarget:{...h.resolution,serverSideBoundingBox:await h.resolution.locator.boundingBox({timeout:5e3})},browserCache:h.target},thoughts:h.thoughts}}async targetingActionWithAILocator(e){let{action:r,command:o,description:n,tracer:i,cacheKey:a,targetName:s,cache:c,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:d,cacheBustReason:m}=e,p=await this.findElement({description:n,tracer:i,skipFetchingFullWebviewContent:l,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(o),memory:c?.memory,webviewMemory:xQ(c),metadata:d,cacheBustReason:m});if(!p.success){if(p.updatedLocatorMemory&&c){let b={...c,memory:p.updatedLocatorMemory};ud({command:o,cacheKey:a,targetName:s,updatedCache:b,updatedWithAI:true,logger:this.logger});}throw new M("NoMatchingElementError",p.thoughts??"No matching element found")}let f=p.thoughts,{result:h,resolvedTarget:S}=await this.executeActionWithWebviewReconstructRetry({action:r,resolvedTarget:p.resolvedTarget,reason:"webview target closed during AI-located action"});return ud({command:o,cacheKey:a,targetName:s,updatedCache:Dc(S),updatedWithAI:true,logger:this.logger}),{result:h,thoughts:f}}async wrapTargetingAction(e){let{action:r,description:o,command:n,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:c,skipFetchingFullWebviewContent:l=false,removeWebviewContent:u=false}=e,d,m={commandId:n.id};if(i==="cache"&&"cache"in n&&n.cache){let T=n.cache;a==="target"&&"target"in T?d=T.target:a==="fromTarget"&&"fromTarget"in T?d=T.fromTarget:a==="toTarget"&&"toTarget"in T&&(d=T.toTarget);}let p=false,f,h=cloneDeep(d);if(n.disableCache&&(this.logger.debug({command:n},"Cache explicitly disabled for command"),p=true,f="Cache explicitly disabled",h=void 0),s&&(p=true,f=f??"Cache invalidated after resolution",h=void 0),h&&!bc(h?.resolvedDescription??"",o)&&(this.logger.info({description:o,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=true,f="Description mismatch",h=void 0),!h)return this.logger.info({description:o,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:r,command:n,description:o,tracer:c,cacheKey:i,targetName:a,cache:d,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m,cacheBustReason:f});let S=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,b=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,y;try{this.options?.emulator?.waitForStability&&await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let{resolvedTarget:T}=await c.startAsyncSpan("CACHE_RESOLUTION",async N=>{let D=Date.now(),x;for(;Date.now()-D<3e3;){y=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let A;try{A=(await Kp({target:h,domState:y,stateManager:this.stateManager,logger:this.logger})).resolvedTarget;}catch(z){if(x=z,z instanceof we){this.logger.warn({err:z},"Failed to resolve target cache, retrying"),await Wa(500,this.aborter.controller?.signal);continue}throw this.logger.error({err:z},"Failed to resolve target cache"),z}let B=Dc(A),O=diff(h,B);return O&&Object.keys(O).length>0&&this.logger.info({cacheDiffs:O},"Successfully resolved target with cache"),N.attributes.serializedElement=A.type==="WEBVIEW"?A.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":A.elementOnlySerializedXml??"Unknown element",{resolvedTarget:A,updatedCache:B}}throw x}),{result:v,resolvedTarget:w}=await this.executeActionWithWebviewReconstructRetry({action:r,resolvedTarget:T,reason:"webview target closed during cached action"});return ud({command:n,cacheKey:i,targetName:a,updatedCache:Dc(w),updatedWithAI:!1,logger:this.logger}),_t.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${S}`,`hasAdditionalElements:${b}`,`orgId:${this.orgId}`,"cliVersion:0.97.3"]),{result:v,thoughts:"Successfully executed preset action with cache"}}catch(T){if(this.throwIfAborted(),T instanceof M&&T.reason!=="InternalWebAgentError")throw this.logger.error({err:T},"Failed to execute action with target cache (fatal)"),T;return _t.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${S}`,`hasAdditionalElements:${b}`,`orgId:${this.orgId}`,"cliVersion:0.97.3"]),this.logger.warn({err:T},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:r,command:n,description:o,tracer:c,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:l,removeWebviewContent:u,metadata:m})}}async executeActionWithWebviewReconstructRetry(e){let{action:r,resolvedTarget:o,reason:n}=e;try{return {result:await r(o),resolvedTarget:o}}catch(i){if(this.throwIfAborted(),o.type!=="WEBVIEW"||!this.errorLooksLikeClosedWebviewTarget(i)||(this.logger.warn({err:i},"Webview target appears closed or crashed during action, reconstructing browser and retrying once"),!(await this.stateManager.reconstructActiveWebviewBrowser(n))?.browserController))throw i;let s=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true}),{resolvedTarget:c}=await Kp({target:Dc(o),domState:s,stateManager:this.stateManager,logger:this.logger,signal:this.abortSignal});return {result:await r(c),resolvedTarget:c}}}errorLooksLikeClosedWebviewTarget(e){let r=j(e);return ["Target closed","Target crashed","Page crashed","Target page, context or browser has been closed","Session closed. Most likely the page has been closed"].some(o=>r.includes(o))}constructPerformerParams(){return {stateManager:this.stateManager,generator:this.generator,driver:this.driver,logger:this.logger,fixtures:this.fixtures,aborter:this.aborter,orgId:this.orgId,aiSettings:this.aiSettings,options:this.options}}getBoundsFromNativeCache(e){if(!e.bounds)throw new M("ActionFailureError","Native element cache has no bounds");let[r,o,n,i]=e.bounds;if(r===void 0||o===void 0||n===void 0||i===void 0)throw new M("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return {left:r,top:o,width:n-r,height:i-o}}calculateSwipeCoordinates({containerBounds:e,direction:r,desiredDelta:o}){let n=e.left+e.width/2,i=e.top+e.height/2;if(r==="up"||r==="down"){let a=e.height*Qn,s=e.top+a,c=e.top+e.height-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u,m=r==="down"?c-d/2:s+d/2;return {startX:n,startY:m,actualDelta:u}}else {let a=e.width*Qn,s=e.left+a,c=e.left+e.width-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u;return {startX:r==="right"?c-d/2:s+d/2,startY:i,actualDelta:u}}}invertDirection(e){if(e==="up")return "down";if(e==="down")return "up";if(e==="left")return "right";if(e==="right")return "left";throw new Error(`Unreachable code: ${e}`)}async performRawSwipe({startX:e,startY:r,deltaPixels:o,direction:n,durationMs:i=300}){let a=Math.abs(o),s=e,c=r;n==="up"||n==="down"?c=n==="up"?r-a:r+a:s=n==="left"?e-a:e+a,await this.driver.executeInNativeContext(this.logger,async l=>{await l.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:r},{type:"pointerDown",button:0},{type:"pause",duration:250},{type:"pointerMove",duration:i,x:s,y:c},{type:"pause",duration:500},{type:"pointerUp",button:0}]}]),await l.releaseActions();},{operationName:"performRawSwipe"}),await ce(Bke,this.abortSignal);}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}get abortSignal(){return this.aborter.controller?.signal}get aiSettingsCopy(){return cloneDeep(this.aiSettings)}get optionsCopy(){return cloneDeep(this.options)}};function Lc(t){if(t.type==="WEBVIEW"){let a=t.browserTarget.serverSideBoundingBox;return a?{left:a.x,top:a.y,width:a.width,height:a.height}:void 0}let{bounds:e}=t;if(!e)return;let[r,o,n,i]=e;if(!(r===void 0||o===void 0||n===void 0||i===void 0))return {left:r,top:o,width:n-r,height:i-o}}function OQ(t){return "iterations"in t}function $ke(t){let e={relativePosition:t.relativePosition?Kt(t.relativePosition):void 0};if(t.iterations!==void 0&&(!Number.isInteger(t.iterations)||t.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(t.tapDelayMs!==void 0&&(!Number.isInteger(t.tapDelayMs)||t.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(t.iterations&&t.iterations>1&&t.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(t.tapDelayMs!==void 0&&(!t.iterations||t.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(t.longPress){if(t.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return {...e,longPress:true,longPressDurationMs:t.longPressDurationMs}}return t.iterations!==void 0?{...e,iterations:t.iterations,tapDelayMs:t.tapDelayMs}:e}var Yp=class extends Rr{async tapOnNativeCoordinates(e){let r=e.x,o=e.y;if(this.logger.info({x:r,y:o},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeInNativeContext(this.logger,n=>n.executeScript("mobile: longClickGesture",[{x:r,y:o,duration:e.longPressDurationMs??2e3}]),{operationName:"longPress"});if(OQ(e)){let n=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.executeInNativeContext(this.logger,a=>a.tap({x:r,y:o}),{operationName:"tap"}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,n));return}await this.driver.executeInNativeContext(this.logger,n=>n.tap({x:r,y:o}),{operationName:"tap"});}async tapOnNativeTarget(e,r){let[o,n,i,a]=e.bounds,s=i-o,c=a-n,l=r?.relativePosition?.x??s/2,u=r?.relativePosition?.y??c/2;l=Math.max(0,Math.min(l,s)),u=Math.max(0,Math.min(u,c));let d=o+l,m=n+u;return await this.tapOnNativeCoordinates({x:d,y:m,...r}),{x:d,y:m}}async tapOnWebviewTarget(e,r){let{controller:o}=e,n,i=1;return r&&OQ(r)?(n=r.tapDelayMs,i=r.iterations):r&&"longPress"in r&&(n=r.longPressDurationMs),(await o.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),c=sr__default.join(tmpdir(),"momentic","downloads"),l=sr__default.join(c,this.orgId,s);return mkdirSync(l,{recursive:true}),l}},{delayMs:n,relativePosition:r?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:r}){return await ue().startAsyncSpan("EMULATOR_INTERACTION",async n=>{if(n.attributes.options=r,"type"in e&&e.type==="NATIVE"){let i=await this.tapOnNativeTarget(e,r);n.attributes.point=i,n.targetBounds=Lc(e);}else {n.withinWebview=true;let i=await this.tapOnWebviewTarget(e,r);n.attributes.point=i,n.targetBounds=Lc(e);}},{name:"Tap on target"})}async executeTap({command:e}){let r=ue(),o=$ke(e);if(e.target.type==="coordinates"||e.target.type==="absolute_percent"){let a=await this.driver.executeInNativeContext(this.logger,l=>l.getWindowSize(),{operationName:"getTapWindowSize"}),s,c;return e.target.type==="coordinates"?(s=e.target.xPercent*a.width,c=e.target.yPercent*a.height):(s=e.target.x/100*a.width,c=e.target.y/100*a.height),await r.startAsyncSpan("EMULATOR_INTERACTION",async l=>{await this.tapOnNativeCoordinates({...o,x:s,y:c}),l.attributes.point={x:s,y:c};},{name:`Tap at coordinates ${s}, ${c}`}),{success:true,message:`Tapped at ${s}, ${c}`}}let n=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:r,action:a=>this.tapOnTarget({target:a,options:o}),description:n});return {success:true,message:i}}};var kc=class extends Rr{async doPress({keycode:e,longPress:r}){await ue().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeInNativeContext(this.logger,n=>n.executeScript("mobile: pressKey",[{keycode:e,isLongPress:r}]),{operationName:"pressKey"}),{name:"Send key events to emulator"});}};var dd=25,NQ=150,ow=class extends Rr{async doType(e){let r=ue();if(!e.target){if(e.clearContent)throw new M("UserConfigurationError","Clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(e),{success:true,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:r,action:async n=>{"type"in n&&n.type==="NATIVE"?await this.doNativeType(e,n):await this.doWebviewType(e,n);},description:e.target.description});return {success:true,message:o}}async doWebviewType(e,r){await ue().startAsyncSpan("EMULATOR_INTERACTION",async n=>{n.withinWebview=true;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??dd};n.attributes.options=i;let{controller:a,browserTarget:s}=r;await a.browser.typeIntoTarget(e.text,s,i);},{name:"Typing within web view"});}async doNativeType(e,r){e.clearContent?(await this.tapNativeTargetForType(r,{longPress:true}),await this.clearContent()):await this.tapNativeTargetForType(r),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e);}async tapNativeTargetForType(e,r){let o=ue(),n=new Yp(this.constructPerformerParams());await o.startAsyncSpan("EMULATOR_INTERACTION",async i=>{i.attributes.options=r??{};let a=await n.tapOnNativeTarget(e,r);i.attributes.point=a,i.targetBounds=Lc(e);},{name:"Tap on target"});}async sendKeys(e){let r=ue(),o=e.keyPressDelayMs??dd;await r.startAsyncSection("Waiting for system keyboard to open",async(n,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.executeInNativeContext(this.logger,l=>l.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;let c=Date.now()-s;c<500&&await new Promise(l=>setTimeout(l,500-c));}i.attributes.timedOut=true;}),await r.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{o!==dd&&await this.driver.executeInNativeContext(this.logger,async i=>i.updateSettings({keyInjectionDelay:o}),{operationName:"updateKeyInjectionDelay"});let n=[];for(let i=0;i<e.text.length;i+=NQ)n.push(e.text.slice(i,i+NQ));for(let i of n)await this.driver.executeInNativeContext(this.logger,async a=>a.keys(i),{operationName:"typeWithCustomKeyDelay",attemptTimeoutMs:Gv(o,i),maxAttempts:1});}finally{o!==dd&&await this.driver.executeInNativeContext(this.logger,async n=>n.updateSettings({keyInjectionDelay:dd}),{operationName:"updateKeyInjectionDelay"});}},{name:`Typing with a ${o}ms delay`});}async clearContent(){let e=ue();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper());}catch(r){this.logger.warn({err:r},"Failed to find select all button, continuing...");}}async clearContentHelper(){await this.driver.executeInNativeContext(this.logger,async r=>{let o=r.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await o.waitForExist({timeout:750}),await o.click();},{operationName:"selectAllText",maxAttempts:1}),await new kc(this.constructPerformerParams()).doPress({keycode:67});}};var DQ=.8,jke=C__default.object({navigationBar:C__default.object({visible:C__default.boolean(),x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()}),statusBar:C__default.object({visible:C__default.boolean(),x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()})});function g0(t,e){t.attributes.scrollableElementType=e.type,t.attributes.scrollableElementDisplay=Ms(e),e.type==="CUSTOM"&&(t.attributes.scrollableElementDescription=e.target.description);}var Xp=class extends Rr{async getHardcodedScrollableElementBounds(e,r){let o;switch(e.type){case "SCREEN":o=this.getContainerBoundsFromViewport(r);break;case "OPEN_APP":try{let n=jke.parse(await this.driver.executeInNativeContext(this.logger,i=>i.executeScript("mobile: getSystemBars",[]),{operationName:"getSystemBars"}));o=this.getContainerBoundsFromViewport(r),n.navigationBar.visible&&(o.height=Math.max(1,o.height-n.navigationBar.height)),n.statusBar.visible&&(o.top+=n.statusBar.height,o.height=Math.max(1,o.height-n.statusBar.height));}catch(n){this.logger.warn({err:n},"Failed to get system bars, using hardcoded bounds"),o=this.getContainerBoundsFromViewport(r);}break;case "OPEN_WEBVIEW":{let n=await this.stateManager.getActiveWebviewNodes();if(n.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),n=await this.stateManager.getActiveWebviewNodes()),n.length===0)throw new Error("No active webviews found");if(n.length>1){let a=n.map(s=>({id:s.id,ele:s.originalElement.outerHTML,bounds:s.bounds}));throw new Error(`Multiple active webviews found. Momentic currently only supports a single active webview at a time. Discovered nodes: ${JSON.stringify(a)}`)}let i=n[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");o=this.getContainerBoundsFromBounds(i);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return o}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:Math.max(1,e.width),height:Math.max(1,e.height)}}getContainerBoundsFromBounds(e){let r=e[0],o=e[1],n=e[2],i=e[3],a=n-r,s=i-o;return {left:r,top:o,width:Math.max(1,a),height:Math.max(1,s)}}async executeSwipe(e){let r=ue(),o=Ms(e.scrollableElement);if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:i,startY:a,deltaPixels:s}=e.scrollableElement;return await r.startAsyncSpan("EMULATOR_INTERACTION",async c=>{g0(c,e.scrollableElement),c.attributes.startX=i,c.attributes.startY=a,c.attributes.deltaPixels=s,c.attributes.direction=e.direction,await this.performRawSwipe({startX:i,startY:a,deltaPixels:s,direction:e.direction,durationMs:e.durationMs});},{name:`Swipe ${e.direction} in ${o}`}),{success:true,message:"Successfully executed swipe action"}}if(e.scrollableElement.type!=="CUSTOM"){let i=await this.driver.executeInNativeContext(this.logger,s=>s.getWindowRect(),{operationName:"getSwipeViewportRect"}),a=await this.getHardcodedScrollableElementBounds(e.scrollableElement,i);return await r.startAsyncSpan("EMULATOR_INTERACTION",async s=>{g0(s,e.scrollableElement),await this.swipeByAbsoluteCoordinates({span:s,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:a,relativePosition:e.relativePosition?Kt(e.relativePosition):void 0});},{name:`Swipe ${e.direction} in ${o}`}),{success:true,message:"Successfully executed swipe action"}}let{thoughts:n}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async i=>ue().startAsyncSpan("EMULATOR_INTERACTION",async s=>(g0(s,e.scrollableElement),"type"in i&&i.type==="NATIVE"?this.scrollInNativeContainer({span:s,cmd:e,target:i}):(s.withinWebview=true,this.swipeInWebview({span:s,cmd:e,target:i}))),{name:`Swipe ${e.direction} in ${o}`}),tracer:r});return {success:true,message:n}}async scrollInNativeContainer({span:e,cmd:r,target:o}){if(!o.bounds||o.bounds.length<4)throw new M("ActionFailureError","Native container cache has no bounds");let n=o.bounds,i=n[2]-n[0],a=n[3]-n[1];await this.swipeByAbsoluteCoordinates({span:e,direction:r.direction,percent:r.viewportPercent,durationMs:r.durationMs,containerBounds:{left:n[0],top:n[1],width:Math.max(1,i),height:Math.max(1,a)},relativePosition:r.relativePosition?Kt(r.relativePosition):void 0});}async swipeInWebview({span:e,cmd:r,target:o}){let{controller:n,browserTarget:i}=o;if(!n.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=r.direction==="down"||r.direction==="up",c=await i.locator.boundingBox();if(!c)throw new Error("Failed to get bounds for webview container");let l=Math.floor(c.width*Qn),u=Math.floor(c.height*Qn),d=Math.max(1,c.width-l*2),m=Math.max(1,c.height-u*2),p,f;if(r.relativePosition){let b=Kt(r.relativePosition);p=c.x+b.x,f=c.y+b.y;}else p=c.x+c.width/2,f=c.y+c.height/2;let h={x:p,y:f},S=(s?m:d)*(r.viewportPercent??DQ)*(s?r.direction==="down"?1:-1:r.direction==="right"?1:-1);e.attributes.startPoint=h,e.attributes.scrollPixelAmount=S,await n.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:S,deltaY:s?S:0,steps:10,dragDurationMs:r.durationMs,fromTarget:h});}async swipeByAbsoluteCoordinates({span:e,direction:r,percent:o=DQ,durationMs:n=500,containerBounds:i,relativePosition:a}){e.attributes.containerBounds=i;let s=i.width*Qn,c=i.height*Qn,l,u;if(r==="up"||r==="down"?(l=(i.height-2*c)*o,u=Math.floor(l/(n/1e3))):(l=(i.width-2*s)*o,u=Math.floor(l/(n/1e3))),e.attributes.pixelDelta=l,e.attributes.pixelsPerSecond=u,a){let d=i.left+a.x,m=i.top+a.y;await this.performRawSwipe({startX:d,startY:m,deltaPixels:l,direction:r,durationMs:n});}else {let d=i.width*Qn,m=i.height*Qn,p={left:i.left+d,top:i.top+m,width:Math.max(1,i.width-2*d),height:Math.max(1,i.height-2*m)};await this.driver.executeInNativeContext(this.logger,f=>f.executeScript("mobile: swipeGesture",[{...p,direction:r,percent:o,speed:u}]),{operationName:"swipeGesture"});}}};var Hke=20,S0=.9,Jp=.5,b0=.2;var nw=class extends Xp{async executeScrollTo(e){let r=e.target.description,o=e.scrollStepPercent??S0,n=await this.tryUseCachedScrollPosition(e,r);return n||this.searchForElement({cmd:e,description:r,scrollStepPercent:o})}async resolveContainer({scrollableElement:e,containerCache:r,aiMetadata:o}){let n=await this.driver.executeInNativeContext(this.logger,u=>u.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(e.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:n.width,height:n.height},diffThresholdPercent:Jp};if(e.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(e,n),diffThresholdPercent:Jp};let i=ue(),a=e.target.description;if(r){let u=this.getBoundsFromNativeCache(r);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:r,diffThresholdPercent:cp({containerBounds:u,viewport:n,defaultThresholdPercent:Jp})}}let s=await this.findElement({description:a,tracer:i,metadata:o});if(!s.success)throw new M("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:c}=s;if(c.type!=="NATIVE")throw new Error(`ActionFailureError: Custom scroll container "${a}" resolved to a webview element. Custom containers must be native elements.`);let l=this.getBoundsFromNativeCache(c);return this.logger.info({bounds:l},"Got container bounds from AI"),{bounds:l,cache:c,diffThresholdPercent:cp({containerBounds:l,viewport:n,defaultThresholdPercent:Jp})}}async tryUseCachedScrollPosition(e,r){let o=e.cache?.target;return o?o.type==="WEBVIEW"?this.tryUseWebviewCache(e,r):o.scrollDetails?this.tryUseNativeScrollCache(e,r,o):null:null}async tryUseWebviewCache(e,r){let o=ue();try{let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:o,description:r,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i);}});return {success:!0,message:n}}catch(n){return this.logger.warn({err:n},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,r,o){let n=o.scrollDetails,i=ue(),a=e.scrollStepPercent??S0;if(n.pixelDelta===0)return this.logger.info("Skipping cached scroll-position replay because it would not move the viewport"),null;let s=n.scrollableElement.type==="CUSTOM"?n.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:n.scrollableElement,containerCache:s,direction:n.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let l=await this.tryFindElement({cmd:e,description:r,tracer:i,scrollDetails:n,useAIIfCacheFails:!0});if(l)return l;this.logger.info("Element not found at cached position, undoing scroll");}catch(l){this.logger.warn({err:l},"Error finding element at cached position, will undo scroll");}let c=n.direction==="down"?"up":"down";return this.logger.info({pixelDelta:n.pixelDelta,originalDirection:n.direction,undoDirection:c,scrollableElementType:n.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:n.scrollableElement,containerCache:s,direction:c,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:n,useAIIfCacheFails:i=true}){let a,s,c=false,l=n,u=y0(e.cache?.target);if(u&&u.resolvedDescription!==void 0&&bc(u.resolvedDescription,r)&&!e.disableCache){let p=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true,removeWebviewContent:true});try{let{resolvedTarget:f}=await Kp({target:u,domState:p,stateManager:this.stateManager,logger:this.logger});a=f,c=!0,s="Successfully resolved scroll to target with cache.",this.logger.info("Successfully resolved scroll to target from cache");}catch(f){this.logger.warn({err:f},"Failed to resolve target from cache");}}if(a&&c&&a.type==="NATIVE"&&n){let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:n});l=p.scrollDetails,p.resolvedTarget?a=p.resolvedTarget:(a=void 0,c=false);}if(!a&&!i)return null;if(!a)try{let p=bC(r),f=await this.findElement({description:p,tracer:o,metadata:{commandId:e.id,source:"SCROLL_TO"}});if(!f.success)return null;a=f.resolvedTarget,s=f.thoughts;}catch(p){if(p instanceof M&&p.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:p},"Failed to find scroll-to target with AI"),p}if(a&&!c&&a.type==="NATIVE"&&n)try{let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:n});l=p.scrollDetails,p.resolvedTarget&&(a=p.resolvedTarget);}catch(p){this.logger.warn({err:p},"Failed to reposition AI-resolved scroll-to target for stable cache generation");}if(a.type==="WEBVIEW"){await this.scrollWebviewTargetIntoView(a);let p=y0(Dc(a));return ud({command:e,updatedCache:p,updatedWithAI:!c,logger:this.logger}),{success:true,message:s}}let m=Dc(a);if(m.type!=="NATIVE")throw new Error("Expected native target cache for scroll-to");return ud({command:e,updatedCache:y0({...m,scrollDetails:l}),updatedWithAI:!c,logger:this.logger}),{success:true,message:s}}async correctNativeTargetIntoView({cmd:e,resolvedTarget:r,scrollDetails:o}){let n=await this.getCorrectiveScrollForTarget({resolvedTarget:r});if(!n)return {resolvedTarget:r,scrollDetails:o};this.logger.info({bounds:r.bounds,correction:n},"Repositioning scroll-to target to the preferred viewport anchor");let i=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0,a=await this.scrollByPixelDelta({pixelDelta:n.pixelDelta,scrollableElement:o.scrollableElement,containerCache:i,direction:n.direction,scrollStepPercent:e.scrollStepPercent??S0,aiMetadata:{commandId:e.id},useVisualDiff:true});if(a===0)return this.logger.info({bounds:r.bounds,correction:n},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:r,scrollDetails:o};let s={...o,pixelDelta:zv({currentPixelDelta:o.pixelDelta,baseDirection:o.direction,correctionDirection:n.direction,correctionPixels:a})},c=await this.stateManager.getDomState({skipFetchingFullWebviewContent:true,removeWebviewContent:true}),l;try{({resolvedTarget:l}=await Kp({target:r,domState:c,stateManager:this.stateManager,logger:this.logger}));}catch(d){return this.logger.warn({err:d},"Failed to re-resolve scroll-to target after corrective scroll"),{scrollDetails:s}}if(l.type!=="NATIVE")return {scrollDetails:s};let u=await this.getCorrectiveScrollForTarget({resolvedTarget:l});return u?(this.logger.warn({bounds:l.bounds,correction:u},"Corrective scroll still did not bring the scroll-to target into the preferred viewport anchor"),{resolvedTarget:l,scrollDetails:s}):{resolvedTarget:l,scrollDetails:s}}async searchForElement({cmd:e,description:r,scrollStepPercent:o}){let n=ue(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch({cmd:e,description:r,tracer:n,scrollStepPercent:o,resolvedContainer:i})}async scrollAndSearch({cmd:e,description:r,tracer:o,scrollStepPercent:n,resolvedContainer:i}){let a=0,s=i.bounds,c=i.diffThresholdPercent,l=e.scrollableElement.type==="CUSTOM_COORDINATES"?e.scrollableElement:void 0,u;l?u=Math.abs(l.deltaPixels):u=this.calculateSwipeCoordinates({containerBounds:s,direction:e.direction,desiredDelta:dc({containerBounds:s,containerInsetRatio:Qn})*n}).actualDelta;let d=true,m=e.maxScrollAttempts??Hke;for(let h=0;h<m;h++){this.throwIfAborted();let S=this.buildScrollDetails(e,a,i.cache),b=await this.tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:S});if(b)return b;if(!d)throw new Error(`ActionFailureError: Could not find element "${r}" after scrolling to the end`);this.logger.debug({attempt:h,cumulativePixelDelta:a},"Element not found, scrolling further"),d=await this.scrollByPage({direction:e.direction,containerBounds:s,scrollStepPercent:n,diffThresholdPercent:c,rawCoordinates:l}),a+=e.direction==="down"?u:-u;}let p=this.buildScrollDetails(e,a,i.cache),f=await this.tryFindElement({cmd:e,description:r,tracer:o,scrollDetails:p});if(f)return f;throw new Error(`ActionFailureError: Could not find element "${r}" after ${m} scroll attempts`)}buildScrollDetails(e,r,o){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:r,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:o},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:r,browserTarget:o}=e;await r.browser.hover(o);}async scrollByPage({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n,rawCoordinates:i}){return ue().startAsyncSpan("EMULATOR_INTERACTION",async s=>(s.attributes.containerBounds=r,s.attributes.direction=e,(await this.executeScrollGesture({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n,rawCoordinates:i})).canScrollMore),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:r,containerCache:o,direction:n,scrollStepPercent:i,aiMetadata:a,useVisualDiff:s=false}){if(e===0)return 0;let c=ue(),l,u=Jp,d,m,p;if(r.type==="CUSTOM_COORDINATES")d=r.startX,m=r.startY,p=r.deltaPixels;else {l=await this.resolveContainer({scrollableElement:r,containerCache:o,aiMetadata:a});let h=l.bounds;u=l.diffThresholdPercent;let S=dc({containerBounds:h,containerInsetRatio:Qn})*i,b=this.calculateSwipeCoordinates({containerBounds:h,direction:n,desiredDelta:S});d=b.startX,m=b.startY,p=b.actualDelta;}let f=Math.ceil(Math.abs(e)/p);return this.logger.debug({pixelDelta:e,direction:n,scrollableElementType:r.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),c.startAsyncSpan("EMULATOR_INTERACTION",async h=>{h.attributes.pixelDelta=e,h.attributes.numScrolls=f,h.attributes.maxScrollPerStep=p,h.attributes.startX=d,h.attributes.startY=m;let S=this.invertDirection(n),b=0;for(let y=0;y<f;y++){this.throwIfAborted();let T=Math.abs(e)-b,v=Math.min(p,T);if(s){let w=await this.executeScrollGesture({direction:n,containerBounds:l?.bounds,scrollStepPercent:i,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:v}});if(w.didScroll&&(b+=v),!w.canScrollMore)break}else await this.performRawSwipe({startX:d,startY:m,deltaPixels:v,direction:S}),b+=v;}return h.attributes.appliedPixels=b,b},{name:`Scroll ${n} by ${Math.abs(e)}px`})}async executeScrollGesture({direction:e,containerBounds:r,scrollStepPercent:o,diffThresholdPercent:n=Jp,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,c,l;if(i)s=i.startX,c=i.startY,l=i.deltaPixels;else {if(!r)throw new Error("Expected container bounds for scroll gesture");let f=dc({containerBounds:r,containerInsetRatio:Qn})*o,h=this.calculateSwipeCoordinates({containerBounds:r,direction:e,desiredDelta:f});s=h.startX,c=h.startY,l=h.actualDelta;}await this.performRawSwipe({startX:s,startY:c,deltaPixels:l,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=cc(a,u),m=d>n,p=d>n;return this.logger.debug({diffPercent:d,didScroll:m,diffThresholdPercent:n,canScrollMore:p,direction:e,actualDelta:l,rawCoordinates:i},"Scroll gesture visual diff result"),{didScroll:m,canScrollMore:p}}async getCorrectiveScrollForTarget({resolvedTarget:e}){let r=e.bounds;if(!r||r.length<4)return;let o=await this.stateManager.getViewportBounds(),n=Math.max(1,o.bottom-o.top),i=r[1],a=r[3],s=$v({viewportTop:o.top,viewportBottom:o.bottom,elementHeight:a-r[1],targetTopRatio:b0}),c=o.top+n*b0,l=o.bottom-n*b0,u=i>=o.top&&a<=o.bottom,d=i<c||a>l,m=e.resolvedNode.getAttribute("displayed")!=="false"&&e.resolvedNode.getAttribute("visible")!=="false",p=s-i;if(!(u&&m&&!d)){if(p>0)return {direction:"up",pixelDelta:p};if(p<0)return {direction:"down",pixelDelta:Math.abs(p)}}}};function y0(t){return !t||t.type!=="NATIVE"?t:jv(t)}var iw=class extends Rr{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:true,message:"Installed APK."}}async installApkFromUri(e){let r=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${sr__default.resolve(r.localPath)}`),this.logger.info({uri:e,localPath:r.localPath},"Installed APK on device");}finally{r.cleanup();}}async resolveUriToLocalApk(e){try{let r=new URL(e);if(r.protocol==="file:"){let o=r.href.slice(7),n;if(so.existsSync(o))n=o;else if(so.existsSync(sr__default.join("/",o)))n=sr__default.join("/",o);else throw new M("UserConfigurationError",`APK not found at path: ${o}`);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}if(r.protocol==="http:"||r.protocol==="https:"){let o=await this.fetchWithTimeout(r);if(!o.ok)throw new M("UserInfrastructureError",`Failed to download APK from ${e} (status ${o.status})`);let n=await o.arrayBuffer(),i=Buffer.from(n),a=await this.writeBufferToTempFile(i,r.pathname);return {localPath:a,cleanup:()=>{try{so.unlinkSync(a);}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file");}}}}throw new M("UserConfigurationError",`Unsupported URI scheme for APK installation: ${r.protocol}`)}catch(r){if(r instanceof TypeError){let o=sr__default.resolve(e);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}throw r}}assertFileExists(e){try{so.accessSync(e);}catch{throw new M("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let r=AbortSignal.timeout(9e4);return await fetch(e,{signal:r})}async writeBufferToTempFile(e,r){let o=sr__default.extname(r)||".apk",n=sr__default.join(tmpdir(),`momentic-apk-${randomUUID()}${o}`);return so.writeFileSync(n,e),n}};async function LQ({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,abortSignal:a}){let s=ue();if(!t.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(t.schema){let u=ym(t.schema);if(u)throw new M("UserConfigurationError",u)}let c="",l="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{c=await n(),l=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await r.getAndroidTextExtraction({goal:t.goal,emulatorState:c,returnSchema:t.schema,screenshot:`data:image/png;base64,${l}`},{disableCache:!!t.disableCache,abortSignal:a,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["android-text-extraction"]});if(u.result=d,Hv({tracer:s,span:u,screenshot:l,emulatorState:c,logger:e}),d.result==="NOT_FOUND")return {success:!1,message:"No relevant data found for extraction goal on this page"};if(d.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}})}var aw=class extends Rr{async dragNative(e,r,o){let{left:n,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:c,top:l,width:u,height:d}=this.getBoundsFromNativeCache(r),m=n+a/2,p=i+s/2,f=c+u/2,h=l+d/2,S=o?.hoverDuration??500,b=o?.dragDuration??1e3;await this.driver.executeInNativeContext(this.logger,async y=>{await y.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:m,y:p},{type:"pointerDown",button:0},{type:"pause",duration:S},{type:"pointerMove",duration:b,x:f,y:h},{type:"pointerUp",button:0}]}]),await y.releaseActions();},{operationName:"dragAndDrop"});}async dragWebview(e,r,o){let{controller:n}=e;if(e.controller!==r.controller)throw new M("UserConfigurationError","Cannot drag and drop between different webviews");let i=o?.dragDuration??1e3,a=o?.hoverDuration??1e3,s;o?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await n.browser.dragAndDrop(e.browserTarget,r.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i});}async executeDragAndDrop({command:e}){let r=ue();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new M("UserConfigurationError","Drag and drop only supports description targets for now");let o=e.fromTarget.description,{result:n,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:r,description:o,cacheKey:"cache",targetName:"fromTarget",action:async l=>l}),a=e.toTarget.description,{result:s,thoughts:c}=await this.wrapTargetingAction({command:e,tracer:r,description:a,cacheKey:"cache",targetName:"toTarget",action:async l=>l});if(n.type!==s.type)throw new M("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${n.type}, To=${s.type}`);return await r.startAsyncSpan("EMULATOR_INTERACTION",async l=>{n.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(n,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):n.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(l.withinWebview=true,await this.dragWebview(n,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}));},{name:"Drag and drop"}),{success:true,message:`${i}
|
|
5580
5580
|
${c}`}}};var sw=class{async getTextContent(e){return await e.textContent()??""}async getAttribute(e,r){return await e.getAttribute(r,{timeout:3e3})??""}async getTagName(e){return await e.evaluate(r=>r.tagName)}async isEditable(e){return await e.isEditable({timeout:Zr*1e3})}async isEnabled(e){return await e.isEnabled({timeout:Zr*1e3})}async isFocused(e){return await e.evaluate(r=>r===document.activeElement)}async getStyleProperty(e,r){return await e.evaluate((o,n)=>window.getComputedStyle(o).getPropertyValue(n),r)}},lw=class{async getTextContent(e){return fp(e)}async getAttribute(e,r){return e.getAttribute(r)??""}async getTagName(e){return e.tagName}async isEditable(e){throw new Error("Cannot perform editable check on native element")}async isEnabled(e){return e.getAttribute("enabled")==="true"}async isFocused(e){return e.getAttribute("focused")==="true"}async getStyleProperty(e,r){throw new Error("Cannot perform computed style checks on native element")}};var qke=5e3,cw=class extends Rr{async executeElementCheck(e){let r=Date.now(),o=(e.timeout??Zr)*1e3,n=o+1e4,i,a=0,s=500,c=cloneDeep(e.cache);if(e.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Element check step");for(;a-r<o;){if(Date.now()-r>n){this.logger.warn("Exceeded max system timeout for element check, exiting...");break}if(this.throwIfAborted(),i=await this.executeElementCheckHelper(e),a=Date.now(),!i.success)e.cache=c,c=cloneDeep(c),await ce(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),qke);else return i}let l=await this.executeElementCheckHelper(e,{cacheIsInvalidAfterResolution:true});if(!l.success&&c&&e.cache){let u=bg({logger:this.logger,originalTarget:rm(c)?c.target:void 0,newTarget:e.cache.target});u&&Us(c.target,u)&&(e.cache={target:u,updatedAt:e.cache.updatedAt});}return l}async executeElementCheckHelper(e,r){let o=ue();if(e.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Element check step");let n=$m(e.assertion);try{return (await this.wrapTargetingAction({...r??{},command:e,tracer:o,action:async a=>"type"in a&&a.type==="NATIVE"?await this.executeNativeElementCheck(e,a):await this.executeWebviewElementCheck(e,a),description:e.target.description,skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).result}catch(i){return n&&(i instanceof M&&i.reason==="NoMatchingElementError"||i instanceof va)?{success:true}:{success:false,message:`Failed to evaluate element content assertion: ${i instanceof Error?i.message:`${i}`}`}}}async executeNativeElementCheck(e,r){let o=ue(),{assertion:n}=e,i=r.resolvedNode;return await o.startAsyncSpan("ELEMENT_ASSERTION",async a=>{a.targetBounds=Lc(r);let s=await this.executeElementAssertion({assertion:n,element:i,elementPropertyAccessors:new lw,span:a});return a.result=s,s},{name:"Native element check"})}async executeWebviewElementCheck(e,r){let o=ue(),n=r.browserTarget.locator,i=e.assertion;return await o.startAsyncSpan("ELEMENT_ASSERTION",async a=>{a.targetBounds=Lc(r),await r.controller.browser.highlight(n);let s=await this.executeElementAssertion({assertion:i,element:n,elementPropertyAccessors:new sw,span:a});return a.result=s,s},{name:"Webview element check"})}async executeElementAssertion({assertion:e,element:r,elementPropertyAccessors:o,span:n}){switch(e.type){case "ELEMENT_CONTENT":{let i=await o.getTextContent(r)??"";return n.attributes.elementTextContent=Cr(i,500,true),sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})?{success:true}:{success:false,message:`The content ${fo(e)} '${e.value}': ${i}`}}case "ELEMENT_ATTRIBUTE":{"evaluate"in r&&(n.attributes.elementOuterHtml=Cr(await r.evaluate(a=>a.cloneNode(false).outerHTML),500,true));let i;try{i=await o.getAttribute(r,e.attr);}catch{i=null;}if(!sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let a=fo(e);return {success:false,message:`The attribute ${e.attr} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:true}}case "ELEMENT_EXISTENCE":{let i=false;switch(e.condition){case "EDITABLE":i=await o.isEditable(r);break;case "VISIBLE":case "EXISTS":i=true;break;case "ENABLED":{i=await o.isEnabled(r);break}case "FOCUSED":i=await o.isFocused(r);break;default:throw e.condition,new Error("Unrecognized element condition type")}return i=e.negated?!i:i,i?{success:true}:{success:false,message:`The element ${fo(e)}`}}case "ELEMENT_NAME":{let i=await o.getTagName(r);return sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:true})?{success:true}:{success:false,message:`The element tag name ${fo(e)} '${e.value}': ${i}`}}case "ELEMENT_STYLE":{let i=await o.getStyleProperty(r,e.property);if(!sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let a=fo(e);return {success:false,message:`The style property ${e.property} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:true}}default:throw new Error("Unrecognized element assertion type")}}};var Kke=5e3,uw=class extends Rr{async executeScreenCheck(e){let{timeout:r}=e,o=Date.now(),n=(r??Zr)*1e3,i=n+1e4,a=0,s=500;for(;a-o<n;){if(Date.now()-o>i){this.logger.warn("Exceeded max system timeout for screen check, exiting...");break}this.throwIfAborted();let c=await this.executeScreenCheckHelper(e);if(a=Date.now(),!c.success)await ce(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),Kke);else return c}return await this.executeScreenCheckHelper(e)}async executeScreenCheckHelper(e){return await ue().startAsyncSection("Execute screen check",async(o,n)=>{let[i,a]=await Promise.all([this.executeNativeScreenCheckHelper({span:n,command:e}),this.executeWebviewScreenCheckHelper(e)]);return a?e.assertion.negated?i.success&&a.success?i:i.success?a:i:i.success?i:a:i})}async executeNativeScreenCheckHelper({span:e,command:r}){let{assertion:o}=r;switch(o.type){case "CONTENT":try{let n=(await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).graph.document.documentElement?.outerHTML;if(!n)throw new Error("Failed to get screen HTML");let i=n.includes(o.value)===!o.negated;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),i?{success:!0}:(e.attributes.screenContent=n,{success:!1,message:`The screen ${zm({...o,negated:!o.negated})}.`})}catch(n){return {success:false,message:`Failed to evaluate screen content assertion: ${n instanceof Error?n.message:`${n}`}`}}default:return o.type,{success:false,message:`Unsupported screen check assertion type: ${o.type}`}}}async executeWebviewScreenCheckHelper(e){let r=await this.stateManager.getActiveWebview();if(!r||!r.browserController)return;let o=r.browserController.browser;return await EN({assertion:e.assertion,logger:this.logger,browser:o,autoExpandIframes:!!o.userBrowserSettings.autoExpandIframes})}};var dw=class extends Rr{async doUninstallApk(e){return await this.uninstallApkPackage(e.packageName),{success:true,message:"Uninstalled APK."}}async uninstallApkPackage(e){let r=e.replace(/^package:/,""),o=await this.stateManager.executeRawADBCommand(`shell pm list packages | grep -E "^package:${r}$" || true`);if(!o||o.length===0)throw new M("UserConfigurationError",`Package ${r} not found`);if(o.split(`
|
|
5581
5581
|
`).filter(i=>!!i).length>1)throw new M("UserConfigurationError",`Multiple packages found for ${r}`);try{await this.stateManager.executeRawADBCommand(`uninstall ${r}`);}catch(i){throw new M("UserInfrastructureError",`Failed to uninstall package ${r}: ${i}`)}}};var FQ=z.object({"Android-Package":z.string(),Browser:z.string(),"Protocol-Version":z.string(),"User-Agent":z.string(),"V8-Version":z.string(),"WebKit-Version":z.string(),webSocketDebuggerUrl:z.string()}),UQ=z.object({description:z.string(),devtoolsFrontendUrl:z.string(),id:z.string(),title:z.string(),type:z.string(),url:z.string(),webSocketDebuggerUrl:z.string()}),BQ=z.object({proc:z.string(),webview:z.string(),webviewName:z.string()}),VQ=z.array(BQ.extend({info:FQ.optional(),pages:z.array(UQ).optional()}));z.array(BQ.extend({info:FQ,pages:z.array(UQ)}));var mw=class t{driver;limbarClient;device;logger;webviews=new Map;fixtures;orgId;options;aborter;constructor({driver:e,limbarClient:r,logger:o,device:n,fixtures:i,orgId:a,options:s,aborter:c}){this.driver=e,this.limbarClient=r,this.device=n,this.logger=o,this.fixtures=i,this.orgId=a,this.options=s,this.aborter=c;for(let l of ["SIGINT","SIGTERM"])process.on(l,async()=>{await this.cleanupWebviews();});}static async init({driver:e,logger:r,fixtures:o,limbarClient:n,orgId:i,adbPort:a,options:s,aborter:c,playwrightDevice:l}){let u;if(l)u=l;else {let m=(await _android.devices()).filter(p=>p._initializer?.serial?.endsWith(a.toString())||p._initializer?.serial?.endsWith((a-1).toString()));if(r.warn({devices:m.map(p=>({serial:p._initializer?.serial,model:p._initializer?.model}))},"No playwright device provided, using ADB to find device"),m.length===0)throw new M("UserInfrastructureError",`Momentic found no devices listening on port ${a} or ${a-1}. This can occur if Android Studio reuses existing emulators. Please run 'adb emu kill' and 'adb disconnect' and retry.`);if(m.length>1)throw new M("UserInfrastructureError",`Momentic found multiple devices on the ports ${a} or ${a-1}. This can occur if Android Studio reuses existing emulators. Please run 'adb emu kill' and 'adb disconnect' and retry.`);u=m[0];}return new t({driver:e,logger:r,device:u,fixtures:o,orgId:i,options:s,aborter:c,limbarClient:n})}async getContexts(){let e=await this.driver.executeInNativeContext(this.logger,o=>o.getContexts({}),{operationName:"getContexts"}),r=Array.from(this.webviews.values());return {contexts:e,webviews:r.map(o=>({contextId:o.contextId,packageName:o.packageName,active:o.active,hasPlaywright:!!o.browserController,lastSeen:o.lastSeen,socketName:o.socketName}))}}async getRawScreenshotBase64({maxAttempts:e=3,signal:r}={}){let o=ue(),n=r??this.aborter.controller?.signal,i={maxAttempts:e,signal:n,operationName:"takeScreenshot"};return await o.startAsyncSpan("EMULATOR_READ_STATE",async()=>{if(this.limbarClient){let a=this.limbarClient,s=await lp(this.logger,async()=>a.screenshot(),i);if(s.dataUri.startsWith("data:image/png;base64,"))return s.dataUri.slice(22);throw new M("InternalWebAgentError",`Emulator provider returned unexpected screenshot URI: ${s.dataUri}`)}return this.driver.executeInNativeContext(this.logger,a=>a.takeScreenshot(),i)},{name:"Take screenshot",signal:n,timeoutMs:3e4})}async getCurrentScreenshotPngString(){return `data:image/png;base64,${await this.getRawScreenshotBase64({maxAttempts:1})}`}async waitForScreenshotStability({timeoutMs:e,signal:r,reason:o,tolerancePercent:n=1}){let i=Mm({signal:r,timeoutMs:e});await ue().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=o;let s,c=false;for(;!i.aborted;){let l=Date.now();if(s)try{let d=await this.getRawScreenshotBase64({maxAttempts:1,signal:i});if(cc(s,d)<=n){c=!0;break}s=d;}catch(d){this.logger.warn({err:d},"Failed to get screenshot during stability wait");}else try{s=await this.getRawScreenshotBase64({maxAttempts:1,signal:i});}catch(d){this.logger.warn({err:d},"Failed to get initial screenshot during stability wait");}let u=Math.max(250,Date.now()-l);await Wa(Math.min(1e4,u),i);}c||(a.attributes.timedOut=true,this.logger.warn({purpose:o},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({timeoutMs:e,signal:r,reason:o}){await ue().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async n=>{n.attributes.reason=o;let i=Mm({signal:r,timeoutMs:e}),a,s=false;for(;!i.aborted;){let c,l=Date.now();try{c=await this.getPageSource(i);let d=createHash("md5").update(c).digest("hex");if(a&&a===d){s=!0;break}a=d;}catch(d){this.logger.warn({err:d},"Failed to get page source during stability wait");}let u=Math.max(250,Date.now()-l);await Wa(Math.min(1e4,u),i);}s||(n.attributes.timedOut=true,this.logger.warn({purpose:o},"Timed out waiting for page source stability"));});}async getCurrentPackage(){let e=await this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: getCurrentPackage"),{operationName:"getCurrentPackage"});return typeof e=="string"?e:void 0}async getActiveWebviewNodes(){let r=(await this.getDomState({skipFetchingFullWebviewContent:true,removeWebviewContent:true})).graph,o=[];for(let[n,i]of r.idToElement.entries())o.some(a=>a.id===n)||ub(i)&&o.push({id:n,originalElement:i,bounds:cd(i)});return o}async getActiveWebviewContent(){let e=await this.getActiveWebview();if(!e||!e.browserController)return;this.throwIfAborted();let r=e.browserController;return (await ue().startAsyncSpan("EMULATOR_READ_STATE",()=>r.getBrowserState({abortSignal:this.aborter.controller?.signal,skipWait:true,skipWaitForPageLoad:true,logger:this.logger,serializationOpts:{noId:true}}),{name:"Get webview content",signal:this.aborter.controller?.signal})).serializedTree}async getDomState(e){return await ue().startAsyncSection("Get emulator state XML",async()=>{let o;if(!e?.skipFetchingFullWebviewContent&&!this.options.disableMomenticAccessibilityTree)try{o=await this.getActiveWebviewContent();}catch(c){this.logger.error({err:c},"Could not get webview info to get the nested DOM state");}this.throwIfAborted();let i=e?.filterOffscreenElements??true?await this.getViewportBounds():void 0,a=await this.getPageSource();return {graph:await CQ(a,this.logger,{injectedWebviewContent:o,disableMomenticAccessibilityTree:this.options.disableMomenticAccessibilityTree,removeWebviewContent:e?.removeWebviewContent,viewportBounds:i})}},{timeoutMs:3e4})}async getPageSource(e){let r=e??this.aborter.controller?.signal;return await ue().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(this.logger,n=>n.getPageSource(),{signal:r,operationName:"getPageSource"}),{name:"Get Android page source",signal:r,timeoutMs:3e4})}async getViewportBounds(){let e=await this.driver.executeInNativeContext(this.logger,r=>r.getWindowRect(),{operationName:"getViewportBounds"});return {left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height}}refreshPromise;refreshInterval;webviewConnectionPromises=new Map;async refreshWebviewsManually(e){if(!this.options.disableMomenticAccessibilityTree){if(this.refreshPromise){await this.refreshPromise;return}this.refreshInterval&&(clearInterval(this.refreshInterval),this.refreshInterval=void 0),this.refreshPromise=this.doRefreshWebview(e,{currentAppOnly:true}).catch(r=>{this.logger.warn({err:r},"Error refreshing webviews, continuing...");}).finally(()=>{this.refreshPromise=void 0;}),await this.refreshPromise;}}async doRefreshWebview(e,{currentAppOnly:r}){if(this.options.disableMomenticAccessibilityTree)return;this.logger.info({reason:e,currentAppOnly:r},"Refreshing webviews"),this.throwIfAborted();let o=await this.getCurrentPackage();if(r&&o==="com.android.permissioncontroller")return;let n=await this.getDetailedContexts();if(!n){this.logger.warn("No context details, not proceeding with refreshing webviews");return}let i=Date.now(),a=new Set;for(let s of n){if(this.throwIfAborted(),s.webview==="NATIVE_APP")continue;let c=s.info["Android-Package"];if(r&&o&&c!==o&&c!=="com.android.chrome"){this.logger.debug({packageName:c,currentPkgName:o},"Skipping webview outside the active package during manual refresh");continue}a.add(s.webview);let l=!this.webviews.has(s.webview),u=!this.webviews.get(s.webview)?.active;if(l||u){let d={contextId:s.webview,packageName:c,active:false,lastSeen:i,socketName:s.proc.startsWith("@")?s.proc.substring(1):s.proc};this.logger.info({contextId:d.contextId,packageName:d.packageName,socketName:d.socketName},l?"New webview detected":"Inactive webview detected"),this.webviews.set(s.webview,d),this.logger.info({webviewInfo:d},`Connecting Playwright to webview: ${s.webview}`);let m=await this.connectPlaywrightToAvailableWebview(d);if(!m)continue;d.browserController=m,d.active=true;}}for(let[s,c]of this.webviews.entries())r&&o&&c.packageName!==o||!a.has(s)&&c.active&&(this.logger.info(`Disconnecting dead webview ${s}`),this.disconnectPlaywrightFromWebview(c),c.active=false);this.logger.info("Refreshed webviews");}async getActiveWebview(){if(this.options.disableMomenticAccessibilityTree)return;await this.refreshPromise;let e=await this.driver.executeInNativeContext(this.logger,a=>a.execute("mobile: getCurrentPackage"),{operationName:"getActiveWebviewCurrentPackage"}),r=async()=>{e!==void 0&&typeof e!="string"&&this.logger.warn({currentPkg:e},"Unexpected getCurrentPackage result");let a=[];for(let s of this.webviews.values())s.packageName===e&&s.active&&a.push(s);return this.logger.info({currentPkg:e,allWebviews:Array.from(this.webviews.values()).map(s=>({contextId:s.contextId,packageName:s.packageName,active:s.active}))},`getActiveWebview: found ${a.length} matching webviews`),a},o=await r();if(o.length===0&&(await ue().startAsyncSection("Refresh webviews",async()=>{await this.refreshWebviewsManually("no matching webview during getActiveWebview");}),o=await r()),o.length>1)throw new M("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let n=o[0];if(!n)return;if(this.hasUsableWebviewBrowser(n)||(this.logger.warn({contextId:n.contextId,packageName:n.packageName},"Active webview browser is unhealthy, reconstructing"),await this.reconstructWebviewBrowser(n,"active webview page or target crashed"),this.hasUsableWebviewBrowser(n)))return n;if(await ue().startAsyncSection("Refresh webviews after browser reconstruction failed",async()=>{await this.refreshWebviewsManually("active webview browser reconstruction failed");}),o=await r(),o.length>1)throw new M("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let i=o[0];if(i){if(this.hasUsableWebviewBrowser(i))return i;this.logger.warn({contextId:i.contextId,packageName:i.packageName},"Refreshed active webview is still unhealthy after reconstruction");}}async reconstructActiveWebviewBrowser(e){if(this.options.disableMomenticAccessibilityTree)return;await this.refreshPromise;let r=await this.driver.executeInNativeContext(this.logger,i=>i.execute("mobile: getCurrentPackage"),{operationName:"reconstructActiveWebviewCurrentPackage"});if(r!==void 0&&typeof r!="string"){this.logger.warn({currentPkg:r},"Unexpected getCurrentPackage result");return}let o=[];for(let i of this.webviews.values())i.packageName===r&&i.active&&o.push(i);if(o.length>1)throw new M("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let n=o[0];if(n)return await this.reconstructWebviewBrowser(n,e),this.hasUsableWebviewBrowser(n)?n:void 0}hasUsableWebviewBrowser(e){let r=e.browserController;if(!r||!e.active)return false;let o=r.browser;if(o.closed)return false;let n;try{n=o.getActivePage();}catch(i){return this.logger.warn({err:i,contextId:e.contextId},"Failed to resolve active page for webview browser health check"),false}return !n.isClosed()}async reconstructWebviewBrowser(e,r){this.logger.info({contextId:e.contextId,packageName:e.packageName,reason:r},"Reconstructing webview browser"),await this.disconnectPlaywrightFromWebview(e),e.active=false;let o=await this.connectPlaywrightToAvailableWebview(e);o&&(e.browserController=o,e.active=true);}getDeviceSerial(){let e=this.driver.capabilities,r=o=>{if(!e||typeof e!="object")return;let n=e[o];return typeof n=="string"?n:void 0};return r("deviceUDID")||r("udid")||r("appium:udid")||r("appium:deviceUDID")}async executeRawADBCommandWithArgs(e){let r=this.getDeviceSerial();this.logger.info({serial:r,args:e},"Executing ADB command");let o=await Dr(e,{serial:r,timeoutMs:15e3,throwOnError:true});return this.logger.info({result:o},"ADB command result"),o}async executeRawADBCommand(e){let r=this.getDeviceSerial(),o=e.trim().split(/\s+/).filter(i=>i.length>0);this.logger.info({serial:r,cmdArgs:o},"Executing ADB command");let n=await Dr(o,{serial:r,timeoutMs:15e3,throwOnError:true});return this.logger.info({result:n},"ADB command result"),n}async cleanupWebviews(){this.refreshInterval&&(clearInterval(this.refreshInterval),this.refreshInterval=void 0);for(let[e,r]of this.webviews.entries())this.logger.info(`Disconnecting webview ${e}`),this.disconnectPlaywrightFromWebview(r),r.active=false;}async getDetailedContexts(){return await ue().startAsyncSpan("EMULATOR_READ_STATE",async()=>{let r=await this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: getContexts"),{operationName:"getDetailedContexts"});this.aborter.controller?.signal.throwIfAborted();let o;try{o=VQ.parse(r);}catch(n){throw new M("InternalWebAgentError",`Failed to parse contexts. Original error:
|
|
5582
5582
|
${n}
|
|
5583
5583
|
Raw: ${JSON.stringify(r)}`)}return o.filter(n=>n.webviewName?!n.info||!n.pages?false:n.pages.filter(a=>{if(!a.title)return false;let s=a.url;return !(!s||s===""||s.startsWith("about:blank")||s.startsWith("chrome-error:"))}).length?true:(this.logger.debug({context:n},"Webview has no qualified pages, skipping"),false):true)},{name:"Get available contexts",signal:this.aborter.controller?.signal})}async createBrowserController({context:e,page:r}){return await ue().startSection("Run remote Chrome initialization",async(n,i)=>{let a={};i.attributes.timings=a;let s=await oS.fromExistingContext({context:e,page:r,attachTimeoutMs:8e3,logger:this.logger,timingRecorder:a,userBrowserSettings:{...this.options.browserSettings,disableBrowserMonitoring:true},properties:{isNewHeadless:false,allowedA11yIgnoreReasonsOverride:[],isAndroid:true},storage:this.fixtures.storage,enricher:this.fixtures.browserEnricher});try{return new SC({browser:s,generator:this.fixtures.browserGenerator,logger:this.logger,orgId:this.orgId,storage:this.fixtures.storage,localCodeEvalTools:this.fixtures.localCodeEvalTools,visualDiffScreenshotStorage:new aE})}catch(c){throw await s.cleanup(),c}})}async connectPlaywrightToWebview(e,r){return ue().startAsyncSection("Connect headless browser client to webview",async()=>{for(let n=0;n<2;n++)try{let i=await this.connectPlaywrightToWebviewHelper(e,r);return i?{kind:"connected",browserController:i}:{kind:"failed"}}catch(i){if(i instanceof Gf)return {kind:"not_found"};if(this.errorLooksLikeUnattachableWebview(i))return this.logger.info({err:i,packageName:e,socketName:r},"Skipping Playwright connection for webview because the target is not attachable"),{kind:"not_attachable"};this.logger.warn({err:i},"Failed to connect Playwright to webview, retrying...");}return {kind:"failed"}},{signal:this.aborter.controller?.signal})}errorLooksLikeUnattachableWebview(e){let r=j(e);return ["No page found in existing context","Target closed","Target crashed","Page crashed","Target page, context or browser has been closed","Session closed. Most likely the page has been closed"].some(o=>r.includes(o))}async connectPlaywrightToAvailableWebview(e){let r=this.webviewConnectionPromises.get(e.contextId);if(r)return this.logger.debug({contextId:e.contextId},"Waiting for existing webview connection attempt"),r;let o=ue().startAsyncSection("Connect Playwright to available webview",async()=>await this.connectPlaywrightToAvailableWebviewHelper(e),{signal:this.aborter.controller?.signal}).catch(n=>{this.logger.warn({err:n,contextId:e.contextId},"Failed to connect Playwright to webview, continuing...");});return this.webviewConnectionPromises.set(e.contextId,o),o.finally(()=>{this.webviewConnectionPromises.get(e.contextId)===o&&this.webviewConnectionPromises.delete(e.contextId);}),o}async connectPlaywrightToAvailableWebviewHelper(e){let{contextId:r,packageName:o}=e,n=await this.connectPlaywrightToWebview(o??"",e.socketName);if(n.kind==="connected")return this.logger.info(`Connected Playwright to webview ${r}`),n.browserController;if(o!=="com.android.chrome"||n.kind!=="not_found")return;this.logger.info({webviewInfo:e},`Connecting Playwright to Android Chrome: ${r}`);let i=await this.connectPlaywrightToChrome(e);return i&&this.logger.info(`Connected Playwright to Android Chrome: ${r}`),i}extractSocketNameFromWebview(e,r){if("_socketName"in e&&typeof e._socketName=="string")return e._socketName;if("_data"in e&&e._data?.socketName)return e._data.socketName;r.warn({pkg:e.pkg()},"Could not extract socket name from webview");}async connectPlaywrightToWebviewHelper(e,r){let o=this.device.webViews(),n=o.find(l=>!(l.pkg()!==e&&e!=="com.android.chrome"||this.extractSocketNameFromWebview(l,this.logger)!==r));if(!n)throw this.logger.warn({webviews:o.map(l=>({pkg:l.pkg,name:this.extractSocketNameFromWebview(l,this.logger)}))},"Could not find matching webview in Playwright device list"),new Gf(e,r);let i=await n.page(),a=i.url();if(a===""||a.startsWith("about:blank")||a.startsWith("chrome-error:")){let l=`Webview ${e} with socket ${r} is not a valid webview`;this.logger.warn({pageUrl:a},l);return}let s=i.context();return await this.createBrowserController({context:s,page:i})}async connectPlaywrightToChrome(e){return await ue().startAsyncSpan("EMULATOR_READ_STATE",async()=>this.connectPlaywrightToChromeHelper(e),{name:"Connect headless browser client to Chrome",signal:this.aborter.controller?.signal})}async connectPlaywrightToChromeHelper(e){let{contextId:r,socketName:o}=e,n,i=e.forwardedPort;try{this.logger.info({contextId:r,socketName:o},"Connecting to Chrome webview");let a;if(e.forwardedPort)a=`http://127.0.0.1:${e.forwardedPort}`,this.logger.info({contextId:r,endpoint:a,socketName:o},"Using existing forwarded port");else {let l=await this.forwardDevToolsSocket(e.socketName);e.forwardedPort=l,i=l,a=`http://127.0.0.1:${l}`,this.logger.info({contextId:r,endpoint:a,socketName:o},`Forwarding DevTools socket for ${e.socketName}`);}this.logger.info({endpoint:a,socketName:o},"Connecting to CDP endpoint"),n=await chromium.connectOverCDP({endpointURL:a,timeout:8e3});let s=n.contexts()[0];if(!s){this.logger.warn("No browser context available after CDP connection"),await n.close(),n=void 0;return}let c=await this.createBrowserController({context:s});return i=void 0,n=void 0,c}catch(a){this.logger.warn({err:a},`Error connecting Playwright to webview ${e.contextId}, continuing...`);return}finally{if(n)try{await n.close();}catch(a){this.logger.warn({err:a,contextId:r},"Failed to close orphaned CDP browser after webview connection failure");}if(i)try{await this.removeDevToolsForwarding(i);}catch(a){this.logger.warn({err:a,contextId:r,forwardedPort:i},"Failed to remove forwarded port after webview connection failure");}finally{e.forwardedPort===i&&(e.forwardedPort=void 0);}}}async disconnectPlaywrightFromWebview(e){if(e.browserController)try{this.logger.info(`Disconnecting Playwright from webview: ${e.contextId}`),await e.browserController.browser.cleanup();}catch(r){this.logger.error({err:r},`Error disconnecting Playwright from webview ${e.contextId}:`);}finally{e.browserController=void 0;}if(e.forwardedPort)try{await this.removeDevToolsForwarding(e.forwardedPort);}catch(r){this.logger.error({err:r},`Error removing forwarded port for webview ${e.contextId}:`);}finally{e.forwardedPort=void 0;}}async forwardDevToolsSocket(e){this.logger.info("Setting up port forwarding for DevTools");let r=1e4+Math.floor(Math.random()*1e4),o=this.getDeviceSerial();this.logger.info({deviceId:o},`Device ID from capabilities: ${o||"not found"}`);let n=e&&e.trim().length>0?`localabstract:${e}`:"localabstract:chrome_devtools_remote";return await this.executeRawADBCommand(`forward tcp:${r} ${n}`),this.logger.info(`Successfully forwarded DevTools socket to port ${r}`),r}async removeDevToolsForwarding(e){await this.executeRawADBCommand(`forward --remove tcp:${e}`),this.logger.info("Successfully removed port forwarding");}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};var Fc=class t extends Rr{appsWithGrantedPermissions=new Set;parseInstalledPackageLines(e){return e?.split(`
|
|
5584
5584
|
`).filter(r=>r.trim().startsWith("package:")).map(r=>r.replace("package:","").trim()).filter(r=>r.length>0&&!r.startsWith("io.appium"))??[]}constructor(e){super(e);}static async init({driver:e,generator:r,logger:o,fixtures:n,orgId:i,options:a,abortController:s,adbPort:c,limbarClient:l,playwrightDevice:u,aiSettings:d}){let m={controller:s},p=await mw.init({driver:e,logger:o,fixtures:n,orgId:i,limbarClient:l,options:a?.emulator??{},aborter:m,adbPort:c,playwrightDevice:u}),f=new t({driver:e,generator:r,stateManager:p,logger:o,fixtures:n,options:a,aborter:m,orgId:i,aiSettings:d,adbPort:c});return await f.initializeSettings(),f}get emulatorSettings(){return this.options?.emulator??{}}async installApp(e){await this.stateManager.executeRawADBCommand(`install ${sr__default.resolve(e)}`);}async getInstalledApps(){let[e,r]=await Promise.all([this.executeRawADBCommand("shell pm list packages -3"),this.executeRawADBCommand("shell pm list packages")]),o=this.parseInstalledPackageLines(e).sort((a,s)=>a.localeCompare(s)),i=this.parseInstalledPackageLines(r).filter(a=>!o.includes(a)&&!PO(a)).sort((a,s)=>a.localeCompare(s));return {installedApps:o,prunedApps:i}}async executeCommand(e){let r=["type","a11yData","thoughts","cache","code"],o;try{o=await hp({obj:e.command,context:this.fixtures.testContext,bannedKeys:r,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools});}catch(n){throw this.throwIfAborted(),new M("UserConfigurationError",`Failed to substitute template strings in command: ${n.message}`,{errOptions:{cause:n}})}try{return await this.executeCommandHelper(e)}catch(n){throw n.name!=="AbortError"&&this.logger.error({err:n},"Error thrown in action controller"),n}finally{gp(e.command,o);}}async executeCommandHelper({command:e}){let r=ue();switch(e.type){case "TAP":return new Yp(this.constructPerformerParams()).executeTap({command:e});case "TYPE":return await new ow(this.constructPerformerParams()).doType(e);case "AI_CHECK":{let o=this.shouldUseMemoryForCommand(e),n=15,i=e.timeoutSecs?e.timeoutSecs*1e3:5e3,a=UT(i),s=Date.now(),c=0,l,u=false,d;for(;c<n&&!u;){this.throwIfAborted(),u||l&&l-s>=i&&(u=true),c!==0&&await ce(a,this.abortSignal),l=Date.now();try{let m="",p="";await r.startAsyncSpan("EMULATOR_READ_STATE",async()=>{m=await this.getEmulatorDomState(),p=await this.getScreenshotBase64();},{name:"Get emulator state"});let f=await r.startAsyncSpan("AI_ASSERTION_CALL",async h=>{let S=await this.generator.evaluateAndroidAssertion({assertion:e.assertion,screenXml:m,screenshot:p,memory:o?e.cache?.memory:void 0},{logger:this.logger,loggerTags:Ie(this.logger),agentConfigVersion:this.aiSettings.agentConfig?.["android-assertion"],useMemory:o});return h.result={thoughts:S.thoughts,result:S.result},S});if(o&&f.updatedMemory){let h={type:"GCS_TRACES",traces:f.updatedMemory};e.cache={...e.cache??{},memory:h};}if(f.result)return {success:f.result,message:f.thoughts};{let h=`AssertionFailureError: ${f.thoughts}`;d=new Error(h);}}catch(m){this.throwIfAborted(),this.logger.info({err:m},`AI check assert attempt ${c} failed, retrying...`),d=m instanceof Error?m:new Error(`${m}`);}finally{c++;}}return {success:false,message:d?.message}}case "AI_EXTRACT":return LQ({command:e,logger:this.logger,generator:this.generator,aiSettings:this.aiSettings,getEmulatorDomState:()=>this.getEmulatorDomState(),getScreenshotBase64:()=>this.getScreenshotBase64(),abortSignal:this.abortSignal});case "SWIPE":return new Xp(this.constructPerformerParams()).executeSwipe(e);case "SCREEN_CHECK":return new uw(this.constructPerformerParams()).executeScreenCheck(e);case "ELEMENT_CHECK":return await new cw(this.constructPerformerParams()).executeElementCheck(e);case "DRAG_AND_DROP":return await new aw(this.constructPerformerParams()).executeDragAndDrop({command:e});case "SCROLL_TO":return new nw(this.constructPerformerParams()).executeScrollTo(e);case "JAVASCRIPT":{let o;try{o=await _i({orgId:this.orgId,code:e.code,fragment:!1,context:this.fixtures.testContext,timeoutMs:e.timeout?e.timeout*1e3:void 0,logger:this.logger,localTools:this.fixtures.localCodeEvalTools,signal:this.abortSignal});}catch(n){throw new M("ActionFailureError",n instanceof M?n.message:`${n}`,{errOptions:{cause:n}})}try{JSON.stringify(o);}catch(n){throw new M("UserConfigurationError",`Return value is not serializable: ${n instanceof Error?n.message:`${n}`}`)}return {success:true,output:o}}case "REQUEST":{let o;try{o=new URL(e.url).hostname;}catch(l){throw new M("UserConfigurationError",`Invalid URL: ${l instanceof Error?l.message:`${l}`}`)}let n=new CookieJar,i=y_e(fetch,n),a=Date.now(),s=await Tp({command:e,baseUrl:void 0,logger:this.logger,fetchImplementation:i}),c=em(n,o);return {output:wd.parse({...s,cookies:c}),success:true,message:`Successfully executed request in ${Date.now()-a}ms`}}case "OPEN_NOTIFICATION_DRAWER":return await new kc(this.constructPerformerParams()).doPress({keycode:83}),{success:true};case "OPEN_APP":{let o=e.activityName,n=["-a","android.intent.action.MAIN","-c","android.intent.category.LAUNCHER"];if(!o){let a=["resolve-activity","--brief",...n,e.packageName],s=await Q(this.driver.executeInNativeContext(this.logger,c=>c.execute("mobile: shell",{command:"pm",args:a}),{operationName:"resolveMainActivity"}),{signal:this.abortSignal,milliseconds:1e4});if(typeof s!="string")throw new M("UserConfigurationError",`Could not find main activity name for package ${e.packageName}. Unexpected output: ${s}`);if(s.includes("No activity found"))throw new M("UserConfigurationError",`No activity found for package ${e.packageName}.`);if(o=s.trim().split(`
|
|
5585
|
-
`).pop()?.replace(/^.*\//,""),!o)throw new M("UserConfigurationError",`Could not parse main activity name for package ${e.packageName}. Raw output: ${s}`)}if(this.options?.emulator?.autoGrantPermissions&&!this.appsWithGrantedPermissions.has(e.packageName)){let a={permissions:"all",appPackage:e.packageName,action:"grant"};await this.driver.executeInNativeContext(this.logger,s=>s.executeScript("mobile: changePermissions",[a]),{operationName:"changePermissions"}),this.appsWithGrantedPermissions.add(e.packageName);}let i=["start",...n,"-f","0x10200000"];if(e.intentExtras)try{let a=JSON.parse(e.intentExtras);for(let[s,c]of Object.entries(a))i.push("-e",s,typeof c=="string"?c:JSON.stringify(c));}catch(a){throw new M("UserConfigurationError",`Invalid intent extras does not parse as valid JSON: ${a instanceof Error?a.message:`${a}`}`)}return i.push("-n",`${e.packageName}/${o}`),await this.driver.executeInNativeContext(this.logger,a=>a.execute("mobile: shell",{command:"am",args:i}),{operationName:"startApp"}),await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.abortSignal,reason:"Waiting for stability after app launch"}),this.stateManager.refreshWebviewsManually("new app launch"),{success:true}}case "PRESS":{let o=new kc(this.constructPerformerParams());switch(e.key){case "HOME":await o.doPress({keycode:3});break;case "BACK":await o.doPress({keycode:4});break;case "APP_SWITCHER":await o.doPress({keycode:187});break;case "POWER":await o.doPress({keycode:26});break;case "SEARCH":await o.doPress({keycode:84});break;case "VOLUME_UP":await o.doPress({keycode:24});break;case "VOLUME_DOWN":await o.doPress({keycode:25});break;case "VOLUME_MUTE":await o.doPress({keycode:164});break}return {success:true}}case "PRESS_KEYBOARD":{let o=new kc(this.constructPerformerParams()),n=i=>o.doPress({keycode:i});switch(e.key){case "CLOSE_KEYBOARD":{let i=Date.now();for(;Date.now()-i<2e3&&(await this.driver.executeInNativeContext(this.logger,s=>s.hideKeyboard(),{operationName:"hideKeyboard"}),!!await this.driver.executeInNativeContext(this.logger,s=>s.isKeyboardShown(),{operationName:"isKeyboardShown"})););break}case "ENTER":await n(66);break;case "BACKSPACE":await n(67);break;}return {success:true}}case "WAIT":return await ce(e.timeoutSecs*1e3,this.aborter.controller?.signal),{success:true};case "INSTALL_APP":return new iw(this.constructPerformerParams()).doInstallApk(e);case "UNINSTALL_APP":return new dw(this.constructPerformerParams()).doUninstallApk(e);case "ADD_FILE":{let o=await Uv(e.file);return await this.driver.executeInNativeContext(this.logger,async n=>{await n.pushFile(e.storageLocation,o),await n.execute("mobile: shell",{command:"am",args:["broadcast","-a","android.intent.action.MEDIA_SCANNER_SCAN_FILE","-d",`file://${e.storageLocation}`]});},{operationName:"addFile",attemptTimeoutMs:12e4}),{success:true}}case "TOGGLE_SETTINGS":return await this.driver.executeInNativeContext(this.logger,async o=>{switch(e.settingsType){case "AIRPLANE_MODE":await o.appiumToggleAirplaneMode();break;case "DATA":await o.appiumToggleData();break;case "WIFI":await o.appiumToggleWiFi();break;case "LOCATION":await o.appiumToggleLocationServices();break;default:throw e.settingsType,new M("UserConfigurationError",`Unknown settings type: ${e.settingsType}`)}},{operationName:"toggleSettings"}),{success:true};case "ROTATE_ORIENTATION":return await this.driver.executeInNativeContext(this.logger,async o=>{await o.execute("mobile: shell",{command:"settings",args:["put","system","accelerometer_rotation","0"]}),await o.execute("mobile: shell",{command:"settings",args:["put","system","user_rotation",e.orientation==="LANDSCAPE"?"1":"0"]});},{operationName:"rotateOrientation"}),{success:true,output:{newViewportBounds:await this.getViewportBounds()}};case "ADB_COMMAND":{let o;try{o=JSON.parse(e.jsonArgs??"[]");}catch(a){throw new M("UserConfigurationError",`Invalid JSON for ADB command arguments: ${a instanceof Error?a.message:`${a}`}`)}let n=C__default.string().array().safeParse(o);if(!n.success)throw new M("UserConfigurationError",`Invalid ADB command arguments: ${n.error.message}`);let i=await this.executeRawADBCommandWithArgs([e.command,...n.data]);return this.logger.info({output:i},"ADB command executed successfully"),{success:true,output:i,message:"ADB command executed successfully"}}case "APPIUM_EXECUTE":{let o=JSON.parse(e.jsonArgs??"{}"),n=await this.driver.executeInNativeContext(this.logger,async i=>i.execute(e.command,o),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:n},"Appium command executed successfully"),{success:true,output:n,message:"Appium command executed successfully"}}case "KILL_APP":{let o=await this.stateManager.getCurrentPackage();if(!o)throw new M("UserConfigurationError","No package is currently active");await this.driver.executeInNativeContext(this.logger,async n=>{await n.execute("mobile: shell",{command:"input",args:["keyevent","KEYCODE_HOME"]}),await n.terminateApp(o);},{operationName:"killApp"});try{await t5({packageName:o,driver:this.driver,abortSignal:this.abortSignal,logger:this.logger});}catch(n){this.throwIfAborted(),this.logger.warn({err:n,packageName:o},"Failed to remove package from recents, continuing...");}return {success:true}}case "STATE":{await this.stateManager.refreshWebviewsManually("debug cmd");let o=await this.stateManager.getDomState(),n=await this.stateManager.getContexts(),i={xml:o.graph.xml,contexts:n};return this.logger.info({result:i},"State debug command output"),{output:i,success:true}}default:{return {success:true}}}}async initializeSettings(){let{latitude:e,longitude:r}=this.options?.emulator?.geolocation??Ld;await this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: setGeolocation",{latitude:e,longitude:r}),{operationName:"setGeolocation"}),await Promise.all([this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_COARSE_LOCATION"]}),{operationName:"grantCoarseLocationPermission"}),this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_FINE_LOCATION"]}),{operationName:"grantFineLocationPermission"}),this.driver.executeInNativeContext(this.logger,o=>o.updateSettings({keyInjectionDelay:dd}),{operationName:"initializeKeyInjectionDelay"})]);}async getScreenshotBase64(){return this.stateManager.getRawScreenshotBase64()}async getScreenshotPngString(){return this.stateManager.getCurrentScreenshotPngString()}async getEmulatorDomState(){return (await this.stateManager.getDomState({})).graph.xml}async executeRawADBCommandWithArgs(e){return this.stateManager.executeRawADBCommandWithArgs(e)}async executeRawADBCommand(e){return this.stateManager.executeRawADBCommand(e)}async softReset(){await o5(this,this.logger),this.fixtures.testContext.resetToInitial();}async getViewportBounds(){return this.stateManager.getViewportBounds()}async waitForScreenshotStability(e){return this.stateManager.waitForScreenshotStability({timeoutMs:e.timeoutMs??3e3,reason:e.reason,signal:this.aborter.controller?.signal})}async getMobileFailureRecoveryPlan(e){return this.generator.getAndroidFailureRecoveryPlan(e,{disableCache:true,abortSignal:this.abortSignal,loggerTags:Ie(this.logger)})}async waitForPageSourceStability(e){await this.stateManager.waitForPageSourceStability({timeoutMs:e.timeoutMs??3e3,reason:e.reason,signal:this.aborter.controller?.signal});}resetAbortController(e){this.aborter.controller=e??new AbortController;}isAborted(){return this.aborter.controller?.signal.aborted}abort(){this.aborter.controller?.abort();}async cleanup(){await this.stateManager.cleanupWebviews();}get abortSignal(){return this.aborter.controller?.signal}get context(){return this.fixtures.testContext}get localCodeEvalTools(){return this.fixtures.localCodeEvalTools}};var iFe=new CT(30,60*1e3),T0="https://api.momentic.ai",fw,$Q,Qp=t=>{T0=t;},pb=()=>T0;var bw=t=>{$Q=t;},fs=()=>$Q,Xt=()=>fw;var mb,E0,jQ,HQ,GQ,hw,WQ,qQ=({authInfo:t,apiKey:e,apiClient:r})=>{fw=r,mb=t.orgId,E0=t.userId,jQ=t.email,HQ=t.name,GQ=t.pylonEmailHash,hw=e,WQ=t.selfServe;},v0=async({apiClient:t,apiKey:e,skipPrompts:r})=>{let o=await Gg({client:t});return qQ({authInfo:o,apiKey:e,apiClient:t}),o},KQ=async t=>{if(fw&&mb&&hw)return mb;let e=new pr({baseUrl:T0,apiKey:t,logger:I});fw=e;try{let r=await e.getAuthInfo();return qQ({authInfo:r,apiKey:t,apiClient:e}),r.orgId}catch(r){throw new Error(`Error checking API key against server: ${r}`,{cause:r})}},qr=()=>{if(!mb)throw new Error("Your organization ID is invalid.");return mb},md=()=>{if(!E0)throw new Error("Your user ID is invalid.");return E0},yw=()=>jQ,YQ=()=>HQ,XQ=()=>GQ,Ew=()=>WQ,JQ=()=>{if(!hw)throw new Error("Your API key is invalid.");return hw},gw,Sw,Uc=()=>{Sw?.abort(),Sw=void 0;},Tw=(t,e)=>{gw=t,Uc(),Sw=new AbortController;let r=Sw.signal,o=[t.configFilePath];t.config.environments?.forEach(n=>{if(!n.envFile)return;let i=sr__default.resolve(t.rootDir,n.envFile);try{if(so.lstatSync(i).isSymbolicLink())return;so.existsSync(i)&&o.push(i);}catch(a){I.warn({err:a},`Failed to check if env file ${i} exists`);}});try{aFe({filesToWatch:o,revalidator:e,signal:r,project:t});}catch(n){I.error({err:n},"Failed to start config file watchers");}},bt=()=>{if(!gw)throw new Ft("No Momentic project is currently loaded. Open or select a project before invoking this action.");return gw};function aFe({filesToWatch:t,revalidator:e,signal:r,project:o}){I.debug("Starting watch on the following files:"),t.forEach(n=>{I.debug(`- ${n}`);}),t.forEach(n=>{let i=async(s,c)=>{s.mtime.getTime()!==c.mtime.getTime()&&(iFe.increment("setLocalProject")&&I.warn(`A file change under the ${o.rootDir} directory has caused Momentic to reload its configuration more than 30 times in the last minute. Rapid changes to files may indicate your momentic.config.yaml 'include' glob is incorrect. Please ensure temporary, library, and auto-generated files are not included in Momentic's context.`),gw=await Promise.resolve(e(o.configFilePath)));};so.watchFile(n,{persistent:false},i);let a=()=>{so.unwatchFile(n,i),r.removeEventListener("abort",a);};r.addEventListener("abort",a);});}function We(t){return function(...e){let r=e[e.length-1],o=t(...e);Promise.resolve(o).catch(r);}}var lFe="0.97.2",pd=_m({app:"desktop-server",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:lFe});(async()=>{try{let t=await kg(pd);t.gitBranchName&&pd.addBinding("branch",t.gitBranchName);}catch{}})();var ZQ=Router();ZQ.get("/",async(t,e)=>{let r=bt(),o=Xt();if(!o){e.status(500).json({message:"API client not initialized"});return}let n=await dr(pd,o,r),i=n?.gitProtectedBranches&&n?.gitBranchName&&n.gitProtectedBranches.includes(n.gitBranchName),{noCache:a,alwaysSaveCache:s}=fs(),c=!a&&(s||!i);e.status(200).json({saveCaches:c,checkedOutBranch:n?.gitBranchName});});var C0=ZQ;var dFe=5e3,mFe=[".js",".mjs",".cjs",".ts"];function A0(t={}){let e=Router();function r(){let d=bt();return sr__default.dirname(d.configFilePath)}function o(d){return sr__default.join(r(),...d)}function n(d){let m=sr__default.relative(r(),d);return m?m.split(sr__default.sep):[]}function i(d,m){let p=so.statSync(d),f=n(d);return RM.parse({name:m,absolutePath:d,relativePath:f.join(sr__default.sep),pathSegments:f,isDirectory:p.isDirectory(),size:p.size,createdAt:p.birthtime,modifiedAt:p.mtime,accessedAt:p.atime})}function a(d){let m=sr__default.relative(r(),d);return m===""||!m.startsWith("..")&&!sr__default.isAbsolute(m)}async function s(d){let m=bt();return ep(["*"],{cwd:d,ignore:m.config.exclude??[],maxDepth:1,nodir:false,signal:AbortSignal.timeout(dFe)})}function c(d){let m=d.trimStart().replace(/^file:\/\//,"").replaceAll("\\","/"),p=m.lastIndexOf("/");return p===-1?{directoryText:"",filePrefix:m}:{directoryText:m.slice(0,p+1),filePrefix:m.slice(p+1)}}function l(d){return d.replaceAll("\\","/").split("/").filter(m=>m&&m!==".")}function u({sourceDirectoryPath:d,targetPath:m,isDirectory:p}){let f=sr__default.relative(d,m).split(sr__default.sep).join("/");return p?f?`${f}/`:"./":f}return e.post("/file-reference-suggestions",We(async(d,m,p)=>{let f=MV.safeParse(d.body);if(!f.success){m.status(400).json({error:`Failed to parse file-reference-suggestions body: ${f.error.message}`});return}let{sourceDirectoryPath:h="",value:S}=f.data,b=new Set((f.data.allowedExtensions??mFe).map(A=>A.toLowerCase())),y=c(S);if(y.directoryText.startsWith("/")){m.status(200).json({suggestions:[]});return}let T=sr__default.resolve(r(),...l(h)),v=sr__default.resolve(T,...l(y.directoryText));if(!a(T)||!a(v)){m.status(200).json({suggestions:[]});return}if(!so.existsSync(v)||!so.statSync(v).isDirectory()){m.status(200).json({suggestions:[]});return}let w;try{w=await s(v);}catch(A){if(A instanceof Error&&A.name==="TimeoutError"){m.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw A}let N=w.map(A=>{let B=sr__default.join(v,A);return {entryName:A,targetPath:B,isDirectory:so.statSync(B).isDirectory()}}),D=y.filePrefix.toLowerCase(),x=N.filter(A=>A.entryName.startsWith(".")||!A.entryName.toLowerCase().startsWith(D)?false:A.isDirectory?true:b.has(sr__default.extname(A.entryName).toLowerCase())).sort((A,B)=>A.isDirectory!==B.isDirectory?A.isDirectory?-1:1:A.entryName.localeCompare(B.entryName)).map(A=>({name:A.entryName,isDirectory:A.isDirectory,value:u({sourceDirectoryPath:T,targetPath:A.targetPath,isDirectory:A.isDirectory})}));m.status(200).json({suggestions:x});})),e.post("/",We(async(d,m,p)=>{let f;try{f=_V.parse(d.body).pathSegments;}catch(v){m.status(400).json({error:`Failed to parse folder read body: ${v}`});return}let h=o(f);if(!so.existsSync(h)){m.status(404).json({error:`Path not found: ${f.join(sr__default.sep)}`});return}if(!so.statSync(h).isDirectory()){m.status(400).json({error:`Path is not a directory: ${f.join(sr__default.sep)}`});return}let b;try{b=await s(h);}catch(v){if(v instanceof Error&&v.name==="TimeoutError"){m.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw v}let y=b.map(v=>{let w=sr__default.join(h,v);return i(w,v)});if(t.allowedFileTypes){let v=new Set(t.allowedFileTypes);y=(await Promise.all(y.map(async w=>{if(w.isDirectory||!(w.name.endsWith(".test.yaml")||w.name.endsWith(".module.yaml")))return w;let D=await pFe(w.absolutePath);return D!==void 0&&v.has(D)?w:null}))).filter(w=>w!==null);}let T={absolutePath:h,pathSegments:f,contents:y};m.status(200).json(T);})),e.put("/",We(async(d,m,p)=>{let f;try{f=xV.parse(d.body).pathSegments;}catch(b){m.status(400).json({error:`Failed to parse folder create body: ${b}`});return}let h=o(f);if(so.existsSync(h)){m.status(200).json({success:true,message:`Folder already exists: ${f.join(sr__default.sep)}`,pathSegments:f});return}so.mkdirSync(h,{recursive:true});let S={success:true,message:`Folder created: ${f.join(sr__default.sep)}`,pathSegments:f};m.status(201).json(S);})),e.patch("/",We(async(d,m,p)=>{let f,h;try{let v=PV.parse(d.body);f=v.pathSegments,h=v.newPathSegments;}catch(v){m.status(400).json({error:`Failed to parse folder update body: ${v}`});return}let S=o(f),b=o(h);if(!so.existsSync(S)){m.status(400).json({error:`Folder not found: ${f.join(sr__default.sep)}`});return}if(so.existsSync(b)){m.status(400).json({error:`Destination already exists: ${h.join(sr__default.sep)}`});return}let y=sr__default.dirname(b);so.existsSync(y)||so.mkdirSync(y,{recursive:true}),so.renameSync(S,b);let T={success:true,message:`Folder moved from ${f.join(sr__default.sep)} to ${h.join(sr__default.sep)}`,pathSegments:h};m.status(200).json(T);})),e.delete("/",We(async(d,m,p)=>{let f,h=true;try{let T=IV.parse(d.body);f=T.pathSegments,h=T.recursive??!0;}catch(T){m.status(400).json({error:`Failed to parse folder delete body: ${T}`});return}let S=o(f);if(!so.existsSync(S)){m.status(200).json({success:true,message:`Folder not found: ${f.join(sr__default.sep)}`,pathSegments:f});return}if(!so.statSync(S).isDirectory()){m.status(400).json({error:`Path is not a directory: ${f.join(sr__default.sep)}`});return}try{if(h)so.rmSync(S,{recursive:!0,force:!0});else {if(so.readdirSync(S).length>0){m.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${f.join("/")}`});return}so.rmdirSync(S);}}catch(T){let{status:v,body:w}=WY(T,`delete folder ${f.join("/")}`);m.status(v).json(w);return}let y={success:true,message:`Folder deleted: ${f.join("/")}`,pathSegments:f};m.status(200).json(y);})),e}async function pFe(t){try{let e=await so.promises.open(t,"r");try{let r=Buffer.alloc(4096),{bytesRead:o}=await e.read(r,0,r.length,0);return r.toString("utf-8",0,o).match(/^fileType:\s*(.+)$/m)?.[1]?.trim()}finally{await e.close();}}catch{}}var QQ=Router();QQ.get("/",async(t,e)=>{let r=bt(),o=Xt();if(!o){e.status(500).json({message:"API client not initialized"});return}let n=await dr(pd,o,r);e.status(200).json(n);});var w0=QQ;var vw=class t extends uc{static async init(e){let r=await uc.connectAppium(e);return new t(r)}async executeWebViewScript(e,r,o,...n){let i=await this.executeInContext(e,r,async a=>{let s=new Function("...args",`${Qg.safariUtilsLibJs};
|
|
5585
|
+
`).pop()?.replace(/^.*\//,""),!o)throw new M("UserConfigurationError",`Could not parse main activity name for package ${e.packageName}. Raw output: ${s}`)}if(this.options?.emulator?.autoGrantPermissions&&!this.appsWithGrantedPermissions.has(e.packageName)){let a={permissions:"all",appPackage:e.packageName,action:"grant"};await this.driver.executeInNativeContext(this.logger,s=>s.executeScript("mobile: changePermissions",[a]),{operationName:"changePermissions"}),this.appsWithGrantedPermissions.add(e.packageName);}let i=["start",...n,"-f","0x10200000"];if(e.intentExtras)try{let a=JSON.parse(e.intentExtras);for(let[s,c]of Object.entries(a))i.push("-e",s,typeof c=="string"?c:JSON.stringify(c));}catch(a){throw new M("UserConfigurationError",`Invalid intent extras does not parse as valid JSON: ${a instanceof Error?a.message:`${a}`}`)}return i.push("-n",`${e.packageName}/${o}`),await this.driver.executeInNativeContext(this.logger,a=>a.execute("mobile: shell",{command:"am",args:i}),{operationName:"startApp"}),await this.stateManager.waitForPageSourceStability({timeoutMs:3e3,signal:this.abortSignal,reason:"Waiting for stability after app launch"}),this.stateManager.refreshWebviewsManually("new app launch"),{success:true}}case "PRESS":{let o=new kc(this.constructPerformerParams());switch(e.key){case "HOME":await o.doPress({keycode:3});break;case "BACK":await o.doPress({keycode:4});break;case "APP_SWITCHER":await o.doPress({keycode:187});break;case "POWER":await o.doPress({keycode:26});break;case "SEARCH":await o.doPress({keycode:84});break;case "VOLUME_UP":await o.doPress({keycode:24});break;case "VOLUME_DOWN":await o.doPress({keycode:25});break;case "VOLUME_MUTE":await o.doPress({keycode:164});break}return {success:true}}case "PRESS_KEYBOARD":{let o=new kc(this.constructPerformerParams()),n=i=>o.doPress({keycode:i});switch(e.key){case "CLOSE_KEYBOARD":{let i=Date.now();for(;Date.now()-i<2e3&&(await this.driver.executeInNativeContext(this.logger,s=>s.hideKeyboard(),{operationName:"hideKeyboard"}),!!await this.driver.executeInNativeContext(this.logger,s=>s.isKeyboardShown(),{operationName:"isKeyboardShown"})););break}case "ENTER":await n(66);break;case "BACKSPACE":await n(67);break;}return {success:true}}case "WAIT":return await ce(e.timeoutSecs*1e3,this.aborter.controller?.signal),{success:true};case "INSTALL_APP":return new iw(this.constructPerformerParams()).doInstallApk(e);case "UNINSTALL_APP":return new dw(this.constructPerformerParams()).doUninstallApk(e);case "ADD_FILE":{let o=await Uv(e.file);return await this.driver.executeInNativeContext(this.logger,async n=>{await n.pushFile(e.storageLocation,o),await n.execute("mobile: shell",{command:"am",args:["broadcast","-a","android.intent.action.MEDIA_SCANNER_SCAN_FILE","-d",`file://${e.storageLocation}`]});},{operationName:"addFile",attemptTimeoutMs:12e4}),{success:true}}case "TOGGLE_SETTINGS":return await this.driver.executeInNativeContext(this.logger,async o=>{switch(e.settingsType){case "AIRPLANE_MODE":await o.appiumToggleAirplaneMode();break;case "DATA":await o.appiumToggleData();break;case "WIFI":await o.appiumToggleWiFi();break;case "LOCATION":await o.appiumToggleLocationServices();break;default:throw e.settingsType,new M("UserConfigurationError",`Unknown settings type: ${e.settingsType}`)}},{operationName:"toggleSettings"}),{success:true};case "ROTATE_ORIENTATION":return await this.driver.executeInNativeContext(this.logger,async o=>{await o.execute("mobile: shell",{command:"settings",args:["put","system","accelerometer_rotation","0"]}),await o.execute("mobile: shell",{command:"settings",args:["put","system","user_rotation",e.orientation==="LANDSCAPE"?"1":"0"]});},{operationName:"rotateOrientation"}),{success:true,output:{newViewportBounds:await this.getViewportBounds()}};case "ADB_COMMAND":{let o;try{o=JSON.parse(e.jsonArgs??"[]");}catch(a){throw new M("UserConfigurationError",`Invalid JSON for ADB command arguments: ${a instanceof Error?a.message:`${a}`}`)}let n=C__default.string().array().safeParse(o);if(!n.success)throw new M("UserConfigurationError",`Invalid ADB command arguments: ${n.error.message}`);let i=await this.executeRawADBCommandWithArgs([e.command,...n.data]);return this.logger.info({output:i},"ADB command executed successfully"),{success:true,output:i,message:"ADB command executed successfully"}}case "APPIUM_EXECUTE":{let o=JSON.parse(e.jsonArgs??"{}"),n=await this.driver.executeInNativeContext(this.logger,async i=>i.execute(e.command,o),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:n},"Appium command executed successfully"),{success:true,output:n,message:"Appium command executed successfully"}}case "KILL_APP":{let o=await this.stateManager.getCurrentPackage();if(!o)throw new M("UserConfigurationError","No package is currently active");await this.driver.executeInNativeContext(this.logger,async n=>{await n.execute("mobile: shell",{command:"input",args:["keyevent","KEYCODE_HOME"]}),await n.terminateApp(o);},{operationName:"killApp"});try{await t5({packageName:o,driver:this.driver,abortSignal:this.abortSignal,logger:this.logger});}catch(n){this.throwIfAborted(),this.logger.warn({err:n,packageName:o},"Failed to remove package from recents, continuing...");}return {success:true}}case "STATE":{await this.stateManager.refreshWebviewsManually("debug cmd");let o=await this.stateManager.getDomState(),n=await this.stateManager.getContexts(),i={xml:o.graph.xml,contexts:n};return this.logger.info({result:i},"State debug command output"),{output:i,success:true}}default:{return {success:true}}}}async initializeSettings(){let{latitude:e,longitude:r}=this.options?.emulator?.geolocation??Ld;await this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: setGeolocation",{latitude:e,longitude:r}),{operationName:"setGeolocation"}),await Promise.all([this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_COARSE_LOCATION"]}),{operationName:"grantCoarseLocationPermission"}),this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_FINE_LOCATION"]}),{operationName:"grantFineLocationPermission"}),this.driver.executeInNativeContext(this.logger,o=>o.updateSettings({keyInjectionDelay:dd}),{operationName:"initializeKeyInjectionDelay"})]);}async getScreenshotBase64(){return this.stateManager.getRawScreenshotBase64()}async getScreenshotPngString(){return this.stateManager.getCurrentScreenshotPngString()}async getEmulatorDomState(){return (await this.stateManager.getDomState({})).graph.xml}async executeRawADBCommandWithArgs(e){return this.stateManager.executeRawADBCommandWithArgs(e)}async executeRawADBCommand(e){return this.stateManager.executeRawADBCommand(e)}async softReset(){await o5(this,this.logger),this.fixtures.testContext.resetToInitial();}async getViewportBounds(){return this.stateManager.getViewportBounds()}async waitForScreenshotStability(e){return this.stateManager.waitForScreenshotStability({timeoutMs:e.timeoutMs??3e3,reason:e.reason,signal:this.aborter.controller?.signal})}async getMobileFailureRecoveryPlan(e){return this.generator.getAndroidFailureRecoveryPlan(e,{disableCache:true,abortSignal:this.abortSignal,loggerTags:Ie(this.logger)})}async waitForPageSourceStability(e){await this.stateManager.waitForPageSourceStability({timeoutMs:e.timeoutMs??3e3,reason:e.reason,signal:this.aborter.controller?.signal});}resetAbortController(e){this.aborter.controller=e??new AbortController;}isAborted(){return this.aborter.controller?.signal.aborted}abort(){this.aborter.controller?.abort();}async cleanup(){await this.stateManager.cleanupWebviews();}get abortSignal(){return this.aborter.controller?.signal}get context(){return this.fixtures.testContext}get localCodeEvalTools(){return this.fixtures.localCodeEvalTools}};var iFe=new CT(30,60*1e3),T0="https://api.momentic.ai",fw,$Q,Qp=t=>{T0=t;},pb=()=>T0;var bw=t=>{$Q=t;},fs=()=>$Q,Xt=()=>fw;var mb,E0,jQ,HQ,GQ,hw,WQ,qQ=({authInfo:t,apiKey:e,apiClient:r})=>{fw=r,mb=t.orgId,E0=t.userId,jQ=t.email,HQ=t.name,GQ=t.pylonEmailHash,hw=e,WQ=t.selfServe;},v0=async({apiClient:t,apiKey:e,skipPrompts:r})=>{let o=await Gg({client:t});return qQ({authInfo:o,apiKey:e,apiClient:t}),o},KQ=async t=>{if(fw&&mb&&hw)return mb;let e=new pr({baseUrl:T0,apiKey:t,logger:I});fw=e;try{let r=await e.getAuthInfo();return qQ({authInfo:r,apiKey:t,apiClient:e}),r.orgId}catch(r){throw new Error(`Error checking API key against server: ${r}`,{cause:r})}},qr=()=>{if(!mb)throw new Error("Your organization ID is invalid.");return mb},md=()=>{if(!E0)throw new Error("Your user ID is invalid.");return E0},yw=()=>jQ,YQ=()=>HQ,XQ=()=>GQ,Ew=()=>WQ,JQ=()=>{if(!hw)throw new Error("Your API key is invalid.");return hw},gw,Sw,Uc=()=>{Sw?.abort(),Sw=void 0;},Tw=(t,e)=>{gw=t,Uc(),Sw=new AbortController;let r=Sw.signal,o=[t.configFilePath];t.config.environments?.forEach(n=>{if(!n.envFile)return;let i=sr__default.resolve(t.rootDir,n.envFile);try{if(so.lstatSync(i).isSymbolicLink())return;so.existsSync(i)&&o.push(i);}catch(a){I.warn({err:a},`Failed to check if env file ${i} exists`);}});try{aFe({filesToWatch:o,revalidator:e,signal:r,project:t});}catch(n){I.error({err:n},"Failed to start config file watchers");}},bt=()=>{if(!gw)throw new Ft("No Momentic project is currently loaded. Open or select a project before invoking this action.");return gw};function aFe({filesToWatch:t,revalidator:e,signal:r,project:o}){I.debug("Starting watch on the following files:"),t.forEach(n=>{I.debug(`- ${n}`);}),t.forEach(n=>{let i=async(s,c)=>{s.mtime.getTime()!==c.mtime.getTime()&&(iFe.increment("setLocalProject")&&I.warn(`A file change under the ${o.rootDir} directory has caused Momentic to reload its configuration more than 30 times in the last minute. Rapid changes to files may indicate your momentic.config.yaml 'include' glob is incorrect. Please ensure temporary, library, and auto-generated files are not included in Momentic's context.`),gw=await Promise.resolve(e(o.configFilePath)));};so.watchFile(n,{persistent:false},i);let a=()=>{so.unwatchFile(n,i),r.removeEventListener("abort",a);};r.addEventListener("abort",a);});}function We(t){return function(...e){let r=e[e.length-1],o=t(...e);Promise.resolve(o).catch(r);}}var lFe="0.97.3",pd=_m({app:"desktop-server",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:lFe});(async()=>{try{let t=await kg(pd);t.gitBranchName&&pd.addBinding("branch",t.gitBranchName);}catch{}})();var ZQ=Router();ZQ.get("/",async(t,e)=>{let r=bt(),o=Xt();if(!o){e.status(500).json({message:"API client not initialized"});return}let n=await dr(pd,o,r),i=n?.gitProtectedBranches&&n?.gitBranchName&&n.gitProtectedBranches.includes(n.gitBranchName),{noCache:a,alwaysSaveCache:s}=fs(),c=!a&&(s||!i);e.status(200).json({saveCaches:c,checkedOutBranch:n?.gitBranchName});});var C0=ZQ;var dFe=5e3,mFe=[".js",".mjs",".cjs",".ts"];function A0(t={}){let e=Router();function r(){let d=bt();return sr__default.dirname(d.configFilePath)}function o(d){return sr__default.join(r(),...d)}function n(d){let m=sr__default.relative(r(),d);return m?m.split(sr__default.sep):[]}function i(d,m){let p=so.statSync(d),f=n(d);return RM.parse({name:m,absolutePath:d,relativePath:f.join(sr__default.sep),pathSegments:f,isDirectory:p.isDirectory(),size:p.size,createdAt:p.birthtime,modifiedAt:p.mtime,accessedAt:p.atime})}function a(d){let m=sr__default.relative(r(),d);return m===""||!m.startsWith("..")&&!sr__default.isAbsolute(m)}async function s(d){let m=bt();return ep(["*"],{cwd:d,ignore:m.config.exclude??[],maxDepth:1,nodir:false,signal:AbortSignal.timeout(dFe)})}function c(d){let m=d.trimStart().replace(/^file:\/\//,"").replaceAll("\\","/"),p=m.lastIndexOf("/");return p===-1?{directoryText:"",filePrefix:m}:{directoryText:m.slice(0,p+1),filePrefix:m.slice(p+1)}}function l(d){return d.replaceAll("\\","/").split("/").filter(m=>m&&m!==".")}function u({sourceDirectoryPath:d,targetPath:m,isDirectory:p}){let f=sr__default.relative(d,m).split(sr__default.sep).join("/");return p?f?`${f}/`:"./":f}return e.post("/file-reference-suggestions",We(async(d,m,p)=>{let f=MV.safeParse(d.body);if(!f.success){m.status(400).json({error:`Failed to parse file-reference-suggestions body: ${f.error.message}`});return}let{sourceDirectoryPath:h="",value:S}=f.data,b=new Set((f.data.allowedExtensions??mFe).map(A=>A.toLowerCase())),y=c(S);if(y.directoryText.startsWith("/")){m.status(200).json({suggestions:[]});return}let T=sr__default.resolve(r(),...l(h)),v=sr__default.resolve(T,...l(y.directoryText));if(!a(T)||!a(v)){m.status(200).json({suggestions:[]});return}if(!so.existsSync(v)||!so.statSync(v).isDirectory()){m.status(200).json({suggestions:[]});return}let w;try{w=await s(v);}catch(A){if(A instanceof Error&&A.name==="TimeoutError"){m.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw A}let N=w.map(A=>{let B=sr__default.join(v,A);return {entryName:A,targetPath:B,isDirectory:so.statSync(B).isDirectory()}}),D=y.filePrefix.toLowerCase(),x=N.filter(A=>A.entryName.startsWith(".")||!A.entryName.toLowerCase().startsWith(D)?false:A.isDirectory?true:b.has(sr__default.extname(A.entryName).toLowerCase())).sort((A,B)=>A.isDirectory!==B.isDirectory?A.isDirectory?-1:1:A.entryName.localeCompare(B.entryName)).map(A=>({name:A.entryName,isDirectory:A.isDirectory,value:u({sourceDirectoryPath:T,targetPath:A.targetPath,isDirectory:A.isDirectory})}));m.status(200).json({suggestions:x});})),e.post("/",We(async(d,m,p)=>{let f;try{f=_V.parse(d.body).pathSegments;}catch(v){m.status(400).json({error:`Failed to parse folder read body: ${v}`});return}let h=o(f);if(!so.existsSync(h)){m.status(404).json({error:`Path not found: ${f.join(sr__default.sep)}`});return}if(!so.statSync(h).isDirectory()){m.status(400).json({error:`Path is not a directory: ${f.join(sr__default.sep)}`});return}let b;try{b=await s(h);}catch(v){if(v instanceof Error&&v.name==="TimeoutError"){m.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw v}let y=b.map(v=>{let w=sr__default.join(h,v);return i(w,v)});if(t.allowedFileTypes){let v=new Set(t.allowedFileTypes);y=(await Promise.all(y.map(async w=>{if(w.isDirectory||!(w.name.endsWith(".test.yaml")||w.name.endsWith(".module.yaml")))return w;let D=await pFe(w.absolutePath);return D!==void 0&&v.has(D)?w:null}))).filter(w=>w!==null);}let T={absolutePath:h,pathSegments:f,contents:y};m.status(200).json(T);})),e.put("/",We(async(d,m,p)=>{let f;try{f=xV.parse(d.body).pathSegments;}catch(b){m.status(400).json({error:`Failed to parse folder create body: ${b}`});return}let h=o(f);if(so.existsSync(h)){m.status(200).json({success:true,message:`Folder already exists: ${f.join(sr__default.sep)}`,pathSegments:f});return}so.mkdirSync(h,{recursive:true});let S={success:true,message:`Folder created: ${f.join(sr__default.sep)}`,pathSegments:f};m.status(201).json(S);})),e.patch("/",We(async(d,m,p)=>{let f,h;try{let v=PV.parse(d.body);f=v.pathSegments,h=v.newPathSegments;}catch(v){m.status(400).json({error:`Failed to parse folder update body: ${v}`});return}let S=o(f),b=o(h);if(!so.existsSync(S)){m.status(400).json({error:`Folder not found: ${f.join(sr__default.sep)}`});return}if(so.existsSync(b)){m.status(400).json({error:`Destination already exists: ${h.join(sr__default.sep)}`});return}let y=sr__default.dirname(b);so.existsSync(y)||so.mkdirSync(y,{recursive:true}),so.renameSync(S,b);let T={success:true,message:`Folder moved from ${f.join(sr__default.sep)} to ${h.join(sr__default.sep)}`,pathSegments:h};m.status(200).json(T);})),e.delete("/",We(async(d,m,p)=>{let f,h=true;try{let T=IV.parse(d.body);f=T.pathSegments,h=T.recursive??!0;}catch(T){m.status(400).json({error:`Failed to parse folder delete body: ${T}`});return}let S=o(f);if(!so.existsSync(S)){m.status(200).json({success:true,message:`Folder not found: ${f.join(sr__default.sep)}`,pathSegments:f});return}if(!so.statSync(S).isDirectory()){m.status(400).json({error:`Path is not a directory: ${f.join(sr__default.sep)}`});return}try{if(h)so.rmSync(S,{recursive:!0,force:!0});else {if(so.readdirSync(S).length>0){m.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${f.join("/")}`});return}so.rmdirSync(S);}}catch(T){let{status:v,body:w}=WY(T,`delete folder ${f.join("/")}`);m.status(v).json(w);return}let y={success:true,message:`Folder deleted: ${f.join("/")}`,pathSegments:f};m.status(200).json(y);})),e}async function pFe(t){try{let e=await so.promises.open(t,"r");try{let r=Buffer.alloc(4096),{bytesRead:o}=await e.read(r,0,r.length,0);return r.toString("utf-8",0,o).match(/^fileType:\s*(.+)$/m)?.[1]?.trim()}finally{await e.close();}}catch{}}var QQ=Router();QQ.get("/",async(t,e)=>{let r=bt(),o=Xt();if(!o){e.status(500).json({message:"API client not initialized"});return}let n=await dr(pd,o,r);e.status(200).json(n);});var w0=QQ;var vw=class t extends uc{static async init(e){let r=await uc.connectAppium(e);return new t(r)}async executeWebViewScript(e,r,o,...n){let i=await this.executeInContext(e,r,async a=>{let s=new Function("...args",`${Qg.safariUtilsLibJs};
|
|
5586
5586
|
const userFn = ${o.toString()};
|
|
5587
5587
|
try {
|
|
5588
5588
|
return userFn(momenticFunctions, ...args);
|
|
5589
5589
|
} catch (e) {
|
|
5590
5590
|
return { _failed: true, _error: e.message }
|
|
5591
|
-
}`);return a.execute(s,...n)},{operationName:"executeWebViewScript"});if(i&&typeof i=="object"&&"_failed"in i)throw new Error(`Error executing script in webview: ${i._error||"Unknown error"}`);return i}async healthcheck(){await this.driver.getWindowHandle();}};async function eee({logger:t,driverLogLevel:e="error",emulator:r,callbacks:o}){let{onStatusUpdate:n}=o,i=t.child({emulatorName:r.name}),a={platformName:"iOS","appium:noReset":true,"appium:fullReset":false,"appium:shouldTerminateApp":false,"appium:forceAppLaunch":false,"appium:autoLaunch":false,"appium:newCommandTimeout":3600,"appium:autoWebview":false,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":true,"appium:fullContextList":false,"appium:additionalWebviewBundleIds":["*"],"appium:waitForIdleTimeout":0,"appium:reduceMotion":true,"appium:settings":{customSnapshotTimeout:0,animationCoolOffTimeout:0},...r.extraCapabilities};n("Starting Appium session...");let s={capabilities:a},c=await vw.init({logger:i,logLevel:e,callbacks:{...o,restartWda:r.restartWda?async l=>{await r.restartWda?.(l);}:void 0,onFailure:async({err:l,attempt:u})=>{let d=Vv(l),m=u<3&&d;return m&&i.warn({err:l},"Appium driver manifest race detected on first attempt, restarting Appium and retrying"),{shouldRetry:m}}},wdioOpts:s});return i.info({capabilities:a,emulatorName:r.name},"Started Appium driver"),c}async function tee({wdaUrl:t,token:e}){try{let r=new AbortController;return setTimeout(()=>r.abort(),3e3),await fetch(t+"/status",{headers:{Authorization:`Bearer ${e}`},signal:r.signal}),!0}catch{return false}}var Cw={"appium:waitForIdleTimeout":2,"appium:commandTimeouts":"30000","appium:skipLogCapture":true,"appium:disableAutomaticScreenshots":true,"appium:simpleIsVisibleCheck":true};var yFe=["[com.apple.","loadConfigurationForEnvironment"],EFe=["com.apple.Accessibility","com.apple.news","com.apple.locationd","NewsToday","NewsTodayIntents","apsd","APSConfiguration","APSOutgoingQueue","APSCourierConnection","APSNetworkMonitor","loadConfigurationForEnvironment"],TFe=new Set(["D","Df","Db"]),vFe=new Set(["I"]),CFe=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\s+(\S+)\s+/,AFe="https://storage.googleapis.com/mobile-drivers/WebDriverAgentRunner-Build-Sim-arm64-v10.4.5.zip",oee=6e4;function wFe(t){let e=CFe.exec(t)?.[1];if(!e)return false;let r=yFe.some(n=>t.includes(n)),o=EFe.some(n=>t.includes(n));return TFe.has(e)?r||o:vFe.has(e)?o:false}async function nee({wdaUrl:t,token:e,limbarClient:r,logger:o,onStatusUpdate:n}){await tee({wdaUrl:t,token:e})||(n("Starting WebDriverAgent..."),o.debug("WDA is not running on the iOS emulator"),await r.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),o.debug("WDA launched"));}var fb=class t{apiClient;name;extraCapabilities;limbarToken;limbarWebRtcUrl;limbarApiUrl;limbarWdaUrl;limbarRegion;limbarClient;onStatusUpdate;logStream=void 0;constructor({apiClient:e,limbarToken:r,limbarWebRtcUrl:o,limbarApiUrl:n,limbarWdaUrl:i,limbarRegion:a,emulatorName:s,limbarClient:c,onStatusUpdate:l}){this.apiClient=e,this.name=s,this.limbarToken=r,this.limbarWebRtcUrl=o,this.limbarApiUrl=n,this.limbarWdaUrl=i,this.limbarRegion=a,this.limbarClient=c,this.extraCapabilities={...Cw,"appium:automationName":"@limrun/xcuitest","appium:webDriverAgentUrl":this.limbarWdaUrl,"appium:wdaLocalPort":443,"appium:useNewWDA":false,"appium:usePreinstalledWDA":true,"appium:limInstanceApiUrl":n,"appium:limInstanceToken":r,"appium:wdaRequestHeaders":{Authorization:`Bearer ${r}`}},this.onStatusUpdate=l;}static async init(e){let{apiClient:r,logger:o,creationOpts:n,logLevel:i,orgId:a,sessionId:s,onStatusUpdate:c,onConnectionStateChange:l}=e,u=n.appToInstall?.channel,d=n.appToInstall?.tag;c("Creating iOS emulator");let{token:m,webRtcUrl:p,wdaUrl:f,apiUrl:h,id:S,region:b,appDownloadUrl:y,appMd5:T}=await r.createIosEmulator({...n,hostname:hostname(),sessionId:s,installAppOnClient:true});o.info({emulatorName:S,region:b,sessionId:s},"ios instance creation ok"),c("Connecting to iOS emulator...");let v;try{v=await _t.recordDuration({fn:async()=>await Q(createInstanceClient({apiUrl:h,token:m,logLevel:i}),{milliseconds:oee,message:`Timed out after ${oee}ms connecting to iOS emulator ${S}`}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${a}`]}),l&&v.onConnectionStateChange(l),c("Installing WebDriverAgent...");let w=v;return await _t.recordDuration({fn:async()=>{await aee({limbarClient:w,url:AFe,md5:void 0,logger:o,emulatorName:S,assetLabel:"WebDriverAgent"});},name:"test_event_duration",tags:["name:limbar-wda-install","clientOs:ios",`orgId:${a}`]}),await nee({wdaUrl:f,token:m,limbarClient:w,logger:o,onStatusUpdate:c}),y&&(c(`Installing iOS app${u?` with channel ${u}`:""}${d?` and tag ${d}`:""}`),await _t.recordDuration({fn:async()=>{await aee({limbarClient:w,url:y,md5:T,logger:o,emulatorName:S,assetLabel:"iOS app"});},name:"test_event_duration",tags:["name:limbar-app-install","clientOs:ios",`orgId:${a}`]})),(async()=>{try{let[N,D]=await Promise.allSettled([Fm("limserver-1.limrun.net"),Fm("125.253.92.199")]);o.info({limserver:N.status==="fulfilled"?N.value:N.reason,ip125:D.status==="fulfilled"?D.value:D.reason},"Limbar network diagnostics");}catch(N){o.warn({err:N},"Failed to run network diagnostics");}})(),new t({apiClient:r,limbarToken:m,limbarWebRtcUrl:p,limbarApiUrl:h,limbarWdaUrl:f,limbarRegion:b,emulatorName:S,limbarClient:w,onStatusUpdate:c})}catch(w){throw o.warn({err:w,emulatorName:S},"iOS emulator init failed after creation; cleaning up remote instance"),await RFe({apiClient:r,limbarClient:v,id:S,logger:o}),w}}tap(e,r){return this.limbarClient.tap(e,r)}nativeA11yTreeJson(){return this.limbarClient.elementTree()}async screenshotPngBase64(){let e=await this.limbarClient.screenshot(),r=Buffer.from(e.base64,"base64"),o=yN.decode(r),n=new PNG({width:o.width,height:o.height});return n.data=Buffer.from(o.data),PNG.sync.write(n).toString("base64")}listApps(){return this.limbarClient.listApps()}terminateApp(e){return this.limbarClient.terminateApp(e)}setOrientation(e){return this.limbarClient.setOrientation(e==="LANDSCAPE"?"Landscape":"Portrait")}pressKey(e){return this.limbarClient.pressKey(e)}async resetSettings(){let e=await this.limbarClient.simctl(["privacy","booted","reset","all"]).wait();if(e.code!==0)throw new Error(`simctl privacy reset returned non-zero exit code: ${e.code} stderr: ${e.stderr}`)}async startScreenRecording(){await this.limbarClient.startRecording({quality:RecordingQuality.Q5});}async stopScreenRecording(e){await this.limbarClient.stopRecording({localPath:e});}addSyslogListener(e){this.logStream||(this.logStream=this.limbarClient.streamSyslog());let r=o=>{wFe(o)||e(o);};return this.logStream.on("line",r),()=>{this.logStream?.off("line",r);}}async restartWda(e){await nee({wdaUrl:this.limbarWdaUrl,token:this.limbarToken,limbarClient:this.limbarClient,logger:e,onStatusUpdate:this.onStatusUpdate});}async close(){try{this.logStream?.stop();}catch{}try{this.limbarClient.disconnect();}catch{}await this.apiClient.deleteIosEmulator(this.name);}};async function RFe(t){let{apiClient:e,limbarClient:r,id:o,logger:n}=t;if(r)try{r.disconnect();}catch(i){n.warn({err:i,emulatorName:o},"Failed to disconnect limbar client during init cleanup");}try{await e.deleteIosEmulator(o);}catch(i){n.warn({err:i,emulatorName:o},"Failed to delete iOS emulator during init cleanup");}}var iee=12e4,Aw=6,_Fe=1e3;async function aee(t){let{limbarClient:e,url:r,md5:o,logger:n,emulatorName:i,assetLabel:a}=t,s;for(let c=1;c<=Aw;c++)try{await Q(e.installApp(r,{md5:o}),{milliseconds:iee,message:`Timed out after ${iee}ms installing ${a} on emulator ${i}`});return}catch(l){if(s=l,c===Aw)break;let u=_Fe*2**(c-1);n.warn({url:r,err:l,emulatorName:i,assetLabel:a,attempt:c,maxAttempts:Aw,backoffMs:u},`Failed to install ${a} on Limbar emulator; retrying after backoff`),await ce(u);}throw n.error({url:r,err:s,emulatorName:i,assetLabel:a,maxAttempts:Aw},`Failed to install ${a} on Limbar emulator (no more retries)`),new M("UserConfigurationError",`Failed to install ${a} on emulator ${i}: ${s}`)}var MFe=C__default.array(C__default.object({bundle_id:C__default.string(),name:C__default.string()})),Rw=class{constructor(e){this.udid=e;}async exec(e,r=[]){return new Promise((o,n)=>{execFile$1("idb",[...e,"--udid",this.udid,...r],(i,a)=>{i?n(i):o(a.trim());});})}async execBuffer(e,r=[]){return new Promise((o,n)=>{execFile$1("idb",[...e,"--udid",this.udid,...r],{encoding:"buffer",maxBuffer:10*1024*1024},(i,a)=>{i?n(i):o(a);});})}async describeDevice(){return this.exec(["describe"])}async tap({x:e,y:r}){await this.exec(["ui","tap"],[Math.round(e).toString(),Math.round(r).toString()]);}async elementTree(){return this.exec(["ui","describe-all"])}async listApps(){let e=await this.exec(["list-apps","--json"]),r=JSON.parse(e);return MFe.parse(r).map(o=>({bundleId:o.bundle_id,name:o.name}))}async terminate(e){await this.exec(["terminate"],[e]);}async pressKey(e){await this.exec(["ui","press"],[e]);}async screenshot(){let e=await this.execBuffer(["screenshot"],["-"]),r=Buffer.from([137,80,78,71,13,10,26,10]);if(e.length<r.length||!e.subarray(0,r.length).equals(r))throw new Error(`idb screenshot returned invalid PNG data (got ${e.length} bytes)`);return e.toString("base64")}async disconnect(){await this.exec(["disconnect"]);}};async function hb(t){try{return (await new Simctl().getDeviceTypes()).filter(o=>o.includes("iPhone"))}catch(e){return t.warn({err:e},"Got error listing local iPhone device types, returning empty list"),[]}}var _w=class t{name;extraCapabilities;simctl;idb;constructor({name:e,simctl:r,idb:o}){this.name=e,this.simctl=r,this.idb=o,this.extraCapabilities={...Cw,"appium:automationName":"XCUITest","appium:udid":r.udid??void 0};}static async init(e,r){let o=new Simctl,n=r.emulatorName??`momentic-${Date.now()}`,i=await hb(e);if(!i.includes(r.deviceType))throw new M("UserConfigurationError",`Invalid device type: ${r.deviceType}. Valid device types are: ${i.join(", ")}. If you are sure the device type is correct, please make sure it is installed and available in Xcode.`);let a;try{let s=await o.createDevice(n,r.deviceType,"26.3");o.udid=s,a=async()=>{try{await o.shutdownDevice();}catch{}await o.deleteDevice();},await o.bootDevice(),await o.startBootMonitor({timeout:12e4}),r.appFilePath&&await o.installApp(r.appFilePath);let c=new Rw(s);return new t({name:n,simctl:o,idb:c})}catch(s){throw await a?.(),s}}async tap(e,r){await this.idb.tap({x:e,y:r});}async nativeA11yTreeJson(){return this.idb.elementTree()}async screenshotPngBase64(){return this.idb.screenshot()}async listApps(){return this.idb.listApps()}async terminateApp(e){await this.idb.terminate(e);}async pressKey(e){await this.idb.pressKey(e);}async resetSettings(){}async close(){try{await this.idb.disconnect();}catch{}try{await this.simctl.shutdownDevice();}catch{}await this.simctl.deleteDevice();}};var xFe=5e3;async function ef({creationOpts:t,apiClient:e,logger:r,driverLogLevel:o,orgId:n,sessionId:i,callbacks:a}){let s=Date.now();r.info("Starting ios driver creation");let{onLimbarConnectionStateChange:c,onStatusUpdate:l}=a,u=[],d=async()=>{let p=u.toReversed();for(let f of p)try{await Q(f(),{milliseconds:xFe,fallback:()=>{}});}catch(h){if(AT(h))continue;r.warn({err:h},"Error running cleanup task");}};l("Starting iOS emulator creation...");let m;switch(t.type){case "remote":{m=await fb.init({apiClient:e,logger:r,creationOpts:t,orgId:n,sessionId:i,onStatusUpdate:l,onConnectionStateChange:c,logLevel:o});break}case "local":{m=await _w.init(r,t);break}}u.push(async()=>{await m.close();});try{let p=await eee({logger:r,driverLogLevel:o,emulatorStart:s,emulator:m,apiClient:e,creationOpts:t,orgId:n,sessionId:i,callbacks:a});return u.push(()=>p.close()),p.executeInNativeContext(r,f=>f.getPageSource(),{operationName:"Warm up Appium cache"}).catch(()=>{}),{driver:p,emulator:m,limbarParams:m instanceof fb?{token:m.limbarToken,webRtcUrl:m.limbarWebRtcUrl,region:m.limbarRegion,osVersion:t.type==="remote"?t.osVersion:void 0}:void 0,cleanup:d}}catch(p){throw await d(),new Error(`Failed to start Appium driver: ${p}`,{cause:p})}}var OFe=100,NFe=2500,cee=4e3,DFe="...";async function Mw({emulator:t,onLogs:e}){if(!t.addSyslogListener)return;let r=create({fetcher:async n=>{e(n);},resolver:()=>{},scheduler:windowedFiniteBatchScheduler({windowMs:NFe,maxBatchSize:OFe})}),o=n=>{let i=n.toString().trim();i.length!==0&&(i.length>cee&&(i=i.slice(0,cee)+DFe),r.fetch(i).catch(()=>{}));};return t.addSyslogListener(o)}var uee="NATIVE_APP";var kFe=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),FFe=new Set([]),UFe=new Set(["name","label","traits"]),BFe=new Set(["live-region","drawing-order"]),VFe=new Set(["visible","enabled"]);function dee(t){let e={},r=t.tagName,o=reduce(t.attributes,(n,i)=>(n[i.name]=i.value,n),{});for(let[n,i]of Object.entries(o))kFe.has(n)||n==="class"&&r===i||n==="focusable"&&i==="true"&&o.clickable==="true"||FFe.has(n)&&i==="false"||UFe.has(n)&&i===""||VFe.has(n)&&i==="true"||BFe.has(n)&&i==="0"||(e[n]=i);return e.name&&e.label&&e.name===e.label&&delete e.label,e.name&&e.value&&e.name===e.value&&delete e.value,e}function Zs(t){let e=t.getAttribute("x"),r=t.getAttribute("y"),o=t.getAttribute("width"),n=t.getAttribute("height");if(e===null||r===null||o===null||n===null)return;let i=parseFloat(e),a=parseFloat(r),s=parseFloat(o),c=parseFloat(n);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(c)))return {x1:i,y1:a,x2:i+s,y2:a+c}}function R0(t,e){let{x1:r,y1:o,x2:n,y2:i}=e;t.setAttribute("bounds",`[${r},${o},${n},${i}]`);}function zFe(t){let e=t.match(/\[([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\]/);if(!e)return;let r=parseFloat(e[1]),o=parseFloat(e[2]),n=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(r)||isNaN(o)||isNaN(n)||isNaN(i)||n<r||i<o))return {x1:r,y1:o,x2:n,y2:i}}function xw(t){let e=t.getAttribute("bounds");if(e)return zFe(e)}function mee(t,e){if(!e)return true;let r=Zs(t);return r?_0(r,e):true}function _0(t,e){if(!e)return true;let{x1:r,y1:o,x2:n,y2:i}=t;return !(n<e.left||r>e.right||i<e.top||o>e.bottom)}function Pw(t){let e=t.cloneNode(true);for(let r of Array.from(e.children)){let o=r;for(let n of Array.from(o.children))o.removeChild(n);}return e.outerHTML}var pee=new Set(["XCUIElementTypeWebView"]);function WFe(t){if(pee.has(t.tagName))return true;let e=t.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let r=e.match(/UUID=([A-F0-9-]+)/),o=e.match(/WebViewProcessID=(\d+)/);if(r&&o)return true}return false}function qFe(t){return t.startsWith("XCUIElementType")?t.substring(15):t}function fee({state:t,originalElement:e,prunedElement:r,isInWebview:o,idInWebview:n}){let{idCounter:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c}=t,l=i.value++;r.setAttribute("id",String(l)),a.set(l,r),o?c.set(l,n):s.set(l,e);}function hee(t){if(!pee.has(t.tagName)&&t.tagName==="XCUIElementTypeOther"&&t.hasAttribute("name")&&t.hasAttribute("label"))return t;for(let e of Array.from(t.children)){let r=hee(e);if(r)return r}}function KFe({webviewNativeRootBounds:t,webviewDocumentRootBounds:e}){let r=t.x1-e.x,o=t.y1-e.y;if(!Number.isFinite(r)||!Number.isFinite(o))return t;let n=t.x2-t.x1,i=t.y2-t.y1;return {x1:r,y1:o,x2:r+n,y2:o+i}}function gee(t,e,r,o){let{document:n}=r,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=o;if(e.type==="element"){let s=n.createElement(e.role||e.tag);if(e.name&&s.setAttribute("name",e.name),e.description&&s.setAttribute("description",e.description),e.classes&&e.classes.length>0&&s.setAttribute("classes",e.classes.join(" ")),e.attrs)for(let[u,d]of Object.entries(e.attrs))s.setAttribute(u,d);let c=e.boundingRect,l={x1:i.x1+c.x,y1:i.y1+c.y,x2:i.x1+c.x+c.width,y2:i.y1+c.y+c.height};if(!_0(l,a))return;R0(s,l),fee({state:r,prunedElement:s,isInWebview:true,idInWebview:e.momenticWebviewElementId}),t.appendChild(s);for(let u of e.children)gee(s,u,r,o);}else if(e.type==="text"){let s=n.createElement("text");t.appendChild(s);let c=n.createTextNode(e.text);s.appendChild(c);}}function See(t,e,r,o){let{pruneElementsOutsideBounds:n}=o,{document:i}=r;fee({state:r,originalElement:t,prunedElement:e,isInWebview:false});let a=dee(t);for(let[l,u]of Object.entries(a))e.setAttribute(l,u);let s=Zs(t);if(s&&R0(e,s),WFe(t)){let{removeWebviewContent:l,injectedWebviewContent:u}=o;if(l)return;if(u&&Zs(t)){let m=hee(t),p=m?Zs(m):void 0;if(m&&p){r.webviewRootElement=m,r.webviewRootBounds=p,gee(e,u.root,r,{parentFrameBounds:KFe({webviewNativeRootBounds:p,webviewDocumentRootBounds:u.rootBoundingBox}),pruneElementsOutsideBounds:n});return}}}let c=Array.from(t.childNodes??[]);for(let l of c){let u=l.nodeType;if(u===3){let d=l.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=l;if(!mee(d,n))continue;let m=i.createElement(qFe(d.tagName));See(d,m,r,o),e.appendChild(m);}}}async function M0(t,e,r){let o=t.parseFromString("<AppiumAUT/>","text/xml"),n=new Map,i=new Map,a=new Map,s={document:o,idToPrunedElement:n,idToOriginalElement:i,idToIdInWebview:a,idCounter:{value:0},webviewRootElement:void 0,webviewRootBounds:void 0},c=o.documentElement;See(e,c,s,r);let l=new XMLSerializer().serializeToString(o),u=await Tke.format(l,{parser:"xml",plugins:[Eke],printWidth:120,tabWidth:1,singleAttributePerLine:false});return {prunedDocument:o,idToPrunedElement:n,idToOriginalElement:i,idToIdInWebview:a,webviewRootElement:s.webviewRootElement,webviewRootBounds:s.webviewRootBounds,prunedXml:u}}async function bee(t,e){let r=new DOMParser,o=r.parseFromString(t,"text/xml"),n=o.documentElement;if(!n)throw new Error("No root element found in XML");if(n.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c,webviewRootElement:l,webviewRootBounds:u}=await M0(r,n,e);return {xml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c,webviewRootElement:l,webviewRootBounds:u,originalDocument:o}}var yee=(R=>(R.GenericElement="GenericElement",R.Any="Any",R.Other="Other",R.Application="Application",R.Group="Group",R.Window="Window",R.Sheet="Sheet",R.Drawer="Drawer",R.Alert="Alert",R.Dialog="Dialog",R.Button="Button",R.RadioButton="RadioButton",R.RadioGroup="RadioGroup",R.CheckBox="CheckBox",R.DisclosureTriangle="DisclosureTriangle",R.PopUpButton="PopUpButton",R.ComboBox="ComboBox",R.MenuButton="MenuButton",R.ToolbarButton="ToolbarButton",R.Popover="Popover",R.Keyboard="Keyboard",R.Key="Key",R.NavigationBar="NavigationBar",R.TabBar="TabBar",R.TabGroup="TabGroup",R.Toolbar="Toolbar",R.StatusBar="StatusBar",R.Table="Table",R.TableRow="TableRow",R.TableColumn="TableColumn",R.Outline="Outline",R.OutlineRow="OutlineRow",R.Browser="Browser",R.CollectionView="CollectionView",R.Slider="Slider",R.PageIndicator="PageIndicator",R.ProgressIndicator="ProgressIndicator",R.ActivityIndicator="ActivityIndicator",R.SegmentedControl="SegmentedControl",R.Picker="Picker",R.PickerWheel="PickerWheel",R.Switch="Switch",R.Toggle="Toggle",R.Link="Link",R.Image="Image",R.Icon="Icon",R.SearchField="SearchField",R.ScrollView="ScrollView",R.ScrollBar="ScrollBar",R.StaticText="StaticText",R.TextField="TextField",R.SecureTextField="SecureTextField",R.DatePicker="DatePicker",R.TextView="TextView",R.Menu="Menu",R.MenuItem="MenuItem",R.MenuBar="MenuBar",R.MenuBarItem="MenuBarItem",R.Map="Map",R.WebView="WebView",R.IncrementArrow="IncrementArrow",R.DecrementArrow="DecrementArrow",R.Heading="Heading",R.Cell="Cell",R))(yee||{}),Eee=C__default.lazy(()=>C__default.object({AXFrame:C__default.string(),AXUniqueId:C__default.string().nullable(),AXLabel:C__default.string().nullable(),AXValue:C__default.string().nullable(),frame:C__default.object({x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()}),role:C__default.string(),role_description:C__default.string(),subrole:C__default.string().nullable(),type:C__default.nativeEnum(yee),title:C__default.string().nullable(),help:C__default.string().nullable(),content_required:C__default.boolean(),custom_actions:C__default.array(C__default.string()),enabled:C__default.boolean(),children:C__default.array(Eee).default([])}));function XFe(t){return C__default.array(Eee).parse(JSON.parse(t))}async function Iw(t,e){let r=new DOMParser,o=XFe(t),n=JFe(r,o),{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s}=await M0(r,n.documentElement,{removeWebviewContent:false,injectedWebviewContent:void 0,pruneElementsOutsideBounds:e.pruneElementsOutsideBounds});return {xml:i,idToPrunedElement:a,idToOriginalElement:s,originalDocument:n,webviewRootElement:void 0,idToIdInWebview:new Map,webviewRootBounds:void 0}}function JFe(t,e){let r=t.parseFromString("<hierarchy/>","text/xml"),o=r.documentElement;for(let n=0;n<e.length;n++){let i=e[n],a=Tee(i,r);o.appendChild(a);}return r}function Tee(t,e){let r=t.type,o=e.createElement(r);if(o.setAttribute("type",r),o.setAttribute("x",String(t.frame.x.toFixed(2))),o.setAttribute("y",String(t.frame.y.toFixed(2))),o.setAttribute("width",String(t.frame.width.toFixed(2))),o.setAttribute("height",String(t.frame.height.toFixed(2))),t.AXLabel!==null&&o.setAttribute("label",t.AXLabel),t.AXValue!==null&&o.setAttribute("value",t.AXValue),t.title!==null&&o.setAttribute("title",t.title),t.help!==null&&o.setAttribute("help",t.help),o.setAttribute("enabled",String(t.enabled)),t.children)for(let n=0;n<t.children.length;n++){let i=t.children[n],a=Tee(i,e);o.appendChild(a);}return o}function fd(t){let e=[],r=t;for(;r;){let o=r.parentElement;if(!o||o.tagName==="AppiumAUT"){e.unshift(`${r.tagName}[1]`);break}let n=r.tagName,i=Array.from(o.children).filter(s=>s.tagName===n),a=1;for(let s=0;s<i.length;s++)if(i[s]===r){a=s+1;break}e.unshift(`${n}[${a}]`),r=o;}return `/${e.join("/")}`}var Ow=class t{driver;emulator;options;aborter;constructor({driver:e,emulator:r,aborter:o,options:n}){this.driver=e,this.emulator=r,this.aborter=o,this.options=n;}static async init({driver:e,emulator:r,aborter:o,options:n}){return new t({driver:e,aborter:o,emulator:r,options:n})}async getContexts(e){let r=await this.driver.executeInNativeContext(e,async n=>await n.getContexts({}),{operationName:"getContexts"}),o=r.filter(n=>n!==uee);return {contexts:r.map(n=>n),webviews:o}}async getRawScreenshotBase64({logger:e,totalAttempts:r=3,signal:o}){let n=ue(),i=o??this.aborter.controller?.signal;return await n.startAsyncSpan("EMULATOR_READ_STATE",async()=>await lp(e,()=>this.emulator.screenshotPngBase64(),{maxAttempts:r,signal:i,operationName:"takeScreenshot"}),{name:"Take screenshot",signal:i,timeoutMs:3e4})}async getCurrentScreenshotPngString(e){return `data:image/png;base64,${await this.getRawScreenshotBase64({logger:e,totalAttempts:1})}`}async waitForScreenshotStability({logger:e,timeoutMs:r,signal:o,reason:n,tolerancePercent:i=1}){await ue().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=n;let s=Mm({signal:o,timeoutMs:r}),c,l=false;for(;!s.aborted;){let u=Date.now();if(c)try{let m=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});if(cc(c,m)<=i){l=!0;break}c=m;}catch(m){e.warn({err:m},"Failed to get screenshot during stability wait");}else try{c=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});}catch(m){e.warn({err:m},"Failed to get initial screenshot during stability wait");}let d=Math.max(250,Date.now()-u);await Wa(Math.min(1e4,d),s);}l||(a.attributes.timedOut=true,e.warn({purpose:n},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({logger:e,timeoutMs:r,signal:o,reason:n}){await ue().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=n;let a=Mm({signal:o,timeoutMs:r}),s,c=false;for(;!a.aborted;){let l,u=Date.now();try{l=await Q(this.emulator.nativeA11yTreeJson(),{milliseconds:1e4,signal:a,message:"Getting the native accessibility tree timed out after 10s"});let m=createHash("md5").update(l).digest("hex");if(s&&s===m){c=!0;break}s=m;}catch(m){e.warn({err:m},"Failed to get page source during stability wait");}let d=Math.max(250,Date.now()-u);await Wa(Math.min(1e4,d),a);}c||(i.attributes.timedOut=true,e.warn({purpose:n},"Timed out waiting for page source stability"));});}async getActiveWebview(e){let o=(await this.getContexts(e)).webviews;if(o.length>1)throw new M("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return o[0]}async getActiveWebviewContent(e){let r=await this.getActiveWebview(e);if(!r)return;this.throwIfAborted();let o=await this.driver.executeWebViewScript(e,r,n=>n.dumpA11yTree());return {context:r,...o}}async getDomState(e,r){let n=r?.filterOffscreenElements??true?await this.getViewportBounds(e):void 0,i;if(!r?.skipFetchingFullWebviewContent)try{i=await this.getActiveWebviewContent(e);}catch(c){e.error({err:c},"Could not get webview info to get the nested DOM state");}if(this.throwIfAborted(),!i&&this.options?.disableMomenticAccessibilityTree){let c=await this.getNativePageSource();this.throwIfAborted();let l=await Iw(c,{pruneElementsOutsideBounds:n});return {sourceTree:"native",graph:l,webviewContent:void 0}}let a=await this.getAppiumPageSource(e);return this.throwIfAborted(),{graph:await bee(a,{injectedWebviewContent:i,removeWebviewContent:r?.removeWebviewContent,pruneElementsOutsideBounds:n}),sourceTree:"appium",webviewContent:i}}async getNativePageSource(){return await ue().startAsyncSpan("EMULATOR_READ_STATE",async()=>this.emulator.nativeA11yTreeJson(),{name:"Get iOS page source",signal:this.aborter.controller?.signal,timeoutMs:3e4})}async getAppiumPageSource(e,r){let o=r??this.aborter.controller?.signal;return await ue().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(e,i=>i.getPageSource(),{signal:o,operationName:"getPageSource"}),{name:"Get page source",signal:o,timeoutMs:3e4})}async getViewportBounds(e){let r=await this.driver.executeInNativeContext(e,async o=>o.getWindowRect(),{operationName:"getViewportBounds"});return {left:r.x,top:r.y,right:r.x+r.width,bottom:r.y+r.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};async function Cee({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,throwIfAborted:a,abortSignal:s}){let c=ue(),l=15,u=t.timeoutSecs?t.timeoutSecs*1e3:5e3,d=UT(u),m=Date.now(),p=0,f,h=false,S;for(;p<l&&!h;){a(),h||f&&f-m>=u&&(h=true),p!==0&&await ce(d,s),f=Date.now();try{let b="",y="";await c.startAsyncSpan("EMULATOR_READ_STATE",async()=>{b=await n(),y=await i();},{name:"Get emulator state"});let T=await r.evaluateIosAssertion({assertion:t.assertion,screenXml:b,screenshot:y},{logger:e,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["ios-assertion"]});if(T.result)return {success:T.result,message:T.thoughts};{let v=`AssertionFailureError: ${T.thoughts}`;S=new Error(v);}}catch(b){a(),e.info({err:b},`AI check assert attempt ${p} failed, retrying...`),S=b instanceof Error?b:new Error(`${b}`);}finally{p++;}}return {success:false,message:S?.message}}async function Aee({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,abortSignal:a}){if(!t.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(t.schema){let u=ym(t.schema);if(u)throw new M("UserConfigurationError",u)}let s=ue(),c="",l="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{c=await n(),l=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await r.getIosTextExtraction({goal:t.goal,emulatorState:c,returnSchema:t.schema,screenshot:`data:image/png;base64,${l}`},{disableCache:!!t.disableCache,abortSignal:a,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["ios-text-extraction"]});if(u.result=d,Hv({tracer:s,span:u,screenshot:l,emulatorState:c,logger:e}),d.result==="NOT_FOUND")return {success:!1,message:"No relevant data found for extraction goal on this page"};if(d.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}})}function Bc(t){let{x1:e,y1:r,x2:o,y2:n}=t.bounds;return {left:e,top:r,width:o-e,height:n-r}}var hs="element-6066-11e4-a52e-4f735466cecf";function gs(t,e){return Math.abs(t-e)<1}function tf(t,e){let r=e.x2-e.x1,o=(e.x1+e.x2)/2,n=(t.x1+t.x2)/2;if(!rs(e.tolerance,o,n,Math.min(1,r)))return false;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(t.y1+t.y2)/2;return rs(e.tolerance,a,s,Math.min(1,i))}function rf(t,e){let r=t.x2-t.x1,o=t.y2-t.y1;return rs(e.tolerance,e.width,r,Math.min(1,e.width))?rs(e.tolerance,e.height,o,Math.min(1,e.height)):false}function of(t){return t.type==="WEBVIEW",t.cache}function nf(t){let{command:e,cacheKey:r="cache",targetName:o="target",updatedCache:n}=t;fM(e)&&(e[r]={...e[r],[o]:Hd.parse(n)},t.updatedWithAI&&(e[r].updatedAt=new Date,e[r].updatedAtLoggerTags=Ie(t.logger)));}var gb="name";async function wee(t,e,r){return await e.executeInNativeContext(t,o=>o.isElementDisplayed(r),{operationName:"isElementRendered"})}async function af(t,e,r,o){return await e.executeInNativeContext(t,n=>n.getElementAttribute(r,o),{operationName:"getAttributeFromIosElement"})}async function x0(t,e,r){return await e.executeInNativeContext(t,async o=>{try{let n=await o.findElement("xpath",r);if(!n)return null;let i=n[hs];if(!i)return null;let a=await o.getElementRect(i);return {elementId:i,rect:a}}catch{return null}},{operationName:"findElementByXPath"})}async function Ree(t,e,r){let o=fd(r),n=await x0(t,e,o);if(n)return {xPath:o,...n}}async function P0({logger:t,emulatorState:e,driver:r,idInWebview:o,requirements:n}){let i=e.graph.webviewRootElement?fd(e.graph.webviewRootElement):void 0;if(!i||!e.webviewContent||!e.graph.webviewRootBounds)throw new Error("Cannot build webview target cache without webview root information");let a=await eUe({logger:t,driver:r,webviewRootBounds:e.graph.webviewRootBounds,nodeIdInWebview:o,aiGeneratedRequirements:n,webviewContent:e.webviewContent});if(!a)throw new Error("Failed to build browser cache for webview element");return {xPath:i,bounds:[e.graph.webviewRootBounds.x1,e.graph.webviewRootBounds.y1,e.graph.webviewRootBounds.x2,e.graph.webviewRootBounds.y2],browserCache:a}}async function eUe({logger:t,driver:e,webviewRootBounds:r,nodeIdInWebview:o,aiGeneratedRequirements:n,webviewContent:i}){let a=await e.executeWebViewScript(t,i.context,(c,l,u,d)=>c.generateCacheFromWebviewElementId(l,u,d),i.generatedAt,o,{attributesToFetch:n?.attributesRequired??[]});if(!a)return;let s={x:r.x1-i.rootBoundingBox.x+a.boundingBox.x,y:r.y1-i.rootBoundingBox.y+a.boundingBox.y,width:a.boundingBox.width,height:a.boundingBox.height};return {id:a.id,generatedSelectors:a.selectors,boundingBox:s,requirements:{text:n?.textRequired?a.textContent:void 0,attributes:a.attributes,boundingBox:n?.boundsRequired?s:void 0,shape:n?.shapeSpecificity?{tolerance:n.shapeSpecificity,width:a.boundingBox.width,height:a.boundingBox.height}:void 0,position:n?.positionSpecificity?{tolerance:n.positionSpecificity,x1:s.x,y1:s.y,x2:s.x+s.width,y2:s.y+s.height}:void 0}}}async function tUe(t,e,r,o){if(!o||!o.length)return;let n={};for(let i of o){let a=await af(t,e,r,i);a!==null&&(n[i]=a);}return Object.keys(n).length?n:void 0}async function _ee({logger:t,driver:e,node:r,requirements:o}){let n=await Ree(t,e,r);if(!n){t.warn("Failed to generate valid xPath selector for element");return}let{xPath:i,rect:a,elementId:s}=n,c={x1:a.x,y1:a.y,x2:a.x+a.width,y2:a.y+a.height};return {xPath:i,bounds:[c.x1,c.y1,c.x2,c.y2],requirements:{requiredText:o?.textRequired?await af(t,e,s,gb)??void 0:void 0,requiredAttributes:await tUe(t,e,s,o?.attributesRequired?.filter(l=>!(o.textRequired&&l===gb))),requiredBounds:o?.boundsRequired,position:o?.positionSpecificity?{x1:c.x1,y1:c.y1,x2:c.x2,y2:c.y2,tolerance:o?.positionSpecificity}:void 0,shape:o?.shapeSpecificity?{width:c.x2-c.x1,height:c.y2-c.y1,tolerance:o?.shapeSpecificity}:void 0}}}async function Mee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n}){let i=n.graph.idToPrunedElement.get(r.id);if(!i)throw new Error(`Could not find node with id: ${r.id}`);let a=xw(i);if(!a)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${o}`);let s=[];for(let{id:d,requirements:m}of r.additionalElements??[]){let p=n.graph.idToIdInWebview.get(d);if(p!==void 0){try{let S=await P0({logger:t,driver:e,emulatorState:n,idInWebview:p,requirements:m});s.push(S);}catch(S){t.warn({err:S},`Failed to build webview cache for related element with id: ${d}`);}continue}let f=n.graph.idToOriginalElement.get(d);if(!f){t.warn(`Could not find original element for additional element with id: ${d}`);continue}let h=await _ee({logger:t,driver:e,node:f,requirements:m});h&&s.push(h);}let c=n.graph.idToIdInWebview.get(r.id);if(c!==void 0){let d={type:"WEBVIEW",bounds:a,cache:{type:"WEBVIEW"}};try{let m=await P0({logger:t,driver:e,emulatorState:n,idInWebview:c,requirements:r.requirements});return {...d,cache:{type:"WEBVIEW",resolvedDescription:o,requiredRelatedElements:s,...m}}}catch(m){return t.warn({err:m},"Failed to build webview target cache"),d}}let l=n.graph.idToOriginalElement.get(r.id);if(!l)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${r.id}, description: ${o}`);let u=await _ee({logger:t,driver:e,node:l,requirements:r.requirements});return u?{type:"NATIVE",bounds:a,cache:{type:"NATIVE",...u,resolvedDescription:o,sourceTree:"appium",requiredRelatedElements:s,elementOnlySerializedXml:Pw(l)}}:(t.warn("Failed to generate valid cache for element"),{type:"NATIVE",cache:{type:"NATIVE"},bounds:a})}async function I0({logger:t,driver:e,stateManager:r,parentWebviewBounds:o,cache:n}){if(!n||!n.generatedSelectors)throw new we("Cache is missing required attributes");let i=await r.getActiveWebview(t);if(!i)throw new we("No active webview context found");let a=await e.executeWebViewScript(t,i,(u,d)=>u.resolveWebviewTargetCache(d),{selectors:n.generatedSelectors,attributesToFetch:Object.keys(n.requirements?.attributes??{})});if(!a)throw new we("Failed to resolve webview target using cache");let s=o.x1-a.rootBoundingBox.x+a.boundingBox.x,c=o.y1-a.rootBoundingBox.y+a.boundingBox.y,l={x1:s,y1:c,x2:s+a.boundingBox.width,y2:c+a.boundingBox.height};return n.requirements&&rUe(t,l,a,n.requirements),l}function rUe(t,e,r,o){if(!o)return;let{attributes:n,text:i,position:a,shape:s}=o;if(i!==void 0&&i.length>0&&r.textContent!==i)throw new we(`Text content mismatch: expected "${i}", got "${r.textContent}"`);if(n)for(let[c,l]of Object.entries(n)){let u=r.attributes[c];if(u!==l)throw new we(`Attribute ${c} mismatch: expected "${l}", got "${u}"`)}if(a&&!tf(e,a))throw new we(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(e)}`);if(s&&!rf(e,s))throw new we(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(e)}`)}async function xee(t,e,r,o,n){if(!o)return;let{requiredAttributes:i,requiredText:a,requiredBounds:s,position:c,shape:l}=o;if(a!==void 0&&a.length>0){let u=await af(t,e,r,gb);if(u!==a)throw new we(`Resolved element text mismatch: expected ${a}, got ${u}`)}if(i)for(let[u,d]of Object.entries(i)){let m=await af(t,e,r,u)??void 0;if(m!==d)throw new we(`Attribute ${u} mismatch: expected ${d}, got ${m}`)}if(s&&n){let{originalBounds:u,newBounds:d}=n;if(!u)throw new we("Cannot validate bounds requirements without original bounds in cache");if(!(gs(u.x1,d.x1)&&gs(u.y1,d.y1)&&gs(u.x2,d.x2)&&gs(u.y2,d.y2))){let p=f=>`[${f.x1},${f.y1},${f.x2},${f.y2}]`;throw new we(`Bounds changed from ${p(u)} to ${p(d)}`)}}if(c&&n&&!tf(n.newBounds,c))throw new we(`Position mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(n.newBounds)}`);if(l&&n&&!rf(n.newBounds,l))throw new we(`Shape mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(n.newBounds)}`)}async function Pee({logger:t,driver:e,xPath:r,elementType:o,skipVisibilityCheck:n=false}){let i=await x0(t,e,r);if(!i)throw new we(`Could not resolve ${o} via XPath: ${r}`);let{elementId:a}=i;if(!n&&!await wee(t,e,a))throw new we(`${o} resolved via XPath is not rendered: ${r}`);return i}async function Iee({target:t,driver:e,stateManager:r,logger:o}){if(!t.xPath)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);if(t.requiredRelatedElements){let s=t.requiredRelatedElements;for(let c of s){let{elementId:l,rect:u}=await Pee({logger:o,driver:e,xPath:c.xPath,elementType:"related element",skipVisibilityCheck:!!c.browserCache});if(c.browserCache){let d={x1:u.x,y1:u.y,x2:u.x+u.width,y2:u.y+u.height};await I0({logger:o,driver:e,stateManager:r,parentWebviewBounds:d,cache:c.browserCache});}else await xee(o,e,l,c.requirements);}}let{elementId:n,rect:i}=await Pee({logger:o,driver:e,xPath:t.xPath,elementType:"element",skipVisibilityCheck:t.type==="WEBVIEW"}),a={x1:i.x,y1:i.y,x2:i.x+i.width,y2:i.y+i.height};if(t.type==="WEBVIEW"){let s=await I0({logger:o,driver:e,stateManager:r,parentWebviewBounds:a,cache:t.browserCache});return {type:"WEBVIEW",bounds:s,cache:t}}return await xee(o,e,n,t.requirements,{originalBounds:t.bounds?{x1:t.bounds[0],y1:t.bounds[1],x2:t.bounds[2],y2:t.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...t,bounds:[a.x1,a.y1,a.x2,a.y2]}}}function Nee({aiResponse:t,description:e,emulatorState:r}){let o=r.graph.idToPrunedElement.get(t.id);if(!o)throw new Error(`Could not find node with id: ${t.id}`);let n=xw(o);if(!n)throw new Error(`Could not determine bounds for element with id: ${t.id}, description: ${e}`);let i=r.graph.idToOriginalElement.get(t.id);if(!i)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${t.id}, description: ${e}`);let a=fd(i),s=Pw(i),c=Oee({requirements:t.requirements,element:i}),l=(t.additionalElements??[]).map(({id:u,requirements:d})=>{let m=r.graph.idToOriginalElement.get(u);return m?{xPath:fd(m),requirements:Oee({requirements:d,element:m})}:void 0}).filter(u=>!!u);return {type:"NATIVE",bounds:n,cache:{type:"NATIVE",bounds:[n.x1,n.y1,n.x2,n.y2],resolvedDescription:e,sourceTree:r.sourceTree,xPath:a,elementOnlySerializedXml:s,requirements:c,requiredRelatedElements:l}}}function Oee({requirements:t,element:e}){let r;if((t?.positionSpecificity||t?.shapeSpecificity)&&(r=Zs(e),!r))throw new M("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:t?.textRequired?e.textContent??void 0:void 0,requiredAttributes:oUe(e,t?.attributesRequired),requiredBounds:t?.boundsRequired,position:t?.positionSpecificity?{x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,tolerance:t?.positionSpecificity}:void 0,shape:t?.shapeSpecificity?{width:r.x2-r.x1,height:r.y2-r.y1,tolerance:t?.shapeSpecificity}:void 0}}function oUe(t,e){if(t&&!(!e||e.length===0))return Object.fromEntries(e.map(r=>[r,t.getAttribute(r)]).filter(([,r])=>r!==null))}async function Lee(t,e,r,o){if(!r)return;let{requiredAttributes:n,requiredText:i,requiredBounds:a,position:s,shape:c}=r;if(i!==void 0&&i.length>0){let l=e.textContent;if(l!==i)throw new we(`Resolved element text mismatch: expected ${i}, got ${l}`)}if(n)for(let[l,u]of Object.entries(n)){let d=e.getAttribute(l)??void 0;if(d!==u)throw new we(`Attribute ${l} mismatch: expected ${u}, got ${d}`)}if(a&&o){let{originalBounds:l,newBounds:u}=o;if(!l)throw new we("Cannot validate bounds requirements without original bounds in cache");if(!(gs(l.x1,u.x1)&&gs(l.y1,u.y1)&&gs(l.x2,u.x2)&&gs(l.y2,u.y2))){let m=p=>`[${p.x1},${p.y1},${p.x2},${p.y2}]`;throw new we(`Bounds changed from ${m(l)} to ${m(u)}`)}}if(s&&o&&!tf(o.newBounds,s))throw new we(`Position mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(o.newBounds)}`);if(c&&o&&!rf(o.newBounds,c))throw new we(`Shape mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(o.newBounds)}`)}async function kee({target:t,logger:e,emulator:r}){if(!t.xPath)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);let o=await r.nativeA11yTreeJson(),n=await Iw(o,{pruneElementsOutsideBounds:void 0});if(t.requiredRelatedElements){let s=t.requiredRelatedElements;for(let c of s){let l=wQ.evaluateXPathToFirstNode(c.xPath,n.originalDocument);if(!l)throw new we(`Required related element not found for XPath: ${c.xPath}`);await Lee(e,l,c.requirements);}}let i=wQ.evaluateXPathToFirstNode(t.xPath,n.originalDocument);if(!i)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);let a=Zs(i);if(!a)throw new we(`Could not determine bounds for cached target via XPath: ${t.xPath}`);return await Lee(e,i,t.requirements,{originalBounds:t.bounds?{x1:t.bounds[0],y1:t.bounds[1],x2:t.bounds[2],y2:t.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...t,bounds:[a.x1,a.y1,a.x2,a.y2]}}}async function Fee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n}){switch(n.sourceTree){case "appium":return await Mee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n});case "native":return await Nee({aiResponse:r,description:o,emulatorState:n});default:{let i=n.sourceTree;throw new Error(`Unsupported source tree type for building iOS target cache: ${i}`)}}}async function Uee({target:t,driver:e,stateManager:r,logger:o,emulator:n}){if(t.type==="WEBVIEW"||!t.sourceTree||t.sourceTree=="appium")return await Iee({target:t,driver:e,stateManager:r,logger:o});switch(t.sourceTree){case "native":return await kee({target:t,logger:o,emulator:n});default:{let i=t.sourceTree;throw new Error(`Unsupported source tree type for resolving iOS target cache: ${i}`)}}}var Kr=class{emulator;driver;stateManager;generator;fixtures;orgId;aiSettings;emulatorSettings;aborter;constructor(e){this.stateManager=e.stateManager,this.driver=e.driver,this.emulator=e.emulator,this.aborter=e.aborter,this.fixtures=e.fixtures,this.orgId=e.orgId,this.generator=e.generator,this.aiSettings=e.aiSettings,this.emulatorSettings=e.emulatorSettings;}async findElement({logger:e,tracer:r,description:o,skipFetchingFullWebviewContent:n=false,removeWebviewContent:i=false,filterOffscreenElements:a=true,useMemory:s=false,metadata:c,cacheBustReason:l}){let u=e.child({...c});await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before locating an element with AI"});let{emulatorState:d,screenshot:m}=await r.startAsyncSection("Get emulator state",async()=>{let h=await this.stateManager.getCurrentScreenshotPngString(e);return {emulatorState:await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:n,removeWebviewContent:i,filterOffscreenElements:a}),screenshot:h}}),p;try{p=await r.startAsyncSpan("AI_LOCATOR_CALL",async h=>{l&&(h.attributes.cacheBustReason=l);let S=await this.generator.getIosElementLocation({description:o,screenXml:d.graph.xml,screenshot:m,source:c?.source==="SCROLL_TO"?"SCROLL_TO":void 0},{logger:u,loggerTags:Ie(u),abortSignal:this.aborter.controller?.signal,useMemory:s,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]});return h.result=S,S});}catch(h){throw this.throwIfAborted(),u.error({err:h},"Failed to locate element"),new Error(`ActionFailureError: Failed to locate element: ${h instanceof Error?h.message:h}`,{cause:h})}if(p.id===-1)throw new M("NoMatchingElementError",p.thoughts??"No matching element found");let f=await Fee({logger:e,driver:this.driver,aiResponse:p,description:o,emulatorState:d});return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:(f.type==="NATIVE"?f.cache.elementOnlySerializedXml:void 0)??"Unknown element"},attributes:{},subSpans:[]}),{resolvedTarget:f,thoughts:p.thoughts}}async targetingActionWithAILocator(e){let{tracer:r,action:o,command:n,description:i,cacheKey:a,targetName:s,skipFetchingFullWebviewContent:c,removeWebviewContent:l,metadata:u,logger:d,cacheBustReason:m}=e,p=await this.findElement({logger:d,tracer:r,description:i,skipFetchingFullWebviewContent:c,removeWebviewContent:l,metadata:u,cacheBustReason:m}),f=p.thoughts,h=await o(p.resolvedTarget);return nf({command:n,cacheKey:a,targetName:s,updatedCache:of(p.resolvedTarget),updatedWithAI:true,logger:d}),{result:h,thoughts:f}}async targetingActionWithCache({logger:e,tracer:r,action:o,command:n,cacheKey:i,targetName:a,cacheCopyForAttempt:s}){this.emulatorSettings?.waitForStability!==false&&await this.stateManager.waitForPageSourceStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let c=await this.resolveTargetCacheWithTracing({logger:e,tracer:r,cache:s}),l=await o(c);return nf({command:n,cacheKey:i,targetName:a,updatedCache:of(c),updatedWithAI:false,logger:e}),{result:l,thoughts:"Successfully executed preset action with cache"}}async resolveTargetCacheWithTracing({logger:e,tracer:r,cache:o,retryWithinSmartWaiting:n=true}){let{resolvedTarget:i}=await r.startAsyncSpan("CACHE_RESOLUTION",async a=>{let s=Date.now(),c;for(;!n||Date.now()-s<3e3;)try{let l=await Uee({target:o,driver:this.driver,stateManager:this.stateManager,logger:e,emulator:this.emulator});return a.attributes.serializedElement=(l.type==="NATIVE"?l.cache.elementOnlySerializedXml:void 0)??"Unknown element",{resolvedTarget:l}}catch(l){if(c=l,l instanceof we){if(!n)throw l;e.warn({err:l},"Failed to resolve target cache, retrying"),await Wa(500,this.aborter.controller?.signal);continue}throw e.error({err:l},"Failed to resolve target cache"),l}throw c});return i}async wrapTargetingAction(e){let{tracer:r,logger:o,action:n,description:i,command:a,cacheKey:s="cache",targetName:c="target",cacheIsInvalidAfterResolution:l,skipFetchingFullWebviewContent:u=false,removeWebviewContent:d=false}=e,m={commandId:a.id},p=false,f,h;if(s==="cache"&&"cache"in a&&a.cache){let S=a.cache;c==="target"&&"target"in S?h=cloneDeep(S.target):c==="fromTarget"&&"fromTarget"in S?h=cloneDeep(S.fromTarget):c==="toTarget"&&"toTarget"in S&&(h=cloneDeep(S.toTarget));}if(a.disableCache&&(o.debug({command:a},"Cache explicitly disabled for command"),p=true,f="Cache explicitly disabled",h=void 0),l&&(p=true,f=f??"Cache invalidated after resolution",h=void 0),h&&!bc(h.resolvedDescription??"",i)&&(o.info({description:i,cacheDescription:h.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=true,f="Description mismatch",h=void 0),h){let S=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements;try{let b=await this.targetingActionWithCache({logger:o,tracer:r,action:n,command:a,cacheKey:s,targetName:c,cacheCopyForAttempt:h});return _t.increment("cache_target_resolution_v2",1,["outcome:hit","platform:mobile-native",`hasRequirements:${S}`,`orgId:${this.orgId}`,"cliVersion:0.97.2"]),b}catch(b){if(this.throwIfAborted(),b instanceof M&&b.reason!=="InternalWebAgentError")throw o.error({err:b},"Failed to execute action with target cache (fatal)"),b;_t.increment("cache_target_resolution_v2",1,["outcome:miss","platform:mobile-native",`hasRequirements:${S}`,`orgId:${this.orgId}`,"cliVersion:0.97.2"]),o.warn({err:b},"Failed to execute action with target cache, retrying with AI");}}return o.info({description:i,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),await this.targetingActionWithAILocator({tracer:r,action:n,command:a,description:i,cacheKey:s,targetName:c,skipFetchingFullWebviewContent:u,removeWebviewContent:d,metadata:m,logger:o,cacheBustReason:f})}constructPerformerParams(){return {emulator:this.emulator,stateManager:this.stateManager,driver:this.driver,fixtures:this.fixtures,emulatorSettings:this.emulatorSettings,aborter:this.aborter,orgId:this.orgId,generator:this.generator,aiSettings:this.aiSettings}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}get abortSignal(){return this.aborter.controller?.signal}};var Dw=class extends Kr{async doDrag(e,r,o,n,i){let{x1:a,y1:s,x2:c,y2:l}=o.bounds,u=a+(c-a)/2,d=s+(l-s)/2;r.attributes.startPoint={x:u,y:d};let{x1:m,y1:p,x2:f,y2:h}=n.bounds,S=m+(f-m)/2,b=p+(h-p)/2;r.attributes.endPoint={x:S,y:b};let y=i?.hoverDuration??500,T=i?.dragDuration??1e3;T===0&&(T=1);let w=Math.sqrt(Math.pow(S-u,2)+Math.pow(b-d,2))/T*1e3;await this.driver.executeInNativeContext(e,async N=>{await N.execute("mobile: dragFromToWithVelocity",{fromX:u,fromY:d,toX:S,toY:b,pressDuration:y/1e3,velocity:w,holdDuration:.5});},{operationName:"dragAndDrop"});}async executeDragAndDrop({logger:e,command:r}){let o=ue();if(r.fromTarget.type!=="description"||r.toTarget.type!=="description")throw new M("UserConfigurationError","Drag and drop only supports description targets for now");let n=r.fromTarget.description,{result:i,thoughts:a}=await this.wrapTargetingAction({command:r,tracer:o,description:n,cacheKey:"cache",targetName:"fromTarget",action:async u=>u,logger:e}),s=r.toTarget.description,{result:c,thoughts:l}=await this.wrapTargetingAction({command:r,tracer:o,description:s,cacheKey:"cache",targetName:"toTarget",action:async u=>u,logger:e});return await o.startAsyncSpan("EMULATOR_INTERACTION",async u=>{await this.doDrag(e,u,i,c,{hoverDuration:r.hoverDuration,dragDuration:r.dragDuration});},{name:"Drag and drop"}),{success:true,message:`${a}
|
|
5591
|
+
}`);return a.execute(s,...n)},{operationName:"executeWebViewScript"});if(i&&typeof i=="object"&&"_failed"in i)throw new Error(`Error executing script in webview: ${i._error||"Unknown error"}`);return i}async healthcheck(){await this.driver.getWindowHandle();}};async function eee({logger:t,driverLogLevel:e="error",emulator:r,callbacks:o}){let{onStatusUpdate:n}=o,i=t.child({emulatorName:r.name}),a={platformName:"iOS","appium:noReset":true,"appium:fullReset":false,"appium:shouldTerminateApp":false,"appium:forceAppLaunch":false,"appium:autoLaunch":false,"appium:newCommandTimeout":3600,"appium:autoWebview":false,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":true,"appium:fullContextList":false,"appium:additionalWebviewBundleIds":["*"],"appium:waitForIdleTimeout":0,"appium:reduceMotion":true,"appium:settings":{customSnapshotTimeout:0,animationCoolOffTimeout:0},...r.extraCapabilities};n("Starting Appium session...");let s={capabilities:a},c=await vw.init({logger:i,logLevel:e,callbacks:{...o,restartWda:r.restartWda?async l=>{await r.restartWda?.(l);}:void 0,onFailure:async({err:l,attempt:u})=>{let d=Vv(l),m=u<3&&d;return m&&i.warn({err:l},"Appium driver manifest race detected on first attempt, restarting Appium and retrying"),{shouldRetry:m}}},wdioOpts:s});return i.info({capabilities:a,emulatorName:r.name},"Started Appium driver"),c}async function tee({wdaUrl:t,token:e}){try{let r=new AbortController;return setTimeout(()=>r.abort(),3e3),await fetch(t+"/status",{headers:{Authorization:`Bearer ${e}`},signal:r.signal}),!0}catch{return false}}var Cw={"appium:waitForIdleTimeout":2,"appium:commandTimeouts":"30000","appium:skipLogCapture":true,"appium:disableAutomaticScreenshots":true,"appium:simpleIsVisibleCheck":true};var yFe=["[com.apple.","loadConfigurationForEnvironment"],EFe=["com.apple.Accessibility","com.apple.news","com.apple.locationd","NewsToday","NewsTodayIntents","apsd","APSConfiguration","APSOutgoingQueue","APSCourierConnection","APSNetworkMonitor","loadConfigurationForEnvironment"],TFe=new Set(["D","Df","Db"]),vFe=new Set(["I"]),CFe=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+\s+(\S+)\s+/,AFe="https://storage.googleapis.com/mobile-drivers/WebDriverAgentRunner-Build-Sim-arm64-v10.4.5.zip",oee=6e4;function wFe(t){let e=CFe.exec(t)?.[1];if(!e)return false;let r=yFe.some(n=>t.includes(n)),o=EFe.some(n=>t.includes(n));return TFe.has(e)?r||o:vFe.has(e)?o:false}async function nee({wdaUrl:t,token:e,limbarClient:r,logger:o,onStatusUpdate:n}){await tee({wdaUrl:t,token:e})||(n("Starting WebDriverAgent..."),o.debug("WDA is not running on the iOS emulator"),await r.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),o.debug("WDA launched"));}var fb=class t{apiClient;name;extraCapabilities;limbarToken;limbarWebRtcUrl;limbarApiUrl;limbarWdaUrl;limbarRegion;limbarClient;onStatusUpdate;logStream=void 0;constructor({apiClient:e,limbarToken:r,limbarWebRtcUrl:o,limbarApiUrl:n,limbarWdaUrl:i,limbarRegion:a,emulatorName:s,limbarClient:c,onStatusUpdate:l}){this.apiClient=e,this.name=s,this.limbarToken=r,this.limbarWebRtcUrl=o,this.limbarApiUrl=n,this.limbarWdaUrl=i,this.limbarRegion=a,this.limbarClient=c,this.extraCapabilities={...Cw,"appium:automationName":"@limrun/xcuitest","appium:webDriverAgentUrl":this.limbarWdaUrl,"appium:wdaLocalPort":443,"appium:useNewWDA":false,"appium:usePreinstalledWDA":true,"appium:limInstanceApiUrl":n,"appium:limInstanceToken":r,"appium:wdaRequestHeaders":{Authorization:`Bearer ${r}`}},this.onStatusUpdate=l;}static async init(e){let{apiClient:r,logger:o,creationOpts:n,logLevel:i,orgId:a,sessionId:s,onStatusUpdate:c,onConnectionStateChange:l}=e,u=n.appToInstall?.channel,d=n.appToInstall?.tag;c("Creating iOS emulator");let{token:m,webRtcUrl:p,wdaUrl:f,apiUrl:h,id:S,region:b,appDownloadUrl:y,appMd5:T}=await r.createIosEmulator({...n,hostname:hostname(),sessionId:s,installAppOnClient:true});o.info({emulatorName:S,region:b,sessionId:s},"ios instance creation ok"),c("Connecting to iOS emulator...");let v;try{v=await _t.recordDuration({fn:async()=>await Q(createInstanceClient({apiUrl:h,token:m,logLevel:i}),{milliseconds:oee,message:`Timed out after ${oee}ms connecting to iOS emulator ${S}`}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${a}`]}),l&&v.onConnectionStateChange(l),c("Installing WebDriverAgent...");let w=v;return await _t.recordDuration({fn:async()=>{await aee({limbarClient:w,url:AFe,md5:void 0,logger:o,emulatorName:S,assetLabel:"WebDriverAgent"});},name:"test_event_duration",tags:["name:limbar-wda-install","clientOs:ios",`orgId:${a}`]}),await nee({wdaUrl:f,token:m,limbarClient:w,logger:o,onStatusUpdate:c}),y&&(c(`Installing iOS app${u?` with channel ${u}`:""}${d?` and tag ${d}`:""}`),await _t.recordDuration({fn:async()=>{await aee({limbarClient:w,url:y,md5:T,logger:o,emulatorName:S,assetLabel:"iOS app"});},name:"test_event_duration",tags:["name:limbar-app-install","clientOs:ios",`orgId:${a}`]})),(async()=>{try{let[N,D]=await Promise.allSettled([Fm("limserver-1.limrun.net"),Fm("125.253.92.199")]);o.info({limserver:N.status==="fulfilled"?N.value:N.reason,ip125:D.status==="fulfilled"?D.value:D.reason},"Limbar network diagnostics");}catch(N){o.warn({err:N},"Failed to run network diagnostics");}})(),new t({apiClient:r,limbarToken:m,limbarWebRtcUrl:p,limbarApiUrl:h,limbarWdaUrl:f,limbarRegion:b,emulatorName:S,limbarClient:w,onStatusUpdate:c})}catch(w){throw o.warn({err:w,emulatorName:S},"iOS emulator init failed after creation; cleaning up remote instance"),await RFe({apiClient:r,limbarClient:v,id:S,logger:o}),w}}tap(e,r){return this.limbarClient.tap(e,r)}nativeA11yTreeJson(){return this.limbarClient.elementTree()}async screenshotPngBase64(){let e=await this.limbarClient.screenshot(),r=Buffer.from(e.base64,"base64"),o=yN.decode(r),n=new PNG({width:o.width,height:o.height});return n.data=Buffer.from(o.data),PNG.sync.write(n).toString("base64")}listApps(){return this.limbarClient.listApps()}terminateApp(e){return this.limbarClient.terminateApp(e)}setOrientation(e){return this.limbarClient.setOrientation(e==="LANDSCAPE"?"Landscape":"Portrait")}pressKey(e){return this.limbarClient.pressKey(e)}async resetSettings(){let e=await this.limbarClient.simctl(["privacy","booted","reset","all"]).wait();if(e.code!==0)throw new Error(`simctl privacy reset returned non-zero exit code: ${e.code} stderr: ${e.stderr}`)}async startScreenRecording(){await this.limbarClient.startRecording({quality:RecordingQuality.Q5});}async stopScreenRecording(e){await this.limbarClient.stopRecording({localPath:e});}addSyslogListener(e){this.logStream||(this.logStream=this.limbarClient.streamSyslog());let r=o=>{wFe(o)||e(o);};return this.logStream.on("line",r),()=>{this.logStream?.off("line",r);}}async restartWda(e){await nee({wdaUrl:this.limbarWdaUrl,token:this.limbarToken,limbarClient:this.limbarClient,logger:e,onStatusUpdate:this.onStatusUpdate});}async close(){try{this.logStream?.stop();}catch{}try{this.limbarClient.disconnect();}catch{}await this.apiClient.deleteIosEmulator(this.name);}};async function RFe(t){let{apiClient:e,limbarClient:r,id:o,logger:n}=t;if(r)try{r.disconnect();}catch(i){n.warn({err:i,emulatorName:o},"Failed to disconnect limbar client during init cleanup");}try{await e.deleteIosEmulator(o);}catch(i){n.warn({err:i,emulatorName:o},"Failed to delete iOS emulator during init cleanup");}}var iee=12e4,Aw=6,_Fe=1e3;async function aee(t){let{limbarClient:e,url:r,md5:o,logger:n,emulatorName:i,assetLabel:a}=t,s;for(let c=1;c<=Aw;c++)try{await Q(e.installApp(r,{md5:o}),{milliseconds:iee,message:`Timed out after ${iee}ms installing ${a} on emulator ${i}`});return}catch(l){if(s=l,c===Aw)break;let u=_Fe*2**(c-1);n.warn({url:r,err:l,emulatorName:i,assetLabel:a,attempt:c,maxAttempts:Aw,backoffMs:u},`Failed to install ${a} on Limbar emulator; retrying after backoff`),await ce(u);}throw n.error({url:r,err:s,emulatorName:i,assetLabel:a,maxAttempts:Aw},`Failed to install ${a} on Limbar emulator (no more retries)`),new M("UserConfigurationError",`Failed to install ${a} on emulator ${i}: ${s}`)}var MFe=C__default.array(C__default.object({bundle_id:C__default.string(),name:C__default.string()})),Rw=class{constructor(e){this.udid=e;}async exec(e,r=[]){return new Promise((o,n)=>{execFile$1("idb",[...e,"--udid",this.udid,...r],(i,a)=>{i?n(i):o(a.trim());});})}async execBuffer(e,r=[]){return new Promise((o,n)=>{execFile$1("idb",[...e,"--udid",this.udid,...r],{encoding:"buffer",maxBuffer:10*1024*1024},(i,a)=>{i?n(i):o(a);});})}async describeDevice(){return this.exec(["describe"])}async tap({x:e,y:r}){await this.exec(["ui","tap"],[Math.round(e).toString(),Math.round(r).toString()]);}async elementTree(){return this.exec(["ui","describe-all"])}async listApps(){let e=await this.exec(["list-apps","--json"]),r=JSON.parse(e);return MFe.parse(r).map(o=>({bundleId:o.bundle_id,name:o.name}))}async terminate(e){await this.exec(["terminate"],[e]);}async pressKey(e){await this.exec(["ui","press"],[e]);}async screenshot(){let e=await this.execBuffer(["screenshot"],["-"]),r=Buffer.from([137,80,78,71,13,10,26,10]);if(e.length<r.length||!e.subarray(0,r.length).equals(r))throw new Error(`idb screenshot returned invalid PNG data (got ${e.length} bytes)`);return e.toString("base64")}async disconnect(){await this.exec(["disconnect"]);}};async function hb(t){try{return (await new Simctl().getDeviceTypes()).filter(o=>o.includes("iPhone"))}catch(e){return t.warn({err:e},"Got error listing local iPhone device types, returning empty list"),[]}}var _w=class t{name;extraCapabilities;simctl;idb;constructor({name:e,simctl:r,idb:o}){this.name=e,this.simctl=r,this.idb=o,this.extraCapabilities={...Cw,"appium:automationName":"XCUITest","appium:udid":r.udid??void 0};}static async init(e,r){let o=new Simctl,n=r.emulatorName??`momentic-${Date.now()}`,i=await hb(e);if(!i.includes(r.deviceType))throw new M("UserConfigurationError",`Invalid device type: ${r.deviceType}. Valid device types are: ${i.join(", ")}. If you are sure the device type is correct, please make sure it is installed and available in Xcode.`);let a;try{let s=await o.createDevice(n,r.deviceType,"26.3");o.udid=s,a=async()=>{try{await o.shutdownDevice();}catch{}await o.deleteDevice();},await o.bootDevice(),await o.startBootMonitor({timeout:12e4}),r.appFilePath&&await o.installApp(r.appFilePath);let c=new Rw(s);return new t({name:n,simctl:o,idb:c})}catch(s){throw await a?.(),s}}async tap(e,r){await this.idb.tap({x:e,y:r});}async nativeA11yTreeJson(){return this.idb.elementTree()}async screenshotPngBase64(){return this.idb.screenshot()}async listApps(){return this.idb.listApps()}async terminateApp(e){await this.idb.terminate(e);}async pressKey(e){await this.idb.pressKey(e);}async resetSettings(){}async close(){try{await this.idb.disconnect();}catch{}try{await this.simctl.shutdownDevice();}catch{}await this.simctl.deleteDevice();}};var xFe=5e3;async function ef({creationOpts:t,apiClient:e,logger:r,driverLogLevel:o,orgId:n,sessionId:i,callbacks:a}){let s=Date.now();r.info("Starting ios driver creation");let{onLimbarConnectionStateChange:c,onStatusUpdate:l}=a,u=[],d=async()=>{let p=u.toReversed();for(let f of p)try{await Q(f(),{milliseconds:xFe,fallback:()=>{}});}catch(h){if(AT(h))continue;r.warn({err:h},"Error running cleanup task");}};l("Starting iOS emulator creation...");let m;switch(t.type){case "remote":{m=await fb.init({apiClient:e,logger:r,creationOpts:t,orgId:n,sessionId:i,onStatusUpdate:l,onConnectionStateChange:c,logLevel:o});break}case "local":{m=await _w.init(r,t);break}}u.push(async()=>{await m.close();});try{let p=await eee({logger:r,driverLogLevel:o,emulatorStart:s,emulator:m,apiClient:e,creationOpts:t,orgId:n,sessionId:i,callbacks:a});return u.push(()=>p.close()),p.executeInNativeContext(r,f=>f.getPageSource(),{operationName:"Warm up Appium cache"}).catch(()=>{}),{driver:p,emulator:m,limbarParams:m instanceof fb?{token:m.limbarToken,webRtcUrl:m.limbarWebRtcUrl,region:m.limbarRegion,osVersion:t.type==="remote"?t.osVersion:void 0}:void 0,cleanup:d}}catch(p){throw await d(),new Error(`Failed to start Appium driver: ${p}`,{cause:p})}}var OFe=100,NFe=2500,cee=4e3,DFe="...";async function Mw({emulator:t,onLogs:e}){if(!t.addSyslogListener)return;let r=create({fetcher:async n=>{e(n);},resolver:()=>{},scheduler:windowedFiniteBatchScheduler({windowMs:NFe,maxBatchSize:OFe})}),o=n=>{let i=n.toString().trim();i.length!==0&&(i.length>cee&&(i=i.slice(0,cee)+DFe),r.fetch(i).catch(()=>{}));};return t.addSyslogListener(o)}var uee="NATIVE_APP";var kFe=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),FFe=new Set([]),UFe=new Set(["name","label","traits"]),BFe=new Set(["live-region","drawing-order"]),VFe=new Set(["visible","enabled"]);function dee(t){let e={},r=t.tagName,o=reduce(t.attributes,(n,i)=>(n[i.name]=i.value,n),{});for(let[n,i]of Object.entries(o))kFe.has(n)||n==="class"&&r===i||n==="focusable"&&i==="true"&&o.clickable==="true"||FFe.has(n)&&i==="false"||UFe.has(n)&&i===""||VFe.has(n)&&i==="true"||BFe.has(n)&&i==="0"||(e[n]=i);return e.name&&e.label&&e.name===e.label&&delete e.label,e.name&&e.value&&e.name===e.value&&delete e.value,e}function Zs(t){let e=t.getAttribute("x"),r=t.getAttribute("y"),o=t.getAttribute("width"),n=t.getAttribute("height");if(e===null||r===null||o===null||n===null)return;let i=parseFloat(e),a=parseFloat(r),s=parseFloat(o),c=parseFloat(n);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(c)))return {x1:i,y1:a,x2:i+s,y2:a+c}}function R0(t,e){let{x1:r,y1:o,x2:n,y2:i}=e;t.setAttribute("bounds",`[${r},${o},${n},${i}]`);}function zFe(t){let e=t.match(/\[([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\]/);if(!e)return;let r=parseFloat(e[1]),o=parseFloat(e[2]),n=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(r)||isNaN(o)||isNaN(n)||isNaN(i)||n<r||i<o))return {x1:r,y1:o,x2:n,y2:i}}function xw(t){let e=t.getAttribute("bounds");if(e)return zFe(e)}function mee(t,e){if(!e)return true;let r=Zs(t);return r?_0(r,e):true}function _0(t,e){if(!e)return true;let{x1:r,y1:o,x2:n,y2:i}=t;return !(n<e.left||r>e.right||i<e.top||o>e.bottom)}function Pw(t){let e=t.cloneNode(true);for(let r of Array.from(e.children)){let o=r;for(let n of Array.from(o.children))o.removeChild(n);}return e.outerHTML}var pee=new Set(["XCUIElementTypeWebView"]);function WFe(t){if(pee.has(t.tagName))return true;let e=t.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let r=e.match(/UUID=([A-F0-9-]+)/),o=e.match(/WebViewProcessID=(\d+)/);if(r&&o)return true}return false}function qFe(t){return t.startsWith("XCUIElementType")?t.substring(15):t}function fee({state:t,originalElement:e,prunedElement:r,isInWebview:o,idInWebview:n}){let{idCounter:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c}=t,l=i.value++;r.setAttribute("id",String(l)),a.set(l,r),o?c.set(l,n):s.set(l,e);}function hee(t){if(!pee.has(t.tagName)&&t.tagName==="XCUIElementTypeOther"&&t.hasAttribute("name")&&t.hasAttribute("label"))return t;for(let e of Array.from(t.children)){let r=hee(e);if(r)return r}}function KFe({webviewNativeRootBounds:t,webviewDocumentRootBounds:e}){let r=t.x1-e.x,o=t.y1-e.y;if(!Number.isFinite(r)||!Number.isFinite(o))return t;let n=t.x2-t.x1,i=t.y2-t.y1;return {x1:r,y1:o,x2:r+n,y2:o+i}}function gee(t,e,r,o){let{document:n}=r,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=o;if(e.type==="element"){let s=n.createElement(e.role||e.tag);if(e.name&&s.setAttribute("name",e.name),e.description&&s.setAttribute("description",e.description),e.classes&&e.classes.length>0&&s.setAttribute("classes",e.classes.join(" ")),e.attrs)for(let[u,d]of Object.entries(e.attrs))s.setAttribute(u,d);let c=e.boundingRect,l={x1:i.x1+c.x,y1:i.y1+c.y,x2:i.x1+c.x+c.width,y2:i.y1+c.y+c.height};if(!_0(l,a))return;R0(s,l),fee({state:r,prunedElement:s,isInWebview:true,idInWebview:e.momenticWebviewElementId}),t.appendChild(s);for(let u of e.children)gee(s,u,r,o);}else if(e.type==="text"){let s=n.createElement("text");t.appendChild(s);let c=n.createTextNode(e.text);s.appendChild(c);}}function See(t,e,r,o){let{pruneElementsOutsideBounds:n}=o,{document:i}=r;fee({state:r,originalElement:t,prunedElement:e,isInWebview:false});let a=dee(t);for(let[l,u]of Object.entries(a))e.setAttribute(l,u);let s=Zs(t);if(s&&R0(e,s),WFe(t)){let{removeWebviewContent:l,injectedWebviewContent:u}=o;if(l)return;if(u&&Zs(t)){let m=hee(t),p=m?Zs(m):void 0;if(m&&p){r.webviewRootElement=m,r.webviewRootBounds=p,gee(e,u.root,r,{parentFrameBounds:KFe({webviewNativeRootBounds:p,webviewDocumentRootBounds:u.rootBoundingBox}),pruneElementsOutsideBounds:n});return}}}let c=Array.from(t.childNodes??[]);for(let l of c){let u=l.nodeType;if(u===3){let d=l.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=l;if(!mee(d,n))continue;let m=i.createElement(qFe(d.tagName));See(d,m,r,o),e.appendChild(m);}}}async function M0(t,e,r){let o=t.parseFromString("<AppiumAUT/>","text/xml"),n=new Map,i=new Map,a=new Map,s={document:o,idToPrunedElement:n,idToOriginalElement:i,idToIdInWebview:a,idCounter:{value:0},webviewRootElement:void 0,webviewRootBounds:void 0},c=o.documentElement;See(e,c,s,r);let l=new XMLSerializer().serializeToString(o),u=await Tke.format(l,{parser:"xml",plugins:[Eke],printWidth:120,tabWidth:1,singleAttributePerLine:false});return {prunedDocument:o,idToPrunedElement:n,idToOriginalElement:i,idToIdInWebview:a,webviewRootElement:s.webviewRootElement,webviewRootBounds:s.webviewRootBounds,prunedXml:u}}async function bee(t,e){let r=new DOMParser,o=r.parseFromString(t,"text/xml"),n=o.documentElement;if(!n)throw new Error("No root element found in XML");if(n.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c,webviewRootElement:l,webviewRootBounds:u}=await M0(r,n,e);return {xml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:c,webviewRootElement:l,webviewRootBounds:u,originalDocument:o}}var yee=(R=>(R.GenericElement="GenericElement",R.Any="Any",R.Other="Other",R.Application="Application",R.Group="Group",R.Window="Window",R.Sheet="Sheet",R.Drawer="Drawer",R.Alert="Alert",R.Dialog="Dialog",R.Button="Button",R.RadioButton="RadioButton",R.RadioGroup="RadioGroup",R.CheckBox="CheckBox",R.DisclosureTriangle="DisclosureTriangle",R.PopUpButton="PopUpButton",R.ComboBox="ComboBox",R.MenuButton="MenuButton",R.ToolbarButton="ToolbarButton",R.Popover="Popover",R.Keyboard="Keyboard",R.Key="Key",R.NavigationBar="NavigationBar",R.TabBar="TabBar",R.TabGroup="TabGroup",R.Toolbar="Toolbar",R.StatusBar="StatusBar",R.Table="Table",R.TableRow="TableRow",R.TableColumn="TableColumn",R.Outline="Outline",R.OutlineRow="OutlineRow",R.Browser="Browser",R.CollectionView="CollectionView",R.Slider="Slider",R.PageIndicator="PageIndicator",R.ProgressIndicator="ProgressIndicator",R.ActivityIndicator="ActivityIndicator",R.SegmentedControl="SegmentedControl",R.Picker="Picker",R.PickerWheel="PickerWheel",R.Switch="Switch",R.Toggle="Toggle",R.Link="Link",R.Image="Image",R.Icon="Icon",R.SearchField="SearchField",R.ScrollView="ScrollView",R.ScrollBar="ScrollBar",R.StaticText="StaticText",R.TextField="TextField",R.SecureTextField="SecureTextField",R.DatePicker="DatePicker",R.TextView="TextView",R.Menu="Menu",R.MenuItem="MenuItem",R.MenuBar="MenuBar",R.MenuBarItem="MenuBarItem",R.Map="Map",R.WebView="WebView",R.IncrementArrow="IncrementArrow",R.DecrementArrow="DecrementArrow",R.Heading="Heading",R.Cell="Cell",R))(yee||{}),Eee=C__default.lazy(()=>C__default.object({AXFrame:C__default.string(),AXUniqueId:C__default.string().nullable(),AXLabel:C__default.string().nullable(),AXValue:C__default.string().nullable(),frame:C__default.object({x:C__default.number(),y:C__default.number(),width:C__default.number(),height:C__default.number()}),role:C__default.string(),role_description:C__default.string(),subrole:C__default.string().nullable(),type:C__default.nativeEnum(yee),title:C__default.string().nullable(),help:C__default.string().nullable(),content_required:C__default.boolean(),custom_actions:C__default.array(C__default.string()),enabled:C__default.boolean(),children:C__default.array(Eee).default([])}));function XFe(t){return C__default.array(Eee).parse(JSON.parse(t))}async function Iw(t,e){let r=new DOMParser,o=XFe(t),n=JFe(r,o),{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s}=await M0(r,n.documentElement,{removeWebviewContent:false,injectedWebviewContent:void 0,pruneElementsOutsideBounds:e.pruneElementsOutsideBounds});return {xml:i,idToPrunedElement:a,idToOriginalElement:s,originalDocument:n,webviewRootElement:void 0,idToIdInWebview:new Map,webviewRootBounds:void 0}}function JFe(t,e){let r=t.parseFromString("<hierarchy/>","text/xml"),o=r.documentElement;for(let n=0;n<e.length;n++){let i=e[n],a=Tee(i,r);o.appendChild(a);}return r}function Tee(t,e){let r=t.type,o=e.createElement(r);if(o.setAttribute("type",r),o.setAttribute("x",String(t.frame.x.toFixed(2))),o.setAttribute("y",String(t.frame.y.toFixed(2))),o.setAttribute("width",String(t.frame.width.toFixed(2))),o.setAttribute("height",String(t.frame.height.toFixed(2))),t.AXLabel!==null&&o.setAttribute("label",t.AXLabel),t.AXValue!==null&&o.setAttribute("value",t.AXValue),t.title!==null&&o.setAttribute("title",t.title),t.help!==null&&o.setAttribute("help",t.help),o.setAttribute("enabled",String(t.enabled)),t.children)for(let n=0;n<t.children.length;n++){let i=t.children[n],a=Tee(i,e);o.appendChild(a);}return o}function fd(t){let e=[],r=t;for(;r;){let o=r.parentElement;if(!o||o.tagName==="AppiumAUT"){e.unshift(`${r.tagName}[1]`);break}let n=r.tagName,i=Array.from(o.children).filter(s=>s.tagName===n),a=1;for(let s=0;s<i.length;s++)if(i[s]===r){a=s+1;break}e.unshift(`${n}[${a}]`),r=o;}return `/${e.join("/")}`}var Ow=class t{driver;emulator;options;aborter;constructor({driver:e,emulator:r,aborter:o,options:n}){this.driver=e,this.emulator=r,this.aborter=o,this.options=n;}static async init({driver:e,emulator:r,aborter:o,options:n}){return new t({driver:e,aborter:o,emulator:r,options:n})}async getContexts(e){let r=await this.driver.executeInNativeContext(e,async n=>await n.getContexts({}),{operationName:"getContexts"}),o=r.filter(n=>n!==uee);return {contexts:r.map(n=>n),webviews:o}}async getRawScreenshotBase64({logger:e,totalAttempts:r=3,signal:o}){let n=ue(),i=o??this.aborter.controller?.signal;return await n.startAsyncSpan("EMULATOR_READ_STATE",async()=>await lp(e,()=>this.emulator.screenshotPngBase64(),{maxAttempts:r,signal:i,operationName:"takeScreenshot"}),{name:"Take screenshot",signal:i,timeoutMs:3e4})}async getCurrentScreenshotPngString(e){return `data:image/png;base64,${await this.getRawScreenshotBase64({logger:e,totalAttempts:1})}`}async waitForScreenshotStability({logger:e,timeoutMs:r,signal:o,reason:n,tolerancePercent:i=1}){await ue().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=n;let s=Mm({signal:o,timeoutMs:r}),c,l=false;for(;!s.aborted;){let u=Date.now();if(c)try{let m=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});if(cc(c,m)<=i){l=!0;break}c=m;}catch(m){e.warn({err:m},"Failed to get screenshot during stability wait");}else try{c=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});}catch(m){e.warn({err:m},"Failed to get initial screenshot during stability wait");}let d=Math.max(250,Date.now()-u);await Wa(Math.min(1e4,d),s);}l||(a.attributes.timedOut=true,e.warn({purpose:n},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({logger:e,timeoutMs:r,signal:o,reason:n}){await ue().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=n;let a=Mm({signal:o,timeoutMs:r}),s,c=false;for(;!a.aborted;){let l,u=Date.now();try{l=await Q(this.emulator.nativeA11yTreeJson(),{milliseconds:1e4,signal:a,message:"Getting the native accessibility tree timed out after 10s"});let m=createHash("md5").update(l).digest("hex");if(s&&s===m){c=!0;break}s=m;}catch(m){e.warn({err:m},"Failed to get page source during stability wait");}let d=Math.max(250,Date.now()-u);await Wa(Math.min(1e4,d),a);}c||(i.attributes.timedOut=true,e.warn({purpose:n},"Timed out waiting for page source stability"));});}async getActiveWebview(e){let o=(await this.getContexts(e)).webviews;if(o.length>1)throw new M("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return o[0]}async getActiveWebviewContent(e){let r=await this.getActiveWebview(e);if(!r)return;this.throwIfAborted();let o=await this.driver.executeWebViewScript(e,r,n=>n.dumpA11yTree());return {context:r,...o}}async getDomState(e,r){let n=r?.filterOffscreenElements??true?await this.getViewportBounds(e):void 0,i;if(!r?.skipFetchingFullWebviewContent)try{i=await this.getActiveWebviewContent(e);}catch(c){e.error({err:c},"Could not get webview info to get the nested DOM state");}if(this.throwIfAborted(),!i&&this.options?.disableMomenticAccessibilityTree){let c=await this.getNativePageSource();this.throwIfAborted();let l=await Iw(c,{pruneElementsOutsideBounds:n});return {sourceTree:"native",graph:l,webviewContent:void 0}}let a=await this.getAppiumPageSource(e);return this.throwIfAborted(),{graph:await bee(a,{injectedWebviewContent:i,removeWebviewContent:r?.removeWebviewContent,pruneElementsOutsideBounds:n}),sourceTree:"appium",webviewContent:i}}async getNativePageSource(){return await ue().startAsyncSpan("EMULATOR_READ_STATE",async()=>this.emulator.nativeA11yTreeJson(),{name:"Get iOS page source",signal:this.aborter.controller?.signal,timeoutMs:3e4})}async getAppiumPageSource(e,r){let o=r??this.aborter.controller?.signal;return await ue().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(e,i=>i.getPageSource(),{signal:o,operationName:"getPageSource"}),{name:"Get page source",signal:o,timeoutMs:3e4})}async getViewportBounds(e){let r=await this.driver.executeInNativeContext(e,async o=>o.getWindowRect(),{operationName:"getViewportBounds"});return {left:r.x,top:r.y,right:r.x+r.width,bottom:r.y+r.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};async function Cee({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,throwIfAborted:a,abortSignal:s}){let c=ue(),l=15,u=t.timeoutSecs?t.timeoutSecs*1e3:5e3,d=UT(u),m=Date.now(),p=0,f,h=false,S;for(;p<l&&!h;){a(),h||f&&f-m>=u&&(h=true),p!==0&&await ce(d,s),f=Date.now();try{let b="",y="";await c.startAsyncSpan("EMULATOR_READ_STATE",async()=>{b=await n(),y=await i();},{name:"Get emulator state"});let T=await r.evaluateIosAssertion({assertion:t.assertion,screenXml:b,screenshot:y},{logger:e,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["ios-assertion"]});if(T.result)return {success:T.result,message:T.thoughts};{let v=`AssertionFailureError: ${T.thoughts}`;S=new Error(v);}}catch(b){a(),e.info({err:b},`AI check assert attempt ${p} failed, retrying...`),S=b instanceof Error?b:new Error(`${b}`);}finally{p++;}}return {success:false,message:S?.message}}async function Aee({command:t,logger:e,generator:r,aiSettings:o,getEmulatorDomState:n,getScreenshotBase64:i,abortSignal:a}){if(!t.goal.trim())throw new M("ActionFailureError","Cannot perform AI extraction without goal");if(t.schema){let u=ym(t.schema);if(u)throw new M("UserConfigurationError",u)}let s=ue(),c="",l="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{c=await n(),l=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await r.getIosTextExtraction({goal:t.goal,emulatorState:c,returnSchema:t.schema,screenshot:`data:image/png;base64,${l}`},{disableCache:!!t.disableCache,abortSignal:a,loggerTags:Ie(e),agentConfigVersion:o.agentConfig?.["ios-text-extraction"]});if(u.result=d,Hv({tracer:s,span:u,screenshot:l,emulatorState:c,logger:e}),d.result==="NOT_FOUND")return {success:!1,message:"No relevant data found for extraction goal on this page"};if(d.thoughts?.includes("MaxGenerationLengthExceededError"))throw new M("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=j(d);throw m.includes("MaxGenerationLengthExceededError")?new M("UserConfigurationError","You tried to extract too much data. Please rephrase your query to limit the results returned or use a JavaScript step instead."):m.includes("AIProviderError")&&m.includes("time")?new M("AIProviderError","The AI provider responded with an error. This may be because you tried to extract too much data. Please limit extraction results to 2000 characters.",{errOptions:{cause:d}}):d}})}function Bc(t){let{x1:e,y1:r,x2:o,y2:n}=t.bounds;return {left:e,top:r,width:o-e,height:n-r}}var hs="element-6066-11e4-a52e-4f735466cecf";function gs(t,e){return Math.abs(t-e)<1}function tf(t,e){let r=e.x2-e.x1,o=(e.x1+e.x2)/2,n=(t.x1+t.x2)/2;if(!rs(e.tolerance,o,n,Math.min(1,r)))return false;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(t.y1+t.y2)/2;return rs(e.tolerance,a,s,Math.min(1,i))}function rf(t,e){let r=t.x2-t.x1,o=t.y2-t.y1;return rs(e.tolerance,e.width,r,Math.min(1,e.width))?rs(e.tolerance,e.height,o,Math.min(1,e.height)):false}function of(t){return t.type==="WEBVIEW",t.cache}function nf(t){let{command:e,cacheKey:r="cache",targetName:o="target",updatedCache:n}=t;fM(e)&&(e[r]={...e[r],[o]:Hd.parse(n)},t.updatedWithAI&&(e[r].updatedAt=new Date,e[r].updatedAtLoggerTags=Ie(t.logger)));}var gb="name";async function wee(t,e,r){return await e.executeInNativeContext(t,o=>o.isElementDisplayed(r),{operationName:"isElementRendered"})}async function af(t,e,r,o){return await e.executeInNativeContext(t,n=>n.getElementAttribute(r,o),{operationName:"getAttributeFromIosElement"})}async function x0(t,e,r){return await e.executeInNativeContext(t,async o=>{try{let n=await o.findElement("xpath",r);if(!n)return null;let i=n[hs];if(!i)return null;let a=await o.getElementRect(i);return {elementId:i,rect:a}}catch{return null}},{operationName:"findElementByXPath"})}async function Ree(t,e,r){let o=fd(r),n=await x0(t,e,o);if(n)return {xPath:o,...n}}async function P0({logger:t,emulatorState:e,driver:r,idInWebview:o,requirements:n}){let i=e.graph.webviewRootElement?fd(e.graph.webviewRootElement):void 0;if(!i||!e.webviewContent||!e.graph.webviewRootBounds)throw new Error("Cannot build webview target cache without webview root information");let a=await eUe({logger:t,driver:r,webviewRootBounds:e.graph.webviewRootBounds,nodeIdInWebview:o,aiGeneratedRequirements:n,webviewContent:e.webviewContent});if(!a)throw new Error("Failed to build browser cache for webview element");return {xPath:i,bounds:[e.graph.webviewRootBounds.x1,e.graph.webviewRootBounds.y1,e.graph.webviewRootBounds.x2,e.graph.webviewRootBounds.y2],browserCache:a}}async function eUe({logger:t,driver:e,webviewRootBounds:r,nodeIdInWebview:o,aiGeneratedRequirements:n,webviewContent:i}){let a=await e.executeWebViewScript(t,i.context,(c,l,u,d)=>c.generateCacheFromWebviewElementId(l,u,d),i.generatedAt,o,{attributesToFetch:n?.attributesRequired??[]});if(!a)return;let s={x:r.x1-i.rootBoundingBox.x+a.boundingBox.x,y:r.y1-i.rootBoundingBox.y+a.boundingBox.y,width:a.boundingBox.width,height:a.boundingBox.height};return {id:a.id,generatedSelectors:a.selectors,boundingBox:s,requirements:{text:n?.textRequired?a.textContent:void 0,attributes:a.attributes,boundingBox:n?.boundsRequired?s:void 0,shape:n?.shapeSpecificity?{tolerance:n.shapeSpecificity,width:a.boundingBox.width,height:a.boundingBox.height}:void 0,position:n?.positionSpecificity?{tolerance:n.positionSpecificity,x1:s.x,y1:s.y,x2:s.x+s.width,y2:s.y+s.height}:void 0}}}async function tUe(t,e,r,o){if(!o||!o.length)return;let n={};for(let i of o){let a=await af(t,e,r,i);a!==null&&(n[i]=a);}return Object.keys(n).length?n:void 0}async function _ee({logger:t,driver:e,node:r,requirements:o}){let n=await Ree(t,e,r);if(!n){t.warn("Failed to generate valid xPath selector for element");return}let{xPath:i,rect:a,elementId:s}=n,c={x1:a.x,y1:a.y,x2:a.x+a.width,y2:a.y+a.height};return {xPath:i,bounds:[c.x1,c.y1,c.x2,c.y2],requirements:{requiredText:o?.textRequired?await af(t,e,s,gb)??void 0:void 0,requiredAttributes:await tUe(t,e,s,o?.attributesRequired?.filter(l=>!(o.textRequired&&l===gb))),requiredBounds:o?.boundsRequired,position:o?.positionSpecificity?{x1:c.x1,y1:c.y1,x2:c.x2,y2:c.y2,tolerance:o?.positionSpecificity}:void 0,shape:o?.shapeSpecificity?{width:c.x2-c.x1,height:c.y2-c.y1,tolerance:o?.shapeSpecificity}:void 0}}}async function Mee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n}){let i=n.graph.idToPrunedElement.get(r.id);if(!i)throw new Error(`Could not find node with id: ${r.id}`);let a=xw(i);if(!a)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${o}`);let s=[];for(let{id:d,requirements:m}of r.additionalElements??[]){let p=n.graph.idToIdInWebview.get(d);if(p!==void 0){try{let S=await P0({logger:t,driver:e,emulatorState:n,idInWebview:p,requirements:m});s.push(S);}catch(S){t.warn({err:S},`Failed to build webview cache for related element with id: ${d}`);}continue}let f=n.graph.idToOriginalElement.get(d);if(!f){t.warn(`Could not find original element for additional element with id: ${d}`);continue}let h=await _ee({logger:t,driver:e,node:f,requirements:m});h&&s.push(h);}let c=n.graph.idToIdInWebview.get(r.id);if(c!==void 0){let d={type:"WEBVIEW",bounds:a,cache:{type:"WEBVIEW"}};try{let m=await P0({logger:t,driver:e,emulatorState:n,idInWebview:c,requirements:r.requirements});return {...d,cache:{type:"WEBVIEW",resolvedDescription:o,requiredRelatedElements:s,...m}}}catch(m){return t.warn({err:m},"Failed to build webview target cache"),d}}let l=n.graph.idToOriginalElement.get(r.id);if(!l)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${r.id}, description: ${o}`);let u=await _ee({logger:t,driver:e,node:l,requirements:r.requirements});return u?{type:"NATIVE",bounds:a,cache:{type:"NATIVE",...u,resolvedDescription:o,sourceTree:"appium",requiredRelatedElements:s,elementOnlySerializedXml:Pw(l)}}:(t.warn("Failed to generate valid cache for element"),{type:"NATIVE",cache:{type:"NATIVE"},bounds:a})}async function I0({logger:t,driver:e,stateManager:r,parentWebviewBounds:o,cache:n}){if(!n||!n.generatedSelectors)throw new we("Cache is missing required attributes");let i=await r.getActiveWebview(t);if(!i)throw new we("No active webview context found");let a=await e.executeWebViewScript(t,i,(u,d)=>u.resolveWebviewTargetCache(d),{selectors:n.generatedSelectors,attributesToFetch:Object.keys(n.requirements?.attributes??{})});if(!a)throw new we("Failed to resolve webview target using cache");let s=o.x1-a.rootBoundingBox.x+a.boundingBox.x,c=o.y1-a.rootBoundingBox.y+a.boundingBox.y,l={x1:s,y1:c,x2:s+a.boundingBox.width,y2:c+a.boundingBox.height};return n.requirements&&rUe(t,l,a,n.requirements),l}function rUe(t,e,r,o){if(!o)return;let{attributes:n,text:i,position:a,shape:s}=o;if(i!==void 0&&i.length>0&&r.textContent!==i)throw new we(`Text content mismatch: expected "${i}", got "${r.textContent}"`);if(n)for(let[c,l]of Object.entries(n)){let u=r.attributes[c];if(u!==l)throw new we(`Attribute ${c} mismatch: expected "${l}", got "${u}"`)}if(a&&!tf(e,a))throw new we(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(e)}`);if(s&&!rf(e,s))throw new we(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(e)}`)}async function xee(t,e,r,o,n){if(!o)return;let{requiredAttributes:i,requiredText:a,requiredBounds:s,position:c,shape:l}=o;if(a!==void 0&&a.length>0){let u=await af(t,e,r,gb);if(u!==a)throw new we(`Resolved element text mismatch: expected ${a}, got ${u}`)}if(i)for(let[u,d]of Object.entries(i)){let m=await af(t,e,r,u)??void 0;if(m!==d)throw new we(`Attribute ${u} mismatch: expected ${d}, got ${m}`)}if(s&&n){let{originalBounds:u,newBounds:d}=n;if(!u)throw new we("Cannot validate bounds requirements without original bounds in cache");if(!(gs(u.x1,d.x1)&&gs(u.y1,d.y1)&&gs(u.x2,d.x2)&&gs(u.y2,d.y2))){let p=f=>`[${f.x1},${f.y1},${f.x2},${f.y2}]`;throw new we(`Bounds changed from ${p(u)} to ${p(d)}`)}}if(c&&n&&!tf(n.newBounds,c))throw new we(`Position mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(n.newBounds)}`);if(l&&n&&!rf(n.newBounds,l))throw new we(`Shape mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(n.newBounds)}`)}async function Pee({logger:t,driver:e,xPath:r,elementType:o,skipVisibilityCheck:n=false}){let i=await x0(t,e,r);if(!i)throw new we(`Could not resolve ${o} via XPath: ${r}`);let{elementId:a}=i;if(!n&&!await wee(t,e,a))throw new we(`${o} resolved via XPath is not rendered: ${r}`);return i}async function Iee({target:t,driver:e,stateManager:r,logger:o}){if(!t.xPath)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);if(t.requiredRelatedElements){let s=t.requiredRelatedElements;for(let c of s){let{elementId:l,rect:u}=await Pee({logger:o,driver:e,xPath:c.xPath,elementType:"related element",skipVisibilityCheck:!!c.browserCache});if(c.browserCache){let d={x1:u.x,y1:u.y,x2:u.x+u.width,y2:u.y+u.height};await I0({logger:o,driver:e,stateManager:r,parentWebviewBounds:d,cache:c.browserCache});}else await xee(o,e,l,c.requirements);}}let{elementId:n,rect:i}=await Pee({logger:o,driver:e,xPath:t.xPath,elementType:"element",skipVisibilityCheck:t.type==="WEBVIEW"}),a={x1:i.x,y1:i.y,x2:i.x+i.width,y2:i.y+i.height};if(t.type==="WEBVIEW"){let s=await I0({logger:o,driver:e,stateManager:r,parentWebviewBounds:a,cache:t.browserCache});return {type:"WEBVIEW",bounds:s,cache:t}}return await xee(o,e,n,t.requirements,{originalBounds:t.bounds?{x1:t.bounds[0],y1:t.bounds[1],x2:t.bounds[2],y2:t.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...t,bounds:[a.x1,a.y1,a.x2,a.y2]}}}function Nee({aiResponse:t,description:e,emulatorState:r}){let o=r.graph.idToPrunedElement.get(t.id);if(!o)throw new Error(`Could not find node with id: ${t.id}`);let n=xw(o);if(!n)throw new Error(`Could not determine bounds for element with id: ${t.id}, description: ${e}`);let i=r.graph.idToOriginalElement.get(t.id);if(!i)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${t.id}, description: ${e}`);let a=fd(i),s=Pw(i),c=Oee({requirements:t.requirements,element:i}),l=(t.additionalElements??[]).map(({id:u,requirements:d})=>{let m=r.graph.idToOriginalElement.get(u);return m?{xPath:fd(m),requirements:Oee({requirements:d,element:m})}:void 0}).filter(u=>!!u);return {type:"NATIVE",bounds:n,cache:{type:"NATIVE",bounds:[n.x1,n.y1,n.x2,n.y2],resolvedDescription:e,sourceTree:r.sourceTree,xPath:a,elementOnlySerializedXml:s,requirements:c,requiredRelatedElements:l}}}function Oee({requirements:t,element:e}){let r;if((t?.positionSpecificity||t?.shapeSpecificity)&&(r=Zs(e),!r))throw new M("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:t?.textRequired?e.textContent??void 0:void 0,requiredAttributes:oUe(e,t?.attributesRequired),requiredBounds:t?.boundsRequired,position:t?.positionSpecificity?{x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,tolerance:t?.positionSpecificity}:void 0,shape:t?.shapeSpecificity?{width:r.x2-r.x1,height:r.y2-r.y1,tolerance:t?.shapeSpecificity}:void 0}}function oUe(t,e){if(t&&!(!e||e.length===0))return Object.fromEntries(e.map(r=>[r,t.getAttribute(r)]).filter(([,r])=>r!==null))}async function Lee(t,e,r,o){if(!r)return;let{requiredAttributes:n,requiredText:i,requiredBounds:a,position:s,shape:c}=r;if(i!==void 0&&i.length>0){let l=e.textContent;if(l!==i)throw new we(`Resolved element text mismatch: expected ${i}, got ${l}`)}if(n)for(let[l,u]of Object.entries(n)){let d=e.getAttribute(l)??void 0;if(d!==u)throw new we(`Attribute ${l} mismatch: expected ${u}, got ${d}`)}if(a&&o){let{originalBounds:l,newBounds:u}=o;if(!l)throw new we("Cannot validate bounds requirements without original bounds in cache");if(!(gs(l.x1,u.x1)&&gs(l.y1,u.y1)&&gs(l.x2,u.x2)&&gs(l.y2,u.y2))){let m=p=>`[${p.x1},${p.y1},${p.x2},${p.y2}]`;throw new we(`Bounds changed from ${m(l)} to ${m(u)}`)}}if(s&&o&&!tf(o.newBounds,s))throw new we(`Position mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(o.newBounds)}`);if(c&&o&&!rf(o.newBounds,c))throw new we(`Shape mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(o.newBounds)}`)}async function kee({target:t,logger:e,emulator:r}){if(!t.xPath)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);let o=await r.nativeA11yTreeJson(),n=await Iw(o,{pruneElementsOutsideBounds:void 0});if(t.requiredRelatedElements){let s=t.requiredRelatedElements;for(let c of s){let l=wQ.evaluateXPathToFirstNode(c.xPath,n.originalDocument);if(!l)throw new we(`Required related element not found for XPath: ${c.xPath}`);await Lee(e,l,c.requirements);}}let i=wQ.evaluateXPathToFirstNode(t.xPath,n.originalDocument);if(!i)throw new we(`Could not resolve cached target via XPath: ${t.xPath}`);let a=Zs(i);if(!a)throw new we(`Could not determine bounds for cached target via XPath: ${t.xPath}`);return await Lee(e,i,t.requirements,{originalBounds:t.bounds?{x1:t.bounds[0],y1:t.bounds[1],x2:t.bounds[2],y2:t.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...t,bounds:[a.x1,a.y1,a.x2,a.y2]}}}async function Fee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n}){switch(n.sourceTree){case "appium":return await Mee({logger:t,driver:e,aiResponse:r,description:o,emulatorState:n});case "native":return await Nee({aiResponse:r,description:o,emulatorState:n});default:{let i=n.sourceTree;throw new Error(`Unsupported source tree type for building iOS target cache: ${i}`)}}}async function Uee({target:t,driver:e,stateManager:r,logger:o,emulator:n}){if(t.type==="WEBVIEW"||!t.sourceTree||t.sourceTree=="appium")return await Iee({target:t,driver:e,stateManager:r,logger:o});switch(t.sourceTree){case "native":return await kee({target:t,logger:o,emulator:n});default:{let i=t.sourceTree;throw new Error(`Unsupported source tree type for resolving iOS target cache: ${i}`)}}}var Kr=class{emulator;driver;stateManager;generator;fixtures;orgId;aiSettings;emulatorSettings;aborter;constructor(e){this.stateManager=e.stateManager,this.driver=e.driver,this.emulator=e.emulator,this.aborter=e.aborter,this.fixtures=e.fixtures,this.orgId=e.orgId,this.generator=e.generator,this.aiSettings=e.aiSettings,this.emulatorSettings=e.emulatorSettings;}async findElement({logger:e,tracer:r,description:o,skipFetchingFullWebviewContent:n=false,removeWebviewContent:i=false,filterOffscreenElements:a=true,useMemory:s=false,metadata:c,cacheBustReason:l}){let u=e.child({...c});await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before locating an element with AI"});let{emulatorState:d,screenshot:m}=await r.startAsyncSection("Get emulator state",async()=>{let h=await this.stateManager.getCurrentScreenshotPngString(e);return {emulatorState:await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:n,removeWebviewContent:i,filterOffscreenElements:a}),screenshot:h}}),p;try{p=await r.startAsyncSpan("AI_LOCATOR_CALL",async h=>{l&&(h.attributes.cacheBustReason=l);let S=await this.generator.getIosElementLocation({description:o,screenXml:d.graph.xml,screenshot:m,source:c?.source==="SCROLL_TO"?"SCROLL_TO":void 0},{logger:u,loggerTags:Ie(u),abortSignal:this.aborter.controller?.signal,useMemory:s,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]});return h.result=S,S});}catch(h){throw this.throwIfAborted(),u.error({err:h},"Failed to locate element"),new Error(`ActionFailureError: Failed to locate element: ${h instanceof Error?h.message:h}`,{cause:h})}if(p.id===-1)throw new M("NoMatchingElementError",p.thoughts??"No matching element found");let f=await Fee({logger:e,driver:this.driver,aiResponse:p,description:o,emulatorState:d});return r.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:(f.type==="NATIVE"?f.cache.elementOnlySerializedXml:void 0)??"Unknown element"},attributes:{},subSpans:[]}),{resolvedTarget:f,thoughts:p.thoughts}}async targetingActionWithAILocator(e){let{tracer:r,action:o,command:n,description:i,cacheKey:a,targetName:s,skipFetchingFullWebviewContent:c,removeWebviewContent:l,metadata:u,logger:d,cacheBustReason:m}=e,p=await this.findElement({logger:d,tracer:r,description:i,skipFetchingFullWebviewContent:c,removeWebviewContent:l,metadata:u,cacheBustReason:m}),f=p.thoughts,h=await o(p.resolvedTarget);return nf({command:n,cacheKey:a,targetName:s,updatedCache:of(p.resolvedTarget),updatedWithAI:true,logger:d}),{result:h,thoughts:f}}async targetingActionWithCache({logger:e,tracer:r,action:o,command:n,cacheKey:i,targetName:a,cacheCopyForAttempt:s}){this.emulatorSettings?.waitForStability!==false&&await this.stateManager.waitForPageSourceStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let c=await this.resolveTargetCacheWithTracing({logger:e,tracer:r,cache:s}),l=await o(c);return nf({command:n,cacheKey:i,targetName:a,updatedCache:of(c),updatedWithAI:false,logger:e}),{result:l,thoughts:"Successfully executed preset action with cache"}}async resolveTargetCacheWithTracing({logger:e,tracer:r,cache:o,retryWithinSmartWaiting:n=true}){let{resolvedTarget:i}=await r.startAsyncSpan("CACHE_RESOLUTION",async a=>{let s=Date.now(),c;for(;!n||Date.now()-s<3e3;)try{let l=await Uee({target:o,driver:this.driver,stateManager:this.stateManager,logger:e,emulator:this.emulator});return a.attributes.serializedElement=(l.type==="NATIVE"?l.cache.elementOnlySerializedXml:void 0)??"Unknown element",{resolvedTarget:l}}catch(l){if(c=l,l instanceof we){if(!n)throw l;e.warn({err:l},"Failed to resolve target cache, retrying"),await Wa(500,this.aborter.controller?.signal);continue}throw e.error({err:l},"Failed to resolve target cache"),l}throw c});return i}async wrapTargetingAction(e){let{tracer:r,logger:o,action:n,description:i,command:a,cacheKey:s="cache",targetName:c="target",cacheIsInvalidAfterResolution:l,skipFetchingFullWebviewContent:u=false,removeWebviewContent:d=false}=e,m={commandId:a.id},p=false,f,h;if(s==="cache"&&"cache"in a&&a.cache){let S=a.cache;c==="target"&&"target"in S?h=cloneDeep(S.target):c==="fromTarget"&&"fromTarget"in S?h=cloneDeep(S.fromTarget):c==="toTarget"&&"toTarget"in S&&(h=cloneDeep(S.toTarget));}if(a.disableCache&&(o.debug({command:a},"Cache explicitly disabled for command"),p=true,f="Cache explicitly disabled",h=void 0),l&&(p=true,f=f??"Cache invalidated after resolution",h=void 0),h&&!bc(h.resolvedDescription??"",i)&&(o.info({description:i,cacheDescription:h.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=true,f="Description mismatch",h=void 0),h){let S=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements;try{let b=await this.targetingActionWithCache({logger:o,tracer:r,action:n,command:a,cacheKey:s,targetName:c,cacheCopyForAttempt:h});return _t.increment("cache_target_resolution_v2",1,["outcome:hit","platform:mobile-native",`hasRequirements:${S}`,`orgId:${this.orgId}`,"cliVersion:0.97.3"]),b}catch(b){if(this.throwIfAborted(),b instanceof M&&b.reason!=="InternalWebAgentError")throw o.error({err:b},"Failed to execute action with target cache (fatal)"),b;_t.increment("cache_target_resolution_v2",1,["outcome:miss","platform:mobile-native",`hasRequirements:${S}`,`orgId:${this.orgId}`,"cliVersion:0.97.3"]),o.warn({err:b},"Failed to execute action with target cache, retrying with AI");}}return o.info({description:i,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),await this.targetingActionWithAILocator({tracer:r,action:n,command:a,description:i,cacheKey:s,targetName:c,skipFetchingFullWebviewContent:u,removeWebviewContent:d,metadata:m,logger:o,cacheBustReason:f})}constructPerformerParams(){return {emulator:this.emulator,stateManager:this.stateManager,driver:this.driver,fixtures:this.fixtures,emulatorSettings:this.emulatorSettings,aborter:this.aborter,orgId:this.orgId,generator:this.generator,aiSettings:this.aiSettings}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}get abortSignal(){return this.aborter.controller?.signal}};var Dw=class extends Kr{async doDrag(e,r,o,n,i){let{x1:a,y1:s,x2:c,y2:l}=o.bounds,u=a+(c-a)/2,d=s+(l-s)/2;r.attributes.startPoint={x:u,y:d};let{x1:m,y1:p,x2:f,y2:h}=n.bounds,S=m+(f-m)/2,b=p+(h-p)/2;r.attributes.endPoint={x:S,y:b};let y=i?.hoverDuration??500,T=i?.dragDuration??1e3;T===0&&(T=1);let w=Math.sqrt(Math.pow(S-u,2)+Math.pow(b-d,2))/T*1e3;await this.driver.executeInNativeContext(e,async N=>{await N.execute("mobile: dragFromToWithVelocity",{fromX:u,fromY:d,toX:S,toY:b,pressDuration:y/1e3,velocity:w,holdDuration:.5});},{operationName:"dragAndDrop"});}async executeDragAndDrop({logger:e,command:r}){let o=ue();if(r.fromTarget.type!=="description"||r.toTarget.type!=="description")throw new M("UserConfigurationError","Drag and drop only supports description targets for now");let n=r.fromTarget.description,{result:i,thoughts:a}=await this.wrapTargetingAction({command:r,tracer:o,description:n,cacheKey:"cache",targetName:"fromTarget",action:async u=>u,logger:e}),s=r.toTarget.description,{result:c,thoughts:l}=await this.wrapTargetingAction({command:r,tracer:o,description:s,cacheKey:"cache",targetName:"toTarget",action:async u=>u,logger:e});return await o.startAsyncSpan("EMULATOR_INTERACTION",async u=>{await this.doDrag(e,u,i,c,{hoverDuration:r.hoverDuration,dragDuration:r.dragDuration});},{name:"Drag and drop"}),{success:true,message:`${a}
|
|
5592
5592
|
${l}`}}};var Lw=class{driver;logger;constructor(e,r){this.driver=e,this.logger=r;}async getTextContent(e){let r=e.cache.xPath;return r?await this.driver.executeInNativeContext(this.logger,async n=>{try{let a=(await n.findElement("xpath",r))[hs];if(!a)return "";let s=await n.getElementAttribute(a,"label"),c=await n.getElementAttribute(a,"value");return [s,c].filter(u=>!!u&&u.trim().length>0).join(" ").trim()}catch{return ""}},{operationName:"getNativeElementTextContent"})??"":""}async getAttribute(e,r){let o=e.cache.xPath;return o?await this.driver.executeInNativeContext(this.logger,async i=>{try{let s=(await i.findElement("xpath",o))[hs];return s?await i.getElementAttribute(s,r)??"":""}catch{return ""}},{operationName:"getNativeElementAttribute"})??"":""}async getTagName(e){let r=e.cache.xPath;return r?await this.driver.executeInNativeContext(this.logger,async n=>{try{let a=(await n.findElement("xpath",r))[hs];return a?await n.getElementTagName(a)??"":""}catch{return ""}},{operationName:"getNativeElementTagName"})??"":""}async isEditable(e){throw new M("UserConfigurationError","Editable checks are not supported on iOS native elements")}async isEnabled(e){let r=e.cache.xPath;return r?await this.driver.executeInNativeContext(this.logger,async o=>{try{let i=(await o.findElement("xpath",r))[hs];return i?await o.isElementEnabled(i):!1}catch{return false}},{operationName:"isNativeElementEnabled"}):false}async isFocused(e){let r=await this.getAttribute(e,"focused");return r==="true"||r==="1"}async getStyleProperty(e,r){throw new M("UserConfigurationError","Computed style checks are not supported on iOS native elements")}},kw=class{driver;webviewContext;logger;constructor(e,r,o){this.driver=e,this.webviewContext=r,this.logger=o;}getCenter(e){let{x1:r,y1:o,x2:n,y2:i}=e.bounds;return {x:(r+n)/2,y:(o+i)/2}}async getTextContent(e){let{x:r,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let c=document.elementFromPoint(a,s);return c?c.innerText??c.textContent??"":""},r,o)??""}async getAttribute(e,r){let{x:o,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(a,s,c,l)=>{let u=document.elementFromPoint(s,c);return u?u.getAttribute(l)??"":""},o,n,r)??""}async getTagName(e){let{x:r,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let c=document.elementFromPoint(a,s);return c?c.tagName:""},r,o)??""}async isEditable(e){let{x:r,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let c=document.elementFromPoint(a,s);if(!c)return false;let l=c.tagName;return l==="INPUT"||l==="TEXTAREA"||l==="SELECT"||c.isContentEditable},r,o)}async isEnabled(e){let{x:r,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let c=document.elementFromPoint(a,s);return c?!c.disabled:false},r,o)}async isFocused(e){let{x:r,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let c=document.elementFromPoint(a,s);return c?document.activeElement===c:false},r,o)}async getStyleProperty(e,r){let{x:o,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(a,s,c,l)=>{let u=document.elementFromPoint(s,c);return u?window.getComputedStyle(u).getPropertyValue(l):""},o,n,r)??""}};var nUe=5e3,Fw=class extends Kr{async executeElementCheck({logger:e,command:r}){let o=Date.now(),n=(r.timeout??Zr)*1e3,i=n+1e4,a,s=0,c=500,l=cloneDeep(r.cache);if(r.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Element check step");for(;s-o<n;){if(Date.now()-o>i){e.warn("Exceeded max system timeout for element check, exiting...");break}if(this.throwIfAborted(),a=await this.executeElementCheckHelper({logger:e,command:r}),s=Date.now(),!a.success)r.cache=l,l=cloneDeep(l),await ce(c,this.abortSignal),c=Math.min(Math.floor(c*1.5),nUe);else return a}let u=await this.executeElementCheckHelper({logger:e,command:r,cacheIsInvalidAfterResolution:true});if(!u.success&&l&&r.cache){let d=mq({logger:e,originalTarget:mM(l)?l.target:void 0,newTarget:r.cache.target});d&&Us(l.target,d)&&(r.cache={target:d,updatedAt:r.cache.updatedAt});}return u}async executeElementCheckHelper({logger:e,command:r,cacheIsInvalidAfterResolution:o}){let n=ue();if(r.target.type!=="description")throw new M("UserConfigurationError","x/y targets are not supported for the Element check step");let i=$m(r.assertion);try{return (await this.wrapTargetingAction({...o?{cacheIsInvalidAfterResolution:o}:{},command:r,tracer:n,action:async s=>s.type==="NATIVE"?await this.executeNativeElementCheck(e,r,s):await this.executeWebviewElementCheck(e,r,s),description:r.target.description,logger:e})).result}catch(a){return i&&(a instanceof M&&a.reason==="NoMatchingElementError"||a instanceof va)?{success:true}:{success:false,message:`Failed to evaluate element content assertion: ${a instanceof Error?a.message:`${a}`}`}}}async executeNativeElementCheck(e,r,o){let n=ue(),{assertion:i}=r;return await n.startAsyncSpan("ELEMENT_ASSERTION",async a=>{a.targetBounds=Bc(o);let s=await this.executeElementAssertion({assertion:i,element:o,elementPropertyAccessors:new Lw(this.driver,e),span:a});return a.result=s,s},{name:"Native element check"})}async executeWebviewElementCheck(e,r,o){let n=ue(),{assertion:i}=r,s=(await this.stateManager.getContexts(e)).webviews[0];if(!s)throw new M("UserConfigurationError","No active webview context found for element check");return await n.startAsyncSpan("ELEMENT_ASSERTION",async c=>{c.targetBounds=Bc(o);let l=await this.executeElementAssertion({assertion:i,element:o,elementPropertyAccessors:new kw(this.driver,s,e),span:c});return c.result=l,l},{name:"Webview element check"})}async executeElementAssertion({assertion:e,element:r,elementPropertyAccessors:o,span:n}){switch(e.type){case "ELEMENT_CONTENT":{let i=await o.getTextContent(r)??"";return n.attributes.elementTextContent=Cr(i,500,true),sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})?{success:true}:{success:false,message:`The content ${fo(e)} '${e.value}': ${i}`}}case "ELEMENT_ATTRIBUTE":{let i=null;try{i=await o.getAttribute(r,e.attr);}catch{i=null;}if(!sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let a=fo(e);return {success:false,message:`The attribute ${e.attr} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:true}}case "ELEMENT_EXISTENCE":{let i=false;switch(e.condition){case "EDITABLE":i=await o.isEditable(r);break;case "VISIBLE":case "EXISTS":i=true;break;case "ENABLED":{i=await o.isEnabled(r);break}case "FOCUSED":i=await o.isFocused(r);break;default:throw e.condition,new Error("Unrecognized element condition type")}return i=e.negated?!i:i,i?{success:true}:{success:false,message:`The element ${fo(e)}`}}case "ELEMENT_NAME":{let i=await o.getTagName(r);return sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:true})?{success:true}:{success:false,message:`The element tag name ${fo(e)} '${e.value}': ${i}`}}case "ELEMENT_STYLE":{let i=await o.getStyleProperty(r,e.property);if(!sn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:false})){let a=fo(e);return {success:false,message:`The style property ${e.property} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:true}}default:throw new Error("Unrecognized element assertion type")}}};async function Vee({command:t,orgId:e,logger:r,fixtures:o,abortSignal:n}){let i;try{i=await _i({orgId:e,code:t.code,fragment:!1,context:o.testContext,timeoutMs:t.timeout?t.timeout*1e3:void 0,logger:r,localTools:o.localCodeEvalTools,signal:n});}catch(a){throw new M("ActionFailureError",a instanceof M?a.message:`${a}`,{errOptions:{cause:a}})}try{JSON.stringify(i);}catch(a){throw new M("UserConfigurationError",`Return value is not serializable: ${a instanceof Error?a.message:`${a}`}`)}return {success:true,output:i}}async function zee({command:t,emulator:e}){switch(t.key){case "ENTER":await e.pressKey("enter");break;case "BACKSPACE":await e.pressKey("backspace");break;default:{t.key;}}return {success:true}}var $ee=C__default.object({name:C__default.string(),pid:C__default.number(),bundleId:C__default.string()});var sf=class extends Kr{async doPress(e,{name:r,longPress:o}){return this.driver.executeInNativeContext(e,n=>n.executeScript("mobile: pressButton",[{name:r,isLongPress:o}]),{operationName:"pressButton"})}};var iUe="com.apple.springboard",jee=5,Bw=class extends Kr{async execute(e){let r;for(let o=0;o<jee;o++){this.throwIfAborted();try{let i=await this.driver.executeInNativeContext(e,s=>s.executeScript("mobile: activeAppInfo",[]),{operationName:"getActiveAppInfo"});r=$ee.parse(i).bundleId;}catch(i){throw new M("UserConfigurationError",`Failed to get active app info: ${i.message}`)}if(!r)return {success:true,message:"No active app found"};if(await new sf(this.constructPerformerParams()).doPress(e,{name:"home"}),r!==iUe)return await this.emulator.terminateApp(r),{success:true};await ce(500,this.abortSignal);}throw new M("ActionFailureError",`Failed to dismiss notification after ${jee} attempts, cannot kill the underlying app`)}};var aUe="FBSApplicationLibrary) returned nil";function Hee(t){return j(t).includes(aUe)}async function Gee({driver:t,logger:e,bundleId:r,launchArguments:o}){try{await t.executeInNativeContext(e,n=>n.execute("mobile: launchApp",{bundleId:r,arguments:o}),{operationName:"launchApp"});}catch(n){throw Hee(n)?new fl(`App "${r}" is not installed on the device. Install the app on the device before running this step, or update the step to reference a bundle ID that is installed.`,{cause:n}):n}}async function Wee({command:t,logger:e}){let r;try{r=new URL(t.url).hostname;}catch(c){throw new M("UserConfigurationError",`Invalid URL: ${c instanceof Error?c.message:`${c}`}`)}let o=new CookieJar,n=y_e(fetch,o),i=Date.now(),a=await Tp({command:t,baseUrl:void 0,logger:e,fetchImplementation:n}),s=em(o,r);return {output:wd.parse({...a,cookies:s}),success:true,message:`Successfully executed request in ${Date.now()-i}ms`}}async function qee({command:t,emulator:e,driver:r,logger:o,getViewportBounds:n}){return e.setOrientation?await e.setOrientation(t.orientation):await r.executeInNativeContext(o,async i=>{await i.setOrientation(t.orientation==="LANDSCAPE"?"landscape":"portrait");},{operationName:"setOrientation"}),{success:true,output:{newViewportBounds:await n()}}}var cUe=5e3,Vw=class extends Kr{async executeScreenCheck(e,r){let{timeout:o}=r,n=Date.now(),i=(o??Zr)*1e3,a=i+1e4,s=0,c=500;for(;s-n<i;){if(Date.now()-n>a){e.warn("Exceeded max system timeout for screen check, exiting...");break}this.throwIfAborted();let l=await this.executeScreenCheckHelper(e,r);if(s=Date.now(),!l.success)await ce(c,this.abortSignal),c=Math.min(Math.floor(c*1.5),cUe);else return l}return await this.executeScreenCheckHelper(e,r)}async executeScreenCheckHelper(e,r){let o=await this.executeNativeScreenCheckHelper(e,r);if(!r.assertion.negated&&o.success)return o;let n=await this.executeWebviewScreenCheckHelper(e,r);return n?r.assertion.negated?o.success&&n.success?o:o.success?n:o:o.success?o:n:o}async executeNativeScreenCheckHelper(e,r){let{assertion:o}=r;switch(o.type){case "CONTENT":try{let i=(await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:!0,removeWebviewContent:!0,filterOffscreenElements:!1})).graph.xml;if(!i)throw new Error("Failed to get screen XML");let a=i.includes(o.value)===!o.negated;return i.length>1e4&&(i=i.slice(0,1e4)+"...TRUNCATED"),a?{success:!0}:{success:!1,message:`The screen ${zm({...o,negated:!o.negated})}.`}}catch(n){return {success:false,message:`Failed to evaluate screen content assertion: ${n instanceof Error?n.message:`${n}`}`}}default:return o.type,{success:false,message:`Unsupported screen check assertion type: ${o.type}`}}}async executeWebviewScreenCheckHelper(e,r){let o;try{if(o=await this.stateManager.getActiveWebview(e),!o)return}catch(i){e.warn({err:i},"Failed to get active webview context during screen check");return}let{assertion:n}=r;switch(n.type){case "CONTENT":try{return await this.driver.executeWebViewScript(e,o,(a,s,c)=>document.body.innerHTML.includes(s)===!c,n.value,!!n.negated)?{success:!0}:{success:!1,message:`The webview ${zm({...n,negated:!n.negated})}.`}}catch(i){e.warn({err:i},"Failed to check webview content during screen check");return}default:return}}};var uUe=.9,Vc=.2,dUe=500;function N0(t,e){t.attributes.scrollableElementType=e.type,t.attributes.scrollableElementDisplay=Ms(e),e.type==="CUSTOM"&&(t.attributes.scrollableElementDescription=e.target.description);}var lf=class extends Kr{async getHardcodedScrollableElementBounds(e,r){let o;switch(e.type){case "SCREEN":o=this.getContainerBoundsFromViewport(r);break;case "OPEN_APP":o=this.getContainerBoundsFromViewport(r);break;case "OPEN_WEBVIEW":{o=this.getContainerBoundsFromViewport(r);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return o}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:e.width,height:e.height}}getContainerBoundsFromBounds(e){let r=e.x1,o=e.y1,n=e.x2,i=e.y2,a=n-r,s=i-o;return {left:r,top:o,width:a,height:s}}async executeSwipe({logger:e,command:r}){let o=ue(),n=Ms(r.scrollableElement);if(r.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:a,startY:s,deltaPixels:c}=r.scrollableElement;return await o.startAsyncSpan("EMULATOR_INTERACTION",async l=>{N0(l,r.scrollableElement),await this.performRawSwipe({logger:e,span:l,startX:a,startY:s,deltaPixels:c,direction:r.direction,durationMs:r.durationMs});},{name:`Swipe ${r.direction} in ${n}`}),{success:true,message:"Successfully executed swipe action"}}if(r.scrollableElement.type!=="CUSTOM"){let a=await this.driver.executeInNativeContext(e,async c=>c.getWindowRect(),{operationName:"getSwipeViewportRect"}),s=await this.getHardcodedScrollableElementBounds(r.scrollableElement,a);return await o.startAsyncSpan("EMULATOR_INTERACTION",async c=>{N0(c,r.scrollableElement),await this.swipeByAbsoluteCoordinates({logger:e,span:c,direction:r.direction,percent:r.viewportPercent,durationMs:r.durationMs,containerBounds:s,relativePosition:r.relativePosition?Kt(r.relativePosition):void 0});},{name:`Swipe ${r.direction} in ${n}`}),{success:true,message:"Successfully executed swipe action"}}let{thoughts:i}=await this.wrapTargetingAction({command:r,description:r.scrollableElement.target.description,action:async a=>ue().startAsyncSpan("EMULATOR_INTERACTION",async c=>(N0(c,r.scrollableElement),this.scrollInNativeContainer({logger:e,span:c,cmd:r,target:a})),{name:`Swipe ${r.direction} in ${n}`}),tracer:o,logger:e});return {success:true,message:i}}async scrollInNativeContainer({logger:e,span:r,cmd:o,target:n}){let i=n.bounds,a=this.getContainerBoundsFromBounds(i);await this.swipeByAbsoluteCoordinates({logger:e,span:r,direction:o.direction,percent:o.viewportPercent,durationMs:o.durationMs,containerBounds:a,relativePosition:o.relativePosition?Kt(o.relativePosition):void 0});}async swipeByAbsoluteCoordinates({logger:e,span:r,direction:o,percent:n=uUe,durationMs:i,containerBounds:a,relativePosition:s}){r.attributes.containerBounds=a;let c=o==="up"||o==="down",l=a.width*Vc,u=a.height*Vc,d=c?(a.height-2*u)*n:(a.width-2*l)*n,m,p,f;if(s)m=a.left+s.x,p=a.top+s.y,f=d;else {let h=this.calculateSwipeCoordinates({containerBounds:a,direction:this.invertDirection(o),desiredDelta:d});m=h.startX,p=h.startY,f=h.actualDelta;}await this.performRawSwipe({logger:e,span:r,startX:m,startY:p,deltaPixels:f,direction:o,durationMs:i});}calculateSwipeCoordinates({containerBounds:e,direction:r,desiredDelta:o}){let n=e.left+e.width/2,i=e.top+e.height/2;if(r==="up"||r==="down"){let a=e.height*Vc,s=e.top+a,c=e.top+e.height-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u,m=r==="down"?c-d/2:s+d/2;return {startX:n,startY:m,actualDelta:u}}else {let a=e.width*Vc,s=e.left+a,c=e.left+e.width-a,l=c-s,u=Math.min(Math.abs(o),l),d=l-u;return {startX:r==="right"?c-d/2:s+d/2,startY:i,actualDelta:u}}}invertDirection(e){if(e==="up")return "down";if(e==="down")return "up";if(e==="left")return "right";if(e==="right")return "left";throw new Error(`Unreachable code: ${e}`)}async performRawSwipe({logger:e,span:r,startX:o,startY:n,deltaPixels:i,direction:a,durationMs:s=300}){let c=Math.abs(i),l=Math.max(2,Math.round(s)),u=Math.max(1,Math.min(120,Math.floor(l*.25))),d=Math.max(1,l-u),m=Math.min(c/2,Math.min(12,Math.max(c*.05,1))),p=o,f=n,h=o,S=n;a==="up"||a==="down"?(f=a==="up"?n-c:n+c,h=p,S=a==="up"?f+m:f-m):(p=a==="left"?o-c:o+c,h=a==="left"?p+m:p-m,S=f),r.attributes.pixelDelta=c,r.attributes.startPoint={x:o,y:n},r.attributes.endPoint={x:p,y:f},r.attributes.durationMs=l,await this.driver.executeInNativeContext(e,async b=>{let y={type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:o,y:n},{type:"pointerDown",button:0},{type:"pause",duration:300},{type:"pointerMove",duration:d,x:h,y:S},{type:"pointerMove",duration:u,x:p,y:f},{type:"pause",duration:300},{type:"pointerUp",button:0}]};await b.performActions([y]),await b.releaseActions();},{operationName:"performRawSwipe"}),await ce(dUe,this.abortSignal);}};var mUe=20,D0=.9,cf=.5,L0=.2;function pUe(t){return t.type==="NATIVE"&&t.scrollDetails!==void 0}var zw=class extends lf{async executeScrollTo({logger:e,command:r}){let o=r.target.description,n=r.scrollStepPercent??D0,i=await this.tryUseNativeScrollCache(e,r,o);return i||this.searchForElement({logger:e,cmd:r,description:o,scrollStepPercent:n})}async resolveContainer({logger:e,scrollableElement:r,containerCache:o}){let n=await this.driver.executeInNativeContext(e,async l=>l.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(r.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:n.width,height:n.height},diffThresholdPercent:cf};if(r.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(r,n),diffThresholdPercent:cf};let i=ue(),a=r.target.description;if(o){let l=this.getBoundsFromNativeCache(o);return e.info({bounds:l},"Got container bounds from native cache"),{bounds:l,cache:o,diffThresholdPercent:cp({containerBounds:l,viewport:n,defaultThresholdPercent:cf})}}let{resolvedTarget:s}=await this.findElement({logger:e,description:a,tracer:i});if(s.type!=="NATIVE")throw new Error(`ActionFailureError: Custom scroll container "${a}" resolved to a webview element. Custom containers must be native elements.`);let c=this.getBoundsFromNativeCache(s.cache);return e.info({bounds:c},"Got container bounds from AI"),{bounds:c,cache:s.cache,diffThresholdPercent:cp({containerBounds:c,viewport:n,defaultThresholdPercent:cf})}}getBoundsFromNativeCache(e){if(!e.bounds||e.bounds.length<4)throw new M("ActionFailureError","Native target cache has no bounds");let[r,o,n,i]=e.bounds;return {left:r,top:o,width:n-r,height:i-o}}async tryUseNativeScrollCache(e,r,o){let n=r.cache?.target;if(n&&pUe(n)&&n.scrollDetails!==void 0)return this.tryUseNativeScrollCacheHelper(e,r,o,n)}async tryUseNativeScrollCacheHelper(e,r,o,n){let i=n.scrollDetails,a=ue(),s=r.scrollStepPercent??D0;if(i.pixelDelta===0){e.info("Skipping cached scroll-position replay because it would not move the viewport");return}let c;i.scrollableElement.type==="CUSTOM"&&i.scrollableElement.cache?.type==="NATIVE"&&(c=i.scrollableElement.cache),await this.scrollByPixelDelta({logger:e,pixelDelta:i.pixelDelta,scrollableElement:i.scrollableElement,containerCache:c,direction:i.direction,scrollStepPercent:s});try{let u=await this.tryFindElement({logger:e,cmd:r,description:o,tracer:a,scrollDetails:i,useAIIfCacheFails:!0});if(u)return u;e.info("Element not found at cached position, undoing scroll");}catch(u){e.warn({err:u},"Error finding element at cached position, will undo scroll");}let l=i.direction==="down"?"up":"down";e.info({pixelDelta:i.pixelDelta,originalDirection:i.direction,undoDirection:l,scrollableElementType:i.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({logger:e,pixelDelta:i.pixelDelta,scrollableElement:i.scrollableElement,containerCache:c,direction:l,scrollStepPercent:s});}async tryFindElement({logger:e,cmd:r,description:o,tracer:n,scrollDetails:i,useAIIfCacheFails:a=true}){let s,c,l=false,u=i,d=Kee(r.cache?.target);if(d&&d.type==="NATIVE"&&d.resolvedDescription!==void 0&&bc(d.resolvedDescription,o)&&!r.disableCache)try{s=await this.resolveTargetCacheWithTracing({logger:e,tracer:n,cache:d,retryWithinSmartWaiting:!1}),l=!0,c="Successfully resolved scroll to target with cache.",e.info("Successfully resolved scroll to target from cache");}catch(p){e.warn({err:p},"Failed to resolve target from cache");}if(s&&l&&i){let p=await this.correctNativeTargetIntoView({logger:e,tracer:n,cmd:r,resolvedTarget:s,scrollDetails:i});u=p.scrollDetails,p.resolvedTarget?s=p.resolvedTarget:(s=void 0,l=false);}if(!s&&!a)return null;if(!s)try{let p=bC(o),f=await this.findElement({logger:e,description:p,tracer:n,metadata:{commandId:r.id,source:"SCROLL_TO"}});if(f.resolvedTarget.type!=="NATIVE")return null;s=f.resolvedTarget,c=f.thoughts;}catch(p){if(p instanceof M&&p.reason==="NoMatchingElementError")return null;throw e.warn({err:p},"Failed to find scroll-to target with AI"),p}if(s&&!l&&i)try{let p=await this.correctNativeTargetIntoView({logger:e,tracer:n,cmd:r,resolvedTarget:s,scrollDetails:i});u=p.scrollDetails,p.resolvedTarget&&(s=p.resolvedTarget);}catch(p){e.warn({err:p},"Failed to reposition AI-resolved scroll-to target for stable cache generation");}return nf({command:r,updatedCache:Kee({...of(s),...u?{scrollDetails:u}:{}}),updatedWithAI:!l,logger:e}),{success:true,message:c}}async correctNativeTargetIntoView({logger:e,tracer:r,cmd:o,resolvedTarget:n,scrollDetails:i}){let a=await this.getCorrectiveScrollForTarget({logger:e,resolvedTarget:n});if(!a)return {resolvedTarget:n,scrollDetails:i};e.info({bounds:n.bounds,correction:a},"Repositioning scroll-to target to the preferred viewport anchor");let s=i.scrollableElement.type==="CUSTOM"&&i.scrollableElement.cache?.type==="NATIVE"?i.scrollableElement.cache:void 0,c=await this.scrollByPixelDelta({logger:e,pixelDelta:a.pixelDelta,scrollableElement:i.scrollableElement,containerCache:s,direction:a.direction,scrollStepPercent:o.scrollStepPercent??D0,useVisualDiff:true});if(c===0)return e.info({bounds:n.bounds,correction:a},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:n,scrollDetails:i};let l={...i,pixelDelta:zv({currentPixelDelta:i.pixelDelta,baseDirection:i.direction,correctionDirection:a.direction,correctionPixels:c})},u;try{u=await this.resolveTargetCacheWithTracing({logger:e,tracer:r,cache:n.cache,retryWithinSmartWaiting:!1});}catch(m){return e.warn({err:m},"Failed to re-resolve scroll-to target after corrective scroll"),{scrollDetails:l}}let d=await this.getCorrectiveScrollForTarget({logger:e,resolvedTarget:u});return d?(e.warn({bounds:u.bounds,correction:d},"Corrective scroll did not bring the scroll-to target into the preferred viewport anchor"),{resolvedTarget:u,scrollDetails:l}):{resolvedTarget:u,scrollDetails:l}}async searchForElement({logger:e,cmd:r,description:o,scrollStepPercent:n}){let i=ue(),a=await this.resolveContainer({logger:e,scrollableElement:r.scrollableElement});return this.scrollAndSearch({logger:e,cmd:r,description:o,tracer:i,scrollStepPercent:n,resolvedContainer:a})}async scrollAndSearch({logger:e,cmd:r,description:o,tracer:n,scrollStepPercent:i,resolvedContainer:a}){let s=0,c=a.bounds,l=a.diffThresholdPercent,u=fUe(r.scrollableElement),d=u?Math.abs(u.deltaPixels):this.calculateSwipeCoordinates({containerBounds:c,direction:r.direction,desiredDelta:dc({containerBounds:c,containerInsetRatio:Vc})*i}).actualDelta,m=true,p=r.maxScrollAttempts??mUe;for(let S=0;S<p;S++){this.throwIfAborted();let b=this.buildScrollDetails(r,s,a.cache),y=await this.tryFindElement({logger:e,cmd:r,description:o,tracer:n,scrollDetails:b});if(y)return y;if(!m)throw new Error(`ActionFailureError: Could not find element "${o}" after scrolling to the end`);e.debug({attempt:S,cumulativePixelDelta:s},"Element not found, scrolling further"),m=await this.scrollByPage({logger:e,direction:r.direction,containerBounds:c,scrollStepPercent:i,diffThresholdPercent:l,rawCoordinates:u}),s+=r.direction==="down"?d:-d;}let f=this.buildScrollDetails(r,s,a.cache),h=await this.tryFindElement({logger:e,cmd:r,description:o,tracer:n,scrollDetails:f});if(h)return h;throw new Error(`ActionFailureError: Could not find element "${o}" after ${p} scroll attempts`)}buildScrollDetails(e,r,o){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:r,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:o},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:r,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollByPage({logger:e,direction:r,containerBounds:o,scrollStepPercent:n,diffThresholdPercent:i,rawCoordinates:a}){return ue().startAsyncSpan("EMULATOR_INTERACTION",async c=>(c.attributes.containerBounds=o,c.attributes.direction=r,(await this.executeScrollGesture({logger:e,span:c,direction:r,containerBounds:o,scrollStepPercent:n,diffThresholdPercent:i,rawCoordinates:a})).canScrollMore),{name:`Scroll ${r} by one page`})}async scrollByPixelDelta({logger:e,pixelDelta:r,scrollableElement:o,containerCache:n,direction:i,scrollStepPercent:a,useVisualDiff:s=false}){if(r===0)return 0;let c=ue(),l,u=cf,d,m,p;if(o.type==="CUSTOM_COORDINATES")d=o.startX,m=o.startY,p=o.deltaPixels;else {l=await this.resolveContainer({logger:e,scrollableElement:o,containerCache:n});let S=l.bounds;u=l.diffThresholdPercent;let b=dc({containerBounds:S,containerInsetRatio:Vc})*a,y=this.calculateSwipeCoordinates({containerBounds:S,direction:i,desiredDelta:b});d=y.startX,m=y.startY,p=y.actualDelta;}let f=Math.ceil(Math.abs(r)/p),h=this.invertDirection(i);return e.debug({pixelDelta:r,swipeDirection:h,scrollableElementType:o.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),c.startAsyncSpan("EMULATOR_INTERACTION",async S=>{S.attributes.pixelDelta=r,S.attributes.numScrolls=f,S.attributes.maxScrollPerStep=p,S.attributes.startX=d,S.attributes.startY=m;let b=0;for(let y=0;y<f;y++){this.throwIfAborted();let T=Math.abs(r)-b,v=Math.min(p,T);if(s){let w=await this.executeScrollGesture({logger:e,span:S,direction:i,containerBounds:l?.bounds,scrollStepPercent:a,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:v}});if(w.didScroll&&(b+=v),!w.canScrollMore)break}else await this.performRawSwipe({logger:e,span:S,startX:d,startY:m,deltaPixels:v,direction:h}),b+=v;}return S.attributes.appliedPixels=b,b},{name:`Scroll ${i} by ${Math.abs(r)}px`})}async getCorrectiveScrollForTarget({logger:e,resolvedTarget:r}){let o=r.bounds,n=await this.stateManager.getViewportBounds(e),i=Math.max(1,n.bottom-n.top),a=n.top+i*L0,s=n.bottom-i*L0,c=$v({viewportTop:n.top,viewportBottom:n.bottom,elementHeight:o.y2-o.y1,targetTopRatio:L0}),l=o.y1>=n.top&&o.y2<=n.bottom,u=o.y1<a||o.y2>s,d=await this.isResolvedTargetVisible({logger:e,resolvedTarget:r}),m=c-o.y1;if(!(l&&d!==false&&!u)){if(m>0)return {direction:"up",pixelDelta:m};if(m<0)return {direction:"down",pixelDelta:Math.abs(m)}}}async isResolvedTargetVisible({logger:e,resolvedTarget:r}){if(r.type==="WEBVIEW")return null;let o=r.cache.xPath;if(!o)return Yee(r.cache.elementOnlySerializedXml);let n=await this.getTargetVisibilityFromDriver({logger:e,xPath:o});return n!==null?n:Yee(r.cache.elementOnlySerializedXml)}async getTargetVisibilityFromDriver({logger:e,xPath:r}){try{return await this.driver.executeInNativeContext(e,async o=>{let i=(await o.findElement("xpath",r))?.[hs];if(!i)return null;let a=await o.getElementAttribute(i,"visible");return a?a!=="false":null},{operationName:"getScrollToTargetVisibility"})}catch{return null}}async executeScrollGesture({logger:e,span:r,direction:o,containerBounds:n,scrollStepPercent:i,diffThresholdPercent:a=cf,rawCoordinates:s}){let c=await this.stateManager.getRawScreenshotBase64({logger:e}),l,u,d;if(s)l=s.startX,u=s.startY,d=s.deltaPixels;else {if(!n)throw new Error("Expected container bounds for scroll gesture");let S=dc({containerBounds:n,containerInsetRatio:Vc})*i,b=this.calculateSwipeCoordinates({containerBounds:n,direction:o,desiredDelta:S});l=b.startX,u=b.startY,d=b.actualDelta;}await this.performRawSwipe({logger:e,span:r,startX:l,startY:u,deltaPixels:d,direction:this.invertDirection(o)});let m=await this.stateManager.getRawScreenshotBase64({logger:e}),p=cc(c,m),f=p>a,h=p>a;return e.debug({diffPercent:p,didScroll:f,diffThresholdPercent:a,canScrollMore:h,direction:o,actualDelta:d,rawCoordinates:s},"Scroll gesture visual diff result"),{didScroll:f,canScrollMore:h}}};function Kee(t){return !t||t.type!=="NATIVE"?t:jv(t)}function fUe(t){if(t.type==="CUSTOM_COORDINATES")return t}function Yee(t){if(!t)return null;let e=t.match(/\bvisible="(true|false)"/);return e?e[1]==="true":null}function hUe(t){return "iterations"in t}function gUe(t){let e={relativePosition:t.relativePosition?Kt(t.relativePosition):void 0},r=t.iterations??(t.doubleTap?2:void 0),o=t.tapDelayMs??t.doubleTapDelayMs;if(r!==void 0&&(!Number.isInteger(r)||r<1))throw new M("UserConfigurationError","iterations must be a positive integer");if(o!==void 0&&(!Number.isInteger(o)||o<0))throw new M("UserConfigurationError","tapDelayMs must be >= 0");if(r&&r>1&&t.longPress)throw new M("UserConfigurationError","Cannot specify both more than one tap iteration and long press at the same time");if(o!==void 0&&(!r||r<2))throw new M("UserConfigurationError","tapDelayMs requires iterations >= 2");if(t.longPress){if(o!==void 0)throw new M("UserConfigurationError","tapDelayMs cannot be used with longPress");return {...e,longPress:true,longPressDurationMs:t.longPressDurationMs}}return r!==void 0?{...e,iterations:r,tapDelayMs:o}:e}var uf=class extends Kr{async tapOnAbsoluteCoordinates(e,r){let o=r.x,n=r.y;if(e.info({x:o,y:n},"Tap at coordinates"),"longPress"in r&&r.longPress){let i=(r.longPressDurationMs??2e3)/1e3;await this.driver.executeInNativeContext(e,a=>a.executeScript("mobile: touchAndHold",[{x:o,y:n,duration:i}]),{operationName:"touchAndHold"});return}if(hUe(r)){let i=r.tapDelayMs??100;for(let a=0;a<r.iterations;a++)await this.emulator.tap(o,n),a<r.iterations-1&&await ce(i);return}await this.emulator.tap(o,n);}async tapOnTarget({logger:e,target:r,options:o,targetBounds:n=Bc(r)}){return await ue().startAsyncSpan("EMULATOR_INTERACTION",async a=>{a.attributes.options=o;let{x1:s,y1:c,x2:l,y2:u}=r.bounds,d=l-s,m=u-c,p=o?.relativePosition?.x??d/2,f=o?.relativePosition?.y??m/2;p=Math.max(0,Math.min(p,d)),f=Math.max(0,Math.min(f,m));let h=s+p,S=c+f;await this.tapOnAbsoluteCoordinates(e,{x:h,y:S,...o}),a.attributes.point={x:h,y:S},a.targetBounds=n;},{name:"Tap on target"})}async executeTap({logger:e,command:r}){let o=gUe(r),n=ue();if(r.target.type==="coordinates"||r.target.type==="absolute_percent"){let s=await this.driver.executeInNativeContext(e,async u=>u.getWindowSize(),{operationName:"getTapWindowSize"}),c,l;return r.target.type==="coordinates"?(c=r.target.xPercent*s.width,l=r.target.yPercent*s.height):(c=r.target.x/100*s.width,l=r.target.y/100*s.height),await n.startAsyncSpan("EMULATOR_INTERACTION",async u=>{await this.tapOnAbsoluteCoordinates(e,{...o,x:c,y:l}),u.attributes.point={x:c,y:l};},{name:`Tap at coordinates ${c}, ${l}`}),{success:true,message:`Tapped at ${c}, ${l}`}}let i=r.target.description,{thoughts:a}=await this.wrapTargetingAction({logger:e,tracer:n,command:r,action:s=>this.tapOnTarget({logger:e,target:s,options:o}),description:i});return {success:true,message:a}}};var hd=25,Xee=150,$w=class extends Kr{async doType(e,r){let o=ue();if(!r.target){if(r.clearContent)throw new Error("UserConfigurationError: clearing content is only supported when a target is provided to the Type step");return await this.stateManager.waitForScreenshotStability({logger:e,timeoutMs:3e3,signal:this.aborter.controller?.signal,reason:"Waiting for page to stabilize before typing"}),await this.sendKeys(e,r),{success:true,message:"Successfully executed type action"}}if(r.target.type!=="description")throw new Error("UserConfigurationError: x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({logger:e,tracer:o,command:r,action:async i=>{await this.doTypeHelper(e,r,i);},description:r.target.description});return {success:true,message:n}}async doTypeHelper(e,r,o){let n=new uf(this.constructPerformerParams());r.clearContent?(await n.tapOnTarget({logger:e,target:o,options:{longPress:true},targetBounds:Bc(o)}),await this.clearContent(e)):await n.tapOnTarget({logger:e,target:o,options:{},targetBounds:Bc(o)}),await this.sendKeys(e,r);}async sendKeys(e,r){let o=ue(),n=r.keyPressDelayMs??hd;n<=0&&(n=hd),await o.startAsyncSection("Waiting for system keyboard to open",async(i,a)=>{let s=Date.now();for(;Date.now()-s<3e3;){if(this.throwIfAborted(),await this.driver.executeInNativeContext(e,c=>c.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;await new Promise(c=>setTimeout(c,500));}a.attributes.timedOut=true;}),await o.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{n!==hd&&await this.driver.executeInNativeContext(e,async a=>a.updateSettings({maxTypingFrequency:1e3/n}),{operationName:"updateKeyInjectionDelay"});let i=[];for(let a=0;a<r.text.length;a+=Xee)i.push(r.text.slice(a,a+Xee));for(let a of i)await this.driver.executeInNativeContext(e,async s=>{await s.performActions(bUe(a)),await s.releaseActions();},{operationName:"typeText",maxAttempts:1,attemptTimeoutMs:Gv(n,a)});}finally{n!==hd&&await this.driver.executeInNativeContext(e,async i=>i.updateSettings({maxTypingFrequency:1e3/hd}),{operationName:"resetKeyInjectionDelay"});}},{name:`Typing "${r.text}"${n?` with a ${n}ms delay`:""}`});}async clearContent(e){let r=ue();try{await r.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper(e));}catch(o){e.warn({err:o},"Failed to find select all button, continuing...");}}async clearContentHelper(e){await this.driver.executeInNativeContext(e,async r=>{let o=r.$('-ios predicate string:label == "Select All"');await o.waitForExist({timeout:750}),await o.click();},{operationName:"selectAllText",maxAttempts:1}),await this.driver.executeInNativeContext(e,async r=>{await r.keys(["\uE003"]);},{operationName:"deleteSelectedText"});}};function bUe(t){let e={type:"key",id:"pressKeys",actions:[]};for(let r of [...t])e.actions.push({type:"keyDown",value:r},{type:"keyUp",value:r});return [e]}async function Jee({command:t,abortSignal:e}){return await ce(t.timeoutSecs*1e3,e),{success:true}}async function yUe(t,e){try{await t.executeInNativeContext(e,r=>r.executeScript("mobile: pressButton",[{name:"home"}]),{operationName:"pressHomeButton"}),e.info("Navigated to home screen");}catch(r){e.warn({err:r},"Failed to press home button");}}var k0=["io.appium."],F0=["com.facebook.WebDriverAgentRunner.xctrunner"];async function EUe(t,e){let r;try{r=await t.listApps();}catch(a){e.warn({err:a},"Failed to list installed apps");return}let o=r.filter(({bundleId:a})=>!F0.includes(a)&&!k0.some(s=>a.startsWith(s)));e.info({count:o.length},"Terminating all apps");let i=(await Promise.allSettled(o.map(async a=>{try{return await t.terminateApp(a.bundleId),a.bundleId}catch(s){return e.debug({err:s,bundleId:a.bundleId},"Failed to terminate app (may not be running)"),null}}))).filter(a=>a.status==="fulfilled"&&a.value!==null).length;i>0&&e.info({count:i},"Terminated apps");}async function TUe(t,e){e.info("Resetting privacy settings for all apps");try{await t.resetSettings();}catch(r){e.warn({err:r},"Failed to reset privacy settings");}}async function Zee(t){let{emulator:e,driver:r,logger:o}=t;await yUe(r,o),await EUe(e,o),await TUe(e,o);}var zc=class t extends Kr{emulatorSettings;logger;splitInstalledApps(e){let r=[],o=[];for(let{bundleId:n}of e)if(!(F0.includes(n)||k0.some(i=>n.startsWith(i)))){if(n.startsWith("com.apple.")){o.push(n);continue}r.push(n);}return {installedApps:r,prunedApps:o}}constructor(e){super(e),this.logger=e.logger,this.emulatorSettings=e.emulatorSettings;}static async init({driver:e,logger:r,fixtures:o,orgId:n,options:i,abortController:a,emulator:s,generator:c,aiSettings:l}){let u={controller:a},d=i?.emulator??{},m=await Ow.init({driver:e,orgId:n,emulator:s,options:d,aborter:u}),p=new t({generator:c,aiSettings:l,emulator:s,driver:e,stateManager:m,logger:r,fixtures:o,aborter:u,orgId:n,emulatorSettings:d});return await p.initializeSettings(),p}async executeCommand(e){let r=["type","a11yData","thoughts","cache","code"],o;try{o=await hp({obj:e.command,context:this.fixtures.testContext,bannedKeys:r,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools});}catch(n){throw this.throwIfAborted(),new Error(`ActionFailureError: Failed to substitute template strings in command: ${n.message}`,{cause:n})}try{return await this.executeCommandHelper(e)}catch(n){throw n.name!=="AbortError"&&this.logger.error({err:n},"Error thrown in action controller"),n}finally{gp(e.command,o);}}async executeCommandHelper({command:e}){switch(e.type){case "TAP":return new uf(this.constructPerformerParams()).executeTap({logger:this.logger,command:e});case "SWIPE":return new lf(this.constructPerformerParams()).executeSwipe({logger:this.logger,command:e});case "DRAG_AND_DROP":return new Dw(this.constructPerformerParams()).executeDragAndDrop({logger:this.logger,command:e});case "SCROLL_TO":return new zw(this.constructPerformerParams()).executeScrollTo({logger:this.logger,command:e});case "TYPE":return new $w(this.constructPerformerParams()).doType(this.logger,e);case "STATE":{let r=await this.stateManager.getDomState(this.logger),o=await this.stateManager.getContexts(this.logger);return {output:{xml:r.graph.xml,contexts:o},success:true}}case "OPEN_APP":{let r=[];if(e.intentExtras)try{let o=JSON.parse(e.intentExtras);r=C__default.string().array().parse(o);}catch(o){throw new fl(`Invalid launch arguments: expected a JSON array of strings. ${j(o)}`)}return await Gee({driver:this.driver,logger:this.logger,bundleId:e.packageName,launchArguments:r}),{success:true}}case "KILL_APP":return new Bw(this.constructPerformerParams()).execute(this.logger);case "PRESS":{let r=new sf(this.constructPerformerParams());switch(e.key){case "HOME":await r.doPress(this.logger,{name:"home"});break;case "POWER":await this.driver.executeInNativeContext(this.logger,o=>o.isLocked(),{operationName:"isLocked"})?await this.driver.executeInNativeContext(this.logger,o=>o.unlock(),{operationName:"unlockDevice"}):await this.driver.executeInNativeContext(this.logger,o=>o.lock(),{operationName:"lockDevice"});break}return {success:true}}case "PRESS_KEYBOARD":return zee({command:e,emulator:this.emulator});case "AI_CHECK":return Cee({command:e,logger:this.logger,generator:this.generator,aiSettings:this.aiSettings,getEmulatorDomState:()=>this.getEmulatorDomState(),getScreenshotBase64:()=>this.getScreenshotBase64(),throwIfAborted:()=>this.throwIfAborted(),abortSignal:this.abortSignal});case "AI_EXTRACT":return Aee({command:e,logger:this.logger,generator:this.generator,aiSettings:this.aiSettings,getEmulatorDomState:()=>this.getEmulatorDomState(),getScreenshotBase64:()=>this.getScreenshotBase64(),abortSignal:this.abortSignal});case "JAVASCRIPT":return Vee({command:e,orgId:this.orgId,logger:this.logger,fixtures:this.fixtures,abortSignal:this.abortSignal});case "WAIT":return Jee({command:e,abortSignal:this.aborter.controller?.signal});case "REQUEST":return Wee({command:e,logger:this.logger});case "ROTATE_ORIENTATION":return qee({command:e,emulator:this.emulator,driver:this.driver,logger:this.logger,getViewportBounds:()=>this.getViewportBounds()});case "ADD_FILE":{let r=await Uv(e.file);return await this.driver.executeInNativeContext(this.logger,o=>o.pushFile(e.storageLocation,r),{attemptTimeoutMs:12e4,operationName:"pushFile"}),{success:true}}case "SCREEN_CHECK":return new Vw(this.constructPerformerParams()).executeScreenCheck(this.logger,e);case "ELEMENT_CHECK":return new Fw(this.constructPerformerParams()).executeElementCheck({logger:this.logger,command:e});case "APPIUM_EXECUTE":{let r=JSON.parse(e.jsonArgs??"{}"),o=await this.driver.executeInNativeContext(this.logger,async n=>n.execute(e.command,r),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:o},"Appium command executed successfully"),{success:true,output:o,message:"Appium command executed successfully"}}default:{let r=e;throw new Error(`Unsupported mobile command type: ${r}`)}}}async getMobileFailureRecoveryPlan(){return {thoughts:"Failure recovery is not yet supported for iOS.",scenario:"INELIGIBLE",instructions:void 0}}async waitForPageSourceStability(e){await this.stateManager.waitForPageSourceStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal});}async getInstalledApps(){let e=await this.emulator.listApps();return this.splitInstalledApps(e)}async initializeSettings(){let{latitude:e,longitude:r}=this.emulatorSettings?.geolocation??Ld;await this.driver.executeInNativeContext(this.logger,async o=>{await o.setGeoLocation({latitude:e,longitude:r}),await o.updateSettings({pageSourceExcludedAttributes:"visible,accessible",maxTypingFrequency:1e3/hd,reduceMotion:true});},{operationName:"initializeDeviceSettings"});}async getScreenshotBase64(){return this.stateManager.getRawScreenshotBase64({logger:this.logger})}async getScreenshotPngString(){return this.stateManager.getCurrentScreenshotPngString(this.logger)}async getEmulatorDomState(){return (await this.stateManager.getDomState(this.logger)).graph.xml}async getViewportBounds(){return this.stateManager.getViewportBounds(this.logger)}async waitForScreenshotStability(e){return this.stateManager.waitForScreenshotStability({logger:this.logger,timeoutMs:e.timeoutMs??5e3,reason:e.reason,signal:this.aborter.controller?.signal})}resetAbortController(e){this.aborter.controller=e??new AbortController;}isAborted(){return this.aborter.controller?.signal.aborted}abort(){this.aborter.controller?.abort();}async softReset(){await Zee({emulator:this.emulator,driver:this.driver,logger:this.logger}),this.fixtures.testContext.resetToInitial();}async cleanup(){}get abortSignal(){return this.aborter.controller?.signal}get context(){return this.fixtures.testContext}get localCodeEvalTools(){return this.fixtures.localCodeEvalTools}};function df({appFolderPath:t,source:e,overrideBaseDir:r}){let o=t?.trim();if(!o)return;if(e==="default")return o;let n=e==="override"&&r&&!sr__default.isAbsolute(o)?sr__default.resolve(r,o):sr__default.resolve(o);if(e==="override"&&(!so.existsSync(n)||!so.statSync(n).isDirectory()))throw new Error(`Local iOS app path "${n}" does not exist. Provide a valid directory path.`);return n}var AUe=3;async function ete(t){let{results:e,fixtures:r,work:o}=t,{logger:n}=r,i=e[e.length-1],a=RUe(i,o);if(a)return n.info({failedResult:i,isNotEligible:a},"Skipping failure recovery because of ineligible failure"),{type:"NOT_ELIGIBLE",message:`The failed step is not eligible for failure recovery: ${a}`};n.info({failedResult:i},"Attempting failure recovery"),o.state.failureRecoveryAttempts=(o.state.failureRecoveryAttempts??0)+1;try{return await wUe(t)}catch(s){return n.warn({err:s},"Error during failure recovery attempt, continuing..."),null}}async function wUe(t){let{fixtures:e,results:r,failedStep:o,nextSteps:n,stepTracer:i,work:a,containerParentChain:s}=t,{controller:c,logger:l}=e,u=i.parentTracer,{testMetadata:d}=t.inputs;if(!r.length)throw new Error("Attempted failure recovery with no failed results");let m=s.length>0,p=m&&a.topLevelResults?[...a.topLevelResults,...r]:r,f=m&&a.fullTestSteps?tte(a.fullTestSteps,s):[],h=[...n,...f],S=await c.getScreenshotPngString(),b=await c.getEmulatorDomState(),{results:y}=await FT(l,u,p,{numStepsWithScreenshots:5,addIndices:true,includeBeforeScreenshots:false,screenshotMediaType:"image/png"}),T=h.map(k=>qa(k)),v=d.description.trim(),w=d?.settings?.ai?.failureRecoveryInstructions?.trim()||void 0,{scenario:N,thoughts:D,instructions:x}=await c.getMobileFailureRecoveryPlan({currentScreenshot:S,failedResults:y,currentScreenXml:b,nextStepsSerialized:T,testDescription:v,customInstructions:w});if(N!=="RECOVERABLE")return l.info({scenario:N,thoughts:D,instructions:x},"Failure recovery is not applicable"),{type:"NOT_ELIGIBLE",message:`Momentic's failure recovery agent determined that this failure is not eligible for recovery: ${D}`};if(!x)throw new Error("Momentic's failure recovery agent did not provide any instructions for recovery");let A={id:randomUUID(),type:"MOBILE_AI_ACTION_STEP",text:x},B,O=a.state.failureRecoveryDisabled;O||(a.state.failureRecoveryDisabled=true),l.info("executing mobile step list");try{B=await t.executeMobileStepList({...t,fixtures:{...t.fixtures},listParams:{steps:[A,o],containerName:"AI-recovered step list",tracer:u}});}finally{O||(a.state.failureRecoveryDisabled=O);}let z=B.results[0];if(z&&z.type==="MOBILE_AI_ACTION_STEP")if(yg({results:B.results,onPresetAction:k=>{k.aiSuggested=true;},onModule:k=>{k.aiSuggested=true;},onAiAction:k=>{k.aiSuggested=true;}}),B.status==="SUCCESS"){let k=`The following steps were automatically executed by the failure recovery agent. Analysis: ${D}`;return z.message=k,_t.increment("test_event",1,["name:failure_recovery_success","platform:native",`orgId:${t.inputs.orgId}`]),l.info({thoughts:D},"Failure recovery succeeded"),{type:"ATTEMPTED",status:"SUCCESS",result:B,message:k}}else {_t.increment("test_event",1,["name:failure_recovery_failure","platform:native",`orgId:${t.inputs.orgId}`]);let k=`The following steps were unsuccessfully attempted by the failure recovery agent. Analysis: ${D}`;return z.message=k,z.status="FAILED",l.info({thoughts:D},"Failure recovery failed"),{type:"ATTEMPTED",status:"FAILED",result:B,message:k}}return null}function tte(t,e){if(e.length===0)return [];let r=e[0],o=t.findIndex(a=>a.id===r);if(o===-1)return [];let n=t.slice(o+1);if(e.length===1)return n;let i=t[o];return i.type!=="RESOLVED_MOBILE_MODULE"?n:[...tte(i.steps,e.slice(1)),...n]}function RUe(t,e){if(!t)return "There is no failed result";if(t.type!=="MOBILE_PRESET_STEP")return "The failed step is not a preset action";let r=t.message;return r?r.includes("AbortError:")?"The user aborted the test":jF.some(o=>r.includes(o))?"The failed step is an irrecoverable configuration error":(e.state.failureRecoveryAttempts??0)>AUe?"Too many failure recovery attempts":"":"There is no error message available on the failed step"}async function jw({fixtures:t,step:e,inputs:r,stepTracer:o,work:n}){let i=Date.now(),{logger:a,controller:s}=t,c,l="",u,d=s.emulatorSettings?.disableXmlSnapshots??true;if(!r.interactive){if(n.lastScreenshot&&Date.now()-n.lastScreenshot.capturedAtMs<500)c=n.lastScreenshot.screenshot,l=n.lastScreenshot.snapshotId;else {l=randomUUID();try{c=Buffer.from(await s.getScreenshotBase64(),"base64");}catch(h){a.warn({err:h},"Failed to take before screenshot");}}if(!d)if(n.lastScreenXml)u=n.lastScreenXml.screenXml;else try{u=await s.getEmulatorDomState();}catch(h){a.debug({err:h},"Failed to capture before XML snapshot");}}let m=nI(e.command,a),p=cloneDeep(m?.cache??{}),f={...e,status:"SUCCESS",startTime:i,endTime:Date.now()};try{let h=await s.executeCommand({command:e.command});f={...e,status:h.success?"SUCCESS":"FAILED",message:h.message,startTime:i,endTime:Date.now(),data:h.output};}catch(h){s.isAborted()?f={...e,status:"CANCELLED",message:"Step cancelled.",startTime:i,endTime:Date.now()}:(a.error({err:h},"Failed to execute preset step"),f={...e,status:"FAILED",message:j(h),startTime:i,endTime:Date.now()});}finally{if(!r.interactive){c&&(f.beforeSnapshot=l,o.attachBeforeScreenshot({snapshotId:l,screenshot:c}),!d&&u&&o.attachBeforeXmlSnapshot({snapshotId:l,xml:u}));let b=randomUUID();try{let y=await s.getScreenshotBase64();f.afterSnapshot=b;let T=Buffer.from(y,"base64");o.attachAfterScreenshot({snapshotId:b,screenshot:T}),n.lastScreenshot={capturedAtMs:Date.now(),snapshotId:b,screenshot:T};}catch(y){a.warn({err:y},"Failed to take after screenshot"),n.lastScreenshot=void 0;}if(!d)try{let y=await s.getEmulatorDomState();o.attachAfterXmlSnapshot({snapshotId:b,xml:y}),n.lastScreenXml={snapshotId:b,screenXml:y};}catch(y){a.debug({err:y},"Failed to capture after XML snapshot"),n.lastScreenXml=void 0;}}let h="cache"in e.command?e.command.cache??{}:{};f.status==="FAILED"&&dq({logger:a,step:e,originalAndroidCommandCache:m});let S=diff(p,h);S&&Object.keys(S).length>0&&a.info({diffs:zd(S)},"Updated cache");}return f}async function xUe(t,e,r){let{logger:o,controller:n}=t.fixtures,{stepTracer:i}=t.conditionalParams,a=e.assertion.command;try{let s=await jw({...t,step:e.assertion,stepTracer:i}),c=a.type;switch(c){case "AI_CHECK":case "SCREEN_CHECK":case "ELEMENT_CHECK":return s.status==="SUCCESS"?{type:"passed",conditionResult:s,steps:e.steps}:(o.info(s.message,`${a.type} mobile condition ${r} resolved to false`),{type:"failed",conditionResult:s});case "JAVASCRIPT":{if(s.status!=="SUCCESS")return {type:"execution_error",conditionResult:s};let l=!!s.data;return s.status=l?"SUCCESS":"FAILED",s.message=l?`JavaScript condition evaluated to true (${JSON.stringify(s.data)})`:`JavaScript condition evaluated to false (${JSON.stringify(s.data)})`,o.info({returnValue:s.data,conditionPassed:l},`JavaScript mobile condition ${r} evaluated`),l?{type:"passed",conditionResult:s,steps:e.steps}:{type:"failed",conditionResult:s}}default:return (u=>{throw new Error(`Unsupported mobile conditional command type: ${u}`)})(c)}}catch(s){o.error({err:s},`Mobile condition ${r} failed with error`);let c=s instanceof Error?s.message:"Unknown error during mobile condition evaluation";return {type:"execution_error",conditionResult:{...e.assertion,status:"FAILED",message:c,startTime:Date.now(),endTime:Date.now()}}}finally{n.throwIfAborted();}}function PUe({step:t,fromStepId:e,conditionalChain:r,fromStepParentChain:o}){let n=o.slice(r.length+1);for(let i=0;i<t.blocks.length;i++){let a=t.blocks[i],{result:s}=Gl(a.steps,e,n);if(s)return i}return -1}async function ote(t){let e=Date.now(),{logger:r}=t.fixtures,{fromStep:o}=t.inputs,{step:n,stepTracer:i,executeMobileStepList:a}=t.conditionalParams,s=i.getParentStepIdChain(),c=!!o&&YW(s,o.parentStepIdChain),l=n.elseSteps,u=true,d=[],m,p=false;if(c&&o){let y=PUe({step:n,fromStepId:o.fromStepId,conditionalChain:s,fromStepParentChain:o.parentStepIdChain});y>=0&&(l=n.blocks[y].steps,u=false,p=true,r.info(`Skipping mobile conditional assertion (execution starts from block ${y}), running ${l.length} steps`));}if(!p)for(let y=0;y<n.blocks.length;y++){r.info(`Evaluating mobile condition ${y} in conditional step`);let T=n.blocks[y],v=await xUe(t,T,y);if(d.push(v.conditionResult),m=v.conditionResult,v.type==="execution_error"){let w=v.conditionResult.status==="CANCELLED"?"CANCELLED":"FAILED",N={...n,assertionResult:v.conditionResult,steps:[],startTime:e,endTime:Date.now(),status:w,message:v.conditionResult.message};return Ci({result:N,...vi(d)}),N}if(v.type==="passed"){r.info(`Mobile condition ${y} resolved to true, executing ${v.steps.length} steps`),u=false,l=v.steps;break}}if(!l){r.warn("No mobile conditions resolved to true and no else block was provided, skipping conditional step body");let y={...n,assertionResult:m,steps:[],status:"SUCCESS",startTime:e,endTime:Date.now(),data:d[d.length-1]?.data,message:d[d.length-1]?.message};return Ci({result:y,...vi(d)}),y}u&&r.info("No mobile conditions resolved to true, executing the else block steps"),r.info(`Executing ${l.length} steps in selected mobile conditional block`);let f=await i.startSubSteps(),{results:h,status:S}=await a({...t,listParams:{steps:l,containerName:"mobile conditional block",tracer:f}}),b={...n,assertionResult:m,steps:h,status:S,startTime:e,endTime:Date.now()};return Ci({result:b,...vi([...d,...h])}),b}async function nte(t){let e=Date.now(),r=t.fixtures.controller;try{return await IUe(t)}catch(o){let n=r.isAborted();return {...t.moduleParams.step,steps:[],type:"MOBILE_MODULE_STEP",startTime:e,endTime:Date.now(),status:n?"CANCELLED":"FAILED",message:n?"Step cancelled.":j(o)}}}async function IUe({moduleParams:t,...e}){let r=Date.now(),{step:o,stepTracer:n,executeMobileStepList:i}=t,{controller:a,logger:s}=e.fixtures,c=await OUe({step:o,params:e});Object.keys(c).length>0&&(a.context.setInputs(c),s.info(Wl({json:{inputs:c,moduleId:o.moduleId},maxJsonStringSize:1e3}),"Set mobile module inputs"));let l={};Object.entries(c).forEach(([f,h])=>{l[f]=JSON.stringify(h);});let u={...o,type:"MOBILE_MODULE_STEP",inputs:l,startTime:r,steps:[],endTime:Date.now(),status:"SUCCESS"},d=await n.startSubSteps(),{status:m,results:p}=await i({...e,listParams:{steps:o.steps,containerName:`module ('${o.name}')`,tracer:d}});return u.steps=p,u.status=m,u.endTime=Date.now(),Ci({result:u,...vi(p)}),u}async function OUe({step:t,params:e}){let r={},{logger:o,controller:n}=e.fixtures;for(let i of t.parameters?.parameterNames??[]){let a=t.inputs?.[i]??t.parameters?.defaultParameters?.[i];if(!a){o.warn({k:i},"No value found for parameter in module");continue}r[i]=await _i({orgId:e.inputs.orgId,code:a,fragment:true,logger:o,context:n.context,localTools:n.localCodeEvalTools});}return r}var Qs="finish",$c=C__default.object({message:C__default.string(),success:C__default.boolean()}),Sb=3,bb=`You forgot to call ${Qs}. Review the prior conversation and return only the JSON object that should have been passed as the ${Qs} input. The object must include exactly the fields: "message" (a string describing what was accomplished or why you stopped) and "success" (a boolean indicating whether the goal was achieved).`,yb=t=>{let e=tool({description:"Signal that the AI action has reached a terminal state (either success or failure).",inputSchema:$c,toModelOutput:({output:r})=>r,execute:async({message:r,success:o})=>{let{contextManager:n,logger:i}=t;return i.info({finishMessage:r,success:o},"AI action tool called (finish)"),n.finalState={message:r,status:o?"SUCCESS":"FAILED"},{type:"content",value:[{type:"text",text:"Done"}]}}});return {name:Qs,tool:e}};var Hw=["TAP","TYPE","PRESS","PRESS_KEYBOARD","SWIPE","SCROLL_TO","AI_CHECK","ELEMENT_CHECK","SCREEN_CHECK","WAIT","OPEN_APP","KILL_APP","OPEN_NOTIFICATION_DRAWER","DRAG_AND_DROP"];function DUe(t){return t!==void 0&&Hw.includes(t)}function Gw({input:t,logger:e,tempCaches:r}){let o=cb(t);if(!DUe(o.stepType))throw new Error(`Unsupported AI Action V3 step type: ${o.stepType}. Supported types: ${Hw.join(", ")}`);let n=QA(o,"ANDROID");if(n.type!=="MOBILE_PRESET_STEP")throw new Error(`AI Action V3 only supports preset steps, got: ${n.type}`);if(o.disableCache&&o.cacheId&&e.warn({cacheId:o.cacheId},"--disable-cache was provided with --cache-id; disable cache flag is taking precedent and the cache id will be ignored."),o.cacheId&&!o.disableCache&&Da(n.command)){let i=r[o.cacheId];i?n.command.cache=i.cache:e.warn({cacheId:o.cacheId,commandType:n.command.type},"Temp mobile cache not found for AI action V3 step");}return n}function mf(t){let{id:e,cache:r,...o}=t;return JSON.stringify(o)}function jc(t){if(t.length===0)return "Generated cached steps: (none)";let e=t.map((r,o)=>` ${o}: ${mf(r.command)}`).join(`
|
|
5593
5593
|
`);return `Generated cached steps (${t.length}):
|
|
5594
5594
|
${e}`}var Ww=class{controller;logger;rootStep;subStepIndex=0;callbacks;results=[];generatedSteps=[];tempCaches={};finalState=void 0;constructor(e){this.controller=e.controller,this.logger=e.logger,this.rootStep=e.rootStep,this.callbacks=e.callbacks,this.subStepIndex=0,this.generatedSteps=[...e.initialGeneratedSteps??[]];}async executeSteps(e){let r=[];for(let o of e){let n=this.subStepIndex++;this.callbacks.onAiActionEvent?.({type:"STEP_UPDATE",rootStep:this.rootStep,stepIndex:n,step:o,status:"running"});let i=await this.callbacks.executeStep(o,n);if(this.callbacks.onAiActionEvent?.({type:"STEP_UPDATE",rootStep:this.rootStep,stepIndex:n,step:o,status:i.status==="SUCCESS"?"success":"failed",message:i.message}),r.push(i),i.status!=="SUCCESS")break}return this.results.push(...r),r}spliceGeneratedSteps(e,r,...o){return this.generatedSteps.splice(e,r,...o)}saveTempCacheForCommand(e,r){if(!Da(e)||!e.cache)return;let o=r??crypto.randomUUID();return this.tempCaches[o]={type:e.type,cache:cloneDeep(e.cache)},o}};var UUe="get_emulator_screenshot",ate=t=>{let e=tool({description:"Get the current emulator state. Returns the viewport size and a screenshot by default, and can optionally include emulator XML.",inputSchema:C__default.object({includeEmulatorXml:C__default.boolean().optional()}),toModelOutput:({output:r})=>r,execute:async r=>{let{controller:o,logger:n}=t,i={includeEmulatorXml:r.includeEmulatorXml??false};return n.info(i,"AI action V3 tool called (get_emulator_screenshot)"),pf({controller:o,...i})}});return {name:UUe,tool:e}};async function pf(t){let{controller:e,includeEmulatorXml:r=false}=t,o=await e.getScreenshotBase64(),n=await e.getViewportBounds(),i=n.right-n.left,a=n.bottom-n.top,s=[{type:"text",text:`<viewportSize width="${i}" height="${a}" />`}];if(r){let c=await e.getEmulatorDomState();s.push({type:"text",text:`<emulatorXml>
|
|
@@ -5919,7 +5919,7 @@ Choose the SCROLL_TO container based on which region will actually move:
|
|
|
5919
5919
|
- If an OPEN_APP scroll fails while a nested scrollable region is visible on screen, assume the container was probably wrong and retry with CUSTOM before giving up.
|
|
5920
5920
|
</rule>
|
|
5921
5921
|
</rules>
|
|
5922
|
-
`;function Ote(t){return Kw(t,xte,Ite())}var tl={initializeAIActionConfig:Ote,stepSchema:po,resultSchema:yn};var MBe=5e3;async function Dte({socket:t,logger:e,orgId:r,testMetadata:o,globalOrgSettings:n,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:c,storageFactory:l,cacheStorageFactory:u,localToolsFactory:d,onRemoteEmulatorCreated:m,onRemoteEmulatorDeleted:p,billingReporterFactory:f,globalStateManager:h,getGitMetadata:S,region:b,localApkPath:y,localAvdId:T}){let v=t.id,w=await S(),N=t.handshake.query?.fileName,D=N?sr__default.basename(N,".test.yaml"):"",x=o.id;e=e.child({sessionId:v,testId:x,orgId:r,branch:w.gitBranchName});let A=await l(r),B=o.settings?.defaultEnv,O={};B&&(O=(await A.fetchEnvironment(B,e))?.variables??{});let z={...n.emulator,...o.settings?.emulator},k={...n.ai,useMemory:n.ai?.useMemory!==false,...o.settings?.ai},H=h.getSession(v);if(H){if(e.info("Reconnecting to existing Android session"),H.local)return t.emit("session",H.metadata),H.softDeleted=false,H.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let ne=await u(r,w),L=wl.optional().parse(b??z.region),$=L==="local",F,U,K;if($){if(await h.clearSoftDeletedLocalSessions(e),h.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{avdId:Ln,apkFilePath:sl,apkFilePathSource:ll}=dm({overrideAvdId:T,overrideApkFilePath:y,emulatorSettings:z,defaultApkFilePath:o.settings?.defaultApkFilePath,envVariables:O}),cl=pp({apkFilePath:sl,source:ll});if(!Ln)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${gl} key on the environment.`);K={avdId:Ln,apkFilePath:cl};}else F=o.settings?.defaultChannel,U=o.settings?.defaultTag,K={region:L===Vn?void 0:L,apkToInstall:F?{channel:F,tag:U}:void 0,osVersion:z.remoteEmulatorSettings?.androidVersion??nm};e.info({platform:"ANDROID",isLocalRegion:$,resolvedRegion:L,envName:B,emulatorSettings:z,aiSettings:k},"Starting mobile session with resolved configuration");let ee=Date.now(),V=await i({socket:t,logger:e,creationOpts:K}),{driver:le,cleanup:de,emulatorName:je,adbPort:kt}=V,nt,Fr,Xr,q,Be,jt;"limbarClient"in V&&(nt=V.limbarClient,Fr=V.limbarToken,Xr=V.limbarUrl,q=V.limbarRegion,Be=V.limbarOsVersion,jt=V.playwrightDevice);let it=sr__default.join(tmpdir(),`logcat-logs-${r}-${x}-${v}.txt`);$||await m?.({emulatorName:je,platform:"ANDROID"}),e.info({adbPort:kt,apkChannel:F,apkTag:U,duration:Date.now()-ee,emulatorName:je},"Android emulator session initiated"),e=e.child({emulator:je});let ge=false,ni=false,Bi,Dn,bs,ys,Hc=async()=>{if(ge)return;ge=true,ni=true,clearInterval(bs),bs=void 0;let sl=[async()=>{await Dn?.cleanup();},async()=>{await Bi?.();},async()=>{await de(),$||await p?.({emulatorName:je,platform:"ANDROID"});},async()=>{await ys?.dispose();}].map(ll=>ll().catch(cl=>{e.warn({err:cl},"Failed to clean up socket server resource");}));await Q(Promise.allSettled(sl),{milliseconds:MBe,fallback:()=>{}});};h.registerPendingSession(v,{platform:"ANDROID",cleanup:Hc,emulatorName:je,local:$});let al=async()=>{Bi=await le.executeInNativeContext(e,Ht=>Xv({driver:Ht,onLogs:_r=>{t.emit("logcatLogs",_r);},logFilePath:it}),{operationName:"startLogcatListener"});let Ln=await a(r,e),sl=await s(r,e),ll=await c(r,e);ys=d?await d(r):void 0;let cl=new Ka({logger:e,reporter:await f(r),runType:"mobile-test-run",runId:v,testMetadata:{id:o.id,name:D},isInteractive:true}),_f=new hi({variablesFromEnvironment:O,envName:B,testName:D});if(Dn=await Fc.init({driver:le,generator:Ln,logger:e,limbarClient:nt,playwrightDevice:jt,aiSettings:k,options:{emulator:{...z,browserSettings:n.browser}},fixtures:{storage:A,browserEnricher:ll,browserGenerator:sl,localCodeEvalTools:ys,testContext:_f},orgId:r,adbPort:kt,abortController:new AbortController}),!Dn)throw new Error("Failed to initialize Android controller");let Mf=Dn;if(ni||!t.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");let R=await Mf.getViewportBounds();if(ni||!t.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");bs=xBe({socket:t,testContext:_f});let J={sessionId:v,testId:x,orgId:r,emulatorName:je,testName:D,limbarUrl:Xr,limbarToken:Fr,limbarRegion:q,limbarOsVersion:Be,viewportBounds:R,envName:B};return h.registerSession(v,{platform:"ANDROID",controller:Mf,cacheStorage:ne,cleanup:Hc,emulatorName:je,local:$,metadata:J,logFilePath:it,helpers:el,usageTracker:cl}),t.emit("session",J),J};try{return await al()}catch(Ln){throw await h.removeSession(v,e),Ln}}function xBe({socket:t,testContext:e}){return setInterval(()=>{let r=e.toEditorDisplayCopy();t.emit("emulatorState",{context:r});},3e3)}async function Lte({socket:t,logger:e,globalStateManager:r,authorization:o}){let n=t.id,i=r.getSession(n);i&&i.platform==="ANDROID"&&o&&i.logFilePath&&PBe({testId:i.metadata.testId,sessionId:n,logFilePath:i.logFilePath,authorization:o,logger:e}),await r.removeSession(n,e);}async function PBe({testId:t,sessionId:e,logFilePath:r,authorization:o,logger:n}){try{let i;try{i=await Yw.stat(r);}catch{n.debug({logFilePath:r},"No logcat file found to upload");return}if(i.size===0){n.debug({logFilePath:r},"Logcat file is empty, skipping upload"),await Yw.unlink(r);return}let a=new pr(o),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:t,sessionId:e}),c=await Yw.readFile(r),l=await fetch(s,{headers:{"Content-Length":c.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:c});if(l.status!==200)throw new Error(`Failed to upload logcat: ${l.status} ${await l.text()}`);n.info({testId:t,sessionId:e,objectUrl:RT(s)},"Logcat file uploaded successfully");}catch(i){n.warn({err:i,testId:t,sessionId:e},"Failed to upload logcat file");}finally{try{await Yw.unlink(r);}catch(i){n.warn({err:i,logFilePath:r},"Failed to delete temp logcat file");}}}var IBe=({socket:t,globalStateManager:e})=>async()=>{let r=e.getSession(t.id);if(!r)throw new Error("No active Mobile session found");r.controller.abort();},kte={event:"cancel",createHandler:IBe};var OBe=({logger:t,globalStateManager:e,socket:r})=>async(o,n)=>{let i=e.getSession(r.id);if(!i){n({err:"No active Mobile session found"});return}let a=i.controller;a.resetAbortController();let s=Date.now();try{let c=await a.getEmulatorDomState();t.info({durationMs:Date.now()-s},"Fetched screen XML"),n({screenXml:c});}catch(c){t.error({err:c},"Error fetching screen XML from the session controller"),n({err:c.message});}},Fte={event:"fetchScreenXml",createHandler:OBe};var W0=class{parentTracer;socket;step;orgId;interactionTracer;platform;constructor({step:e,socket:r,parentTracer:o,orgId:n,platform:i}){this.socket=r,this.parentTracer=o,this.step=e,this.orgId=n,this.platform=i,this.interactionTracer=new Mi,Uo.initializeRootTracerContext(this.interactionTracer);}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:r,step:o}=e;if(!cE(o))return;let n=lE(o);_t.distribution("test_mobile_step_duration",r,[`type:${n}`,`platform:${this.platform.toLowerCase()}`,"executor:editor",`orgId:${this.orgId}`]);}async finish(e){this.interactionTracer.finish();let r=this.interactionTracer.getRootSpan(),o={result:e.result,parentStepIdChain:e.parentStepIdChain,trace:vM.parse(r)};switch(o.result.status){case "SUCCESS":this.socket.emit("success",o);break;case "FAILED":this.socket.emit("failure",o);break;case "CANCELLED":this.socket.emit("cancelled",o);break}return {trace:r}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new hf({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId,platform:this.platform})}},hf=class{parentTracer;parentStep;socket;orgId;platform;constructor({parentStep:e,socket:r,parentTracer:o,orgId:n,platform:i}){this.parentTracer=o,this.parentStep=e,this.socket=r,this.orgId=n,this.platform=i;}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:e.parentStepIdChain,attempt:e.attempt}),new W0({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId,platform:this.platform})}async getScreenshot(e){}},Xw=class{constructor(e,r,o){this.socket=e;this.orgId=r;this.platform=o;}appendLogs(){}setActiveVideo(){}async finish(){this.socket.emit("finished");}async startBeforeStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startMainStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startAfterStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}};var NBe=({metadata:t,logger:e,globalStateManager:r,socket:o,useSnapshotIdentityCache:n})=>async(i,a)=>{let s=r.getSession(o.id);if(!s)throw new Error("No active Mobile session found");let c=e.child({testId:i.testMetadata.id});s.controller.resetAbortController();let l=s.usageTracker,u;try{u=await DBe({session:s,params:i,metadata:t,testLogger:c,usageTracker:l,socket:o,useSnapshotIdentityCache:n});}finally{await l.flush(c);}let d={results:s.helpers.resultSchema.array().parse(u.results),status:u.status};a?.(d);};async function DBe({session:t,...e}){switch(t.platform){case "ANDROID":return Ute({session:t,...e});case "IOS":return Ute({session:t,...e});default:return (o=>{throw new Error(`Unsupported platform: ${o}`)})(t)}}async function Ute({session:t,params:e,metadata:r,testLogger:o,usageTracker:n,socket:i,useSnapshotIdentityCache:a}){let s=new Xw(i,r.orgId,t.platform);try{return await ff({platform:t.platform,work:{fastForwardingToStep:!!e.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:t.controller,logger:o,cacheStorage:t.cacheStorage,usageTracker:n},containerName:"entire test",inputs:{steps:t.helpers.stepSchema.array().parse(e.steps),beforeSteps:e.beforeSteps?t.helpers.stepSchema.array().parse(e.beforeSteps):void 0,afterSteps:e.afterSteps?t.helpers.stepSchema.array().parse(e.afterSteps):void 0,fromStep:e.fromStep,toStep:e.toStep,orgId:r.orgId,testName:r.testName,testMetadata:e.testMetadata,interactive:!0,useSnapshotIdentityCache:a},envName:r.envName,tracer:s,callbacks:{step:{onAiActionEvent:c=>{i.emit("aiActionEvent",c);}}},helpers:t.helpers})}finally{await s.finish();}}var Bte={event:"execute",createHandler:NBe};var kBe=({socket:t,globalStateManager:e,keepSessionAlive:r})=>{let o=debounce(r,3e4,{maxWait:6e4});return async()=>{let n=e.getSession(t.id);if(!n)throw new Error("No active Mobile session found");n.emulatorName&&(n.local||o(n.platform,n.emulatorName));}},Vte={event:"keepalive",createHandler:kBe};var FBe=({socket:t,globalStateManager:e,logger:r})=>async(o,n)=>{let i=e.getSession(t.id);if(!i){let s="No active session found";r.error(s),n?.({success:false,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),r.info({platform:i.platform},"Resetting emulator state");try{await a.softReset(),r.info({platform:i.platform},"Emulator reset completed"),n?.({success:!0,message:"Emulator reset successfully"});}catch(s){let c=j(s);r.error({err:s,platform:i.platform},"Failed to reset emulator"),n?.({success:false,err:`Failed to reset emulator: ${c}`});}},zte={event:"reset",createHandler:FBe};var $te=[Bte,kte,zte,Vte,Fte];var BBe=5e3;async function jte({socket:t,logger:e,orgId:r,testMetadata:o,globalOrgSettings:n,localIosDeviceType:i,iosDriverFactory:a,mobileGeneratorFactory:s,browserGeneratorFactory:c,browserEnricherFactory:l,billingReporterFactory:u,storageFactory:d,cacheStorageFactory:m,localToolsFactory:p,onRemoteEmulatorCreated:f,onRemoteEmulatorDeleted:h,globalStateManager:S,getGitMetadata:b,region:y,localAppPath:T}){let v=t.id,w=await b(),N=t.handshake.query?.fileName,D=N?sr__default.basename(N,".test.yaml"):"",x=o.id,A=o.settings?.defaultChannel,B=o.settings?.defaultTag;e=e.child({sessionId:v,testId:x,orgId:r,branch:w.gitBranchName});let O=await d(r),z=o.settings?.defaultEnv,k={};z&&(k=(await O.fetchEnvironment(z,e))?.variables??{});let H={...n.emulator,...o.settings?.emulator},ne={...n.ai,useMemory:n.ai?.useMemory!==false,...o.settings?.ai},L=S.getSession(v);if(L){if(e.info("Reconnecting to existing iOS session"),L.local)return t.emit("session",L.metadata),L.softDeleted=false,L.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let $=await m(r,w),F=wl.optional().parse(y??H.region),U=F==="local",K;if(U){if(await S.clearSoftDeletedLocalSessions(e),S.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{deviceType:ge,appFilePath:ni,appFilePathSource:Bi}=mm({overrideDeviceType:i,overrideAppFilePath:T,emulatorSettings:H,defaultAppFilePath:o.settings?.defaultAppFilePath,envVariables:k});if(!ge)throw new Error(`A device type is required when using a local region. Provide --local-ios-device-type, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);let Dn=df({appFolderPath:ni,source:Bi});K={type:"local",deviceType:ge,appFilePath:Dn};}else K={type:"remote",region:F===Vn?void 0:F,appToInstall:A?{channel:A,tag:B}:void 0,osVersion:im};e.info({platform:"IOS",isLocalRegion:U,resolvedRegion:F,envName:z,emulatorSettings:H,aiSettings:ne},"Starting mobile session with resolved configuration");let ee=Date.now(),{driver:V,cleanup:le,emulator:de,limbarParams:je}=await a({socket:t,logger:e,creationOpts:K});e=e.child({emulator:de.name}),e.info({duration:Date.now()-ee},"iOS emulator session initiated"),U||await f?.({emulatorName:de.name,platform:"IOS"});let kt=false,nt=false,Fr,Xr,q,Be,jt=async()=>{if(kt)return;kt=true,nt=true,q&&(clearInterval(q),q=void 0);let ni=[async()=>{await Xr?.cleanup();},async()=>{Fr?.();},async()=>{await le(),U||await h?.({emulatorName:de.name,platform:"IOS"});},async()=>{await Be?.dispose();}].map(Bi=>Bi().catch(Dn=>{e.warn({err:Dn},"Failed to clean up socket server resource");}));await Q(Promise.allSettled(ni),{milliseconds:BBe,fallback:()=>{}});};S.registerPendingSession(v,{platform:"IOS",cleanup:jt,emulatorName:de.name,local:U});let it=async()=>{Fr=await Mw({emulator:de,onLogs:Ln=>{t.emit("syslogLogs",Ln);}});let ge=await s(r,e),ni=await c(r,e),Bi=await l(r,e);Be=p?await p(r):void 0;let Dn=new Ka({logger:e,reporter:await u(r),runType:"mobile-test-run",runId:v,testMetadata:{id:o.id,name:D},isInteractive:true}),bs=new hi({variablesFromEnvironment:k,envName:z,testName:D});if(Xr=await zc.init({driver:V,generator:ge,logger:e,emulator:de,aiSettings:ne,options:{emulator:{...H,browserSettings:n.browser}},fixtures:{storage:O,browserEnricher:Bi,browserGenerator:ni,localCodeEvalTools:Be,testContext:bs},orgId:r,abortController:new AbortController}),!Xr)throw new Error("Failed to initialize iOS controller");let ys=Xr;if(nt||!t.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");let Hc=await ys.getViewportBounds();if(nt||!t.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");q=VBe({socket:t,testContext:bs});let al={sessionId:v,testId:x,orgId:r,emulatorName:de.name,testName:D,limbarUrl:je?.webRtcUrl,limbarToken:je?.token,limbarRegion:je?.region,limbarOsVersion:je?.osVersion,viewportBounds:Hc,envName:z};return S.registerSession(v,{platform:"IOS",controller:ys,cacheStorage:$,cleanup:jt,emulatorName:de.name,local:U,metadata:al,helpers:tl,usageTracker:Dn}),t.emit("session",al),al};try{return await it()}catch(ge){throw await S.removeSession(v,e),ge}}function VBe({socket:t,testContext:e}){return setInterval(()=>{let r=e.toEditorDisplayCopy();t.emit("emulatorState",{context:r});},3e3)}var Jw=class{sessions=new Map;pendingSessions=new Map;registerPendingSession(e,r){this.pendingSessions.set(e,r);}registerSession(e,r){this.pendingSessions.delete(e),this.sessions.set(e,r);}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let r of this.sessions.values())r.softDeleted===true&&r.local===true&&await this.removeSession(r.metadata.sessionId,e);}hasActiveLocalSession(){for(let e of [...this.sessions.values(),...this.pendingSessions.values()])if(e.local===true)return true;return false}async removeSession(e,r){let o=this.sessions.get(e)??this.pendingSessions.get(e);if(!o)return;let n=r.child({sessionId:e,emulatorName:o.emulatorName,platform:o.platform});try{await this.sessions.get(e)?.usageTracker.flush(n);}catch(i){n.error({err:i},"Error flushing usage tracker before cleanup");}try{await o.cleanup?.(),n.info("Emulator cleaned up by removeSession");}catch(i){n.error({err:i},"Error during emulator cleanup");}finally{this.sessions.delete(e),this.pendingSessions.delete(e);}}async removeAllSessions(e){let r=Array.from(new Set([...this.sessions.keys(),...this.pendingSessions.keys()]));await Promise.all(r.map(o=>this.removeSession(o,e)));}};function Hte(t){let{logger:e,baseServer:r,globalStateManager:o,settingsFactory:n,getOrgId:i}=t,a=new Server(r,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:true,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:true}}),s=async()=>{await o.removeAllSessions(e);};a.on("connection",async l=>{let u=l.id,d=e.child({sessionId:u});d.info({event:"connection",transport:l.conn.transport.name},"Mobile websocket connection initiated"),l.on("disconnect",async f=>{if(e.info({reason:f},"Disconnect received"),f.includes("namespace disconnect")){await Lte({socket:l,globalStateManager:o,logger:d,authorization:t.authorization});return}let h=o.getSession(u);h&&(h.softDeleted=true);});let m,p;try{let f=l.handshake.query?.testMetadata,h=Rl.parse(JSON.parse(f??"")),S=h.id,b=await i({testId:S});switch(p=await n(b,e),h.platform){case "ANDROID":m=await Dte({...t,orgId:b,socket:l,globalStateManager:o,logger:d,globalOrgSettings:p,testMetadata:h});break;case "IOS":m=await jte({...t,orgId:b,socket:l,globalStateManager:o,logger:d,globalOrgSettings:p,testMetadata:h});break;default:throw new Error("Unsupported platform")}}catch(f){d.error({err:f},"Failed to setup mobile connection"),l.emit("error",{message:f instanceof Error?f.message:JSON.stringify(f)}),l.disconnect(true);return}$te.forEach(f=>c(f,{...t,socket:l,metadata:m,globalOrgSettings:p,logger:d}));});let c=(l,u)=>{let d=l.createHandler(u),m=(...p)=>{l.event!=="keepalive"&&u.logger.debug({event:l.event},`Websocket event (${l.event})`);let f=h=>{u.logger.error({event:l.event,err:h instanceof Error?h:new Error(`${h}`)},"Unhandled exception in socket handler"),u.socket.emit("error",{message:h instanceof Error?h.message:typeof h=="string"?h:JSON.stringify(h)});};try{let h=d.apply(this,p);h&&typeof h.catch=="function"&&h.catch(f);}catch(h){f(h);}};u.socket.on(l.event,m);};return {server:a,dispose:s}}async function WBe(t,e){switch(t){case "ANDROID":return {uploadPath:e,cleanup:async()=>{}};case "IOS":{let r=await so.promises.mkdtemp(sr__default.join(Ls.tmpdir(),"momentic-mobile-asset-")),o=sr__default.join(r,"app.zip");return await qBe(e,o),{uploadPath:o,cleanup:()=>so.promises.rm(r,{recursive:true,force:true})}}}}function qBe(t,e){return new Promise((r,o)=>{let n=$Be("zip",{zlib:{level:9}}),i=so.createWriteStream(e);i.on("close",()=>r()),i.on("error",o),n.on("error",o),n.on("warning",a=>{a.code!=="ENOENT"&&o(a);}),n.pipe(i),n.directory(t,false,a=>sr__default.basename(a.name)===".DS_Store"?false:(a.mode=a.stats?.isDirectory()?493:420,a)),n.finalize().catch(o);})}async function KBe(t){let e=jBe.createHash("md5");await new Promise((o,n)=>{so.createReadStream(t).on("data",i=>e.update(i)).on("end",()=>o()).on("error",n);});let r=e.digest();return {md5Base64:r.toString("base64"),md5Hex:r.toString("hex")}}async function Zw({tag:t,channel:e,filePath:r,apiClient:o,logger:n,platform:i}){n.info({channel:e,tag:t,platform:i,filePath:r},"starting asset upload");let a=Date.now(),{uploadPath:s,cleanup:c}=await WBe(i,r);try{let{md5Base64:l,md5Hex:u}=await KBe(s),{size:d}=await so.promises.stat(s),m=await o.generateAssetUploadUrl({channel:e,tag:t??"latest",md5:l,platform:i});if(m.md5&&(m.md5===l||m.md5===u))return n.info({channel:e,tag:t,platform:i,filePath:r,size:d,durationMs:Date.now()-a,skipped:!0},"skipped asset upload (md5 match)"),{skipped:!0};if(!m.uploadUrl)throw new M("InternalPlatformError",`No upload URL was given for asset ${r}`);try{let p=await fetch$1(m.uploadUrl,{headers:{"Content-Length":d.toString(),"Content-Type":"application/octet-stream"},method:"PUT",body:so.createReadStream(s),duplex:"half"});if(p.status!==200)throw new M("InternalPlatformError",`Got error response from emulator platform: ${p.status} ${await p.text()}`);return n.info({channel:e,tag:t,platform:i,filePath:r,size:d,durationMs:Date.now()-a},"finished asset upload"),{skipped:!1}}catch(p){try{await o.deleteAsset(e,t??"latest",i);}catch(f){n.warn({err:f,tag:t,channel:e},"Failed to clean up asset after failed upload");}throw p}}finally{await c();}}async function Qw({channel:t,tag:e,platform:r,apiClient:o,logger:n}){let i=e??"latest";n.info({channel:t,tag:i,platform:r},`Deleting asset ${t}:${i} (${r})...`),await o.deleteAsset(t,i,r),n.info({channel:t,tag:i,platform:r},`Asset ${t}:${i} (${r}) deleted successfully!`);}var YBe=z.object({emulatorName:z.string(),platform:z.enum(Ve)});z.object({runId:z.string(),emulators:z.array(YBe)});var Gte;async function eR(t){await Gte?.registerEmulator(t);}async function tR(t){await Gte?.unregisterEmulator(t);}var rR=new Jw;var K0="0.97.2",yt=_m({app:"mobile-desktop-server",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:K0});(async()=>{try{let t=await kg(yt);t.gitBranchName&&yt.addBinding("branch",t.gitBranchName);}catch{}})();var oR=Router();oR.get("/",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({message:"API client not initialized"});return}let o=await r.getMobileAssets();e.status(200).json(o);}));oR.post("/upload-url",We(async(t,e)=>{let r;try{r=zV.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}let o=Xt();if(!o){e.status(500).json({error:"API client not initialized"});return}let n=sr__default.resolve(r.filePath);if(!existsSync(n)){e.status(400).json({error:`File not found: ${n}`});return}let i=/\.apk$/i.test(n),a=n.endsWith(".app")&&statSync(n).isDirectory();if(!i&&!a){e.status(400).json({error:"Unsupported file type. Only .apk files and .app directories are supported."});return}await Zw({tag:r.tag,channel:r.channel,filePath:n,apiClient:o,logger:yt,platform:i?"ANDROID":"IOS"}),e.sendStatus(204);}));oR.delete("/:channel/:tag/:platform",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let{channel:o,tag:n,platform:i}=t.params;if(!o||!n||!i){e.status(400).json({error:"Missing channel, tag, or platform."});return}let a=rh.safeParse(i.toUpperCase());if(!a.success){e.status(400).json({error:`Invalid platform "${i}". Expected "android" or "ios".`});return}let s=a.data;await Qw({channel:o,tag:n,platform:s,apiClient:r,logger:yt}),e.sendStatus(204);}));var Wte=oR;var bf=Router();async function nR(t){return (await PK(t,yt)).map(o=>{let n=t.mobileModules[o.moduleId];if(!n){I.warn(`Found a dangling mobile module with ID ${o.moduleId} that could not be found on disk.`);return}return {...n,content:o}}).filter(o=>o!==void 0)}bf.get("/",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o);e.status(200).json(n);}));bf.get("/tests-join",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o),i={};for(let s of n)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(o.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await mr(s.fullFilePath,yt,o)})));for(let{id:s,name:c,relativePath:l,test:u}of a){let d=new Set;Ti({steps:u.steps,onPreset:()=>false,onModule:m=>(d.add(m.moduleId),false)});for(let m of d){let p=i[m];p&&p.tests.push({id:s,name:c,relativePath:l});}}e.status(200).json(i);}));bf.get("/:moduleId",We(async(t,e)=>{if(!t.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let r=await vt(bt()),o=r.mobileModules[t.params.moduleId];if(!o){e.status(404).json({error:"Mobile module not found."});return}try{let n=await Uu(o,r,I);e.json(n);}catch(n){e.status(400).json({err:n});}}));bf.patch("/:moduleId/metadata",We(async(t,e)=>{if(!t.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let r;try{r=jV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=bt(),n=await vt(o);xK({moduleId:t.params.moduleId,patch:r,momenticFiles:n,logger:I,project:o}),e.status(201).json({message:"ok"});}));bf.post("/",We(async(t,e)=>{let r;try{r=GV.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ci(r.name);}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let o=bt(),n=await vt(o),i=n.mobileModules;if(Object.values(i).find(s=>s.name===r.name)){e.status(400).json({error:`A mobile module with the name "${r.name}" already exists. Please choose a different name.`});return}let a=sr__default.join(o.rootDir,r.folderPath??"");if(!so.existsSync(a)||!so.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}switch(r.platform){case "ANDROID":{let s=await Ug({...r,folder:a,project:o,momenticFiles:n});e.status(201).json(s);return}case "IOS":{let s=await Ug({...r,folder:a,project:o,momenticFiles:n});e.status(201).json(s);return}}}));var Kte=bf;var Yte=Router();Yte.get("/",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o),i=new Set;o?.mobileTests&&Object.values(o.mobileTests).forEach(l=>{l.labels?.forEach(u=>i.add(u));});let a=Array.from(i).sort(),s=Object.values(o.mobileTests),c={labels:a,modules:n,tests:s};e.status(200).json(c);}));var Xte=Yte;var iR=Router();iR.get("/",We((t,e)=>{let r=av(bt(),yt);e.status(200).json(r);}));iR.get("/names",We((t,e)=>{let o=bt().config.environments?.map(n=>n.name)??[];e.status(200).json(o);}));iR.post("/",We((t,e)=>{let r;try{r=$V.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ci(r.name);}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let o=bt();if(o.config.environments?.find(s=>s.name===r.name)){e.status(400).json({error:`An environment with the name "${r.name}" already exists. Please choose a different name.`});return}let i={...o.config,environments:[...o.config.environments??[],{name:r.name}]};o.config=i,Fu(i,o.configFilePath);let a=Lu(r.name,o,yt);e.status(201).json(a);}));var Jte=iR;var Zte=Router();Zte.get("/",We((t,e)=>{let r={userId:md(),orgId:qr(),email:yw(),name:YQ(),pylonEmailHash:XQ(),cliVersion:K0};e.status(200).json(r);}));var Qte=Zte;var ere=Router();ere.get("/",We(async(t,e)=>{let r=t.query.sessionId;if(!r){e.status(400).json({packages:[]});return}let o=rR.getSession(r);if(!o?.controller){e.status(200).json({packages:[]});return}try{let n=o.controller,{installedApps:i}=await n.getInstalledApps();e.status(200).json({packages:i});}catch(n){yt.error({err:n},"Error fetching installed packages from the session controller"),e.status(200).json({packages:[]});}}));var tre=ere;var rre=Router();rre.get("/",We(async(t,e)=>{let r=await hb(yt);e.status(200).json(r);}));var ore=rre;var aR=Router(),nre=async({platform:t,steps:e,cacheStorage:r,stepId:o,parentStepIdChain:n,testId:i,environment:a})=>{let{result:s,parentChain:c}=Gl(e,o,n);if(!s)return;let l=c.filter(u=>u.type==="RESOLVED_MOBILE_MODULE").map(u=>u.id);return await r.getCacheKeyForStep({platform:t,logger:yt,testId:i,environment:a,parentStepIdChain:l,step:s})};aR.patch("/",We(async(t,e)=>{let r=bt(),o=qr(),n=Xt(),i=r.config?.advanced?.isolateCachesByEnvironment;if(!n){e.status(500).json({error:"API client not initialized"});return}let a;try{a=KV.parse(t.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await dr(yt,n,r),c=Hr({logger:yt,orgId:o,client:n,gitMetadata:s,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:i}),l=await nre({cacheStorage:c,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!l){e.status(400).json({error:"Cache-supporting step not found"});return}await n.updateMobileStepCaches({platform:a.platform,body:{entries:[{key:l,organizationId:o,value:a.value,testId:a.testId,environment:i?a.environment:void 0}]},headers:hu(s)}),e.status(204).send();}));aR.delete("/entry",We(async(t,e)=>{let r=bt(),o=qr(),n=Xt(),i=r.config?.advanced?.isolateCachesByEnvironment;if(!n){e.status(500).json({error:"API client not initialized"});return}let a;try{a=XV.parse(t.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await dr(yt,n,r),c=Hr({logger:yt,orgId:o,client:n,gitMetadata:s,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:i}),l=await nre({cacheStorage:c,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!l){e.status(400).json({error:"Cache-supporting step not found"});return}await n.deleteMobileStepCacheEntry({platform:a.platform,body:{testId:a.testId,key:l,environment:i?a.environment:void 0},headers:hu(s)}),e.status(204).send();}));aR.post("/traces",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let o;try{o=JV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=await r.getMobileStepCacheMemoryTraces(o.platform,o);e.status(200).json(n);}));var ire=aR;fAe("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");var{captureEvent:ti,setAnalyticsIdentity:sR,shutdownAnalytics:lR}=ME({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://p.momentic.ai",platform:"local_mobile_app",identity:"stashed",flushImmediately:true});var gd=Router();gd.patch("/:testPath",We(async(t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o;try{o=BV.parse(t.body);}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}if(o.steps===void 0&&o.beforeSteps===void 0&&o.afterSteps===void 0&&o.settings===void 0&&o.labels===void 0){e.status(400).json({error:"At least one of steps, beforeSteps, afterSteps, settings, or labels is required"});return}let n=bt(),i=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,a=await vt(n);await zs({platform:o.platform,filePath:i,steps:o.steps,beforeSteps:o.beforeSteps,afterSteps:o.afterSteps,settings:o.settings,labels:o.labels,folder:n.rootDir,project:n,momenticFiles:a,schemaVersion:eo});let s={message:"ok"};e.status(200).json(s);}));gd.post("/",We(async(t,e)=>{let r;try{r=FV.parse(t.body);}catch(S){e.status(400).json({error:`Invalid request body: ${S}`});return}let{name:o,description:n,settings:i,pathSegments:a,platform:s}=r;if(!o||typeof o!="string"){e.status(400).json({error:"Missing or invalid 'name' in body"});return}try{ci(o);}catch(S){e.status(400).json({error:j(S)});return}let c=bt(),l=await vt(c),u=sr__default.join(c.rootDir,...a??[]),{fullPath:d,testId:m}=mv({name:o,description:n,settings:i,folder:u,platform:s,project:c,momenticFiles:l});ti({type:"test_editor:test_create",test_platform:fi(s)});let p=sr__default.basename(d),f=sr__default.relative(c.rootDir,d),h={id:m,fileName:p,fullPath:d,relativeFilePath:f};e.status(201).json(h);}));gd.get("/:fileName",We(async(t,e)=>{let r=Xt(),o=qr(),n=t.params.fileName;if(!n){e.status(400).json({error:"Missing fileName in path"});return}if(!r){e.status(500).json({error:"API client not initialized"});return}let i=n.endsWith(".test.yaml")?n:`${n}.test.yaml`,a=sr__default.basename(i).replace(".test.yaml",""),s=bt(),c=sr__default.isAbsolute(i)?i:sr__default.join(s.rootDir,i);if(!so.existsSync(c)){e.status(404).json({error:"Test not found."});return}let l=await vt(s),[u,d]=await Promise.all([mr(c,yt,l),dr(yt,r,s,{includeHostingUsername:false})]);await Hr({logger:yt,orgId:o,client:r,gitMetadata:d,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:s.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:yt,platform:u.platform,testId:u.id,environment:u.settings?.defaultEnv,stepLists:{steps:u.steps,...u.beforeSteps&&{beforeSteps:u.beforeSteps},...u.afterSteps&&{afterSteps:u.afterSteps}},useSnapshotIdentityCache:s.config.fileFormat==="v2"});let p={...u,name:a};e.status(200).json(p);}));gd.patch("/:testPath/metadata",We(async(t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o;try{o=VV.parse(t.body);}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}let n=bt(),i=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,s={message:"ok",newRelativeTestPath:IK(i,o,n).newRelativeTestPath};e.status(200).json(s);}));gd.delete("/:testPath",We((t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o=bt(),n=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,i=sr__default.join(o.rootDir,n);if(!so.existsSync(i)){e.status(404).json({error:"Test not found."});return}so.unlinkSync(i),e.status(200).json({message:"ok"});}));gd.post("/:testPath/duplicate",We(async(t,e)=>{let{testPath:r}=t.params;if(!r){e.status(400).json({error:"Missing testPath in url path."});return}let o;try{o=WV.parse(t.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}try{ci(o.name);}catch(h){e.status(400).json({error:j(h)});return}let n=bt(),i=sr__default.join(n.rootDir,r);if(!so.existsSync(i)){e.status(404).json({error:"Test not found."});return}let a=await vt(n),s;try{s=await mr(i,yt,a);}catch(h){e.status(400).json({error:j(h)});return}let c=Qm({projectConfig:n.config,momenticFiles:a,entityType:"mobile-test"}),{stepsToSave:l}=await ho({platform:s.platform,stepLists:{steps:s.steps,beforeSteps:s.beforeSteps,afterSteps:s.afterSteps},createNewCacheIds:true}),u=oo({fileType:ve.MOBILE_TEST,id:c,schemaVersion:eo,description:s.description,platform:s.platform,settings:s.settings,labels:s.labels,...l});Vy.parse(u);let d=sr__default.dirname(i),m=sr__default.join(d,`${o.name}.test.yaml`);if(so.existsSync(m)){e.status(409).send("A test with this name already exists");return}let p=Bg.stringify(u);so.writeFileSync(m,p,"utf-8");let f={relativeFilePath:sr__default.relative(n.rootDir,m)};e.status(201).json(f);}));var are=gd;var sre=Router();sre.get("/",We((t,e)=>{let r=bt(),o={ai:r.config.ai,displayRoot:r.config.displayRoot};e.status(200).json(o);}));var lre=sre;var cre=Router();cre.post("/traces",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let o;try{o=ZV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=await r.getWebStepCacheMemoryTraces(o);e.status(200).json(n);}));var ure=cre;var Ef=class extends np{constructor(r,o){super(r,o);this.client=r;this.orgId=o;}async fetchEnvironment(r,o){let n=bt();return Lu(r,n,I)}};var gVe=promisify$1(execFile$1);async function dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:n}){let{logger:i,sessionId:a}=t,s=JQ(),c=qr(),l=pb(),u=new pr({apiKey:s,baseUrl:l,logger:i}),d=new Ef(u,c),m=n??o.settings?.defaultEnv,p={};m&&(p=(await d.fetchEnvironment(m,i))?.variables??{});let f={...e.config.emulator,...o.settings?.emulator},h=new es({baseUrl:l,apiKey:s,logger:i,mode:"interactive"}),S=new js(e.config.ai?.agentConfig,{baseUrl:l,apiKey:s,logger:i,mode:"interactive"}),b=new sc({baseUrl:l,apiKey:s,logger:i,mode:"interactive"},S),y=new lc({httpClient:u,fakerSeed:e.config.advanced?.fakerConstantSeed?pm:void 0}),T=new hi({variablesFromEnvironment:p,envName:m,testName:r.name}),v=new Ka({logger:i,reporter:new ac(u),runType:"mobile-test-run",runId:a,testMetadata:r,isInteractive:true});return {logger:i,sessionId:a,orgId:c,apiClient:u,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:{storage:d,browserEnricher:b,browserGenerator:S,localCodeEvalTools:y,testContext:T},aiSettings:{useMemory:true,...e.config.ai,...o.settings?.ai},usageTracker:v}}function SVe(t){return {steps:t.steps,beforeSteps:t.beforeSteps,afterSteps:t.afterSteps}}async function mre({platform:t,project:e,logger:r,orgId:o,apiClient:n,resolvedTest:i,envName:a}){let s=SVe(i);if(e.config.fileFormat!=="v2")return s;let c=await dr(r,n,e),{alwaysSaveCache:l,noCache:u}=fs();return await Hr({logger:r,orgId:o,client:n,gitMetadata:c,regenerateCache:false,alwaysSaveCache:l,noCache:u,isolateCachesByEnvironment:e.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:r,platform:t,testId:i.id,environment:a,stepLists:s,useSnapshotIdentityCache:true}),s}async function pre({provider:t,platform:e,emulatorName:r,cleanupDriver:o}){let n=t==="remote";return n&&await eR({emulatorName:r,platform:e}),async()=>{await o(),n&&await tR({emulatorName:r,platform:e});}}async function fre({managedState:t,project:e,testEntity:r,resolvedTest:o,provider:n,envName:i,localAvdId:a,localApkPath:s}){let{logger:c,sessionId:l,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:S,aiSettings:b,usageTracker:y}=await dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:i}),T=o.settings?.defaultChannel,v=o.settings?.defaultTag,w=await mre({platform:"ANDROID",project:e,logger:c,orgId:u,apiClient:d,resolvedTest:o,envName:m}),N=await bVe({provider:n,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:o,localAvdId:a,localApkPath:s,variablesFromEnvironment:p});c.info({platform:"ANDROID",provider:n,envName:m,emulatorSettings:f,aiSettings:b},"Starting mobile session with resolved configuration");let D=n==="local"?"local":"region"in N?N.region:void 0,x=await mp({apiClient:d,logger:c,creationOpts:n==="remote"?{...N,apkToInstall:T?{channel:T,tag:v}:void 0}:N,orgId:u,sessionId:l,callbacks:{onStatusUpdate:O=>{c.info({status:O},"Android session status update");}}}),A=await pre({provider:n,emulatorName:x.emulatorName,platform:"ANDROID",cleanupDriver:async()=>{await x.cleanup();}}),B;try{let O="limbarClient"in x?{limbarClient:x.limbarClient,limbarToken:x.limbarToken,limbarUrl:x.limbarUrl,limbarRegion:x.limbarRegion,playwrightDevice:x.playwrightDevice}:void 0;B=await Fc.init({driver:x.driver,generator:h,logger:c,limbarClient:O?.limbarClient,playwrightDevice:O?.playwrightDevice,aiSettings:b,options:{emulator:{...f,region:D,browserSettings:e.config.browser}},fixtures:S,orgId:u,adbPort:x.adbPort,abortController:new AbortController});let z=await B.getViewportBounds(),k=B;return {...t,platform:"ANDROID",provider:n,controller:k,cleanup:[async()=>{await Promise.allSettled([k.cleanup(),A(),S.localCodeEvalTools.dispose()]);}],testName:r.name,relativeTestPath:r.relativePath,testFileAbsolutePath:sr__default.join(e.rootDir,r.relativePath),envName:m,orgId:u,emulatorName:x.emulatorName,viewportBounds:z,adbPort:x.adbPort,tempCaches:{},limbarUrl:O?.limbarUrl,limbarToken:O?.limbarToken,limbarRegion:O?.limbarRegion,usageTracker:y,mutableStepState:{platform:"ANDROID",testId:o.id,stepLists:w}}}catch(O){let z=B?[B.cleanup(),A()]:[A()];throw await Promise.allSettled(z),O}}async function hre({managedState:t,project:e,testEntity:r,resolvedTest:o,provider:n,envName:i,localDeviceId:a,localAppPath:s}){let{logger:c,sessionId:l,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:S,aiSettings:b,usageTracker:y}=await dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:i}),T=o.settings?.defaultChannel,v=o.settings?.defaultTag,w=await mre({platform:"IOS",project:e,logger:c,orgId:u,apiClient:d,resolvedTest:o,envName:m}),N=yVe({provider:n,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:o,appChannel:T,appTag:v,localDeviceId:a,localAppPath:s,variablesFromEnvironment:p});c.info({platform:"IOS",provider:n,envName:m,emulatorSettings:f,aiSettings:b},"Starting mobile session with resolved configuration");let D=n==="local"?"local":N.type==="remote"?N.region:void 0,x=await ef({apiClient:d,logger:c,creationOpts:N,orgId:u,sessionId:l,callbacks:{onStatusUpdate:O=>{c.info({status:O},"iOS session status update");}}}),A=await pre({provider:n,emulatorName:x.emulator.name,platform:"IOS",cleanupDriver:async()=>{await x.cleanup();}}),B;try{B=await zc.init({driver:x.driver,generator:h,logger:c,emulator:x.emulator,aiSettings:b,options:{emulator:{...f,region:D,browserSettings:e.config.browser}},fixtures:S,orgId:u,abortController:new AbortController});let O=await B.getViewportBounds(),z=B;return {...t,platform:"IOS",provider:n,controller:z,cleanup:[async()=>{await Promise.allSettled([z.cleanup(),A(),S.localCodeEvalTools.dispose()]);}],testName:r.name,relativeTestPath:r.relativePath,testFileAbsolutePath:sr__default.join(e.rootDir,r.relativePath),envName:m,orgId:u,emulatorName:x.emulator.name,viewportBounds:O,tempCaches:{},limbarUrl:x.limbarParams?.webRtcUrl,limbarToken:x.limbarParams?.token,limbarRegion:x.limbarParams?.region,usageTracker:y,mutableStepState:{platform:"IOS",testId:o.id,stepLists:w}}}catch(O){let z=B?[B.cleanup(),A()]:[A()];throw await Promise.allSettled(z),O}}async function bVe({provider:t,projectRoot:e,emulatorSettings:r,resolvedTest:o,localAvdId:n,localApkPath:i,variablesFromEnvironment:a}){if(t==="remote")return {region:r?.region==="local"?void 0:r?.region,osVersion:r?.remoteEmulatorSettings?.androidVersion??nm};let s=await X0(),{avdId:c,apkFilePath:l,apkFilePathSource:u}=dm({overrideAvdId:n,overrideApkFilePath:i,emulatorSettings:r,defaultApkFilePath:o.settings?.defaultApkFilePath,envVariables:a});if(!c){let d=s.availableAvdIds.length>0?` Known Available AVDs on this machine: ${s.availableAvdIds.join(", ")}.`:"",m=s.avdDiscoveryError?` Failed to list local AVDs: ${s.avdDiscoveryError}.`:"";throw new Error(`AVD ID is required when using a local emulator. Set it on the test (Options -> Emulator -> Local AVD ID), set ${gl} on the environment, or pass localDeviceId directly.${d}${m}`)}if(s.availableAvdIds.length>0&&!s.availableAvdIds.includes(c))throw new Error(`AVD '${c}' is not available on this machine. Available AVDs: ${s.availableAvdIds.join(", ")}.`);return {avdId:c,apkFilePath:pp({apkFilePath:l,source:u,overrideBaseDir:e})}}function yVe({provider:t,projectRoot:e,emulatorSettings:r,resolvedTest:o,appChannel:n,appTag:i,localDeviceId:a,localAppPath:s,variablesFromEnvironment:c}){if(t==="remote")return {type:"remote",region:r?.region==="local"?void 0:r?.region,appToInstall:n?{channel:n,tag:i}:void 0,osVersion:im};let{deviceType:l,appFilePath:u,appFilePathSource:d}=mm({overrideDeviceType:a,overrideAppFilePath:s,emulatorSettings:r,defaultAppFilePath:o.settings?.defaultAppFilePath,envVariables:c});if(!l)throw new Error(`A device type is required when using a local region. Pass localDeviceId, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);return {type:"local",deviceType:l,appFilePath:df({appFolderPath:u,source:d,overrideBaseDir:e})}}async function X0(){try{let{stdout:t}=await gVe(EVe(),["-list-avds"],{encoding:"utf8",timeout:5e3});return {availableAvdIds:t.split(/\r?\n/).map(r=>r.trim()).filter(Boolean)}}catch(t){return {availableAvdIds:[],avdDiscoveryError:j(t)}}}function EVe(){let t=process.platform==="win32"?"emulator.exe":"emulator";return process.env.ANDROID_HOME?sr__default.join(process.env.ANDROID_HOME,"emulator",t):t}var gre=5,J0=class extends JA{isStartingSession=false;constructor(){super({sessionTypeLabel:"mobile MCP session"});}async kill(e,r){try{let o;for(let i of e.cleanup)try{await i();}catch(a){o??=a;}if(o)throw o;await e.usageTracker.flush(e.logger);let n=ZZ(e);return await SQ({apiClient:Xt(),logger:e.logger,orgId:e.orgId,testId:e.testId,sessionId:e.sessionId,reason:r,report:n}),e.logger.info({sessionId:e.sessionId,reason:r,emulatorName:e.emulatorName},"MCP session cleaned up"),{killed:!0,sessionId:e.sessionId,reason:r,report:n}}catch(o){return e.logger.error({err:o,sessionId:e.sessionId,reason:r},"Failed to clean up mobile MCP session"),{killed:false,sessionId:e.sessionId,reason:r}}}touchSession(e){let r=super.touchSession(e);return r?.provider==="remote"&&Xt()?.extendEmulatorTtl(r.platform,r.emulatorName).catch(()=>{}),r}async createSession({logger:e,testId:r,idleTimeoutMs:o,provider:n,envName:i,localDeviceId:a,localAppPath:s,project:c}){let l=this.listSessionIds();if(this.isStartingSession||l.length>0)throw new Error(JSON.stringify({message:"Another mobile MCP session is already active or starting. Please terminate the existing session before creating a new one.",activeSessionIds:l},null,2));this.isStartingSession=true;let u;try{let{entity:d,momenticFiles:m}=await ts(c,{id:r},"mobileTests"),p=await mr(d.fullFilePath,e,m),S=(p.settings?.emulator?.region??c.config.emulator?.region)==="local"?"local":"remote",b=n??S,y,{platform:T}=p,v=e.child({testId:p.id});switch(T){case "ANDROID":u=this.buildManagedSessionState({logger:v,idleTimeoutMs:o,testId:d.id}),y=await fre({managedState:u,project:c,testEntity:d,resolvedTest:p,provider:b,envName:i,localAvdId:a,localApkPath:s});break;case "IOS":u=this.buildManagedSessionState({logger:v,idleTimeoutMs:o,testId:d.id}),y=await hre({managedState:u,project:c,testEntity:d,resolvedTest:p,provider:b,envName:i,localDeviceId:a,localAppPath:s});break;default:return Vt(T)}return v.info({sessionId:y.sessionId,testId:p.id},"Started MCP session for test"),y}catch(d){throw u&&clearTimeout(u.timeoutHandle),d}finally{this.isStartingSession=false;}}},Ho=new J0,Sd=({response:t,sessionId:e,toolName:r})=>{let o=Ho.touchSession(e);if(o)return t.addCleanupCallback(()=>{gQ({session:o,toolCallId:t.toolCallId});}),hQ({session:o,toolCallId:t.toolCallId,toolName:r}),o;t.addError(JSON.stringify({message:`No active session found for id '${e}'.`,availableSessionIds:Ho.listSessionIds()},null,2));};var vVe=4e4,CVe=1e4,Q0,bre=({staticDir:t})=>{Q0=t;},cR=class t{url;server;constructor({url:e,server:r}){this.url=e,this.server=r;}static async init({logger:e,testId:r,testName:o,sessionId:n,platform:i,limbarUrl:a,limbarToken:s,limbarRegion:c,tabLabel:l}){let u=await _Ve({logger:e,assets:AVe()}),d=new URL(`http://localhost:${u.port}/`);return d.searchParams.set("testId",r),o&&d.searchParams.set("testName",o),d.searchParams.set("sessionId",n),d.searchParams.set("platform",i),d.searchParams.set("url",a),d.searchParams.set("token",s),c&&d.searchParams.set("region",c),l&&d.searchParams.set("tabLabel",l),new t({url:d.toString(),server:u})}async shutdown(){this.server?.server.listening&&(await new Promise(e=>{this.server?.server.close(()=>{e();});}),this.server=void 0);}};function AVe(){if(!Q0)throw new Error("Remote control viewer static directory is not configured. Pass remoteControlStaticDir when starting the mobile MCP server.");let t=sr__default.resolve(Q0),e=sr__default.join(t,"index.html");if(!so.existsSync(e))throw new Error(`Remote control viewer index file not found at '${e}'. Ensure mobile-remote-control-frontend is built and copied into npm/mobile-cli/remote-control-static.`);return {staticDir:t,indexHtmlBuffer:so.readFileSync(e)}}function Z0({response:t,statusCode:e,body:r,allow:o}){let n={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"};o&&(n.Allow=o),t.writeHead(e,n),t.end(r);}function Sre({request:t,response:e,buffer:r,contentType:o}){if(e.writeHead(200,{"Content-Type":o,"Cache-Control":"no-store"}),t.method==="HEAD"){e.end();return}e.end(r);}function wVe({staticDir:t,pathname:e}){let r;try{r=decodeURIComponent(e);}catch{return}let o=r==="/"?"index.html":r.replace(/^\/+/,""),n=sr__default.resolve(t,o),i=sr__default.relative(t,n);if(!(i.startsWith("..")||sr__default.isAbsolute(i)))return n}function RVe({request:t,response:e,assets:r}){if(t.method!=="GET"&&t.method!=="HEAD"){Z0({response:e,statusCode:405,body:"Method Not Allowed",allow:"GET, HEAD"});return}let o=new URL(t.url??"/","http://localhost").pathname;if(o==="/"||o==="/index.html"){Sre({request:t,response:e,buffer:r.indexHtmlBuffer,contentType:"text/html; charset=utf-8"});return}let n=wVe({staticDir:r.staticDir,pathname:o});if(!n){Z0({response:e,statusCode:403,body:"Forbidden"});return}if(!so.existsSync(n)||!so.statSync(n).isFile()){Z0({response:e,statusCode:404,body:"Not Found"});return}let i=sr__default.extname(n).toLowerCase(),a=mu[i]??"application/octet-stream";Sre({request:t,response:e,buffer:so.readFileSync(n),contentType:a});}async function _Ve({logger:t,assets:e}){let r=createServer((i,a)=>RVe({request:i,response:a,assets:e})),o=Math.floor(Math.random()*CVe)+vVe,n=await Hl(o,"mobile-mcp-remote-control-viewer");return await new Promise((i,a)=>{let s=c=>{a(c);};r.once("error",s),r.listen(n,()=>{r.off("error",s),i();});}),t.info({port:n,staticDir:e.staticDir},"Started mobile MCP remote control viewer server"),{port:n,server:r}}function ek({logger:t,applicationName:e,cliVersion:r,serverId:o=randomUUID()}){let n={serverId:o,applicationName:e,cliVersion:r},i=qr(),a=t.child({orgId:i,userId:md(),...n});return {info:n,mcpLogger:a,orgId:i}}function tk({sessionIdleTimeoutMinutes:t}){return (t&&t>=1?t:gre)*60*1e3}async function uR({project:t,serverUrl:e,alwaysSaveCache:r,noCache:o,remoteControlStaticDir:n}){bre({staticDir:n}),Qp(e),bw({alwaysSaveCache:r,noCache:o}),sR({userId:md(),orgId:qr(),selfServe:Ew()}),Tw(t,i=>qn({configFilePath:i}));}function dR({project:t,logger:e,apiKey:r,serverUrl:o,supportsFileOutput:n,headfulDefault:i,sessionIdleTimeoutMinutes:a,applicationName:s,cliVersion:c,serverId:l}){let{info:u,mcpLogger:d,orgId:m}=ek({logger:e,applicationName:s,cliVersion:c,serverId:l}),p=new es({baseUrl:o,apiKey:r,logger:d,mode:"interactive"});return {context:{project:t,orgId:m,logger:d,generator:p,serverId:u.serverId,saveChangesToDisk:true,sessionIdleTimeoutMs:tk({sessionIdleTimeoutMinutes:a}),supportsFileOutput:n,headfulDefault:i},info:u}}async function IVe({moduleId:t,name:e,description:r,enabled:o,platform:n,parameters:i,steps:a,project:s}){let c=await vt(s),{stepsToSave:{steps:l}}=await ho({platform:n,stepLists:{steps:a}});Ja({content:{platform:n,moduleId:t,name:e,description:r,enabled:o,parameters:i,steps:l},schemaVersion:eo,momenticFiles:c,project:s});}function OVe({module:t,inputs:e}){return {...t,id:randomUUID(),type:"RESOLVED_MOBILE_MODULE",inputs:e}}async function yre({project:t,logger:e,testPath:r,saveChangesToDisk:o,mutableStepState:n,params:i,initialMomenticFiles:a,platform:s,availableSteps:c,cacheContext:l}){let{stepsToExtract:u,startIndex:d,endIndex:m}=EQ({moduleName:i.name,existingModuleNames:Object.values(a.mobileModules).map(h=>h.name),parameterNames:i.parameters?.parameterNames,defaultParameters:i.parameters?.defaultParameters,parameterEnums:i.parameters?.parameterEnums,moduleInputs:i.moduleInputs,testPath:r,startIndex:i.startIndex,endIndex:i.endIndex,availableSteps:c,containsNestedModuleStep:fq}),p=sr__default.join(t.rootDir,i.folderPath??"");i.folderPath&&so.mkdirSync(p,{recursive:true});let f=await Ug({name:i.name,platform:s,description:i.description??"",enabled:i.enabled??true,steps:u,folder:p,project:t,momenticFiles:a});if(i.parameters!==void 0&&(await IVe({moduleId:f.moduleId,name:i.name,description:i.description??"",enabled:i.enabled??true,platform:s,parameters:i.parameters,steps:u,project:t}),f={...f,name:i.name,description:i.description??"",parameters:i.parameters}),o&&i.startIndex!==void 0&&r!==void 0){let h=await vt(t);if(!c)throw new Error("Mobile module was created successfully, but the source test steps were not available for replacement.");let S=OVe({module:f,inputs:i.moduleInputs}),b=[...c];if(b.splice(d,m-d,S),await zs({platform:s,filePath:r,steps:b,folder:t.rootDir,project:t,momenticFiles:h,schemaVersion:eo}),n&&(n.stepLists={...n.stepLists,steps:b}),l){let{cachesToSave:y,snapshotCachesToSave:T}=await ho({platform:s,stepLists:{steps:b},cacheCreationParams:{orgId:l.orgId,testId:l.testId,environment:l.envName},useSnapshotIdentityCache:l.useSnapshotIdentityCache});try{await l.cacheStorage.saveEntries({platform:s,logger:e,entries:y});}catch(v){e.warn({err:v},"Failed to save mobile step caches after module create, future runs may be slower");}if(l.useSnapshotIdentityCache)try{await l.cacheStorage.saveSnapshotCacheEntries({platform:s,logger:e,entries:T});}catch(v){e.warn({err:v},"Failed to save mobile snapshot identity cache after module create, future runs may regenerate step ids");}}}return f}function Ere(t,e,r){if(!t)return {availableSteps:void 0,mutableStepState:void 0};if(t.platform!==e)throw new Error(`Internal error: test platform ${t.platform} does not match resolved platform ${e}`);return r&&r.testId===t.id&&r.platform===e?{availableSteps:r.stepLists.steps,mutableStepState:r}:{availableSteps:t.steps,mutableStepState:void 0}}async function vre({project:t,logger:e,testPath:r,saveChangesToDisk:o,mutableStepState:n,params:i}){ci(i.name);let a=await vt(t),s=r!==void 0?await mr(sr__default.join(t.rootDir,r),e,a):void 0,c=s?.platform??i.platform??"ANDROID";if(i.platform&&c!==i.platform)throw new Error(`Error: Requested module platform ${i.platform} does not match source test platform ${s?.platform}.`);let l;if(s!==void 0){let d=Xt();if(d){let m=await dr(e,d,t),{alwaysSaveCache:p,noCache:f}=fs();l={cacheStorage:Hr({logger:e,orgId:qr(),client:d,gitMetadata:m,regenerateCache:false,alwaysSaveCache:p,noCache:f,isolateCachesByEnvironment:t.config?.advanced?.isolateCachesByEnvironment}),testId:s.id,orgId:qr(),envName:s.settings?.defaultEnv,useSnapshotIdentityCache:t.config.fileFormat==="v2"};}}let u={project:t,logger:e,testPath:r,saveChangesToDisk:o,params:i,initialMomenticFiles:a,cacheContext:l};switch(c){case "ANDROID":return {module:await yre({...u,platform:"ANDROID",...Ere(s,"ANDROID",n)})};case "IOS":return {module:await yre({...u,platform:"IOS",...Ere(s,"IOS",n)})};default:return Vt(c)}}var Cre=Vo({schema:{name:oy,description:"Get a single fully loaded mobile module by id, exact name, or file path. This returns complete module details including parameters, description, and the full step list. Exactly one selector must be provided.",inputSchema:z.object({selector:tU})},handle:async(t,e,r)=>{let{project:o,logger:n}=t;try{let i=await ts(o,e.selector,"mobileModules"),a=await Uu(i.entity,i.momenticFiles,n);r.addPartFromText(JSON.stringify({module:a},null,2));}catch(i){r.addError(j(i));}}}),Are=Vo({schema:{name:ZF,description:"Create a mobile module. If startIndex is provided, testPath is required and the specified mobile test range is extracted into a module for that test's platform, then replaced with a module invocation in that test. For empty modules, platform defaults to Android unless platform or testPath identifies iOS.",inputSchema:PM},handle:async(t,e,r)=>{try{let o=PM.parse(e),{testPath:n,...i}=o,a=D6({projectRoot:t.project.rootDir,filePath:n,pathLabel:"testPath"}),s;if(a!==void 0){let l=sr__default.join(t.project.rootDir,a);for(let u of Ho.listSessionIds()){let d=Ho.getSession(u);if(d!==void 0&&d.testFileAbsolutePath===l){s=d.mutableStepState;break}}}let c=await vre({project:t.project,logger:t.logger,testPath:a,saveChangesToDisk:t.saveChangesToDisk,mutableStepState:s,params:i});r.addPartFromText(JSON.stringify(c.module,null,2));}catch(o){r.addError(j(o));}}});function mR({step:t,parentChain:e}){let r=t;r.parentStepIdChain=e.map(o=>o.id),delete r.retries,delete r.skipped;}function FVe(t){let e=cloneDeep(t);return Ti({steps:e,earlyStop:false,onPreset:(r,o)=>{if(mR({step:r,parentChain:o.parentChain}),r.type==="MOBILE_PRESET_STEP"){let n=r.command;delete n.cache,delete n.id,delete n.thoughts;}return false},onModule:(r,o)=>{mR({step:r,parentChain:o.parentChain});let n=r;return delete n.enabled,delete n.schemaVersion,false},onConditional:(r,o)=>(mR({step:r,parentChain:o.parentChain}),false),onAiAction:(r,o)=>{mR({step:r,parentChain:o.parentChain});let n=r;return delete n.cache,false}}),e.map((r,o)=>{let n=r;return n.index=o,n})}function rk(t,e){if(t.length===0)return `${e}: (no steps)`;let r=["```json",JSON.stringify(FVe(t),null,2),"```"].join(`
|
|
5922
|
+
`;function Ote(t){return Kw(t,xte,Ite())}var tl={initializeAIActionConfig:Ote,stepSchema:po,resultSchema:yn};var MBe=5e3;async function Dte({socket:t,logger:e,orgId:r,testMetadata:o,globalOrgSettings:n,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:c,storageFactory:l,cacheStorageFactory:u,localToolsFactory:d,onRemoteEmulatorCreated:m,onRemoteEmulatorDeleted:p,billingReporterFactory:f,globalStateManager:h,getGitMetadata:S,region:b,localApkPath:y,localAvdId:T}){let v=t.id,w=await S(),N=t.handshake.query?.fileName,D=N?sr__default.basename(N,".test.yaml"):"",x=o.id;e=e.child({sessionId:v,testId:x,orgId:r,branch:w.gitBranchName});let A=await l(r),B=o.settings?.defaultEnv,O={};B&&(O=(await A.fetchEnvironment(B,e))?.variables??{});let z={...n.emulator,...o.settings?.emulator},k={...n.ai,useMemory:n.ai?.useMemory!==false,...o.settings?.ai},H=h.getSession(v);if(H){if(e.info("Reconnecting to existing Android session"),H.local)return t.emit("session",H.metadata),H.softDeleted=false,H.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let ne=await u(r,w),L=wl.optional().parse(b??z.region),$=L==="local",F,U,K;if($){if(await h.clearSoftDeletedLocalSessions(e),h.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{avdId:Ln,apkFilePath:sl,apkFilePathSource:ll}=dm({overrideAvdId:T,overrideApkFilePath:y,emulatorSettings:z,defaultApkFilePath:o.settings?.defaultApkFilePath,envVariables:O}),cl=pp({apkFilePath:sl,source:ll});if(!Ln)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${gl} key on the environment.`);K={avdId:Ln,apkFilePath:cl};}else F=o.settings?.defaultChannel,U=o.settings?.defaultTag,K={region:L===Vn?void 0:L,apkToInstall:F?{channel:F,tag:U}:void 0,osVersion:z.remoteEmulatorSettings?.androidVersion??nm};e.info({platform:"ANDROID",isLocalRegion:$,resolvedRegion:L,envName:B,emulatorSettings:z,aiSettings:k},"Starting mobile session with resolved configuration");let ee=Date.now(),V=await i({socket:t,logger:e,creationOpts:K}),{driver:le,cleanup:de,emulatorName:je,adbPort:kt}=V,nt,Fr,Xr,q,Be,jt;"limbarClient"in V&&(nt=V.limbarClient,Fr=V.limbarToken,Xr=V.limbarUrl,q=V.limbarRegion,Be=V.limbarOsVersion,jt=V.playwrightDevice);let it=sr__default.join(tmpdir(),`logcat-logs-${r}-${x}-${v}.txt`);$||await m?.({emulatorName:je,platform:"ANDROID"}),e.info({adbPort:kt,apkChannel:F,apkTag:U,duration:Date.now()-ee,emulatorName:je},"Android emulator session initiated"),e=e.child({emulator:je});let ge=false,ni=false,Bi,Dn,bs,ys,Hc=async()=>{if(ge)return;ge=true,ni=true,clearInterval(bs),bs=void 0;let sl=[async()=>{await Dn?.cleanup();},async()=>{await Bi?.();},async()=>{await de(),$||await p?.({emulatorName:je,platform:"ANDROID"});},async()=>{await ys?.dispose();}].map(ll=>ll().catch(cl=>{e.warn({err:cl},"Failed to clean up socket server resource");}));await Q(Promise.allSettled(sl),{milliseconds:MBe,fallback:()=>{}});};h.registerPendingSession(v,{platform:"ANDROID",cleanup:Hc,emulatorName:je,local:$});let al=async()=>{Bi=await le.executeInNativeContext(e,Ht=>Xv({driver:Ht,onLogs:_r=>{t.emit("logcatLogs",_r);},logFilePath:it}),{operationName:"startLogcatListener"});let Ln=await a(r,e),sl=await s(r,e),ll=await c(r,e);ys=d?await d(r):void 0;let cl=new Ka({logger:e,reporter:await f(r),runType:"mobile-test-run",runId:v,testMetadata:{id:o.id,name:D},isInteractive:true}),_f=new hi({variablesFromEnvironment:O,envName:B,testName:D});if(Dn=await Fc.init({driver:le,generator:Ln,logger:e,limbarClient:nt,playwrightDevice:jt,aiSettings:k,options:{emulator:{...z,browserSettings:n.browser}},fixtures:{storage:A,browserEnricher:ll,browserGenerator:sl,localCodeEvalTools:ys,testContext:_f},orgId:r,adbPort:kt,abortController:new AbortController}),!Dn)throw new Error("Failed to initialize Android controller");let Mf=Dn;if(ni||!t.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");let R=await Mf.getViewportBounds();if(ni||!t.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");bs=xBe({socket:t,testContext:_f});let J={sessionId:v,testId:x,orgId:r,emulatorName:je,testName:D,limbarUrl:Xr,limbarToken:Fr,limbarRegion:q,limbarOsVersion:Be,viewportBounds:R,envName:B};return h.registerSession(v,{platform:"ANDROID",controller:Mf,cacheStorage:ne,cleanup:Hc,emulatorName:je,local:$,metadata:J,logFilePath:it,helpers:el,usageTracker:cl}),t.emit("session",J),J};try{return await al()}catch(Ln){throw await h.removeSession(v,e),Ln}}function xBe({socket:t,testContext:e}){return setInterval(()=>{let r=e.toEditorDisplayCopy();t.emit("emulatorState",{context:r});},3e3)}async function Lte({socket:t,logger:e,globalStateManager:r,authorization:o}){let n=t.id,i=r.getSession(n);i&&i.platform==="ANDROID"&&o&&i.logFilePath&&PBe({testId:i.metadata.testId,sessionId:n,logFilePath:i.logFilePath,authorization:o,logger:e}),await r.removeSession(n,e);}async function PBe({testId:t,sessionId:e,logFilePath:r,authorization:o,logger:n}){try{let i;try{i=await Yw.stat(r);}catch{n.debug({logFilePath:r},"No logcat file found to upload");return}if(i.size===0){n.debug({logFilePath:r},"Logcat file is empty, skipping upload"),await Yw.unlink(r);return}let a=new pr(o),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:t,sessionId:e}),c=await Yw.readFile(r),l=await fetch(s,{headers:{"Content-Length":c.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:c});if(l.status!==200)throw new Error(`Failed to upload logcat: ${l.status} ${await l.text()}`);n.info({testId:t,sessionId:e,objectUrl:RT(s)},"Logcat file uploaded successfully");}catch(i){n.warn({err:i,testId:t,sessionId:e},"Failed to upload logcat file");}finally{try{await Yw.unlink(r);}catch(i){n.warn({err:i,logFilePath:r},"Failed to delete temp logcat file");}}}var IBe=({socket:t,globalStateManager:e})=>async()=>{let r=e.getSession(t.id);if(!r)throw new Error("No active Mobile session found");r.controller.abort();},kte={event:"cancel",createHandler:IBe};var OBe=({logger:t,globalStateManager:e,socket:r})=>async(o,n)=>{let i=e.getSession(r.id);if(!i){n({err:"No active Mobile session found"});return}let a=i.controller;a.resetAbortController();let s=Date.now();try{let c=await a.getEmulatorDomState();t.info({durationMs:Date.now()-s},"Fetched screen XML"),n({screenXml:c});}catch(c){t.error({err:c},"Error fetching screen XML from the session controller"),n({err:c.message});}},Fte={event:"fetchScreenXml",createHandler:OBe};var W0=class{parentTracer;socket;step;orgId;interactionTracer;platform;constructor({step:e,socket:r,parentTracer:o,orgId:n,platform:i}){this.socket=r,this.parentTracer=o,this.step=e,this.orgId=n,this.platform=i,this.interactionTracer=new Mi,Uo.initializeRootTracerContext(this.interactionTracer);}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:r,step:o}=e;if(!cE(o))return;let n=lE(o);_t.distribution("test_mobile_step_duration",r,[`type:${n}`,`platform:${this.platform.toLowerCase()}`,"executor:editor",`orgId:${this.orgId}`]);}async finish(e){this.interactionTracer.finish();let r=this.interactionTracer.getRootSpan(),o={result:e.result,parentStepIdChain:e.parentStepIdChain,trace:vM.parse(r)};switch(o.result.status){case "SUCCESS":this.socket.emit("success",o);break;case "FAILED":this.socket.emit("failure",o);break;case "CANCELLED":this.socket.emit("cancelled",o);break}return {trace:r}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new hf({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId,platform:this.platform})}},hf=class{parentTracer;parentStep;socket;orgId;platform;constructor({parentStep:e,socket:r,parentTracer:o,orgId:n,platform:i}){this.parentTracer=o,this.parentStep=e,this.socket=r,this.orgId=n,this.platform=i;}getParentStepIdChain(){return this.parentStep?[...this.parentTracer?.getParentStepIdChain()??[],this.parentStep.id]:[]}async startStep(e){return this.socket.emit("started",{stepId:e.step.id,parentStepIdChain:e.parentStepIdChain,attempt:e.attempt}),new W0({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId,platform:this.platform})}async getScreenshot(e){}},Xw=class{constructor(e,r,o){this.socket=e;this.orgId=r;this.platform=o;}appendLogs(){}setActiveVideo(){}async finish(){this.socket.emit("finished");}async startBeforeStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startMainStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startAfterStepList(){return new hf({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}};var NBe=({metadata:t,logger:e,globalStateManager:r,socket:o,useSnapshotIdentityCache:n})=>async(i,a)=>{let s=r.getSession(o.id);if(!s)throw new Error("No active Mobile session found");let c=e.child({testId:i.testMetadata.id});s.controller.resetAbortController();let l=s.usageTracker,u;try{u=await DBe({session:s,params:i,metadata:t,testLogger:c,usageTracker:l,socket:o,useSnapshotIdentityCache:n});}finally{await l.flush(c);}let d={results:s.helpers.resultSchema.array().parse(u.results),status:u.status};a?.(d);};async function DBe({session:t,...e}){switch(t.platform){case "ANDROID":return Ute({session:t,...e});case "IOS":return Ute({session:t,...e});default:return (o=>{throw new Error(`Unsupported platform: ${o}`)})(t)}}async function Ute({session:t,params:e,metadata:r,testLogger:o,usageTracker:n,socket:i,useSnapshotIdentityCache:a}){let s=new Xw(i,r.orgId,t.platform);try{return await ff({platform:t.platform,work:{fastForwardingToStep:!!e.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:t.controller,logger:o,cacheStorage:t.cacheStorage,usageTracker:n},containerName:"entire test",inputs:{steps:t.helpers.stepSchema.array().parse(e.steps),beforeSteps:e.beforeSteps?t.helpers.stepSchema.array().parse(e.beforeSteps):void 0,afterSteps:e.afterSteps?t.helpers.stepSchema.array().parse(e.afterSteps):void 0,fromStep:e.fromStep,toStep:e.toStep,orgId:r.orgId,testName:r.testName,testMetadata:e.testMetadata,interactive:!0,useSnapshotIdentityCache:a},envName:r.envName,tracer:s,callbacks:{step:{onAiActionEvent:c=>{i.emit("aiActionEvent",c);}}},helpers:t.helpers})}finally{await s.finish();}}var Bte={event:"execute",createHandler:NBe};var kBe=({socket:t,globalStateManager:e,keepSessionAlive:r})=>{let o=debounce(r,3e4,{maxWait:6e4});return async()=>{let n=e.getSession(t.id);if(!n)throw new Error("No active Mobile session found");n.emulatorName&&(n.local||o(n.platform,n.emulatorName));}},Vte={event:"keepalive",createHandler:kBe};var FBe=({socket:t,globalStateManager:e,logger:r})=>async(o,n)=>{let i=e.getSession(t.id);if(!i){let s="No active session found";r.error(s),n?.({success:false,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),r.info({platform:i.platform},"Resetting emulator state");try{await a.softReset(),r.info({platform:i.platform},"Emulator reset completed"),n?.({success:!0,message:"Emulator reset successfully"});}catch(s){let c=j(s);r.error({err:s,platform:i.platform},"Failed to reset emulator"),n?.({success:false,err:`Failed to reset emulator: ${c}`});}},zte={event:"reset",createHandler:FBe};var $te=[Bte,kte,zte,Vte,Fte];var BBe=5e3;async function jte({socket:t,logger:e,orgId:r,testMetadata:o,globalOrgSettings:n,localIosDeviceType:i,iosDriverFactory:a,mobileGeneratorFactory:s,browserGeneratorFactory:c,browserEnricherFactory:l,billingReporterFactory:u,storageFactory:d,cacheStorageFactory:m,localToolsFactory:p,onRemoteEmulatorCreated:f,onRemoteEmulatorDeleted:h,globalStateManager:S,getGitMetadata:b,region:y,localAppPath:T}){let v=t.id,w=await b(),N=t.handshake.query?.fileName,D=N?sr__default.basename(N,".test.yaml"):"",x=o.id,A=o.settings?.defaultChannel,B=o.settings?.defaultTag;e=e.child({sessionId:v,testId:x,orgId:r,branch:w.gitBranchName});let O=await d(r),z=o.settings?.defaultEnv,k={};z&&(k=(await O.fetchEnvironment(z,e))?.variables??{});let H={...n.emulator,...o.settings?.emulator},ne={...n.ai,useMemory:n.ai?.useMemory!==false,...o.settings?.ai},L=S.getSession(v);if(L){if(e.info("Reconnecting to existing iOS session"),L.local)return t.emit("session",L.metadata),L.softDeleted=false,L.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let $=await m(r,w),F=wl.optional().parse(y??H.region),U=F==="local",K;if(U){if(await S.clearSoftDeletedLocalSessions(e),S.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{deviceType:ge,appFilePath:ni,appFilePathSource:Bi}=mm({overrideDeviceType:i,overrideAppFilePath:T,emulatorSettings:H,defaultAppFilePath:o.settings?.defaultAppFilePath,envVariables:k});if(!ge)throw new Error(`A device type is required when using a local region. Provide --local-ios-device-type, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);let Dn=df({appFolderPath:ni,source:Bi});K={type:"local",deviceType:ge,appFilePath:Dn};}else K={type:"remote",region:F===Vn?void 0:F,appToInstall:A?{channel:A,tag:B}:void 0,osVersion:im};e.info({platform:"IOS",isLocalRegion:U,resolvedRegion:F,envName:z,emulatorSettings:H,aiSettings:ne},"Starting mobile session with resolved configuration");let ee=Date.now(),{driver:V,cleanup:le,emulator:de,limbarParams:je}=await a({socket:t,logger:e,creationOpts:K});e=e.child({emulator:de.name}),e.info({duration:Date.now()-ee},"iOS emulator session initiated"),U||await f?.({emulatorName:de.name,platform:"IOS"});let kt=false,nt=false,Fr,Xr,q,Be,jt=async()=>{if(kt)return;kt=true,nt=true,q&&(clearInterval(q),q=void 0);let ni=[async()=>{await Xr?.cleanup();},async()=>{Fr?.();},async()=>{await le(),U||await h?.({emulatorName:de.name,platform:"IOS"});},async()=>{await Be?.dispose();}].map(Bi=>Bi().catch(Dn=>{e.warn({err:Dn},"Failed to clean up socket server resource");}));await Q(Promise.allSettled(ni),{milliseconds:BBe,fallback:()=>{}});};S.registerPendingSession(v,{platform:"IOS",cleanup:jt,emulatorName:de.name,local:U});let it=async()=>{Fr=await Mw({emulator:de,onLogs:Ln=>{t.emit("syslogLogs",Ln);}});let ge=await s(r,e),ni=await c(r,e),Bi=await l(r,e);Be=p?await p(r):void 0;let Dn=new Ka({logger:e,reporter:await u(r),runType:"mobile-test-run",runId:v,testMetadata:{id:o.id,name:D},isInteractive:true}),bs=new hi({variablesFromEnvironment:k,envName:z,testName:D});if(Xr=await zc.init({driver:V,generator:ge,logger:e,emulator:de,aiSettings:ne,options:{emulator:{...H,browserSettings:n.browser}},fixtures:{storage:O,browserEnricher:Bi,browserGenerator:ni,localCodeEvalTools:Be,testContext:bs},orgId:r,abortController:new AbortController}),!Xr)throw new Error("Failed to initialize iOS controller");let ys=Xr;if(nt||!t.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");let Hc=await ys.getViewportBounds();if(nt||!t.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");q=VBe({socket:t,testContext:bs});let al={sessionId:v,testId:x,orgId:r,emulatorName:de.name,testName:D,limbarUrl:je?.webRtcUrl,limbarToken:je?.token,limbarRegion:je?.region,limbarOsVersion:je?.osVersion,viewportBounds:Hc,envName:z};return S.registerSession(v,{platform:"IOS",controller:ys,cacheStorage:$,cleanup:jt,emulatorName:de.name,local:U,metadata:al,helpers:tl,usageTracker:Dn}),t.emit("session",al),al};try{return await it()}catch(ge){throw await S.removeSession(v,e),ge}}function VBe({socket:t,testContext:e}){return setInterval(()=>{let r=e.toEditorDisplayCopy();t.emit("emulatorState",{context:r});},3e3)}var Jw=class{sessions=new Map;pendingSessions=new Map;registerPendingSession(e,r){this.pendingSessions.set(e,r);}registerSession(e,r){this.pendingSessions.delete(e),this.sessions.set(e,r);}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let r of this.sessions.values())r.softDeleted===true&&r.local===true&&await this.removeSession(r.metadata.sessionId,e);}hasActiveLocalSession(){for(let e of [...this.sessions.values(),...this.pendingSessions.values()])if(e.local===true)return true;return false}async removeSession(e,r){let o=this.sessions.get(e)??this.pendingSessions.get(e);if(!o)return;let n=r.child({sessionId:e,emulatorName:o.emulatorName,platform:o.platform});try{await this.sessions.get(e)?.usageTracker.flush(n);}catch(i){n.error({err:i},"Error flushing usage tracker before cleanup");}try{await o.cleanup?.(),n.info("Emulator cleaned up by removeSession");}catch(i){n.error({err:i},"Error during emulator cleanup");}finally{this.sessions.delete(e),this.pendingSessions.delete(e);}}async removeAllSessions(e){let r=Array.from(new Set([...this.sessions.keys(),...this.pendingSessions.keys()]));await Promise.all(r.map(o=>this.removeSession(o,e)));}};function Hte(t){let{logger:e,baseServer:r,globalStateManager:o,settingsFactory:n,getOrgId:i}=t,a=new Server(r,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:true,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:true}}),s=async()=>{await o.removeAllSessions(e);};a.on("connection",async l=>{let u=l.id,d=e.child({sessionId:u});d.info({event:"connection",transport:l.conn.transport.name},"Mobile websocket connection initiated"),l.on("disconnect",async f=>{if(e.info({reason:f},"Disconnect received"),f.includes("namespace disconnect")){await Lte({socket:l,globalStateManager:o,logger:d,authorization:t.authorization});return}let h=o.getSession(u);h&&(h.softDeleted=true);});let m,p;try{let f=l.handshake.query?.testMetadata,h=Rl.parse(JSON.parse(f??"")),S=h.id,b=await i({testId:S});switch(p=await n(b,e),h.platform){case "ANDROID":m=await Dte({...t,orgId:b,socket:l,globalStateManager:o,logger:d,globalOrgSettings:p,testMetadata:h});break;case "IOS":m=await jte({...t,orgId:b,socket:l,globalStateManager:o,logger:d,globalOrgSettings:p,testMetadata:h});break;default:throw new Error("Unsupported platform")}}catch(f){d.error({err:f},"Failed to setup mobile connection"),l.emit("error",{message:f instanceof Error?f.message:JSON.stringify(f)}),l.disconnect(true);return}$te.forEach(f=>c(f,{...t,socket:l,metadata:m,globalOrgSettings:p,logger:d}));});let c=(l,u)=>{let d=l.createHandler(u),m=(...p)=>{l.event!=="keepalive"&&u.logger.debug({event:l.event},`Websocket event (${l.event})`);let f=h=>{u.logger.error({event:l.event,err:h instanceof Error?h:new Error(`${h}`)},"Unhandled exception in socket handler"),u.socket.emit("error",{message:h instanceof Error?h.message:typeof h=="string"?h:JSON.stringify(h)});};try{let h=d.apply(this,p);h&&typeof h.catch=="function"&&h.catch(f);}catch(h){f(h);}};u.socket.on(l.event,m);};return {server:a,dispose:s}}async function WBe(t,e){switch(t){case "ANDROID":return {uploadPath:e,cleanup:async()=>{}};case "IOS":{let r=await so.promises.mkdtemp(sr__default.join(Ls.tmpdir(),"momentic-mobile-asset-")),o=sr__default.join(r,"app.zip");return await qBe(e,o),{uploadPath:o,cleanup:()=>so.promises.rm(r,{recursive:true,force:true})}}}}function qBe(t,e){return new Promise((r,o)=>{let n=$Be("zip",{zlib:{level:9}}),i=so.createWriteStream(e);i.on("close",()=>r()),i.on("error",o),n.on("error",o),n.on("warning",a=>{a.code!=="ENOENT"&&o(a);}),n.pipe(i),n.directory(t,false,a=>sr__default.basename(a.name)===".DS_Store"?false:(a.mode=a.stats?.isDirectory()?493:420,a)),n.finalize().catch(o);})}async function KBe(t){let e=jBe.createHash("md5");await new Promise((o,n)=>{so.createReadStream(t).on("data",i=>e.update(i)).on("end",()=>o()).on("error",n);});let r=e.digest();return {md5Base64:r.toString("base64"),md5Hex:r.toString("hex")}}async function Zw({tag:t,channel:e,filePath:r,apiClient:o,logger:n,platform:i}){n.info({channel:e,tag:t,platform:i,filePath:r},"starting asset upload");let a=Date.now(),{uploadPath:s,cleanup:c}=await WBe(i,r);try{let{md5Base64:l,md5Hex:u}=await KBe(s),{size:d}=await so.promises.stat(s),m=await o.generateAssetUploadUrl({channel:e,tag:t??"latest",md5:l,platform:i});if(m.md5&&(m.md5===l||m.md5===u))return n.info({channel:e,tag:t,platform:i,filePath:r,size:d,durationMs:Date.now()-a,skipped:!0},"skipped asset upload (md5 match)"),{skipped:!0};if(!m.uploadUrl)throw new M("InternalPlatformError",`No upload URL was given for asset ${r}`);try{let p=await fetch$1(m.uploadUrl,{headers:{"Content-Length":d.toString(),"Content-Type":"application/octet-stream"},method:"PUT",body:so.createReadStream(s),duplex:"half"});if(p.status!==200)throw new M("InternalPlatformError",`Got error response from emulator platform: ${p.status} ${await p.text()}`);return n.info({channel:e,tag:t,platform:i,filePath:r,size:d,durationMs:Date.now()-a},"finished asset upload"),{skipped:!1}}catch(p){try{await o.deleteAsset(e,t??"latest",i);}catch(f){n.warn({err:f,tag:t,channel:e},"Failed to clean up asset after failed upload");}throw p}}finally{await c();}}async function Qw({channel:t,tag:e,platform:r,apiClient:o,logger:n}){let i=e??"latest";n.info({channel:t,tag:i,platform:r},`Deleting asset ${t}:${i} (${r})...`),await o.deleteAsset(t,i,r),n.info({channel:t,tag:i,platform:r},`Asset ${t}:${i} (${r}) deleted successfully!`);}var YBe=z.object({emulatorName:z.string(),platform:z.enum(Ve)});z.object({runId:z.string(),emulators:z.array(YBe)});var Gte;async function eR(t){await Gte?.registerEmulator(t);}async function tR(t){await Gte?.unregisterEmulator(t);}var rR=new Jw;var K0="0.97.3",yt=_m({app:"mobile-desktop-server",hostname:hostname(),disableConsoleLogs:true}).child({cliVersion:K0});(async()=>{try{let t=await kg(yt);t.gitBranchName&&yt.addBinding("branch",t.gitBranchName);}catch{}})();var oR=Router();oR.get("/",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({message:"API client not initialized"});return}let o=await r.getMobileAssets();e.status(200).json(o);}));oR.post("/upload-url",We(async(t,e)=>{let r;try{r=zV.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}let o=Xt();if(!o){e.status(500).json({error:"API client not initialized"});return}let n=sr__default.resolve(r.filePath);if(!existsSync(n)){e.status(400).json({error:`File not found: ${n}`});return}let i=/\.apk$/i.test(n),a=n.endsWith(".app")&&statSync(n).isDirectory();if(!i&&!a){e.status(400).json({error:"Unsupported file type. Only .apk files and .app directories are supported."});return}await Zw({tag:r.tag,channel:r.channel,filePath:n,apiClient:o,logger:yt,platform:i?"ANDROID":"IOS"}),e.sendStatus(204);}));oR.delete("/:channel/:tag/:platform",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let{channel:o,tag:n,platform:i}=t.params;if(!o||!n||!i){e.status(400).json({error:"Missing channel, tag, or platform."});return}let a=rh.safeParse(i.toUpperCase());if(!a.success){e.status(400).json({error:`Invalid platform "${i}". Expected "android" or "ios".`});return}let s=a.data;await Qw({channel:o,tag:n,platform:s,apiClient:r,logger:yt}),e.sendStatus(204);}));var Wte=oR;var bf=Router();async function nR(t){return (await PK(t,yt)).map(o=>{let n=t.mobileModules[o.moduleId];if(!n){I.warn(`Found a dangling mobile module with ID ${o.moduleId} that could not be found on disk.`);return}return {...n,content:o}}).filter(o=>o!==void 0)}bf.get("/",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o);e.status(200).json(n);}));bf.get("/tests-join",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o),i={};for(let s of n)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(o.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await mr(s.fullFilePath,yt,o)})));for(let{id:s,name:c,relativePath:l,test:u}of a){let d=new Set;Ti({steps:u.steps,onPreset:()=>false,onModule:m=>(d.add(m.moduleId),false)});for(let m of d){let p=i[m];p&&p.tests.push({id:s,name:c,relativePath:l});}}e.status(200).json(i);}));bf.get("/:moduleId",We(async(t,e)=>{if(!t.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let r=await vt(bt()),o=r.mobileModules[t.params.moduleId];if(!o){e.status(404).json({error:"Mobile module not found."});return}try{let n=await Uu(o,r,I);e.json(n);}catch(n){e.status(400).json({err:n});}}));bf.patch("/:moduleId/metadata",We(async(t,e)=>{if(!t.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let r;try{r=jV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=bt(),n=await vt(o);xK({moduleId:t.params.moduleId,patch:r,momenticFiles:n,logger:I,project:o}),e.status(201).json({message:"ok"});}));bf.post("/",We(async(t,e)=>{let r;try{r=GV.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ci(r.name);}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let o=bt(),n=await vt(o),i=n.mobileModules;if(Object.values(i).find(s=>s.name===r.name)){e.status(400).json({error:`A mobile module with the name "${r.name}" already exists. Please choose a different name.`});return}let a=sr__default.join(o.rootDir,r.folderPath??"");if(!so.existsSync(a)||!so.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}switch(r.platform){case "ANDROID":{let s=await Ug({...r,folder:a,project:o,momenticFiles:n});e.status(201).json(s);return}case "IOS":{let s=await Ug({...r,folder:a,project:o,momenticFiles:n});e.status(201).json(s);return}}}));var Kte=bf;var Yte=Router();Yte.get("/",We(async(t,e)=>{let r=bt(),o=await vt(r),n=await nR(o),i=new Set;o?.mobileTests&&Object.values(o.mobileTests).forEach(l=>{l.labels?.forEach(u=>i.add(u));});let a=Array.from(i).sort(),s=Object.values(o.mobileTests),c={labels:a,modules:n,tests:s};e.status(200).json(c);}));var Xte=Yte;var iR=Router();iR.get("/",We((t,e)=>{let r=av(bt(),yt);e.status(200).json(r);}));iR.get("/names",We((t,e)=>{let o=bt().config.environments?.map(n=>n.name)??[];e.status(200).json(o);}));iR.post("/",We((t,e)=>{let r;try{r=$V.parse(t.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{ci(r.name);}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let o=bt();if(o.config.environments?.find(s=>s.name===r.name)){e.status(400).json({error:`An environment with the name "${r.name}" already exists. Please choose a different name.`});return}let i={...o.config,environments:[...o.config.environments??[],{name:r.name}]};o.config=i,Fu(i,o.configFilePath);let a=Lu(r.name,o,yt);e.status(201).json(a);}));var Jte=iR;var Zte=Router();Zte.get("/",We((t,e)=>{let r={userId:md(),orgId:qr(),email:yw(),name:YQ(),pylonEmailHash:XQ(),cliVersion:K0};e.status(200).json(r);}));var Qte=Zte;var ere=Router();ere.get("/",We(async(t,e)=>{let r=t.query.sessionId;if(!r){e.status(400).json({packages:[]});return}let o=rR.getSession(r);if(!o?.controller){e.status(200).json({packages:[]});return}try{let n=o.controller,{installedApps:i}=await n.getInstalledApps();e.status(200).json({packages:i});}catch(n){yt.error({err:n},"Error fetching installed packages from the session controller"),e.status(200).json({packages:[]});}}));var tre=ere;var rre=Router();rre.get("/",We(async(t,e)=>{let r=await hb(yt);e.status(200).json(r);}));var ore=rre;var aR=Router(),nre=async({platform:t,steps:e,cacheStorage:r,stepId:o,parentStepIdChain:n,testId:i,environment:a})=>{let{result:s,parentChain:c}=Gl(e,o,n);if(!s)return;let l=c.filter(u=>u.type==="RESOLVED_MOBILE_MODULE").map(u=>u.id);return await r.getCacheKeyForStep({platform:t,logger:yt,testId:i,environment:a,parentStepIdChain:l,step:s})};aR.patch("/",We(async(t,e)=>{let r=bt(),o=qr(),n=Xt(),i=r.config?.advanced?.isolateCachesByEnvironment;if(!n){e.status(500).json({error:"API client not initialized"});return}let a;try{a=KV.parse(t.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await dr(yt,n,r),c=Hr({logger:yt,orgId:o,client:n,gitMetadata:s,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:i}),l=await nre({cacheStorage:c,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!l){e.status(400).json({error:"Cache-supporting step not found"});return}await n.updateMobileStepCaches({platform:a.platform,body:{entries:[{key:l,organizationId:o,value:a.value,testId:a.testId,environment:i?a.environment:void 0}]},headers:hu(s)}),e.status(204).send();}));aR.delete("/entry",We(async(t,e)=>{let r=bt(),o=qr(),n=Xt(),i=r.config?.advanced?.isolateCachesByEnvironment;if(!n){e.status(500).json({error:"API client not initialized"});return}let a;try{a=XV.parse(t.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await dr(yt,n,r),c=Hr({logger:yt,orgId:o,client:n,gitMetadata:s,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:i}),l=await nre({cacheStorage:c,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!l){e.status(400).json({error:"Cache-supporting step not found"});return}await n.deleteMobileStepCacheEntry({platform:a.platform,body:{testId:a.testId,key:l,environment:i?a.environment:void 0},headers:hu(s)}),e.status(204).send();}));aR.post("/traces",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let o;try{o=JV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=await r.getMobileStepCacheMemoryTraces(o.platform,o);e.status(200).json(n);}));var ire=aR;fAe("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");var{captureEvent:ti,setAnalyticsIdentity:sR,shutdownAnalytics:lR}=ME({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://p.momentic.ai",platform:"local_mobile_app",identity:"stashed",flushImmediately:true});var gd=Router();gd.patch("/:testPath",We(async(t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o;try{o=BV.parse(t.body);}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}if(o.steps===void 0&&o.beforeSteps===void 0&&o.afterSteps===void 0&&o.settings===void 0&&o.labels===void 0){e.status(400).json({error:"At least one of steps, beforeSteps, afterSteps, settings, or labels is required"});return}let n=bt(),i=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,a=await vt(n);await zs({platform:o.platform,filePath:i,steps:o.steps,beforeSteps:o.beforeSteps,afterSteps:o.afterSteps,settings:o.settings,labels:o.labels,folder:n.rootDir,project:n,momenticFiles:a,schemaVersion:eo});let s={message:"ok"};e.status(200).json(s);}));gd.post("/",We(async(t,e)=>{let r;try{r=FV.parse(t.body);}catch(S){e.status(400).json({error:`Invalid request body: ${S}`});return}let{name:o,description:n,settings:i,pathSegments:a,platform:s}=r;if(!o||typeof o!="string"){e.status(400).json({error:"Missing or invalid 'name' in body"});return}try{ci(o);}catch(S){e.status(400).json({error:j(S)});return}let c=bt(),l=await vt(c),u=sr__default.join(c.rootDir,...a??[]),{fullPath:d,testId:m}=mv({name:o,description:n,settings:i,folder:u,platform:s,project:c,momenticFiles:l});ti({type:"test_editor:test_create",test_platform:fi(s)});let p=sr__default.basename(d),f=sr__default.relative(c.rootDir,d),h={id:m,fileName:p,fullPath:d,relativeFilePath:f};e.status(201).json(h);}));gd.get("/:fileName",We(async(t,e)=>{let r=Xt(),o=qr(),n=t.params.fileName;if(!n){e.status(400).json({error:"Missing fileName in path"});return}if(!r){e.status(500).json({error:"API client not initialized"});return}let i=n.endsWith(".test.yaml")?n:`${n}.test.yaml`,a=sr__default.basename(i).replace(".test.yaml",""),s=bt(),c=sr__default.isAbsolute(i)?i:sr__default.join(s.rootDir,i);if(!so.existsSync(c)){e.status(404).json({error:"Test not found."});return}let l=await vt(s),[u,d]=await Promise.all([mr(c,yt,l),dr(yt,r,s,{includeHostingUsername:false})]);await Hr({logger:yt,orgId:o,client:r,gitMetadata:d,regenerateCache:false,noCache:false,alwaysSaveCache:false,isolateCachesByEnvironment:s.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:yt,platform:u.platform,testId:u.id,environment:u.settings?.defaultEnv,stepLists:{steps:u.steps,...u.beforeSteps&&{beforeSteps:u.beforeSteps},...u.afterSteps&&{afterSteps:u.afterSteps}},useSnapshotIdentityCache:s.config.fileFormat==="v2"});let p={...u,name:a};e.status(200).json(p);}));gd.patch("/:testPath/metadata",We(async(t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o;try{o=VV.parse(t.body);}catch(c){e.status(400).json({error:`Invalid request body: ${c}`});return}let n=bt(),i=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,s={message:"ok",newRelativeTestPath:IK(i,o,n).newRelativeTestPath};e.status(200).json(s);}));gd.delete("/:testPath",We((t,e)=>{let r=t.params.testPath;if(!r){e.status(400).json({error:"Missing testPath in path"});return}let o=bt(),n=r.endsWith(".test.yaml")?r:`${r}.test.yaml`,i=sr__default.join(o.rootDir,n);if(!so.existsSync(i)){e.status(404).json({error:"Test not found."});return}so.unlinkSync(i),e.status(200).json({message:"ok"});}));gd.post("/:testPath/duplicate",We(async(t,e)=>{let{testPath:r}=t.params;if(!r){e.status(400).json({error:"Missing testPath in url path."});return}let o;try{o=WV.parse(t.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}try{ci(o.name);}catch(h){e.status(400).json({error:j(h)});return}let n=bt(),i=sr__default.join(n.rootDir,r);if(!so.existsSync(i)){e.status(404).json({error:"Test not found."});return}let a=await vt(n),s;try{s=await mr(i,yt,a);}catch(h){e.status(400).json({error:j(h)});return}let c=Qm({projectConfig:n.config,momenticFiles:a,entityType:"mobile-test"}),{stepsToSave:l}=await ho({platform:s.platform,stepLists:{steps:s.steps,beforeSteps:s.beforeSteps,afterSteps:s.afterSteps},createNewCacheIds:true}),u=oo({fileType:ve.MOBILE_TEST,id:c,schemaVersion:eo,description:s.description,platform:s.platform,settings:s.settings,labels:s.labels,...l});Vy.parse(u);let d=sr__default.dirname(i),m=sr__default.join(d,`${o.name}.test.yaml`);if(so.existsSync(m)){e.status(409).send("A test with this name already exists");return}let p=Bg.stringify(u);so.writeFileSync(m,p,"utf-8");let f={relativeFilePath:sr__default.relative(n.rootDir,m)};e.status(201).json(f);}));var are=gd;var sre=Router();sre.get("/",We((t,e)=>{let r=bt(),o={ai:r.config.ai,displayRoot:r.config.displayRoot};e.status(200).json(o);}));var lre=sre;var cre=Router();cre.post("/traces",We(async(t,e)=>{let r=Xt();if(!r){e.status(500).json({error:"API client not initialized"});return}let o;try{o=ZV.parse(t.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=await r.getWebStepCacheMemoryTraces(o);e.status(200).json(n);}));var ure=cre;var Ef=class extends np{constructor(r,o){super(r,o);this.client=r;this.orgId=o;}async fetchEnvironment(r,o){let n=bt();return Lu(r,n,I)}};var gVe=promisify$1(execFile$1);async function dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:n}){let{logger:i,sessionId:a}=t,s=JQ(),c=qr(),l=pb(),u=new pr({apiKey:s,baseUrl:l,logger:i}),d=new Ef(u,c),m=n??o.settings?.defaultEnv,p={};m&&(p=(await d.fetchEnvironment(m,i))?.variables??{});let f={...e.config.emulator,...o.settings?.emulator},h=new es({baseUrl:l,apiKey:s,logger:i,mode:"interactive"}),S=new js(e.config.ai?.agentConfig,{baseUrl:l,apiKey:s,logger:i,mode:"interactive"}),b=new sc({baseUrl:l,apiKey:s,logger:i,mode:"interactive"},S),y=new lc({httpClient:u,fakerSeed:e.config.advanced?.fakerConstantSeed?pm:void 0}),T=new hi({variablesFromEnvironment:p,envName:m,testName:r.name}),v=new Ka({logger:i,reporter:new ac(u),runType:"mobile-test-run",runId:a,testMetadata:r,isInteractive:true});return {logger:i,sessionId:a,orgId:c,apiClient:u,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:{storage:d,browserEnricher:b,browserGenerator:S,localCodeEvalTools:y,testContext:T},aiSettings:{useMemory:true,...e.config.ai,...o.settings?.ai},usageTracker:v}}function SVe(t){return {steps:t.steps,beforeSteps:t.beforeSteps,afterSteps:t.afterSteps}}async function mre({platform:t,project:e,logger:r,orgId:o,apiClient:n,resolvedTest:i,envName:a}){let s=SVe(i);if(e.config.fileFormat!=="v2")return s;let c=await dr(r,n,e),{alwaysSaveCache:l,noCache:u}=fs();return await Hr({logger:r,orgId:o,client:n,gitMetadata:c,regenerateCache:false,alwaysSaveCache:l,noCache:u,isolateCachesByEnvironment:e.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:r,platform:t,testId:i.id,environment:a,stepLists:s,useSnapshotIdentityCache:true}),s}async function pre({provider:t,platform:e,emulatorName:r,cleanupDriver:o}){let n=t==="remote";return n&&await eR({emulatorName:r,platform:e}),async()=>{await o(),n&&await tR({emulatorName:r,platform:e});}}async function fre({managedState:t,project:e,testEntity:r,resolvedTest:o,provider:n,envName:i,localAvdId:a,localApkPath:s}){let{logger:c,sessionId:l,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:S,aiSettings:b,usageTracker:y}=await dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:i}),T=o.settings?.defaultChannel,v=o.settings?.defaultTag,w=await mre({platform:"ANDROID",project:e,logger:c,orgId:u,apiClient:d,resolvedTest:o,envName:m}),N=await bVe({provider:n,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:o,localAvdId:a,localApkPath:s,variablesFromEnvironment:p});c.info({platform:"ANDROID",provider:n,envName:m,emulatorSettings:f,aiSettings:b},"Starting mobile session with resolved configuration");let D=n==="local"?"local":"region"in N?N.region:void 0,x=await mp({apiClient:d,logger:c,creationOpts:n==="remote"?{...N,apkToInstall:T?{channel:T,tag:v}:void 0}:N,orgId:u,sessionId:l,callbacks:{onStatusUpdate:O=>{c.info({status:O},"Android session status update");}}}),A=await pre({provider:n,emulatorName:x.emulatorName,platform:"ANDROID",cleanupDriver:async()=>{await x.cleanup();}}),B;try{let O="limbarClient"in x?{limbarClient:x.limbarClient,limbarToken:x.limbarToken,limbarUrl:x.limbarUrl,limbarRegion:x.limbarRegion,playwrightDevice:x.playwrightDevice}:void 0;B=await Fc.init({driver:x.driver,generator:h,logger:c,limbarClient:O?.limbarClient,playwrightDevice:O?.playwrightDevice,aiSettings:b,options:{emulator:{...f,region:D,browserSettings:e.config.browser}},fixtures:S,orgId:u,adbPort:x.adbPort,abortController:new AbortController});let z=await B.getViewportBounds(),k=B;return {...t,platform:"ANDROID",provider:n,controller:k,cleanup:[async()=>{await Promise.allSettled([k.cleanup(),A(),S.localCodeEvalTools.dispose()]);}],testName:r.name,relativeTestPath:r.relativePath,testFileAbsolutePath:sr__default.join(e.rootDir,r.relativePath),envName:m,orgId:u,emulatorName:x.emulatorName,viewportBounds:z,adbPort:x.adbPort,tempCaches:{},limbarUrl:O?.limbarUrl,limbarToken:O?.limbarToken,limbarRegion:O?.limbarRegion,usageTracker:y,mutableStepState:{platform:"ANDROID",testId:o.id,stepLists:w}}}catch(O){let z=B?[B.cleanup(),A()]:[A()];throw await Promise.allSettled(z),O}}async function hre({managedState:t,project:e,testEntity:r,resolvedTest:o,provider:n,envName:i,localDeviceId:a,localAppPath:s}){let{logger:c,sessionId:l,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:S,aiSettings:b,usageTracker:y}=await dre({managedState:t,project:e,testEntity:r,resolvedTest:o,envName:i}),T=o.settings?.defaultChannel,v=o.settings?.defaultTag,w=await mre({platform:"IOS",project:e,logger:c,orgId:u,apiClient:d,resolvedTest:o,envName:m}),N=yVe({provider:n,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:o,appChannel:T,appTag:v,localDeviceId:a,localAppPath:s,variablesFromEnvironment:p});c.info({platform:"IOS",provider:n,envName:m,emulatorSettings:f,aiSettings:b},"Starting mobile session with resolved configuration");let D=n==="local"?"local":N.type==="remote"?N.region:void 0,x=await ef({apiClient:d,logger:c,creationOpts:N,orgId:u,sessionId:l,callbacks:{onStatusUpdate:O=>{c.info({status:O},"iOS session status update");}}}),A=await pre({provider:n,emulatorName:x.emulator.name,platform:"IOS",cleanupDriver:async()=>{await x.cleanup();}}),B;try{B=await zc.init({driver:x.driver,generator:h,logger:c,emulator:x.emulator,aiSettings:b,options:{emulator:{...f,region:D,browserSettings:e.config.browser}},fixtures:S,orgId:u,abortController:new AbortController});let O=await B.getViewportBounds(),z=B;return {...t,platform:"IOS",provider:n,controller:z,cleanup:[async()=>{await Promise.allSettled([z.cleanup(),A(),S.localCodeEvalTools.dispose()]);}],testName:r.name,relativeTestPath:r.relativePath,testFileAbsolutePath:sr__default.join(e.rootDir,r.relativePath),envName:m,orgId:u,emulatorName:x.emulator.name,viewportBounds:O,tempCaches:{},limbarUrl:x.limbarParams?.webRtcUrl,limbarToken:x.limbarParams?.token,limbarRegion:x.limbarParams?.region,usageTracker:y,mutableStepState:{platform:"IOS",testId:o.id,stepLists:w}}}catch(O){let z=B?[B.cleanup(),A()]:[A()];throw await Promise.allSettled(z),O}}async function bVe({provider:t,projectRoot:e,emulatorSettings:r,resolvedTest:o,localAvdId:n,localApkPath:i,variablesFromEnvironment:a}){if(t==="remote")return {region:r?.region==="local"?void 0:r?.region,osVersion:r?.remoteEmulatorSettings?.androidVersion??nm};let s=await X0(),{avdId:c,apkFilePath:l,apkFilePathSource:u}=dm({overrideAvdId:n,overrideApkFilePath:i,emulatorSettings:r,defaultApkFilePath:o.settings?.defaultApkFilePath,envVariables:a});if(!c){let d=s.availableAvdIds.length>0?` Known Available AVDs on this machine: ${s.availableAvdIds.join(", ")}.`:"",m=s.avdDiscoveryError?` Failed to list local AVDs: ${s.avdDiscoveryError}.`:"";throw new Error(`AVD ID is required when using a local emulator. Set it on the test (Options -> Emulator -> Local AVD ID), set ${gl} on the environment, or pass localDeviceId directly.${d}${m}`)}if(s.availableAvdIds.length>0&&!s.availableAvdIds.includes(c))throw new Error(`AVD '${c}' is not available on this machine. Available AVDs: ${s.availableAvdIds.join(", ")}.`);return {avdId:c,apkFilePath:pp({apkFilePath:l,source:u,overrideBaseDir:e})}}function yVe({provider:t,projectRoot:e,emulatorSettings:r,resolvedTest:o,appChannel:n,appTag:i,localDeviceId:a,localAppPath:s,variablesFromEnvironment:c}){if(t==="remote")return {type:"remote",region:r?.region==="local"?void 0:r?.region,appToInstall:n?{channel:n,tag:i}:void 0,osVersion:im};let{deviceType:l,appFilePath:u,appFilePathSource:d}=mm({overrideDeviceType:a,overrideAppFilePath:s,emulatorSettings:r,defaultAppFilePath:o.settings?.defaultAppFilePath,envVariables:c});if(!l)throw new Error(`A device type is required when using a local region. Pass localDeviceId, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);return {type:"local",deviceType:l,appFilePath:df({appFolderPath:u,source:d,overrideBaseDir:e})}}async function X0(){try{let{stdout:t}=await gVe(EVe(),["-list-avds"],{encoding:"utf8",timeout:5e3});return {availableAvdIds:t.split(/\r?\n/).map(r=>r.trim()).filter(Boolean)}}catch(t){return {availableAvdIds:[],avdDiscoveryError:j(t)}}}function EVe(){let t=process.platform==="win32"?"emulator.exe":"emulator";return process.env.ANDROID_HOME?sr__default.join(process.env.ANDROID_HOME,"emulator",t):t}var gre=5,J0=class extends JA{isStartingSession=false;constructor(){super({sessionTypeLabel:"mobile MCP session"});}async kill(e,r){try{let o;for(let i of e.cleanup)try{await i();}catch(a){o??=a;}if(o)throw o;await e.usageTracker.flush(e.logger);let n=ZZ(e);return await SQ({apiClient:Xt(),logger:e.logger,orgId:e.orgId,testId:e.testId,sessionId:e.sessionId,reason:r,report:n}),e.logger.info({sessionId:e.sessionId,reason:r,emulatorName:e.emulatorName},"MCP session cleaned up"),{killed:!0,sessionId:e.sessionId,reason:r,report:n}}catch(o){return e.logger.error({err:o,sessionId:e.sessionId,reason:r},"Failed to clean up mobile MCP session"),{killed:false,sessionId:e.sessionId,reason:r}}}touchSession(e){let r=super.touchSession(e);return r?.provider==="remote"&&Xt()?.extendEmulatorTtl(r.platform,r.emulatorName).catch(()=>{}),r}async createSession({logger:e,testId:r,idleTimeoutMs:o,provider:n,envName:i,localDeviceId:a,localAppPath:s,project:c}){let l=this.listSessionIds();if(this.isStartingSession||l.length>0)throw new Error(JSON.stringify({message:"Another mobile MCP session is already active or starting. Please terminate the existing session before creating a new one.",activeSessionIds:l},null,2));this.isStartingSession=true;let u;try{let{entity:d,momenticFiles:m}=await ts(c,{id:r},"mobileTests"),p=await mr(d.fullFilePath,e,m),S=(p.settings?.emulator?.region??c.config.emulator?.region)==="local"?"local":"remote",b=n??S,y,{platform:T}=p,v=e.child({testId:p.id});switch(T){case "ANDROID":u=this.buildManagedSessionState({logger:v,idleTimeoutMs:o,testId:d.id}),y=await fre({managedState:u,project:c,testEntity:d,resolvedTest:p,provider:b,envName:i,localAvdId:a,localApkPath:s});break;case "IOS":u=this.buildManagedSessionState({logger:v,idleTimeoutMs:o,testId:d.id}),y=await hre({managedState:u,project:c,testEntity:d,resolvedTest:p,provider:b,envName:i,localDeviceId:a,localAppPath:s});break;default:return Vt(T)}return v.info({sessionId:y.sessionId,testId:p.id},"Started MCP session for test"),y}catch(d){throw u&&clearTimeout(u.timeoutHandle),d}finally{this.isStartingSession=false;}}},Ho=new J0,Sd=({response:t,sessionId:e,toolName:r})=>{let o=Ho.touchSession(e);if(o)return t.addCleanupCallback(()=>{gQ({session:o,toolCallId:t.toolCallId});}),hQ({session:o,toolCallId:t.toolCallId,toolName:r}),o;t.addError(JSON.stringify({message:`No active session found for id '${e}'.`,availableSessionIds:Ho.listSessionIds()},null,2));};var vVe=4e4,CVe=1e4,Q0,bre=({staticDir:t})=>{Q0=t;},cR=class t{url;server;constructor({url:e,server:r}){this.url=e,this.server=r;}static async init({logger:e,testId:r,testName:o,sessionId:n,platform:i,limbarUrl:a,limbarToken:s,limbarRegion:c,tabLabel:l}){let u=await _Ve({logger:e,assets:AVe()}),d=new URL(`http://localhost:${u.port}/`);return d.searchParams.set("testId",r),o&&d.searchParams.set("testName",o),d.searchParams.set("sessionId",n),d.searchParams.set("platform",i),d.searchParams.set("url",a),d.searchParams.set("token",s),c&&d.searchParams.set("region",c),l&&d.searchParams.set("tabLabel",l),new t({url:d.toString(),server:u})}async shutdown(){this.server?.server.listening&&(await new Promise(e=>{this.server?.server.close(()=>{e();});}),this.server=void 0);}};function AVe(){if(!Q0)throw new Error("Remote control viewer static directory is not configured. Pass remoteControlStaticDir when starting the mobile MCP server.");let t=sr__default.resolve(Q0),e=sr__default.join(t,"index.html");if(!so.existsSync(e))throw new Error(`Remote control viewer index file not found at '${e}'. Ensure mobile-remote-control-frontend is built and copied into npm/mobile-cli/remote-control-static.`);return {staticDir:t,indexHtmlBuffer:so.readFileSync(e)}}function Z0({response:t,statusCode:e,body:r,allow:o}){let n={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"};o&&(n.Allow=o),t.writeHead(e,n),t.end(r);}function Sre({request:t,response:e,buffer:r,contentType:o}){if(e.writeHead(200,{"Content-Type":o,"Cache-Control":"no-store"}),t.method==="HEAD"){e.end();return}e.end(r);}function wVe({staticDir:t,pathname:e}){let r;try{r=decodeURIComponent(e);}catch{return}let o=r==="/"?"index.html":r.replace(/^\/+/,""),n=sr__default.resolve(t,o),i=sr__default.relative(t,n);if(!(i.startsWith("..")||sr__default.isAbsolute(i)))return n}function RVe({request:t,response:e,assets:r}){if(t.method!=="GET"&&t.method!=="HEAD"){Z0({response:e,statusCode:405,body:"Method Not Allowed",allow:"GET, HEAD"});return}let o=new URL(t.url??"/","http://localhost").pathname;if(o==="/"||o==="/index.html"){Sre({request:t,response:e,buffer:r.indexHtmlBuffer,contentType:"text/html; charset=utf-8"});return}let n=wVe({staticDir:r.staticDir,pathname:o});if(!n){Z0({response:e,statusCode:403,body:"Forbidden"});return}if(!so.existsSync(n)||!so.statSync(n).isFile()){Z0({response:e,statusCode:404,body:"Not Found"});return}let i=sr__default.extname(n).toLowerCase(),a=mu[i]??"application/octet-stream";Sre({request:t,response:e,buffer:so.readFileSync(n),contentType:a});}async function _Ve({logger:t,assets:e}){let r=createServer((i,a)=>RVe({request:i,response:a,assets:e})),o=Math.floor(Math.random()*CVe)+vVe,n=await Hl(o,"mobile-mcp-remote-control-viewer");return await new Promise((i,a)=>{let s=c=>{a(c);};r.once("error",s),r.listen(n,()=>{r.off("error",s),i();});}),t.info({port:n,staticDir:e.staticDir},"Started mobile MCP remote control viewer server"),{port:n,server:r}}function ek({logger:t,applicationName:e,cliVersion:r,serverId:o=randomUUID()}){let n={serverId:o,applicationName:e,cliVersion:r},i=qr(),a=t.child({orgId:i,userId:md(),...n});return {info:n,mcpLogger:a,orgId:i}}function tk({sessionIdleTimeoutMinutes:t}){return (t&&t>=1?t:gre)*60*1e3}async function uR({project:t,serverUrl:e,alwaysSaveCache:r,noCache:o,remoteControlStaticDir:n}){bre({staticDir:n}),Qp(e),bw({alwaysSaveCache:r,noCache:o}),sR({userId:md(),orgId:qr(),selfServe:Ew()}),Tw(t,i=>qn({configFilePath:i}));}function dR({project:t,logger:e,apiKey:r,serverUrl:o,supportsFileOutput:n,headfulDefault:i,sessionIdleTimeoutMinutes:a,applicationName:s,cliVersion:c,serverId:l}){let{info:u,mcpLogger:d,orgId:m}=ek({logger:e,applicationName:s,cliVersion:c,serverId:l}),p=new es({baseUrl:o,apiKey:r,logger:d,mode:"interactive"});return {context:{project:t,orgId:m,logger:d,generator:p,serverId:u.serverId,saveChangesToDisk:true,sessionIdleTimeoutMs:tk({sessionIdleTimeoutMinutes:a}),supportsFileOutput:n,headfulDefault:i},info:u}}async function IVe({moduleId:t,name:e,description:r,enabled:o,platform:n,parameters:i,steps:a,project:s}){let c=await vt(s),{stepsToSave:{steps:l}}=await ho({platform:n,stepLists:{steps:a}});Ja({content:{platform:n,moduleId:t,name:e,description:r,enabled:o,parameters:i,steps:l},schemaVersion:eo,momenticFiles:c,project:s});}function OVe({module:t,inputs:e}){return {...t,id:randomUUID(),type:"RESOLVED_MOBILE_MODULE",inputs:e}}async function yre({project:t,logger:e,testPath:r,saveChangesToDisk:o,mutableStepState:n,params:i,initialMomenticFiles:a,platform:s,availableSteps:c,cacheContext:l}){let{stepsToExtract:u,startIndex:d,endIndex:m}=EQ({moduleName:i.name,existingModuleNames:Object.values(a.mobileModules).map(h=>h.name),parameterNames:i.parameters?.parameterNames,defaultParameters:i.parameters?.defaultParameters,parameterEnums:i.parameters?.parameterEnums,moduleInputs:i.moduleInputs,testPath:r,startIndex:i.startIndex,endIndex:i.endIndex,availableSteps:c,containsNestedModuleStep:fq}),p=sr__default.join(t.rootDir,i.folderPath??"");i.folderPath&&so.mkdirSync(p,{recursive:true});let f=await Ug({name:i.name,platform:s,description:i.description??"",enabled:i.enabled??true,steps:u,folder:p,project:t,momenticFiles:a});if(i.parameters!==void 0&&(await IVe({moduleId:f.moduleId,name:i.name,description:i.description??"",enabled:i.enabled??true,platform:s,parameters:i.parameters,steps:u,project:t}),f={...f,name:i.name,description:i.description??"",parameters:i.parameters}),o&&i.startIndex!==void 0&&r!==void 0){let h=await vt(t);if(!c)throw new Error("Mobile module was created successfully, but the source test steps were not available for replacement.");let S=OVe({module:f,inputs:i.moduleInputs}),b=[...c];if(b.splice(d,m-d,S),await zs({platform:s,filePath:r,steps:b,folder:t.rootDir,project:t,momenticFiles:h,schemaVersion:eo}),n&&(n.stepLists={...n.stepLists,steps:b}),l){let{cachesToSave:y,snapshotCachesToSave:T}=await ho({platform:s,stepLists:{steps:b},cacheCreationParams:{orgId:l.orgId,testId:l.testId,environment:l.envName},useSnapshotIdentityCache:l.useSnapshotIdentityCache});try{await l.cacheStorage.saveEntries({platform:s,logger:e,entries:y});}catch(v){e.warn({err:v},"Failed to save mobile step caches after module create, future runs may be slower");}if(l.useSnapshotIdentityCache)try{await l.cacheStorage.saveSnapshotCacheEntries({platform:s,logger:e,entries:T});}catch(v){e.warn({err:v},"Failed to save mobile snapshot identity cache after module create, future runs may regenerate step ids");}}}return f}function Ere(t,e,r){if(!t)return {availableSteps:void 0,mutableStepState:void 0};if(t.platform!==e)throw new Error(`Internal error: test platform ${t.platform} does not match resolved platform ${e}`);return r&&r.testId===t.id&&r.platform===e?{availableSteps:r.stepLists.steps,mutableStepState:r}:{availableSteps:t.steps,mutableStepState:void 0}}async function vre({project:t,logger:e,testPath:r,saveChangesToDisk:o,mutableStepState:n,params:i}){ci(i.name);let a=await vt(t),s=r!==void 0?await mr(sr__default.join(t.rootDir,r),e,a):void 0,c=s?.platform??i.platform??"ANDROID";if(i.platform&&c!==i.platform)throw new Error(`Error: Requested module platform ${i.platform} does not match source test platform ${s?.platform}.`);let l;if(s!==void 0){let d=Xt();if(d){let m=await dr(e,d,t),{alwaysSaveCache:p,noCache:f}=fs();l={cacheStorage:Hr({logger:e,orgId:qr(),client:d,gitMetadata:m,regenerateCache:false,alwaysSaveCache:p,noCache:f,isolateCachesByEnvironment:t.config?.advanced?.isolateCachesByEnvironment}),testId:s.id,orgId:qr(),envName:s.settings?.defaultEnv,useSnapshotIdentityCache:t.config.fileFormat==="v2"};}}let u={project:t,logger:e,testPath:r,saveChangesToDisk:o,params:i,initialMomenticFiles:a,cacheContext:l};switch(c){case "ANDROID":return {module:await yre({...u,platform:"ANDROID",...Ere(s,"ANDROID",n)})};case "IOS":return {module:await yre({...u,platform:"IOS",...Ere(s,"IOS",n)})};default:return Vt(c)}}var Cre=Vo({schema:{name:oy,description:"Get a single fully loaded mobile module by id, exact name, or file path. This returns complete module details including parameters, description, and the full step list. Exactly one selector must be provided.",inputSchema:z.object({selector:tU})},handle:async(t,e,r)=>{let{project:o,logger:n}=t;try{let i=await ts(o,e.selector,"mobileModules"),a=await Uu(i.entity,i.momenticFiles,n);r.addPartFromText(JSON.stringify({module:a},null,2));}catch(i){r.addError(j(i));}}}),Are=Vo({schema:{name:ZF,description:"Create a mobile module. If startIndex is provided, testPath is required and the specified mobile test range is extracted into a module for that test's platform, then replaced with a module invocation in that test. For empty modules, platform defaults to Android unless platform or testPath identifies iOS.",inputSchema:PM},handle:async(t,e,r)=>{try{let o=PM.parse(e),{testPath:n,...i}=o,a=D6({projectRoot:t.project.rootDir,filePath:n,pathLabel:"testPath"}),s;if(a!==void 0){let l=sr__default.join(t.project.rootDir,a);for(let u of Ho.listSessionIds()){let d=Ho.getSession(u);if(d!==void 0&&d.testFileAbsolutePath===l){s=d.mutableStepState;break}}}let c=await vre({project:t.project,logger:t.logger,testPath:a,saveChangesToDisk:t.saveChangesToDisk,mutableStepState:s,params:i});r.addPartFromText(JSON.stringify(c.module,null,2));}catch(o){r.addError(j(o));}}});function mR({step:t,parentChain:e}){let r=t;r.parentStepIdChain=e.map(o=>o.id),delete r.retries,delete r.skipped;}function FVe(t){let e=cloneDeep(t);return Ti({steps:e,earlyStop:false,onPreset:(r,o)=>{if(mR({step:r,parentChain:o.parentChain}),r.type==="MOBILE_PRESET_STEP"){let n=r.command;delete n.cache,delete n.id,delete n.thoughts;}return false},onModule:(r,o)=>{mR({step:r,parentChain:o.parentChain});let n=r;return delete n.enabled,delete n.schemaVersion,false},onConditional:(r,o)=>(mR({step:r,parentChain:o.parentChain}),false),onAiAction:(r,o)=>{mR({step:r,parentChain:o.parentChain});let n=r;return delete n.cache,false}}),e.map((r,o)=>{let n=r;return n.index=o,n})}function rk(t,e){if(t.length===0)return `${e}: (no steps)`;let r=["```json",JSON.stringify(FVe(t),null,2),"```"].join(`
|
|
5923
5923
|
`);return `${e}:
|
|
5924
5924
|
${r}`}var UVe=`## Note
|
|
5925
5925
|
The "Installed apps" list may still include default or system packages; it is a best-effort view, not a guarantee of user-installed apps only. `;async function BVe({project:t,testFileAbsolutePath:e,supportsFileOutput:r,platform:o,description:n,activeStepLists:i}){let a=[];a.push(`Name: ${sr__default.basename(e,".test.yaml")}`),a.push(`Platform: ${o}`),n&&a.push(`Description: ${n}`),a.push("");let s=i.beforeSteps??[],c=i.afterSteps??[];s.length>0&&(a.push(rk(s,"Setup Steps")),a.push("")),a.push(rk(i.steps,"Main Steps")),c.length>0&&(a.push(""),a.push(rk(c,"Teardown Steps")));let l=a.join(`
|
|
@@ -5937,7 +5937,7 @@ The "Installed apps" list may still include default or system packages; it is a
|
|
|
5937
5937
|
for /f "tokens=5" %a in ('netstat -ano ^| findstr :${t}') do taskkill /PID %a /F
|
|
5938
5938
|
`);}fAe("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");var{captureEvent:_b,setAnalyticsIdentity:roe,shutdownAnalytics:ooe}=ME({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://p.momentic.ai",platform:"mobile_cli",identity:"stashed",flushImmediately:true,onIdentify:k4});async function noe({project:t,logger:e}){let r=await vt(t),o=Object.values(r.mobileTests),n=0,i=new Set,a=[];for(let s of o)try{await mr(s.fullFilePath,e,r);}catch(c){e.error(`Failed to parse mobile test ${s.name} (${s.relativePath})`),vT(c,s.relativePath,a),n++,i.add(s.relativePath);}return {parsingErrors:n,parsingErrorDetails:a,failedTestFilePaths:i}}async function c1e({project:t,filePath:e}){let r={totalErrors:0,parsingErrors:0,parsingErrorDetails:[],failedTestFilePaths:new Set,failedModuleFilePaths:new Set},o=await vt(t);if(e!==void 0)return await u1e({project:t,momenticFiles:o,filePath:e,state:r}),r;for(let n of Object.values(o.mobileModules))await aoe({momenticFiles:o,module:n,state:r});for(let n of Object.values(o.mobileTests))await ioe({momenticFiles:o,test:n,state:r});for(let n of o.metadataParseFailures)coe({failure:n,state:r});return d1e({momenticFiles:o,state:r}),m1e({momenticFiles:o,state:r}),r}function lk(t,e,r){t.totalErrors++,e==="test"?t.failedTestFilePaths.add(r):t.failedModuleFilePaths.add(r);}async function u1e({project:t,momenticFiles:e,filePath:r,state:o}){let n=sr__default.isAbsolute(r)?r:sr__default.resolve(t.rootDir,r),i=sr__default.relative(t.rootDir,n);if(i.startsWith("..")||sr__default.isAbsolute(i)){I.error(`File '${r}' is outside the resolved project at '${t.rootDir}'. Lint a file inside the project, or run without an argument to lint the whole project.`),o.totalErrors++;return}let a=Object.values(e.mobileTests).find(l=>l.fullFilePath===n);if(a){await ioe({momenticFiles:e,test:a,state:o});return}let s=Object.values(e.mobileModules).find(l=>l.fullFilePath===n);if(s){await aoe({momenticFiles:e,module:s,state:o});return}let c=e.metadataParseFailures.find(l=>l.fullPath===n);if(c){coe({failure:c,state:o});return}I.error(`File '${r}' is not a recognized Momentic mobile test or module. Check the 'include' globs in your momentic.config.yaml.`),o.totalErrors++;}async function ioe({momenticFiles:t,test:e,state:r}){if(e.type!==ve.MOBILE_TEST_V2)return;soe({kind:"test",name:e.name,relativePath:e.relativePath,id:e.id,state:r});let{parsed:o}=wi(e.fullFilePath);try{let n=Il.parse(o),i=bm(n.platform);await ov({testV2:n,platform:i,fileResolver:Du({sourceFilePath:e.fullFilePath,momenticFiles:{mobileModules:t.mobileModules}})});}catch(n){loe({err:n,kind:"test",name:e.name,relativePath:e.relativePath,state:r});}}async function aoe({momenticFiles:t,module:e,state:r}){if(e.type!==ve.MOBILE_MODULE_V2)return;soe({kind:"module",name:e.name,relativePath:e.relativePath,id:e.id,state:r});let{parsed:o}=wi(e.fullFilePath);try{nv({moduleV2:o,moduleName:e.name,fileResolver:Du({sourceFilePath:e.fullFilePath,momenticFiles:{mobileModules:t.mobileModules}})});}catch(n){loe({err:n,kind:"module",name:e.name,relativePath:e.relativePath,state:r});}}function soe({kind:t,name:e,relativePath:r,id:o,state:n}){if(Vr.safeParse(o).success)return;let i=t==="test"?"Mobile test":"Mobile module";I.error(`${i} '${e}' (${r}) has an invalid ID: '${o}'. IDs must be kebab-case or a UUID, up to 36 characters.`),lk(n,t,r);}function loe({err:t,kind:e,name:r,relativePath:o,state:n}){if(I.error(`Failed to lint mobile ${e} ${r} (${o})`),lk(n,e,o),n.parsingErrors++,!vT(t,o,n.parsingErrorDetails)){if(t instanceof z.ZodError){TT(t.issues,o,n.parsingErrorDetails);return}n.parsingErrorDetails.push({file:o,field:"",issue:j(t)});}}function coe({failure:t,state:e}){I.error(`Failed to lint mobile ${t.kind} ${t.name} (${t.relativePath})`),lk(e,t.kind,t.relativePath),e.parsingErrors++,TT(t.issues,t.relativePath,e.parsingErrorDetails);}function d1e({momenticFiles:t,state:e}){let r=new Set(Object.values(t.mobileModules).map(n=>n.fullFilePath)),o=new Set(Object.values(t.mobileTests).map(n=>n.fullFilePath));for(let[n,i]of Object.entries(t.duplicateEntities)){let a=i.filter(s=>r.has(s)||o.has(s));if(!(a.length<2)){I.error(`Duplicate ID '${n}' found in the following mobile files:
|
|
5939
5939
|
${a.map(s=>` - ${s}`).join(`
|
|
5940
|
-
`)}`),e.totalErrors++;for(let s of a){let c=sr__default.relative(t.project.rootDir,s);r.has(s)?e.failedModuleFilePaths.add(c):e.failedTestFilePaths.add(c);}}}}function m1e({momenticFiles:t,state:e}){for(let[r,o]of Object.entries(t.mobileTests)){let n=t.mobileModules[r];n&&(I.error(`ID '${r}' is shared between mobile test '${o.relativePath}' and mobile module '${n.relativePath}'. Test and module IDs must be unique across the entire project.`),e.totalErrors++,e.failedTestFilePaths.add(o.relativePath),e.failedModuleFilePaths.add(n.relativePath));}}async function ck({project:t,filePath:e}){let{totalErrors:r,parsingErrors:o,parsingErrorDetails:n,failedTestFilePaths:i,failedModuleFilePaths:a}=await c1e({project:t,filePath:e});if(r===0){I.success("Mobile lint passed. No issues found.");return}n.length>0&&zP({parsingErrors:o,parsingErrorDetails:n,failedTestFilePaths:i,failedModuleFilePaths:a}),I.error(`Found ${r} mobile lint error${r===1?"":"s"} in project.`),process.exit(1);}async function uk({project:t}){if(t.config.fileFormat==="v2"){await ck({project:t,filePath:void 0});return}let{parsingErrors:e,parsingErrorDetails:r,failedTestFilePaths:o}=await noe({project:t,logger:I});e>0&&(zP({parsingErrors:e,parsingErrorDetails:r,failedTestFilePaths:o}),process.exit(1));}async function mk({tests:t,momenticFiles:e,project:r,yes:o,include:n,exclude:i,labels:a,logger:s,quarantinedTestsMetadata:c}){let l=new Set;if(t&&t.length>0){let d=t.some(p=>so.existsSync(p)),m=cwd();d?(m!==r.rootDir&&s.warn(`Test paths resolve against the current directory ('${m}'), not the project root ('${r.rootDir}'). Run from the project root or use substring filters to avoid surprises.`),t.forEach(p=>{if(!so.existsSync(p))throw new Error(`Path '${p}' does not exist.`);let f,h;try{f=so.statSync(p),h=f.isDirectory();}catch(b){s.warn({err:b},`Skipping path ${p} because it cannot be read`);return}let S=sr__default.resolve(p);Object.values(e.mobileTests).filter(b=>h?b.fullFilePath.startsWith(S):b.fullFilePath===S).forEach(b=>{l.add(b.fullFilePath);});})):Object.values(e.mobileTests).forEach(p=>{t.some(f=>p.relativePath.includes(f))&&l.add(p.fullFilePath);});}else !o&&!await Ol("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1)),Object.values(e.mobileTests).forEach(m=>{l.add(m.fullFilePath);});for(let d of Array.from(l)){let m=sr__default.relative(r.rootDir,d);n&&!n.some(p=>new RegExp(p).test(m))&&l.delete(d),i&&i.some(p=>new RegExp(p).test(m))&&l.delete(d);}return (await Promise.all(Array.from(l).map(async d=>{try{let m=sr__default.relative(r.rootDir,d),p=await mr(d,s,e),f=sr__default.basename(d,".test.yaml");if(p.disabled)return null;if(a&&a.length>0){let S=p.labels||[];if(!a.some(y=>S.includes(y)))return null}let h={id:p.id,name:f,description:p.description,schemaVersion:p.schemaVersion,settings:p.settings,fullFilePath:d,relativeFilePath:m,quarantined:!!c[p.id],quarantinedMetadata:c[p.id],labels:p.labels};switch(p.platform){case "ANDROID":return {...h,platform:"ANDROID",steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps};case "IOS":return {...h,platform:"IOS",steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps};default:return (b=>{throw new Error("You missed a case in the switch above")})(p)}}catch(m){s.error(`Failed to read and resolve mobile test at '${d}': ${m}`),process.exit(1);}}))).filter(d=>!!d)}async function pk({project:t,apiClient:e,gitMetadata:r,orgId:o,dryRun:n=false}){let i=await vt(t),a=Object.values(i.mobileTests).filter(S=>S.type===ve.MOBILE_TEST),s=Object.values(i.mobileModules).filter(S=>S.type===ve.MOBILE_MODULE),c=Object.values(i.mobileTests).filter(S=>S.type===ve.MOBILE_TEST_V2).length,l=Object.values(i.mobileModules).filter(S=>S.type===ve.MOBILE_MODULE_V2).length,u={...bO(),alreadyV2TestCount:c,alreadyV2ModuleCount:l},d=t.config.fileFormat!=="v2",{v2ProjectConfig:m,migratedFilePaths:p}=p4(t);!n&&a.length>0&&await h1e({legacyMobileTests:a,momenticFiles:i,project:t,apiClient:e,gitMetadata:r,orgId:o}),await g1e({legacyMobileModules:s,momenticFiles:i,project:t,v2ProjectConfig:m,migratedFilePaths:p,summary:u,dryRun:n}),await y1e({legacyMobileTests:a,momenticFiles:i,project:t,v2ProjectConfig:m,migratedFilePaths:p,summary:u,dryRun:n});let f=u.migratedTestPaths.length>0||u.migratedModulePaths.length>0;return !n&&(d||f)&&gO({project:t,newProjectConfig:m,fileFormatLabel:"v2",migratedFilePaths:p}),u}async function uoe({project:t,apiClient:e,gitMetadata:r}){let{legacyProjectConfig:o,migratedFilePaths:n}=f4(t),i=await vt(t),a=Object.values(i.mobileTests).filter(l=>l.type===ve.MOBILE_TEST_V2),s=Object.values(i.mobileModules).filter(l=>l.type===ve.MOBILE_MODULE_V2);I.info(`Migrating ${a.length} v2 mobile tests and ${s.length} v2 mobile modules to legacy YAML`);let c=new Set;await S1e({v2MobileTests:a,momenticFiles:i,project:t,legacyProjectConfig:o,migratedFilePaths:n,apiClient:e,gitMetadata:r,modulesCoveredByTests:c}),await b1e({v2MobileModules:s,momenticFiles:i,project:t,legacyProjectConfig:o,migratedFilePaths:n,modulesCoveredByTests:c}),gO({project:t,newProjectConfig:o,fileFormatLabel:"legacy",migratedFilePaths:n});}async function h1e({legacyMobileTests:t,momenticFiles:e,project:r,apiClient:o,gitMetadata:n,orgId:i}){if(t.length===0)return;let a={logger:I,orgId:i,client:o,regenerateCache:false,alwaysSaveCache:true,noCache:false,isolateCachesByEnvironment:r.config.advanced?.isolateCachesByEnvironment??false,bustOldestCachePercentage:void 0},s=[Hr({...a,gitMetadata:n})];n.gitMainBranch&&n.gitBranchName!==n.gitMainBranch&&s.push(Hr({...a,gitMetadata:{...n,gitBranchName:n.gitMainBranch,gitCommitTimestamp:n.lastCommitOnMainTimestamp??n.gitCommitTimestamp}})),I.info(`Pushing mobile test snapshots for ${t.length} legacy mobile tests so existing step caches survive the v2 conversion`),await sp(t,ap,async c=>{let l=await mr(c.fullFilePath,I,e),{snapshotCachesToSave:u}=await ho({platform:l.platform,stepLists:{steps:l.steps,beforeSteps:l.beforeSteps,afterSteps:l.afterSteps},useSnapshotIdentityCache:true,cacheCreationParams:{orgId:i,testId:l.id,environment:void 0}});for(let d of s)await d.saveSnapshotCacheEntries({logger:I,platform:l.platform,entries:u});I.dimmed(`Pushed mobile test snapshot for: ${c.relativePath}`);});}async function g1e({legacyMobileModules:t,momenticFiles:e,project:r,v2ProjectConfig:o,migratedFilePaths:n,summary:i,dryRun:a}){await sp(t,ap,async s=>{let c=Zl(s.fullFilePath,I);if(Ig(c))throw new Error(`Expected a legacy mobile module while migrating '${s.relativePath}', but found v2 format`);let l=Ql({module:c,moduleFilePath:s.fullFilePath,momenticFiles:e}),u=Oa.parse(l),d={...u,name:l.name??s.name,steps:qi(u.platform).array().parse(l.steps)};a||Ja({content:d,schemaVersion:eo,momenticFiles:e,project:{...r,config:o},forceSaveOnNoDiffs:true}),n.push(s.fullFilePath),i.migratedModulePaths.push(s.fullFilePath),I.dimmed(` + ${s.relativePath}`);});}async function S1e({v2MobileTests:t,momenticFiles:e,project:r,legacyProjectConfig:o,migratedFilePaths:n,apiClient:i,gitMetadata:a,modulesCoveredByTests:s}){await sp(t,ap,async c=>{let l=await mr(c.fullFilePath,I,e),u=await T1e({platform:l.platform,stepLists:{steps:l.steps,beforeSteps:l.beforeSteps,afterSteps:l.afterSteps},apiClient:i,gitMetadata:a,testId:l.id,environment:void 0,missingSnapshotMessage:`Could not restore legacy step ids for '${c.fullFilePath}' because no mobile snapshot cache was found for test '${l.id}'. Run v2-format migration before undoing it.`}),{moduleUpdates:d}=await ho({platform:l.platform,stepLists:u});for(let m of d)s.add(m.moduleId);await zs({platform:l.platform,filePath:c.fullFilePath,steps:u.steps,beforeSteps:u.beforeSteps,afterSteps:u.afterSteps,settings:l.settings,labels:l.labels,folder:r.rootDir,project:{...r,config:o},momenticFiles:e,schemaVersion:eo,forceFileFormat:"v1"}),n.push(c.fullFilePath),I.dimmed(`Migrated v2 mobile test to legacy: ${c.relativePath}`);});}async function b1e({v2MobileModules:t,momenticFiles:e,project:r,legacyProjectConfig:o,migratedFilePaths:n,modulesCoveredByTests:i}){await sp(t,ap,async a=>{if(i.has(a.id)){n.push(a.fullFilePath);return}let s=Zl(a.fullFilePath,I),c=Ql({module:s,moduleFilePath:a.fullFilePath,momenticFiles:e}),l=Oa.parse(c),u={...l,name:c.name??a.name,steps:qi(l.platform).array().parse(c.steps)};Ja({content:u,schemaVersion:eo,momenticFiles:e,project:{...r,config:o},forceSaveOnNoDiffs:true,forceFileFormat:"v1"}),n.push(a.fullFilePath),I.dimmed(`Migrated unreferenced v2 mobile module to legacy: ${a.relativePath}`);});}async function y1e({legacyMobileTests:t,momenticFiles:e,project:r,v2ProjectConfig:o,migratedFilePaths:n,summary:i,dryRun:a}){await sp(t,ap,async s=>{let c=await mr(s.fullFilePath,I,e);a||await zs({platform:c.platform,filePath:s.fullFilePath,steps:c.steps,beforeSteps:c.beforeSteps,afterSteps:c.afterSteps,settings:c.settings,labels:c.labels,folder:r.rootDir,project:{...r,config:o},momenticFiles:e,schemaVersion:eo}),n.push(s.fullFilePath),i.migratedTestPaths.push(s.fullFilePath),I.dimmed(` + ${s.relativePath}`);});}async function E1e({apiClient:t,gitMetadata:e,testId:r,platform:o,environment:n}){let i=await t.getSnapshotCacheForTest({testId:r,environment:n,platform:o==="ANDROID"?"android":"ios"},hu(e));return KT({entries:i,logger:I})}async function T1e({platform:t,stepLists:e,apiClient:r,gitMetadata:o,testId:n,environment:i,missingSnapshotMessage:a}){let s=await E1e({apiClient:r,gitMetadata:o,testId:n,platform:t,environment:i});s.testStepLists||I.warn(`${a} Minting fresh legacy ids.`);let c=YT({currentStepLists:e,previousSnapshots:s,generateUuid:randomUUID});return c.stats.mintedSteps>0&&I.warn(`Restored legacy mobile YAML with ${c.stats.mintedSteps} newly generated step ids because some steps did not match the snapshot cache.`),c.stepLists}var doe=58890;function yd(t){let e=parseInt(t,10);if(isNaN(e))throw new InvalidArgumentError("Not a number.");return e}function A1e(t){if(t.toUpperCase()==="AUTO")return "AUTO";let e=Number(t);if(isNaN(e))throw new InvalidArgumentError("Not a number or AUTO.");if(!Number.isInteger(e))throw new InvalidArgumentError("Not a number or AUTO.");if(e<=0)throw new InvalidArgumentError("Not a number or AUTO.");return e}var moe=new Option("--port <port>",`Port to run the local app on. Defaults to ${doe}.`).env("PORT").default(doe).argParser(yd),ri=new Option("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").default(Pv(),"value from ~/.momentic/auth.json").argParser(t=>{if(!t)throw new InvalidArgumentError("API key is required. Run `npx @momentic/wizard@latest login` or set MOMENTIC_API_KEY.");return t}).makeOptionMandatory(),nl=new Option("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),ER=new Option("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),oi=new Option("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default(Iv()??"https://api.momentic.ai").argParser(t=>{try{return z.url().parse(t),t}catch{throw new InvalidArgumentError("Not a valid URL.")}}),xb=new Option("-y, --yes","Skip all confirmation prompts.").env("CI"),fk=new Option("--regenerate-cache","Regenerate all caches by starting from an empty cache state. This flag is useful for completely regenerating caches after changing configuration options. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times."),TR=new Option("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),vR=new Option("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:false});function CR(t){return e=>{let r=e.trim();if(r==="")throw new InvalidArgumentError(`${t} must be a non-empty string (whitespace is not allowed).`);return r}}var hk=new Option("--tag <tag>","Tag identifier for the asset.").argParser(CR("--tag")),gk=new Option("--channel <channel>","Channel name for the asset.").argParser(CR("--channel")),AR=new Option("--channel <channel>","Channel name for the asset.").argParser(CR("--channel")).makeOptionMandatory(),Sk=new Option("--tag <tag>","Tag identifier for the asset.").argParser(CR("--tag")).makeOptionMandatory(),bk=new Option("--platform <platform>","Mobile platform for the asset."),poe=new Option("--platform <platform>","Mobile platform for the asset.").makeOptionMandatory(),foe=new Option("--tag-filter <tagFilter>","Case-insensitive substring filter applied to tags when listing a channel."),hoe=new Option("--json","Emit machine-readable JSON output instead of a human-readable table.");function wR(t){if(!t)return "ANDROID";switch(t.toLowerCase()){case "android":return "ANDROID";case "ios":return "IOS";default:throw new InvalidArgumentError('Invalid platform. Valid options are "android" and "ios".')}}var goe=new Option("--env <env>","Environment to run all tests in (overrides test-level configuration)."),Soe=new Option("--android-home <androidHome>","Path to the Android SDK root. Sets ANDROID_HOME for this command."),boe=new Option("--java-home <javaHome>","Path to the Java home directory. Sets JAVA_HOME for this command."),yk=new Option("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(uu).join(", ")}, ${Vn}, ${Object.values(La).join(", ")}.`),Ek=new Option("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),Tk=new Option("--local-apk-path <localApkPath>","Path to a local APK file to install when running tests with a local emulator. Overrides remote asset configuration."),vk=new Option("--local-ios-device-type <localIosDeviceType>","Force tests to use a specific local iOS device type instead of remote emulators."),Ck=new Option("--local-app-path <localAppPath>","Path to a local app file to install when running tests with a local emulator. Overrides remote asset configuration."),yoe=new Option("-p, --parallel <parallel>",['The number of tests to run in parallel. Defaults to 1. Pass "AUTO" to use the number of tests in the current shard.',"Remote (Limbar) runs: each test gets an independent emulator session; parallelism is safe and any org quota is enforced server-side.","Local Android runs: each parallel test must target a distinct AVD. Running parallel > 1 against the same --local-avd-id will conflict.","Local iOS runs: concurrent Appium instances share a driver manifest and may race on startup; prefer parallel=1 for local iOS."].join(" ")).argParser(A1e),Eoe=new Option("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(t=>{let e=yd(t);if(e<1)throw new InvalidArgumentError("Shard index must be greater than 0.");return e}),Toe=new Option("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(yd),Ak=new Option("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),wk=new Option("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),Rk=new Option("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),voe=new Option("--upload-results","Upload test results to the Momentic dashboard.").default(false),w1e=["true","false","on-fail"],Coe=new Option("--video [value]","Record video of mobile test runs. By default, video is recorded. Use the bare flag or pass true, false, or on-fail.").choices(w1e),_k=new Option("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),Aoe=new Option("--ignore-quarantine","Run all tests even if they are quarantined. This is useful for validating that quarantined tests are fixed before moving them out of quarantine.").implies({skipQuarantined:false,onlyQuarantined:false}),woe=new Option("--timeout-minutes <timeoutMinutes>","Maximum number of minutes to run tests before stopping. When the timeout is reached, tests will stop and current results will be printed.").argParser(yd),Roe=new Option("--reporter <reporter>","Output reporter. Live: list (default). File: "+Lv.join(", ")+". File reporters write to --reporter-dir. Pass --reporter multiple times to combine reporters.").default([]).argParser(i4),_oe=new Option("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml.").default("reports"),Moe=new Option("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard."),xoe=new Option("--session-idle-timeout-minutes <timeoutMinutes>","Session idle timeout in minutes. When set, MCP sessions that remain idle for this duration will be automatically terminated. Defaults to 5 minutes.").env("MOMENTIC_SESSION_IDLE_TIMEOUT_MINUTES").argParser(yd),Poe=new Option("--headful [headful]","Launch mobile MCP remote control browsers headfully by default.").argParser(CM),Ioe=new Option("--supports-file-output [supportsFileOutput]","Allow MCP tool responses to include file output references.").argParser(CM),Ooe=new Option("--daemon","Keep session tools alive across MCP stdio calls by routing through a local daemon. Sets the daemon cwd to the directory of the config file, allowing multiple MCP servers to share the same project home."),Noe=new Argument("[results]",`Path to the results archive. Defaults to "${Dg}".`).default(Dg);var Cf="screen-recording.mp4";var Doe={...el,prepareRunParams:async({runTracer:t,metadata:{orgId:e},fixtures:{logger:r,apiClient:o,mobileGenerator:n,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:S},settings:{emulatorSettings:b,aiSettings:y},options:{logLevel:T,localAvdId:v,localApkPath:w,region:N},registerCleanup:D})=>{let x=false,A=[()=>u.dispose()],B=async()=>{x=true;for(let F of A.toReversed())try{await F();}catch(U){ne.warn({err:U},"Failed to run cleanup function");}await s.flush(r);};D?.(async()=>B());let O=wl.optional().parse(N??b.region),z=O==="local",k;if(z){let{avdId:F,apkFilePath:U,apkFilePathSource:K}=dm({overrideAvdId:v,overrideApkFilePath:w,emulatorSettings:b,defaultApkFilePath:f.settings?.defaultApkFilePath,envVariables:S}),ee=pp({apkFilePath:U,source:K});if(!F)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${gl} key on the environment.`);k={avdId:F,apkFilePath:ee};}else k={region:O===Vn?void 0:O,apkToInstall:d?{channel:d,tag:m}:void 0,osVersion:b.remoteEmulatorSettings?.androidVersion??nm};let H=randomUUID(),ne=r.child({runAttemptId:H}),L=await mp({apiClient:o,logger:r,driverLogLevel:T,creationOpts:k,callbacks:{onStatusUpdate:F=>{r.debug({status:F},"Emulator status update");},onHeartbeatFailure:()=>{let F="Appium heartbeat connection lost. Possible ADB tunnel/emulator failure.";x||I.warn(F);},onHeartbeatRestored:()=>{I.info("Appium heartbeat connection restored.");},onLimbarConnectionStateChange:F=>{F==="disconnected"?x||I.warn("Emulator websocket connection lost. Emulator may be unavailable."):(F==="reconnecting"||F==="connecting")&&I.info("Emulator websocket is reconnecting.");}},orgId:e,sessionId:H});A.push(()=>L.cleanup());let $="limbarRegion"in L?L.limbarRegion:void 0;try{let F=await t.startAttempt({emulatorName:L.emulatorName,runAttemptId:H,assetDetails:{avdId:du in k?k.avdId:void 0,tag:"apkToInstall"in k?k.apkToInstall?.tag:void 0,channel:"apkToInstall"in k?k.apkToInstall?.channel:void 0,region:$??O??Vn}});ne=ne.child(F.loggerBindings||{});let U=await L.driver.executeInNativeContext(ne,async de=>Xv({driver:de,onLogs:je=>{F.appendLogs(je);}}),{operationName:"startLogcatListener"});A.push(()=>U());let K=new hi({variablesFromEnvironment:S,envName:h,testName:f.name}),ee="limbarClient"in L?L.limbarClient:void 0,V="playwrightDevice"in L?L.playwrightDevice:void 0,le=await Fc.init({driver:L.driver,generator:n,logger:ne,limbarClient:ee,playwrightDevice:V,orgId:e,adbPort:L.adbPort,options:{emulator:{...b,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:i,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u,testContext:K}});if(A.push(()=>le.cleanup()),F.videoOutputPath&&ee)try{await ee.startRecording({quality:RecordingQuality$1.Q5}),F.setActiveVideo(Cf,new Date),ne.info("Started Android video recording"),A.push(async()=>{if(!F.videoOutputPath)return;let de=sr__default.join(F.videoOutputPath,Cf);await ee.stopRecording({localPath:de}),ne.info({videoPath:de},"Saved Android video recording");});}catch(de){ne.warn({err:de},"Failed to start Android video recording");}return {platform:"ANDROID",envName:h,tracer:F,fixtures:{controller:le,logger:ne,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f,useSnapshotIdentityCache:!1},callbacks:{},cleanup:B}}catch(F){throw await B(),F}}};var Loe={...tl,prepareRunParams:async({runTracer:t,metadata:{orgId:e},fixtures:{logger:r,apiClient:o,mobileGenerator:n,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:S},settings:{emulatorSettings:b,aiSettings:y},options:{logLevel:T,region:v,localIosDeviceType:w,localAppPath:N},registerCleanup:D})=>{let x=false,A=[()=>u.dispose()],B=async()=>{x=true;for(let F of A.toReversed())try{await F();}catch(U){ne.warn({err:U},"Failed to run cleanup function");}await s.flush(r);};D?.(async()=>B());let O=wl.optional().parse(v??b.region),z;if(O==="local"){let{deviceType:F,appFilePath:U,appFilePathSource:K}=mm({overrideDeviceType:w,overrideAppFilePath:N,emulatorSettings:b,defaultAppFilePath:f.settings?.defaultAppFilePath,envVariables:S});if(!F)throw new Error(`A device type is required when using a local region. Provide --local-ios-device-type, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);let ee=df({appFolderPath:U,source:K});z={type:"local",deviceType:F,appFilePath:ee};}else z={type:"remote",region:O===Vn?void 0:O,appToInstall:d?{channel:d,tag:m}:void 0,osVersion:im};let H=randomUUID(),ne=r.child({runAttemptId:H}),L=await ef({apiClient:o,logger:r,driverLogLevel:T,creationOpts:z,callbacks:{onStatusUpdate:F=>{r.debug({status:F},"Emulator status update");},onHeartbeatFailure:()=>{x||I.warn("Appium heartbeat connection lost. Possible emulator failure.");},onHeartbeatRestored:()=>{I.info("Appium heartbeat connection restored.");},onLimbarConnectionStateChange:F=>{F==="disconnected"?x||I.warn("Emulator websocket connection lost. Emulator may be unavailable."):(F==="reconnecting"||F==="connecting")&&I.info("Emulator websocket is reconnecting.");}},orgId:e,sessionId:H});A.push(()=>L.cleanup());let $=L.limbarParams?.region;try{let F=await t.startAttempt({emulatorName:L.emulator.name,runAttemptId:H,assetDetails:{region:$??O??Vn,tag:"appToInstall"in z?z.appToInstall?.tag:void 0,channel:"appToInstall"in z?z.appToInstall?.channel:void 0}});ne=ne.child(F.loggerBindings||{});let U=await Mw({emulator:L.emulator,onLogs:le=>{F.appendLogs(le);}});U&&A.push(async()=>U());let K=new hi({variablesFromEnvironment:S,envName:h,testName:f.name}),ee=await zc.init({driver:L.driver,generator:n,logger:ne,emulator:L.emulator,orgId:e,options:{emulator:{...b,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:i,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u,testContext:K}});A.push(()=>ee?.cleanup());let V=L.emulator;if(F.videoOutputPath&&V.startScreenRecording&&V.stopScreenRecording)try{await V.startScreenRecording(),F.setActiveVideo(Cf,new Date),ne.info("Started iOS video recording"),A.push(async()=>{if(!F.videoOutputPath||!V.stopScreenRecording)return;let le=sr__default.join(F.videoOutputPath,Cf);await V.stopScreenRecording(le),ne.info({videoPath:le},"Saved iOS video recording");});}catch(le){ne.warn({err:le},"Failed to start iOS video recording");}return {platform:"IOS",envName:h,tracer:F,fixtures:{controller:ee,logger:ne,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f,useSnapshotIdentityCache:!1},callbacks:{},cleanup:B}}catch(F){throw await B(),F}}};var Go="0.97.2",{checkCLIVersion:Mk}=m4({packageName:"momentic-mobile",currentVersion:Go,changelogUrl:"https://github.com/momentic-ai/mobile-cli/blob/main/CHANGELOG.md",updateCommand:"npx momentic-mobile@latest upgrade"});var Pk=class{constructor(e,r,o,n,i,a,s){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.diskStorage=i;this.parentTracer=a;this.orgId=s;this.interactionTracer=new Mi(void 0,c=>this.storeTraceAsset(c)),Uo.initializeRootTracerContext(this.interactionTracer);}children=[];finished=false;interactionTracer;getParentStepIdChain(){return []}recordStepDuration(e){let{durationMs:r,step:o}=e;if(!cE(o))return;let n=lE(o);_t.distribution("test_mobile_step_duration",r,[`type:${n}`,`platform:${this.platform.toLowerCase()}`,"executor:cli",`orgId:${this.orgId}`]);}attachBeforeScreenshot(e){let{snapshotId:r,screenshot:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.png`,contents:o});}attachAfterScreenshot(e){let{snapshotId:r,screenshot:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.png`,contents:o});}storeTraceAsset(e){let{snapshotId:r,data:o,extension:n}=e;this.diskStorage.storeFile({name:`${bi}/${r}.${n??"png"}`,contents:o});}attachBeforeXmlSnapshot(e){let{snapshotId:r,xml:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.xml`,contents:o});}attachAfterXmlSnapshot(e){let{snapshotId:r,xml:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.xml`,contents:o});}async finishInternal(e){this.finished||(this.finished=true,this.interactionTracer.finish(),await Promise.all(this.children.map(r=>r.finish({status:oh(e.status),finishedAt:e.finishedAt}))));}async finish(e){return await this.finishInternal({status:e.result.status,finishedAt:new Date(e.result.endTime)}),{trace:this.interactionTracer.getRootSpan()}}async startSubSteps(){let e=new Af(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}},Af=class{constructor(e,r,o,n,i,a){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.diskStorage=i;this.orgId=a;}children=[];finished=false;async getScreenshot(e){return this.diskStorage.readFile(`${bi}/${e}.png`)??this.diskStorage.readFile(`${bi}/${e}.jpeg`)}getParentStepIdChain(){return []}async startStep(e){this.keepalive();let r=new Pk(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this,this.orgId);return this.children.push(r),r}async finish(e){this.finished||(this.finished=true,await Promise.all(this.children.map(r=>r.finishInternal({status:VU(e.status),finishedAt:e.finishedAt}))));}},Ik=class{constructor(e,r,o,n,i,a,s,c,l,u,d){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.runAttemptId=i;this.metadata=a;this.diskStorage=s;this.orgId=c;this.resultSchema=l;this.recordVideo=u;this.assetDetails=d;this.diskStorage.mkdir("assets");let m=n==="IOS"?"assets/logs.syslog":"assets/logs.logcat";this.logStream=this.diskStorage.createFileStream(m),this.resourceUsageStream=this.diskStorage.createFileStream(`${bi}/resource-usage.ndjson`),this.resourceUsageSampler=rj({keepSamples:false,onSample:p=>{this.resourceUsageStream.write(`${JSON.stringify(p)}
|
|
5940
|
+
`)}`),e.totalErrors++;for(let s of a){let c=sr__default.relative(t.project.rootDir,s);r.has(s)?e.failedModuleFilePaths.add(c):e.failedTestFilePaths.add(c);}}}}function m1e({momenticFiles:t,state:e}){for(let[r,o]of Object.entries(t.mobileTests)){let n=t.mobileModules[r];n&&(I.error(`ID '${r}' is shared between mobile test '${o.relativePath}' and mobile module '${n.relativePath}'. Test and module IDs must be unique across the entire project.`),e.totalErrors++,e.failedTestFilePaths.add(o.relativePath),e.failedModuleFilePaths.add(n.relativePath));}}async function ck({project:t,filePath:e}){let{totalErrors:r,parsingErrors:o,parsingErrorDetails:n,failedTestFilePaths:i,failedModuleFilePaths:a}=await c1e({project:t,filePath:e});if(r===0){I.success("Mobile lint passed. No issues found.");return}n.length>0&&zP({parsingErrors:o,parsingErrorDetails:n,failedTestFilePaths:i,failedModuleFilePaths:a}),I.error(`Found ${r} mobile lint error${r===1?"":"s"} in project.`),process.exit(1);}async function uk({project:t}){if(t.config.fileFormat==="v2"){await ck({project:t,filePath:void 0});return}let{parsingErrors:e,parsingErrorDetails:r,failedTestFilePaths:o}=await noe({project:t,logger:I});e>0&&(zP({parsingErrors:e,parsingErrorDetails:r,failedTestFilePaths:o}),process.exit(1));}async function mk({tests:t,momenticFiles:e,project:r,yes:o,include:n,exclude:i,labels:a,logger:s,quarantinedTestsMetadata:c}){let l=new Set;if(t&&t.length>0){let d=t.some(p=>so.existsSync(p)),m=cwd();d?(m!==r.rootDir&&s.warn(`Test paths resolve against the current directory ('${m}'), not the project root ('${r.rootDir}'). Run from the project root or use substring filters to avoid surprises.`),t.forEach(p=>{if(!so.existsSync(p))throw new Error(`Path '${p}' does not exist.`);let f,h;try{f=so.statSync(p),h=f.isDirectory();}catch(b){s.warn({err:b},`Skipping path ${p} because it cannot be read`);return}let S=sr__default.resolve(p);Object.values(e.mobileTests).filter(b=>h?b.fullFilePath.startsWith(S):b.fullFilePath===S).forEach(b=>{l.add(b.fullFilePath);});})):Object.values(e.mobileTests).forEach(p=>{t.some(f=>p.relativePath.includes(f))&&l.add(p.fullFilePath);});}else !o&&!await Ol("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1)),Object.values(e.mobileTests).forEach(m=>{l.add(m.fullFilePath);});for(let d of Array.from(l)){let m=sr__default.relative(r.rootDir,d);n&&!n.some(p=>new RegExp(p).test(m))&&l.delete(d),i&&i.some(p=>new RegExp(p).test(m))&&l.delete(d);}return (await Promise.all(Array.from(l).map(async d=>{try{let m=sr__default.relative(r.rootDir,d),p=await mr(d,s,e),f=sr__default.basename(d,".test.yaml");if(p.disabled)return null;if(a&&a.length>0){let S=p.labels||[];if(!a.some(y=>S.includes(y)))return null}let h={id:p.id,name:f,description:p.description,schemaVersion:p.schemaVersion,settings:p.settings,fullFilePath:d,relativeFilePath:m,quarantined:!!c[p.id],quarantinedMetadata:c[p.id],labels:p.labels};switch(p.platform){case "ANDROID":return {...h,platform:"ANDROID",steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps};case "IOS":return {...h,platform:"IOS",steps:p.steps,beforeSteps:p.beforeSteps,afterSteps:p.afterSteps};default:return (b=>{throw new Error("You missed a case in the switch above")})(p)}}catch(m){s.error(`Failed to read and resolve mobile test at '${d}': ${m}`),process.exit(1);}}))).filter(d=>!!d)}async function pk({project:t,apiClient:e,gitMetadata:r,orgId:o,dryRun:n=false}){let i=await vt(t),a=Object.values(i.mobileTests).filter(S=>S.type===ve.MOBILE_TEST),s=Object.values(i.mobileModules).filter(S=>S.type===ve.MOBILE_MODULE),c=Object.values(i.mobileTests).filter(S=>S.type===ve.MOBILE_TEST_V2).length,l=Object.values(i.mobileModules).filter(S=>S.type===ve.MOBILE_MODULE_V2).length,u={...bO(),alreadyV2TestCount:c,alreadyV2ModuleCount:l},d=t.config.fileFormat!=="v2",{v2ProjectConfig:m,migratedFilePaths:p}=p4(t);!n&&a.length>0&&await h1e({legacyMobileTests:a,momenticFiles:i,project:t,apiClient:e,gitMetadata:r,orgId:o}),await g1e({legacyMobileModules:s,momenticFiles:i,project:t,v2ProjectConfig:m,migratedFilePaths:p,summary:u,dryRun:n}),await y1e({legacyMobileTests:a,momenticFiles:i,project:t,v2ProjectConfig:m,migratedFilePaths:p,summary:u,dryRun:n});let f=u.migratedTestPaths.length>0||u.migratedModulePaths.length>0;return !n&&(d||f)&&gO({project:t,newProjectConfig:m,fileFormatLabel:"v2",migratedFilePaths:p}),u}async function uoe({project:t,apiClient:e,gitMetadata:r}){let{legacyProjectConfig:o,migratedFilePaths:n}=f4(t),i=await vt(t),a=Object.values(i.mobileTests).filter(l=>l.type===ve.MOBILE_TEST_V2),s=Object.values(i.mobileModules).filter(l=>l.type===ve.MOBILE_MODULE_V2);I.info(`Migrating ${a.length} v2 mobile tests and ${s.length} v2 mobile modules to legacy YAML`);let c=new Set;await S1e({v2MobileTests:a,momenticFiles:i,project:t,legacyProjectConfig:o,migratedFilePaths:n,apiClient:e,gitMetadata:r,modulesCoveredByTests:c}),await b1e({v2MobileModules:s,momenticFiles:i,project:t,legacyProjectConfig:o,migratedFilePaths:n,modulesCoveredByTests:c}),gO({project:t,newProjectConfig:o,fileFormatLabel:"legacy",migratedFilePaths:n});}async function h1e({legacyMobileTests:t,momenticFiles:e,project:r,apiClient:o,gitMetadata:n,orgId:i}){if(t.length===0)return;let a={logger:I,orgId:i,client:o,regenerateCache:false,alwaysSaveCache:true,noCache:false,isolateCachesByEnvironment:r.config.advanced?.isolateCachesByEnvironment??false,bustOldestCachePercentage:void 0},s=[Hr({...a,gitMetadata:n})];n.gitMainBranch&&n.gitBranchName!==n.gitMainBranch&&s.push(Hr({...a,gitMetadata:{...n,gitBranchName:n.gitMainBranch,gitCommitTimestamp:n.lastCommitOnMainTimestamp??n.gitCommitTimestamp}})),I.info(`Pushing mobile test snapshots for ${t.length} legacy mobile tests so existing step caches survive the v2 conversion`),await sp(t,ap,async c=>{let l=await mr(c.fullFilePath,I,e),{snapshotCachesToSave:u}=await ho({platform:l.platform,stepLists:{steps:l.steps,beforeSteps:l.beforeSteps,afterSteps:l.afterSteps},useSnapshotIdentityCache:true,cacheCreationParams:{orgId:i,testId:l.id,environment:void 0}});for(let d of s)await d.saveSnapshotCacheEntries({logger:I,platform:l.platform,entries:u});I.dimmed(`Pushed mobile test snapshot for: ${c.relativePath}`);});}async function g1e({legacyMobileModules:t,momenticFiles:e,project:r,v2ProjectConfig:o,migratedFilePaths:n,summary:i,dryRun:a}){await sp(t,ap,async s=>{let c=Zl(s.fullFilePath,I);if(Ig(c))throw new Error(`Expected a legacy mobile module while migrating '${s.relativePath}', but found v2 format`);let l=Ql({module:c,moduleFilePath:s.fullFilePath,momenticFiles:e}),u=Oa.parse(l),d={...u,name:l.name??s.name,steps:qi(u.platform).array().parse(l.steps)};a||Ja({content:d,schemaVersion:eo,momenticFiles:e,project:{...r,config:o},forceSaveOnNoDiffs:true}),n.push(s.fullFilePath),i.migratedModulePaths.push(s.fullFilePath),I.dimmed(` + ${s.relativePath}`);});}async function S1e({v2MobileTests:t,momenticFiles:e,project:r,legacyProjectConfig:o,migratedFilePaths:n,apiClient:i,gitMetadata:a,modulesCoveredByTests:s}){await sp(t,ap,async c=>{let l=await mr(c.fullFilePath,I,e),u=await T1e({platform:l.platform,stepLists:{steps:l.steps,beforeSteps:l.beforeSteps,afterSteps:l.afterSteps},apiClient:i,gitMetadata:a,testId:l.id,environment:void 0,missingSnapshotMessage:`Could not restore legacy step ids for '${c.fullFilePath}' because no mobile snapshot cache was found for test '${l.id}'. Run v2-format migration before undoing it.`}),{moduleUpdates:d}=await ho({platform:l.platform,stepLists:u});for(let m of d)s.add(m.moduleId);await zs({platform:l.platform,filePath:c.fullFilePath,steps:u.steps,beforeSteps:u.beforeSteps,afterSteps:u.afterSteps,settings:l.settings,labels:l.labels,folder:r.rootDir,project:{...r,config:o},momenticFiles:e,schemaVersion:eo,forceFileFormat:"v1"}),n.push(c.fullFilePath),I.dimmed(`Migrated v2 mobile test to legacy: ${c.relativePath}`);});}async function b1e({v2MobileModules:t,momenticFiles:e,project:r,legacyProjectConfig:o,migratedFilePaths:n,modulesCoveredByTests:i}){await sp(t,ap,async a=>{if(i.has(a.id)){n.push(a.fullFilePath);return}let s=Zl(a.fullFilePath,I),c=Ql({module:s,moduleFilePath:a.fullFilePath,momenticFiles:e}),l=Oa.parse(c),u={...l,name:c.name??a.name,steps:qi(l.platform).array().parse(c.steps)};Ja({content:u,schemaVersion:eo,momenticFiles:e,project:{...r,config:o},forceSaveOnNoDiffs:true,forceFileFormat:"v1"}),n.push(a.fullFilePath),I.dimmed(`Migrated unreferenced v2 mobile module to legacy: ${a.relativePath}`);});}async function y1e({legacyMobileTests:t,momenticFiles:e,project:r,v2ProjectConfig:o,migratedFilePaths:n,summary:i,dryRun:a}){await sp(t,ap,async s=>{let c=await mr(s.fullFilePath,I,e);a||await zs({platform:c.platform,filePath:s.fullFilePath,steps:c.steps,beforeSteps:c.beforeSteps,afterSteps:c.afterSteps,settings:c.settings,labels:c.labels,folder:r.rootDir,project:{...r,config:o},momenticFiles:e,schemaVersion:eo}),n.push(s.fullFilePath),i.migratedTestPaths.push(s.fullFilePath),I.dimmed(` + ${s.relativePath}`);});}async function E1e({apiClient:t,gitMetadata:e,testId:r,platform:o,environment:n}){let i=await t.getSnapshotCacheForTest({testId:r,environment:n,platform:o==="ANDROID"?"android":"ios"},hu(e));return KT({entries:i,logger:I})}async function T1e({platform:t,stepLists:e,apiClient:r,gitMetadata:o,testId:n,environment:i,missingSnapshotMessage:a}){let s=await E1e({apiClient:r,gitMetadata:o,testId:n,platform:t,environment:i});s.testStepLists||I.warn(`${a} Minting fresh legacy ids.`);let c=YT({currentStepLists:e,previousSnapshots:s,generateUuid:randomUUID});return c.stats.mintedSteps>0&&I.warn(`Restored legacy mobile YAML with ${c.stats.mintedSteps} newly generated step ids because some steps did not match the snapshot cache.`),c.stepLists}var doe=58890;function yd(t){let e=parseInt(t,10);if(isNaN(e))throw new InvalidArgumentError("Not a number.");return e}function A1e(t){if(t.toUpperCase()==="AUTO")return "AUTO";let e=Number(t);if(isNaN(e))throw new InvalidArgumentError("Not a number or AUTO.");if(!Number.isInteger(e))throw new InvalidArgumentError("Not a number or AUTO.");if(e<=0)throw new InvalidArgumentError("Not a number or AUTO.");return e}var moe=new Option("--port <port>",`Port to run the local app on. Defaults to ${doe}.`).env("PORT").default(doe).argParser(yd),ri=new Option("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").default(Pv(),"value from ~/.momentic/auth.json").argParser(t=>{if(!t)throw new InvalidArgumentError("API key is required. Run `npx @momentic/wizard@latest login` or set MOMENTIC_API_KEY.");return t}).makeOptionMandatory(),nl=new Option("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),ER=new Option("-f, --filter <filter>","Run tests within the project that has a name equal to the filter provided. This option cannot be used together with file path or directory arguments, but substring matches are allowed."),oi=new Option("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default(Iv()??"https://api.momentic.ai").argParser(t=>{try{return z.url().parse(t),t}catch{throw new InvalidArgumentError("Not a valid URL.")}}),xb=new Option("-y, --yes","Skip all confirmation prompts.").env("CI"),fk=new Option("--regenerate-cache","Regenerate all caches by starting from an empty cache state. This flag is useful for completely regenerating caches after changing configuration options. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times."),TR=new Option("--save-cache","Always save updated step caches after successful test runs. By default, caches are not saved when running on protected branches.").env("CI"),vR=new Option("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:false});function CR(t){return e=>{let r=e.trim();if(r==="")throw new InvalidArgumentError(`${t} must be a non-empty string (whitespace is not allowed).`);return r}}var hk=new Option("--tag <tag>","Tag identifier for the asset.").argParser(CR("--tag")),gk=new Option("--channel <channel>","Channel name for the asset.").argParser(CR("--channel")),AR=new Option("--channel <channel>","Channel name for the asset.").argParser(CR("--channel")).makeOptionMandatory(),Sk=new Option("--tag <tag>","Tag identifier for the asset.").argParser(CR("--tag")).makeOptionMandatory(),bk=new Option("--platform <platform>","Mobile platform for the asset."),poe=new Option("--platform <platform>","Mobile platform for the asset.").makeOptionMandatory(),foe=new Option("--tag-filter <tagFilter>","Case-insensitive substring filter applied to tags when listing a channel."),hoe=new Option("--json","Emit machine-readable JSON output instead of a human-readable table.");function wR(t){if(!t)return "ANDROID";switch(t.toLowerCase()){case "android":return "ANDROID";case "ios":return "IOS";default:throw new InvalidArgumentError('Invalid platform. Valid options are "android" and "ios".')}}var goe=new Option("--env <env>","Environment to run all tests in (overrides test-level configuration)."),Soe=new Option("--android-home <androidHome>","Path to the Android SDK root. Sets ANDROID_HOME for this command."),boe=new Option("--java-home <javaHome>","Path to the Java home directory. Sets JAVA_HOME for this command."),yk=new Option("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(uu).join(", ")}, ${Vn}, ${Object.values(La).join(", ")}.`),Ek=new Option("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),Tk=new Option("--local-apk-path <localApkPath>","Path to a local APK file to install when running tests with a local emulator. Overrides remote asset configuration."),vk=new Option("--local-ios-device-type <localIosDeviceType>","Force tests to use a specific local iOS device type instead of remote emulators."),Ck=new Option("--local-app-path <localAppPath>","Path to a local app file to install when running tests with a local emulator. Overrides remote asset configuration."),yoe=new Option("-p, --parallel <parallel>",['The number of tests to run in parallel. Defaults to 1. Pass "AUTO" to use the number of tests in the current shard.',"Remote (Limbar) runs: each test gets an independent emulator session; parallelism is safe and any org quota is enforced server-side.","Local Android runs: each parallel test must target a distinct AVD. Running parallel > 1 against the same --local-avd-id will conflict.","Local iOS runs: concurrent Appium instances share a driver manifest and may race on startup; prefer parallel=1 for local iOS."].join(" ")).argParser(A1e),Eoe=new Option("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(t=>{let e=yd(t);if(e<1)throw new InvalidArgumentError("Shard index must be greater than 0.");return e}),Toe=new Option("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(yd),Ak=new Option("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),wk=new Option("--include <includePatterns...>","Only include tests that match the provided regex patterns. Multiple patterns can be provided. The patterns will be matched against the test file paths and the pattern only needs to match a part of the path for the test to be included."),Rk=new Option("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),voe=new Option("--upload-results","Upload test results to the Momentic dashboard.").default(false),w1e=["true","false","on-fail"],Coe=new Option("--video [value]","Record video of mobile test runs. By default, video is recorded. Use the bare flag or pass true, false, or on-fail.").choices(w1e),_k=new Option("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),Aoe=new Option("--ignore-quarantine","Run all tests even if they are quarantined. This is useful for validating that quarantined tests are fixed before moving them out of quarantine.").implies({skipQuarantined:false,onlyQuarantined:false}),woe=new Option("--timeout-minutes <timeoutMinutes>","Maximum number of minutes to run tests before stopping. When the timeout is reached, tests will stop and current results will be printed.").argParser(yd),Roe=new Option("--reporter <reporter>","Output reporter. Live: list (default). File: "+Lv.join(", ")+". File reporters write to --reporter-dir. Pass --reporter multiple times to combine reporters.").default([]).argParser(i4),_oe=new Option("--reporter-dir <reporterDir>","Output directory to store report files. Relative paths are resolved relative to the project root, which is defined by the detected momentic.config.yaml.").default("reports"),Moe=new Option("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard."),xoe=new Option("--session-idle-timeout-minutes <timeoutMinutes>","Session idle timeout in minutes. When set, MCP sessions that remain idle for this duration will be automatically terminated. Defaults to 5 minutes.").env("MOMENTIC_SESSION_IDLE_TIMEOUT_MINUTES").argParser(yd),Poe=new Option("--headful [headful]","Launch mobile MCP remote control browsers headfully by default.").argParser(CM),Ioe=new Option("--supports-file-output [supportsFileOutput]","Allow MCP tool responses to include file output references.").argParser(CM),Ooe=new Option("--daemon","Keep session tools alive across MCP stdio calls by routing through a local daemon. Sets the daemon cwd to the directory of the config file, allowing multiple MCP servers to share the same project home."),Noe=new Argument("[results]",`Path to the results archive. Defaults to "${Dg}".`).default(Dg);var Cf="screen-recording.mp4";var Doe={...el,prepareRunParams:async({runTracer:t,metadata:{orgId:e},fixtures:{logger:r,apiClient:o,mobileGenerator:n,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:S},settings:{emulatorSettings:b,aiSettings:y},options:{logLevel:T,localAvdId:v,localApkPath:w,region:N},registerCleanup:D})=>{let x=false,A=[()=>u.dispose()],B=async()=>{x=true;for(let F of A.toReversed())try{await F();}catch(U){ne.warn({err:U},"Failed to run cleanup function");}await s.flush(r);};D?.(async()=>B());let O=wl.optional().parse(N??b.region),z=O==="local",k;if(z){let{avdId:F,apkFilePath:U,apkFilePathSource:K}=dm({overrideAvdId:v,overrideApkFilePath:w,emulatorSettings:b,defaultApkFilePath:f.settings?.defaultApkFilePath,envVariables:S}),ee=pp({apkFilePath:U,source:K});if(!F)throw new Error(`An AVD ID is required when using a local region. Provide --local-avd-id, configure a default local AVD ID on the test's settings, or set the ${gl} key on the environment.`);k={avdId:F,apkFilePath:ee};}else k={region:O===Vn?void 0:O,apkToInstall:d?{channel:d,tag:m}:void 0,osVersion:b.remoteEmulatorSettings?.androidVersion??nm};let H=randomUUID(),ne=r.child({runAttemptId:H}),L=await mp({apiClient:o,logger:r,driverLogLevel:T,creationOpts:k,callbacks:{onStatusUpdate:F=>{r.debug({status:F},"Emulator status update");},onHeartbeatFailure:()=>{let F="Appium heartbeat connection lost. Possible ADB tunnel/emulator failure.";x||I.warn(F);},onHeartbeatRestored:()=>{I.info("Appium heartbeat connection restored.");},onLimbarConnectionStateChange:F=>{F==="disconnected"?x||I.warn("Emulator websocket connection lost. Emulator may be unavailable."):(F==="reconnecting"||F==="connecting")&&I.info("Emulator websocket is reconnecting.");}},orgId:e,sessionId:H});A.push(()=>L.cleanup());let $="limbarRegion"in L?L.limbarRegion:void 0;try{let F=await t.startAttempt({emulatorName:L.emulatorName,runAttemptId:H,assetDetails:{avdId:du in k?k.avdId:void 0,tag:"apkToInstall"in k?k.apkToInstall?.tag:void 0,channel:"apkToInstall"in k?k.apkToInstall?.channel:void 0,region:$??O??Vn}});ne=ne.child(F.loggerBindings||{});let U=await L.driver.executeInNativeContext(ne,async de=>Xv({driver:de,onLogs:je=>{F.appendLogs(je);}}),{operationName:"startLogcatListener"});A.push(()=>U());let K=new hi({variablesFromEnvironment:S,envName:h,testName:f.name}),ee="limbarClient"in L?L.limbarClient:void 0,V="playwrightDevice"in L?L.playwrightDevice:void 0,le=await Fc.init({driver:L.driver,generator:n,logger:ne,limbarClient:ee,playwrightDevice:V,orgId:e,adbPort:L.adbPort,options:{emulator:{...b,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:i,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u,testContext:K}});if(A.push(()=>le.cleanup()),F.videoOutputPath&&ee)try{await ee.startRecording({quality:RecordingQuality$1.Q5}),F.setActiveVideo(Cf,new Date),ne.info("Started Android video recording"),A.push(async()=>{if(!F.videoOutputPath)return;let de=sr__default.join(F.videoOutputPath,Cf);await ee.stopRecording({localPath:de}),ne.info({videoPath:de},"Saved Android video recording");});}catch(de){ne.warn({err:de},"Failed to start Android video recording");}return {platform:"ANDROID",envName:h,tracer:F,fixtures:{controller:le,logger:ne,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f,useSnapshotIdentityCache:!1},callbacks:{},cleanup:B}}catch(F){throw await B(),F}}};var Loe={...tl,prepareRunParams:async({runTracer:t,metadata:{orgId:e},fixtures:{logger:r,apiClient:o,mobileGenerator:n,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:S},settings:{emulatorSettings:b,aiSettings:y},options:{logLevel:T,region:v,localIosDeviceType:w,localAppPath:N},registerCleanup:D})=>{let x=false,A=[()=>u.dispose()],B=async()=>{x=true;for(let F of A.toReversed())try{await F();}catch(U){ne.warn({err:U},"Failed to run cleanup function");}await s.flush(r);};D?.(async()=>B());let O=wl.optional().parse(v??b.region),z;if(O==="local"){let{deviceType:F,appFilePath:U,appFilePathSource:K}=mm({overrideDeviceType:w,overrideAppFilePath:N,emulatorSettings:b,defaultAppFilePath:f.settings?.defaultAppFilePath,envVariables:S});if(!F)throw new Error(`A device type is required when using a local region. Provide --local-ios-device-type, configure a default local iOS device type on the test's settings, or set the ${Sl} key on the environment.`);let ee=df({appFolderPath:U,source:K});z={type:"local",deviceType:F,appFilePath:ee};}else z={type:"remote",region:O===Vn?void 0:O,appToInstall:d?{channel:d,tag:m}:void 0,osVersion:im};let H=randomUUID(),ne=r.child({runAttemptId:H}),L=await ef({apiClient:o,logger:r,driverLogLevel:T,creationOpts:z,callbacks:{onStatusUpdate:F=>{r.debug({status:F},"Emulator status update");},onHeartbeatFailure:()=>{x||I.warn("Appium heartbeat connection lost. Possible emulator failure.");},onHeartbeatRestored:()=>{I.info("Appium heartbeat connection restored.");},onLimbarConnectionStateChange:F=>{F==="disconnected"?x||I.warn("Emulator websocket connection lost. Emulator may be unavailable."):(F==="reconnecting"||F==="connecting")&&I.info("Emulator websocket is reconnecting.");}},orgId:e,sessionId:H});A.push(()=>L.cleanup());let $=L.limbarParams?.region;try{let F=await t.startAttempt({emulatorName:L.emulator.name,runAttemptId:H,assetDetails:{region:$??O??Vn,tag:"appToInstall"in z?z.appToInstall?.tag:void 0,channel:"appToInstall"in z?z.appToInstall?.channel:void 0}});ne=ne.child(F.loggerBindings||{});let U=await Mw({emulator:L.emulator,onLogs:le=>{F.appendLogs(le);}});U&&A.push(async()=>U());let K=new hi({variablesFromEnvironment:S,envName:h,testName:f.name}),ee=await zc.init({driver:L.driver,generator:n,logger:ne,emulator:L.emulator,orgId:e,options:{emulator:{...b,browserSettings:p.config.browser}},aiSettings:y,fixtures:{storage:i,browserEnricher:c,browserGenerator:l,localCodeEvalTools:u,testContext:K}});A.push(()=>ee?.cleanup());let V=L.emulator;if(F.videoOutputPath&&V.startScreenRecording&&V.stopScreenRecording)try{await V.startScreenRecording(),F.setActiveVideo(Cf,new Date),ne.info("Started iOS video recording"),A.push(async()=>{if(!F.videoOutputPath||!V.stopScreenRecording)return;let le=sr__default.join(F.videoOutputPath,Cf);await V.stopScreenRecording(le),ne.info({videoPath:le},"Saved iOS video recording");});}catch(le){ne.warn({err:le},"Failed to start iOS video recording");}return {platform:"IOS",envName:h,tracer:F,fixtures:{controller:ee,logger:ne,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:y.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f,useSnapshotIdentityCache:!1},callbacks:{},cleanup:B}}catch(F){throw await B(),F}}};var Go="0.97.3",{checkCLIVersion:Mk}=m4({packageName:"momentic-mobile",currentVersion:Go,changelogUrl:"https://github.com/momentic-ai/mobile-cli/blob/main/CHANGELOG.md",updateCommand:"npx momentic-mobile@latest upgrade"});var Pk=class{constructor(e,r,o,n,i,a,s){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.diskStorage=i;this.parentTracer=a;this.orgId=s;this.interactionTracer=new Mi(void 0,c=>this.storeTraceAsset(c)),Uo.initializeRootTracerContext(this.interactionTracer);}children=[];finished=false;interactionTracer;getParentStepIdChain(){return []}recordStepDuration(e){let{durationMs:r,step:o}=e;if(!cE(o))return;let n=lE(o);_t.distribution("test_mobile_step_duration",r,[`type:${n}`,`platform:${this.platform.toLowerCase()}`,"executor:cli",`orgId:${this.orgId}`]);}attachBeforeScreenshot(e){let{snapshotId:r,screenshot:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.png`,contents:o});}attachAfterScreenshot(e){let{snapshotId:r,screenshot:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.png`,contents:o});}storeTraceAsset(e){let{snapshotId:r,data:o,extension:n}=e;this.diskStorage.storeFile({name:`${bi}/${r}.${n??"png"}`,contents:o});}attachBeforeXmlSnapshot(e){let{snapshotId:r,xml:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.xml`,contents:o});}attachAfterXmlSnapshot(e){let{snapshotId:r,xml:o}=e;this.diskStorage.storeFile({name:`${bi}/${r}.xml`,contents:o});}async finishInternal(e){this.finished||(this.finished=true,this.interactionTracer.finish(),await Promise.all(this.children.map(r=>r.finish({status:oh(e.status),finishedAt:e.finishedAt}))));}async finish(e){return await this.finishInternal({status:e.result.status,finishedAt:new Date(e.result.endTime)}),{trace:this.interactionTracer.getRootSpan()}}async startSubSteps(){let e=new Af(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}},Af=class{constructor(e,r,o,n,i,a){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.diskStorage=i;this.orgId=a;}children=[];finished=false;async getScreenshot(e){return this.diskStorage.readFile(`${bi}/${e}.png`)??this.diskStorage.readFile(`${bi}/${e}.jpeg`)}getParentStepIdChain(){return []}async startStep(e){this.keepalive();let r=new Pk(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this,this.orgId);return this.children.push(r),r}async finish(e){this.finished||(this.finished=true,await Promise.all(this.children.map(r=>r.finishInternal({status:VU(e.status),finishedAt:e.finishedAt}))));}},Ik=class{constructor(e,r,o,n,i,a,s,c,l,u,d){this.keepalive=e;this.testId=r;this.testName=o;this.platform=n;this.runAttemptId=i;this.metadata=a;this.diskStorage=s;this.orgId=c;this.resultSchema=l;this.recordVideo=u;this.assetDetails=d;this.diskStorage.mkdir("assets");let m=n==="IOS"?"assets/logs.syslog":"assets/logs.logcat";this.logStream=this.diskStorage.createFileStream(m),this.resourceUsageStream=this.diskStorage.createFileStream(`${bi}/resource-usage.ndjson`),this.resourceUsageSampler=rj({keepSamples:false,onSample:p=>{this.resourceUsageStream.write(`${JSON.stringify(p)}
|
|
5941
5941
|
`);}});}finished=false;children=[];logStream;resourceUsageStream;resourceUsageSampler;get loggerBindings(){return {runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return sr.resolve(this.diskStorage.cwd(),bi)}appendLogs(e){let r=e.join(`
|
|
5942
5942
|
`);this.logStream.write(r+`
|
|
5943
5943
|
`);}setActiveVideo(e,r){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:r}));}async finish(e){if(this.finished)return;this.finished=true;let{logger:r,status:o,results:n,beforeResults:i,afterResults:a}=e,s={...this.metadata,status:o,assetDetails:this.assetDetails,finishedAt:new Date,results:Bv(n,this.resultSchema,r),beforeResults:i?Bv(i,this.resultSchema,r):void 0,afterResults:a?Bv(a,this.resultSchema,r):void 0};await Promise.all(this.children.map(c=>c.finish({status:s.status,finishedAt:s.finishedAt})));try{this.logStream.end();}catch{}try{this.resourceUsageSampler.stop(),this.resourceUsageStream.end();}catch{}this.recordVideo==="on-fail"&&o==="PASSED"&&(LW(r,this.videoOutputPath),s.activeVideos=void 0),this.diskStorage.storeFile({name:ro,contents:JSON.stringify(s,null,2)});}async startBeforeStepList(){let e=new Af(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async startMainStepList(){let e=new Af(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async startAfterStepList(){let e=new Af(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async getScreenshot(e,r){return this.diskStorage.readFile(`${bi}/${r}.png`)??this.diskStorage.readFile(`${bi}/${r}.jpeg`)}},Ok=class{constructor(e,r,o,n,i,a,s,c,l,u){this.client=e;this.testId=r;this.testName=o;this.platform=n;this.runId=i;this.metadata=a;this.diskStorage=s;this.orgId=c;this.resultSchema=l;this.recordVideo=u;}children=[];finished=false;get loggerBindings(){return {runId:this.runId}}async finish(e){if(this.finished)return;this.finished=true;let r={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||false,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:r.status,results:[],beforeResults:[],afterResults:[]}))),this.diskStorage.storeFile({name:ro,contents:JSON.stringify(r,null,2)}),this.diskStorage.close();}async startAttempt(e){let{runAttemptId:r}=e;this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:ro,contents:JSON.stringify(this.metadata,null,2)});let o=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),n={id:r,schemaVersion:ty,runAttemptSchemaVersion:o2,startedAt:new Date,status:"RUNNING"};o.storeFile({name:ro,contents:JSON.stringify(n,null,2)});let i=debounce(async()=>{await this.client.extendEmulatorTtl(this.platform,e.emulatorName);},3e4,{maxWait:6e4}),a=new Ik(()=>void i(),this.testId,this.testName,this.platform,r,n,o,this.orgId,this.resultSchema,this.recordVideo,e.assetDetails);return this.children.push(a),a}},RR=class t{constructor(e,r,o,n,i,a){this.orgId=e;this.runGroupId=r;this.metadata=o;this.client=n;this.diskStorage=i;this.recordVideo=a;}children=[];finished=false;get loggerBindings(){return {orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:r,outputDir:o,client:n,gitMetadata:i,labels:a,suiteName:s,recordVideo:c}){let l={...i,suiteName:s&&ji(s),id:r,trigger:ui.CLI,startedAt:new Date,status:"RUNNING",cliVersion:Go,labels:a??[]},u=new Wg(o);return u.storeFile({name:ro,contents:JSON.stringify(l,null,2)}),new t(e,r,l,n,u,c??false)}async finish(e){if(this.finished)return;this.finished=true;let{status:r}=e,o={...this.metadata,status:r,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,status:o.status,finishedAt:o.finishedAt}))),this.diskStorage.storeFile({name:ro,contents:JSON.stringify(o,null,2)});}async startRun(e){let r=this.diskStorage.createRunArchive(e.runId,e.logger),o={stepsSnapshot:e.originalSteps.steps,beforeStepsSnapshot:e.originalSteps.beforeSteps??void 0,afterStepsSnapshot:e.originalSteps.afterSteps??void 0,runGroupId:this.runGroupId,testId:e.testId,testName:e.testName?ji(e.testName):e.testName,testDescription:e.testDescription,directory:e.directory,labels:e.testLabels,trigger:"CLI",status:"RUNNING",healStatus:"NOT_ATTEMPTED",environmentName:e.environmentName,cliVersion:Go,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined,quarantinedReason:e.quarantinedReason,executionType:e.platform,aiSettings:e.aiSettings};r.storeFile({name:ro,contents:JSON.stringify(o,null,2)});let n=new Ok(this.client,e.testId,e.testName,e.platform,e.runId,o,r,this.orgId,e.resultSchema,this.recordVideo);return this.children.push(n),n}};function Foe(t){return {platform:t.platform,originalSteps:{steps:cloneDeep(t.steps),beforeSteps:t.beforeSteps?cloneDeep(t.beforeSteps):void 0,afterSteps:t.afterSteps?cloneDeep(t.afterSteps):void 0}}}async function Nk(t){let{inputs:e,fixtures:r,metadata:o,helpers:n}=t,{tracer:i,logger:a}=r,{runId:s}=o,{platform:c,testDefinition:l,project:u}=e,d=new Date,m=await i.startRun({...Foe(l),logger:a,testId:l.id,testName:l.name,directory:dirname(l.relativeFilePath),runId:s,testDescription:l.description,testLabels:l.labels,schemaVersion:l.schemaVersion,quarantined:l.quarantined,quarantinedReason:l.quarantinedMetadata?.quarantinedReason,aiSettings:u.config.ai,resultSchema:n.resultSchema}),p=a.child(m.loggerBindings||{}),f=1+(l.settings?.retries??u.config.retries??hy);for(let h=0;h<f;h++){let S=new Date,b=await D1e({...t,runTracer:m,fixtures:{...r,logger:p},constants:{attemptNumber:h+1,totalAttempts:f}}),y=new Date;if(b.status!=="FAILED")return await m.finish({logger:p,status:b.status,failureRecoveryDetails:b.failureRecoveryDetails,finishedAt:y}),{...b,testMetadata:l,platformType:c,steps:l.steps,startedAt:d,lastAttemptStartedAt:S,finishedAt:y,runId:s,attempts:h+1,filePath:l.relativeFilePath,quarantined:l.quarantined,quarantinedMetadata:l.quarantinedMetadata,status:b.status};if(h!==f-1){p.warn("Retrying failed mobile run");continue}p.error("Mobile test failed after all exhausting attempts");let T={failureReason:b.error?.reason,failureDetails:b.error?{errorMessage:b.error.message,errorStack:b.error.stack}:void 0};return await m.finish({logger:p,status:b.status,...T,failureRecoveryDetails:b.failureRecoveryDetails,finishedAt:y}),{...b,testMetadata:l,platformType:c,steps:l.steps,startedAt:d,lastAttemptStartedAt:S,finishedAt:y,runId:s,...T,attempts:h+1,filePath:l.relativeFilePath,quarantined:l.quarantined,quarantinedMetadata:l.quarantinedMetadata,status:b.status}}throw new Error("This code should not be reachable")}async function D1e(t){let{metadata:e,constants:r,fixtures:o,inputs:n,options:i}=t,{attemptNumber:a,totalAttempts:s}=r,{orgId:c,gitMetadata:l}=e,{apiClient:u,logger:d}=o,{testDefinition:m,logUpdate:p,project:f,envOverride:h}=n,{regenerateCache:S,alwaysSaveCache:b,noCache:y}=i;a!==1&&p("RETRY",`attempt ${a}/${s}`);let T={...n.project.config.emulator,...m.settings?.emulator},v={...f.config.ai,useMemory:f.config.ai?.useMemory!==false,...m.settings?.ai},w=h||m.settings?.defaultEnv,D=(w?Lu(w,f,d):void 0)?.variables??{},x=Hr({logger:d,orgId:c,client:u,gitMetadata:l,regenerateCache:S,alwaysSaveCache:b,noCache:y,isolateCachesByEnvironment:f.config?.advanced?.isolateCachesByEnvironment}),A=new np(u,c),B={type:"API_KEY",baseUrl:u.baseUrl,apiKey:u.apiKey,logger:d,mode:"runner"},O=new es(B),z=new js(v.agentConfig,B),k=new sc(B,z),H=new lc({httpClient:u,fakerSeed:f.config.advanced?.fakerConstantSeed?pm:void 0});return await L1e({...t,fixtures:{...t.fixtures,mobileGenerator:O,storage:A,cacheStorage:x,browserEnricher:k,browserGenerator:z,localCodeEvalTools:H},env:{envName:w,envVariables:D},settings:{aiSettings:v,emulatorSettings:T}})}async function L1e(t){let{inputs:{testDefinition:e},env:{envName:r},helpers:o}=t,n;try{n=await o.prepareRunParams(t);}catch(c){return {status:"FAILED",results:[],error:new M("UserConfigurationError",`Fatal error creating mobile driver: ${j(c)}`)}}let i=t.inputs.project.config.fileFormat==="v2",a;try{a=await ff({...n,containerName:`mobile test ${e.name}`,envName:r,helpers:o,inputs:{...n.inputs,useSnapshotIdentityCache:i}});}finally{await n.cleanup();}await n.tracer.finish({logger:n.fixtures.logger,results:a.results,beforeResults:a.beforeResults,afterResults:a.afterResults,status:a.status});let s;if(a.status==="FAILED"&&a.terminalResult){let c=a.terminalResult.message;s=c?M.fromMessage(c):new M("UnknownError","Unknown failure");}return {...a,error:s}}function _R(t){if(t.status!=="FAILED")return "none";switch(t.failureReason){case "SetupFailureError":return "setup";case "TeardownFailureError":return "teardown";default:return "main"}}function F1e(t){switch(t){case "PASSED":return "passed";case "FAILED":return "failed";case "CANCELLED":return "skipped";case "RETRYING":case "WAITING_FOR_USER":case "PENDING":case "RUNNING":return "unknown";default:return Vt(t)}}function zoe(t){let e=sr__default.relative(".",t);return e===""?t:e}function Uoe(t,e){return Math.max(0,(t.getTime()-e.getTime())/1e3)}function U1e(t,e,r){let o=Uoe(e,t),n=Uoe(r,t);return {start_at:o,end_at:n,duration:Math.max(0,n-o)}}function $oe(t){let e=t.reduce((r,[o,n])=>(!n||Object.keys(r).length>=10||(r[o]=n),r),{});return Object.keys(e).length>0?e:void 0}function B1e(t){if(t.status!=="FAILED"||!t.failureReason)return;let e=Hf({failureReason:t.failureReason,classification:t.failureDetails?.classification,manualClassification:t.failureDetails?.manualClassification,errorMessage:t.failureDetails?.errorMessage});if(!(e.title==null||e.description==null))return `${e.title}: ${e.description}`}function V1e(t){if(t.status!=="FAILED")return;let e=[t.failureDetails?.classification?.summary,t.failureDetails?.classification?.rootCause,t.failureDetails?.errorMessage].filter(o=>!!o),r=t.failureDetails?.errorStack?.split(`
|
|
@@ -5949,4 +5949,4 @@ ${a.map(s=>` - ${s}`).join(`
|
|
|
5949
5949
|
`),await lo(),process.exit(0);});var pze=fn.command("run").alias("test").description("Run tests on the local machine");pze.addOption(ri).addOption(oi).addOption(nl).addOption(ER).addOption(wk).addOption(Rk).addOption(xb).addOption(yoe).addOption(_k).addOption(Toe).addOption(Eoe).addOption(fk).addOption(TR).addOption(vR).addOption(Ak).addOption(voe).addOption(Coe).addOption(Roe).addOption(_oe).addOption(Moe).addOption(Aoe).addOption(woe).addOption(new Option("--labels <labels...>","Only run tests with the specified label(s).")).addOption(hk).addOption(gk).addOption(goe).addOption(yk).addOption(Ek).addOption(Tk).addOption(vk).addOption(Ck).addArgument(new Argument("<tests...>","One or more test file path or folders that exist on the local machine.").argOptional()).action(async(t,e)=>{let{name:r,apiKey:o,server:n,tag:i,channel:a,outputDir:s,reporter:c,reporterDir:l}=e,u=EP(e.logLevel);await kk(),I.debug({appiumHome:OR},"Resolved resource paths");let d=ET(e);RW({shardIndex:e.shardIndex,shardCount:e.shardCount});let m=an(),p=await Ei({text:"Resolving project config...",screen:m},()=>qn({configFilePath:e.config,nameFilter:e.filter})),f=s??p.config.outputDir??Dg,h=e.parallel??p.config.parallel??1,S=e.video??p.config.recordVideo??true,b=bV(S);await uk({project:p});let y=new pr({baseUrl:n,apiKey:o,logger:I}),{orgId:T,userId:v,email:w,selfServe:N}=await Ei({text:"Checking API key...",screen:m},()=>Gg({client:y,skipPrompts:e.yes}));roe({userId:v,orgId:T,email:w,selfServe:N});let D=randomUUID(),x=Pt.child({runGroupId:D,orgId:T,userId:v}),A=await dr(Pt,y,p);x.debug({gitMetadata:A,config:p.config,nodeVersion:process.versions.node},"Got local git metadata");let B=await Xoe(x,y,e.ignoreQuarantine),O=await vt(p),z=await mk({tests:t,yes:e.yes,project:p,momenticFiles:O,include:e.include,exclude:e.exclude,labels:e.labels,logger:I,quarantinedTestsMetadata:B});try{let k=await Koe({options:{...e,parallel:h,outputDir:f,alwaysSaveCache:d.alwaysSaveCache,regenerateCache:d.regenerateCache,noCache:d.noCache,logLevel:u,timeoutMinutes:e.timeoutMinutes,shardIndex:e.shardIndex,shardCount:e.shardCount,reporter:c,reporterDir:l,labels:e.labels,suiteName:r,recordVideo:b},fixtures:{logger:x,project:p,apiClient:y},inputs:{envOverride:e.env,tag:i,channel:a,testDefinitions:z},metadata:{gitMetadata:A,runGroupId:D,orgId:T}});await lo(),process.exit(nW(k)?1:0);}catch(k){Pt.error({err:k},"Failed to run tests locally"),I.error({err:k},"Failed to run tests locally. Rerun with --verbose for more detail."),await lo(),process.exit(1);}});fn.command("init").description("Initialize an empty Momentic project in the current working directory").addOption(new Option("--name <name>","Name of the project")).action(async t=>{I.info("Momentic Mobile project setup wizard"),I.dimmed(" Bootstrap a new Momentic mobile project."),so.existsSync(Xl)&&(I.error(`${Xl} already exists in this directory. Rename or remove it to initialize a new project.`),process.exit(1));let e=t.name??await m2("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app"),r=await YY({cwd:process.cwd(),projectName:e});I.success(`Initialized Momentic project file at ${r.configPath}.`),await lo(),process.exit(0);});fn.command("upgrade").description("Upgrade your configuration to the latest recommended settings").addOption(nl).addOption(ER).addOption(oi).addOption(ri).option("--dry-run","Preview the upgrade without writing any files or pushing snapshots.").action(async t=>{let e=await qn({configFilePath:t.config,nameFilter:t.filter}),r=t.dryRun??false;r||await Yoe();let o=new pr({baseUrl:t.server,apiKey:t.apiKey,logger:Pt}),{orgId:n}=await o.getAuthInfo(),i=await dr(Pt,o,e),a=await h4({project:e,dryRun:r,migrate:()=>pk({project:e,apiClient:o,gitMetadata:i,orgId:n,dryRun:r})});yO({summary:a.migration,fileFormatChanged:a.fileFormatChanged,aiSettings:a.aiSettings,dryRun:r,testNoun:"mobile test",moduleNoun:"mobile module"}),a.fileFormatChanged||SO(a.aiSettings)?r?I.success("Dry run complete. Rerun without --dry-run to apply."):(I.success("Upgraded project to latest recommended settings."),I.dimmed(" Optional: rerun tests with --regenerate-cache to rebuild caches from scratch (slower).")):I.success("Project is already up to date."),await lo(),process.exit(0);});fn.command("install-browsers").description("Install browser executables onto the local machine.").option("-f, --force","Force reinstallation even if the browser executables already exist on disk.").option("-a, --all","Install all browsers types.").argument("[browsers...]",`Browsers to install. Available choices: ${ST.join(", ")}.`).action(async(t,e)=>{!e.all&&t.length===0&&(I.error("No browsers specified."),process.exit(1)),await bT({rawBrowsers:t,force:e.force,all:e.all}),await lo(),process.exit(0);});fn.command("install-skills").description("[DEPRECATED] Install the Momentic skill markdown as SKILL.md. Prefer `npx skills@latest add momentic-ai/skills`.").addOption(new Option("--editor <editor>","Editor to install skills for.").choices(XY).makeOptionMandatory()).action(async t=>{I.warn("`momentic-mobile install-skills` is deprecated. Run `npx skills@latest add momentic-ai/skills` instead.");let e=t.editor,r=fileURLToPath(import.meta.url),o=sr__default.dirname(r),n=sr__default.resolve(o,"..","skills");JY({editor:e,skillsDir:n}),await lo(),process.exit(0);});async function fze(){try{await fn.parseAsync(process.argv),await lo();}catch(t){Pt.error({err:t},"Uncaught error in CLI"),I.error({err:t},"Momentic Mobile CLI exited unexpectedly"),await lo(),process.exit(1);}}fze();
|
|
5950
5950
|
//# sourceMappingURL=out.js.map
|
|
5951
5951
|
//# sourceMappingURL=cli.js.map
|
|
5952
|
-
//# debugId=
|
|
5952
|
+
//# debugId=087d1813-e067-50ce-a81e-c75a44ad3120
|