momentic-mobile 0.88.1 → 0.88.2
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/run-viewer-static/assets/{index-NLgYfy6a.js → index-UE2nPcFc.js} +230 -230
- package/run-viewer-static/index.html +1 -1
- package/static/assets/{index-ADEdl72b.js → index-eSMNPg7I.js} +3 -3
- package/static/index.html +1 -1
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 globalThis?globalThis:"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 globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c91712a2-0f42-5d8f-974c-7398d5eaaeab")}catch(e){}}();
|
|
4
4
|
import * as v from 'zod';
|
|
5
5
|
import v__default, { z, ZodOptional } from 'zod';
|
|
6
6
|
import { extendZodWithOpenApi } from 'zod-openapi';
|
|
@@ -166,11 +166,11 @@ ${this.decisions.map(e=>e.toString()).join(`
|
|
|
166
166
|
To resolve the conflict:`,hR(c,e))),i=l):he.warn("A view or instrument with the name ",e.name,` has already been registered and is incompatible with another registered view.
|
|
167
167
|
`,`Details:
|
|
168
168
|
`,fR(c,e),`To resolve the conflict:
|
|
169
|
-
`,hR(c,e));}}catch(u){n={error:u};}finally{try{s&&!s.done&&(o=a.return)&&o.call(a);}finally{if(n)throw n.error}}return i},r}();var dz=function(){function r(e){this._backingStorages=e;}return r.prototype.record=function(e,t,n,o){this._backingStorages.forEach(function(i){i.record(e,t,n,o);});},r}();Pt();Pt();var mz=function(){function r(e,t){this._instrumentName=e,this._valueType=t,this._buffer=new ti;}return r.prototype.observe=function(e,t){if(t===void 0&&(t={}),typeof e!="number"){he.warn("non-number value provided to metric "+this._instrumentName+": "+e);return}this._valueType===Jn.INT&&!Number.isInteger(e)&&(he.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(t,e);},r}();var pz=function(){function r(){this._buffer=new Map;}return r.prototype.observe=function(e,t,n){if(n===void 0&&(n={}),!!Sf(e)){var o=this._buffer.get(e);if(o==null&&(o=new ti,this._buffer.set(e,o)),typeof t!="number"){he.warn("non-number value provided to metric "+e._descriptor.name+": "+t);return}e._descriptor.valueType===Jn.INT&&!Number.isInteger(t)&&(he.warn("INT value type cannot accept a floating-point value for "+e._descriptor.name+", ignoring the fractional digits."),t=Math.trunc(t),!Number.isInteger(t))||o.set(n,t);}},r}();var yR=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},SR=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},fz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},hz=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},gz=function(){function r(){this._callbacks=[],this._batchCallbacks=[];}return r.prototype.addCallback=function(e,t){var n=this._findCallback(e,t);n>=0||this._callbacks.push({callback:e,instrument:t});},r.prototype.removeCallback=function(e,t){var n=this._findCallback(e,t);n<0||this._callbacks.splice(n,1);},r.prototype.addBatchCallback=function(e,t){var n=new Set(t.filter(Sf));if(n.size===0){he.error("BatchObservableCallback is not associated with valid instruments",t);return}var o=this._findBatchCallback(e,n);o>=0||this._batchCallbacks.push({callback:e,instruments:n});},r.prototype.removeBatchCallback=function(e,t){var n=new Set(t.filter(Sf)),o=this._findBatchCallback(e,n);o<0||this._batchCallbacks.splice(o,1);},r.prototype.observe=function(e,t){return yR(this,void 0,void 0,function(){var n,o,i,a;return SR(this,function(s){switch(s.label){case 0:return n=this._observeCallbacks(e,t),o=this._observeBatchCallbacks(e,t),[4,fB(hz(hz([],fz(n),!1),fz(o),!1))];case 1:return i=s.sent(),a=i.filter(hB).map(function(l){return l.reason}),[2,a]}})})},r.prototype._observeCallbacks=function(e,t){var n=this;return this._callbacks.map(function(o){var i=o.callback,a=o.instrument;return yR(n,void 0,void 0,function(){var s,l;return SR(this,function(c){switch(c.label){case 0:return s=new mz(a._descriptor.name,a._descriptor.valueType),l=Promise.resolve(i(s)),t!=null&&(l=gs(l,t)),[4,l];case 1:return c.sent(),a._metricStorages.forEach(function(u){u.record(s._buffer,e);}),[2]}})})})},r.prototype._observeBatchCallbacks=function(e,t){var n=this;return this._batchCallbacks.map(function(o){var i=o.callback,a=o.instruments;return yR(n,void 0,void 0,function(){var s,l;return SR(this,function(c){switch(c.label){case 0:return s=new pz,l=Promise.resolve(i(s)),t!=null&&(l=gs(l,t)),[4,l];case 1:return c.sent(),a.forEach(function(u){var d=s._buffer.get(u);d!=null&&u._metricStorages.forEach(function(m){m.record(d,e);});}),[2]}})})})},r.prototype._findCallback=function(e,t){return this._callbacks.findIndex(function(n){return n.callback===e&&n.instrument===t})},r.prototype._findBatchCallback=function(e,t){return this._batchCallbacks.findIndex(function(n){return n.callback===e&&gB(n.instruments,t)})},r}();var nie=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o;}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i]);},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e;}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n);}}(),yz=function(r){nie(e,r);function e(t,n,o,i,a){var s=r.call(this,t)||this;return s._attributesProcessor=o,s._aggregationCardinalityLimit=a,s._deltaMetricStorage=new wS(n,s._aggregationCardinalityLimit),s._temporalMetricStorage=new AS(n,i),s}return e.prototype.record=function(t,n,o,i){n=this._attributesProcessor.process(n,o),this._deltaMetricStorage.record(t,n,o,i);},e.prototype.collect=function(t,n){var o=this._deltaMetricStorage.collect();return this._temporalMetricStorage.buildMetrics(t,this._instrumentDescriptor,o,n)},e}(CS);var Sz=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o;}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i]);},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e;}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n);}}(),Qu=function(){function r(){}return r.Noop=function(){return iie},r}();var oie=function(r){Sz(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.process=function(t,n){return t},e}(Qu);var bz=function(r){Sz(e,r);function e(t){var n=r.call(this)||this;return n._allowedAttributeNames=t,n}return e.prototype.process=function(t,n){var o=this,i={};return Object.keys(t).filter(function(a){return o._allowedAttributeNames.includes(a)}).forEach(function(a){return i[a]=t[a]}),i},e}(Qu);var iie=new oie;var aie=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},sie=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},lie=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},Ez=function(){function r(e,t){this._meterProviderSharedState=e,this._instrumentationScope=t,this.metricStorageRegistry=new uz,this.observableRegistry=new gz,this.meter=new az(this);}return r.prototype.registerMetricStorage=function(e){var t=this._registerMetricStorage(e,yz);return t.length===1?t[0]:new dz(t)},r.prototype.registerAsyncMetricStorage=function(e){var t=this._registerMetricStorage(e,cz);return t},r.prototype.collect=function(e,t,n){return aie(this,void 0,void 0,function(){var o,i,a;return sie(this,function(s){switch(s.label){case 0:return [4,this.observableRegistry.observe(t,n?.timeoutMillis)];case 1:return o=s.sent(),i=this.metricStorageRegistry.getStorages(e),i.length===0?[2,null]:(a=i.map(function(l){return l.collect(e,t)}).filter(mB),a.length===0?[2,{errors:o}]:[2,{scopeMetrics:{scope:this._instrumentationScope,metrics:a},errors:o}])}})})},r.prototype._registerMetricStorage=function(e,t){var n=this,o=this._meterProviderSharedState.viewRegistry.findViews(e,this._instrumentationScope),i=o.map(function(l){var c=bB(l,e),u=n.metricStorageRegistry.findOrUpdateCompatibleStorage(c);if(u!=null)return u;var d=l.aggregation.createAggregator(c),m=new t(c,d,l.attributesProcessor,n._meterProviderSharedState.metricCollectors,l.aggregationCardinalityLimit);return n.metricStorageRegistry.register(m),m});if(i.length===0){var a=this._meterProviderSharedState.selectAggregations(e.type),s=a.map(function(l){var c=lie(l,2),u=c[0],d=c[1],m=n.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(u,e);if(m!=null)return m;var p=d.createAggregator(e),f=u.selectCardinalityLimit(e.type),h=new t(e,p,Qu.Noop(),[u],f);return n.metricStorageRegistry.registerForCollector(u,h),h});i=i.concat(s);}return i},r}();var cie=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return {next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},Tz=function(){function r(e){this.resource=e,this.viewRegistry=new ZB,this.metricCollectors=[],this.meterSharedStates=new Map;}return r.prototype.getMeterSharedState=function(e){var t=pB(e),n=this.meterSharedStates.get(t);return n==null&&(n=new Ez(this,e),this.meterSharedStates.set(t,n)),n},r.prototype.selectAggregations=function(e){var t,n,o=[];try{for(var i=cie(this.metricCollectors),a=i.next();!a.done;a=i.next()){var s=a.value;o.push([s,s.selectAggregation(e)]);}}catch(l){t={error:l};}finally{try{a&&!a.done&&(n=i.return)&&n.call(i);}finally{if(t)throw t.error}}return o},r}();var RS=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},xS=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},uie=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},die=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},vz=function(){function r(e,t){this._sharedState=e,this._metricReader=t;}return r.prototype.collect=function(e){return RS(this,void 0,void 0,function(){var t,n,o,i,a=this;return xS(this,function(s){switch(s.label){case 0:return t=jl(Date.now()),n=[],o=[],i=Array.from(this._sharedState.meterSharedStates.values()).map(function(l){return RS(a,void 0,void 0,function(){var c;return xS(this,function(u){switch(u.label){case 0:return [4,l.collect(this,t,e)];case 1:return c=u.sent(),c?.scopeMetrics!=null&&n.push(c.scopeMetrics),c?.errors!=null&&o.push.apply(o,die([],uie(c.errors),!1)),[2]}})})}),[4,Promise.all(i)];case 1:return s.sent(),[2,{resourceMetrics:{resource:this._sharedState.resource,scopeMetrics:n},errors:o}]}})})},r.prototype.forceFlush=function(e){return RS(this,void 0,void 0,function(){return xS(this,function(t){switch(t.label){case 0:return [4,this._metricReader.forceFlush(e)];case 1:return t.sent(),[2]}})})},r.prototype.shutdown=function(e){return RS(this,void 0,void 0,function(){return xS(this,function(t){switch(t.label){case 0:return [4,this._metricReader.shutdown(e)];case 1:return t.sent(),[2]}})})},r.prototype.selectAggregationTemporality=function(e){return this._metricReader.selectAggregationTemporality(e)},r.prototype.selectAggregation=function(e){return this._metricReader.selectAggregation(e)},r.prototype.selectCardinalityLimit=function(e){var t,n,o;return (o=(n=(t=this._metricReader).selectCardinalityLimit)===null||n===void 0?void 0:n.call(t,e))!==null&&o!==void 0?o:2e3},r}();var Cz=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},wz=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},Az=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return {next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function mie(r,e){var t=e??ES.empty();return r?ES.default().merge(t):t}var bR=function(){function r(e){var t,n,o,i,a;if(this._shutdown=!1,this._sharedState=new Tz(mie((a=e?.mergeResourceWithDefaults)!==null&&a!==void 0?a:!0,e?.resource)),e?.views!=null&&e.views.length>0)try{for(var s=Az(e.views),l=s.next();!l.done;l=s.next()){var c=l.value;this._sharedState.viewRegistry.addView(c);}}catch(p){t={error:p};}finally{try{l&&!l.done&&(n=s.return)&&n.call(s);}finally{if(t)throw t.error}}if(e?.readers!=null&&e.readers.length>0)try{for(var u=Az(e.readers),d=u.next();!d.done;d=u.next()){var m=d.value;this.addMetricReader(m);}}catch(p){o={error:p};}finally{try{d&&!d.done&&(i=u.return)&&i.call(u);}finally{if(o)throw o.error}}}return r.prototype.getMeter=function(e,t,n){return t===void 0&&(t=""),n===void 0&&(n={}),this._shutdown?(he.warn("A shutdown MeterProvider cannot provide a Meter"),wA()):this._sharedState.getMeterSharedState({name:e,version:t,schemaUrl:n.schemaUrl}).meter},r.prototype.addMetricReader=function(e){var t=new vz(this._sharedState,e);e.setMetricProducer(t),this._sharedState.metricCollectors.push(t);},r.prototype.shutdown=function(e){return Cz(this,void 0,void 0,function(){return wz(this,function(t){switch(t.label){case 0:return this._shutdown?(he.warn("shutdown may only be called once per MeterProvider"),[2]):(this._shutdown=!0,[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.shutdown(e)}))]);case 1:return t.sent(),[2]}})})},r.prototype.forceFlush=function(e){return Cz(this,void 0,void 0,function(){return wz(this,function(t){switch(t.label){case 0:return this._shutdown?(he.warn("invalid attempt to force flush after MeterProvider shutdown"),[2]):[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.forceFlush(e)}))];case 1:return t.sent(),[2]}})})},r}();var pie=/[\^$\\.+?()[\]{}|]/g,MS=function(){function r(e){e==="*"?(this._matchAll=!0,this._regexp=/.*/):(this._matchAll=!1,this._regexp=new RegExp(r.escapePattern(e)));}return r.prototype.match=function(e){return this._matchAll?!0:this._regexp.test(e)},r.escapePattern=function(e){return "^"+e.replace(pie,"\\$&").replace("*",".*")+"$"},r.hasWildcard=function(e){return e.includes("*")},r}();var ed=function(){function r(e){this._matchAll=e===void 0,this._pattern=e;}return r.prototype.match=function(e){return !!(this._matchAll||e===this._pattern)},r}();var Rz=function(){function r(e){var t;this._nameFilter=new MS((t=e?.name)!==null&&t!==void 0?t:"*"),this._type=e?.type,this._unitFilter=new ed(e?.unit);}return r.prototype.getType=function(){return this._type},r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getUnitFilter=function(){return this._unitFilter},r}();var xz=function(){function r(e){this._nameFilter=new ed(e?.name),this._versionFilter=new ed(e?.version),this._schemaUrlFilter=new ed(e?.schemaUrl);}return r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getVersionFilter=function(){return this._versionFilter},r.prototype.getSchemaUrlFilter=function(){return this._schemaUrlFilter},r}();function fie(r){return r.instrumentName==null&&r.instrumentType==null&&r.instrumentUnit==null&&r.meterName==null&&r.meterVersion==null&&r.meterSchemaUrl==null}var bf=function(){function r(e){var t;if(fie(e))throw new Error("Cannot create view with no selector arguments supplied");if(e.name!=null&&(e?.instrumentName==null||MS.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 bz(e.attributeKeys):this.attributesProcessor=Qu.Noop(),this.name=e.name,this.description=e.description,this.aggregation=(t=e.aggregation)!==null&&t!==void 0?t:Ao.Default(),this.instrumentSelector=new Rz({name:e.instrumentName,type:e.instrumentType,unit:e.instrumentUnit}),this.meterSelector=new xz({name:e.meterName,version:e.meterVersion,schemaUrl:e.meterSchemaUrl}),this.aggregationCardinalityLimit=e.aggregationCardinalityLimit;}return r}();Pt();function gie(){return new cB({url:"https://us-west.metrics.momentic.ai/v1/metrics",headers:{"x-momentic-metrics-api-key":"c60c6a0f-60da-41a7-a61b-07969a0aa303"},temporalityPreference:Vl.DELTA})}var yie=[new bf({instrumentName:"test_event_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new bf({instrumentName:"test_step_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new bf({instrumentName:"test_mobile_step_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)})],_S=class{globalAttributes;provider;meter;counterCache=new Map;histogramCache=new Map;observableGaugeCache=new Map;gaugeValues=new Map;getCounter(e){let t=this.counterCache.get(e);if(t)return t;let n=this.meter.createCounter(e);return this.counterCache.set(e,n),n}getHistogram(e){let t=this.histogramCache.get(e);if(t)return t;let n=this.meter.createHistogram(e);return this.histogramCache.set(e,n),n}ensureObservableGauge(e){let t=this.observableGaugeCache.get(e);if(t)return t;let n=this.meter.createObservableGauge(e);return n.addCallback(o=>{let i=this.gaugeValues.get(e);i!==void 0&&o.observe(i,this.globalAttributes);}),this.observableGaugeCache.set(e,n),n}constructor(e){this.globalAttributes={...e.globalAttributes??{}};let t=typeof process<"u"?"production":"unknown",n=new VA({[Ky]:e.serviceName,[iU]:t,[sU]:typeof process<"u"&&process.env.SERVICE_INSTANCE_ID?process.env.SERVICE_INSTANCE_ID:v4$1()}),o=gie(),i=new mR({exporter:o,exportIntervalMillis:e.exportIntervalMs??6e4});this.provider=new bR({resource:n,readers:[i],views:yie}),jy.setGlobalMeterProvider(this.provider),this.meter=jy.getMeter("momentic-serverless");}increment(e,t,n){try{let o=gA(n,this.globalAttributes);this.getCounter(e).add(typeof t=="number"?t:1,o);}catch{}}gauge(e,t){try{this.ensureObservableGauge(e),this.gaugeValues.set(e,t);}catch{}}distribution(e,t,n){try{let o=gA(n,this.globalAttributes);this.getHistogram(e).record(t,o);}catch{}}async flush(){try{await this.provider.forceFlush();}catch{}}async recordDuration({fn:e,name:t,tags:n}){let o=Date.now();try{return await Promise.resolve(e())}finally{this.distribution(t,Date.now()-o,n);}}};var Et=new $y;function Mz(r){r.disabled||(Et=new _S(r));}var bie=1e4;async function Ef(r){return new Promise(e=>{exec(r,{timeout:bie},(t,n,o)=>{e({command:r,stdout:n,stderr:o,error:t?.message??null,timedOut:t?.killed??!1});});})}async function Eie(r){if(platform()==="win32")return Ef(`tracert ${r}`);let t=await Ef(`traceroute ${r}`);return t.stderr.includes("not found")||t.error?.includes("not found")?Ef(`tracepath ${r}`):t}async function td(r){let t=platform()==="win32",n=t?`ping -n 3 ${r}`:`ping -c 3 ${r}`,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 ${t?"NUL":"/dev/null"} -s ${r}`,[a,s,l]=await Promise.all([Ef(n),Eie(r),Ef(i)]);return {ping:a,traceroute:s,curl:l}}var ER;function Pz(r){ER=r;}function PS(r){r instanceof Wr||ER&&ER(r);}var TR=!1;try{let r=await import('@sentry/node');r.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",dist:"production",release:"mobile-cli-0.88.1",tracesSampleRate:0,sendDefaultPii:!0}),Pz(r.captureException),TR=!0;}catch{}var wie=!1,Iz=(()=>{try{return statSync("/.dockerenv"),!0}catch{return !1}})();async function rd(r){return Fl||wie||Iz?!0:(await N.flush(),await new Promise(t=>setTimeout(t,100)),await confirm({message:r}))}async function Oz(r,e){return Fl||Iz?e:(await input({message:r,default:e})).trim()||e}var vR=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o;}},IS=class r extends Console{_buffer=[];_groupDepth=0;Console=Console;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)});}static write(e,t,n,o=2){let i=new vR(void 0,r.write).stack;if(!i)return e;let a=i.split(`
|
|
169
|
+
`,hR(c,e));}}catch(u){n={error:u};}finally{try{s&&!s.done&&(o=a.return)&&o.call(a);}finally{if(n)throw n.error}}return i},r}();var dz=function(){function r(e){this._backingStorages=e;}return r.prototype.record=function(e,t,n,o){this._backingStorages.forEach(function(i){i.record(e,t,n,o);});},r}();Pt();Pt();var mz=function(){function r(e,t){this._instrumentName=e,this._valueType=t,this._buffer=new ti;}return r.prototype.observe=function(e,t){if(t===void 0&&(t={}),typeof e!="number"){he.warn("non-number value provided to metric "+this._instrumentName+": "+e);return}this._valueType===Jn.INT&&!Number.isInteger(e)&&(he.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(t,e);},r}();var pz=function(){function r(){this._buffer=new Map;}return r.prototype.observe=function(e,t,n){if(n===void 0&&(n={}),!!Sf(e)){var o=this._buffer.get(e);if(o==null&&(o=new ti,this._buffer.set(e,o)),typeof t!="number"){he.warn("non-number value provided to metric "+e._descriptor.name+": "+t);return}e._descriptor.valueType===Jn.INT&&!Number.isInteger(t)&&(he.warn("INT value type cannot accept a floating-point value for "+e._descriptor.name+", ignoring the fractional digits."),t=Math.trunc(t),!Number.isInteger(t))||o.set(n,t);}},r}();var yR=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},SR=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},fz=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},hz=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},gz=function(){function r(){this._callbacks=[],this._batchCallbacks=[];}return r.prototype.addCallback=function(e,t){var n=this._findCallback(e,t);n>=0||this._callbacks.push({callback:e,instrument:t});},r.prototype.removeCallback=function(e,t){var n=this._findCallback(e,t);n<0||this._callbacks.splice(n,1);},r.prototype.addBatchCallback=function(e,t){var n=new Set(t.filter(Sf));if(n.size===0){he.error("BatchObservableCallback is not associated with valid instruments",t);return}var o=this._findBatchCallback(e,n);o>=0||this._batchCallbacks.push({callback:e,instruments:n});},r.prototype.removeBatchCallback=function(e,t){var n=new Set(t.filter(Sf)),o=this._findBatchCallback(e,n);o<0||this._batchCallbacks.splice(o,1);},r.prototype.observe=function(e,t){return yR(this,void 0,void 0,function(){var n,o,i,a;return SR(this,function(s){switch(s.label){case 0:return n=this._observeCallbacks(e,t),o=this._observeBatchCallbacks(e,t),[4,fB(hz(hz([],fz(n),!1),fz(o),!1))];case 1:return i=s.sent(),a=i.filter(hB).map(function(l){return l.reason}),[2,a]}})})},r.prototype._observeCallbacks=function(e,t){var n=this;return this._callbacks.map(function(o){var i=o.callback,a=o.instrument;return yR(n,void 0,void 0,function(){var s,l;return SR(this,function(c){switch(c.label){case 0:return s=new mz(a._descriptor.name,a._descriptor.valueType),l=Promise.resolve(i(s)),t!=null&&(l=gs(l,t)),[4,l];case 1:return c.sent(),a._metricStorages.forEach(function(u){u.record(s._buffer,e);}),[2]}})})})},r.prototype._observeBatchCallbacks=function(e,t){var n=this;return this._batchCallbacks.map(function(o){var i=o.callback,a=o.instruments;return yR(n,void 0,void 0,function(){var s,l;return SR(this,function(c){switch(c.label){case 0:return s=new pz,l=Promise.resolve(i(s)),t!=null&&(l=gs(l,t)),[4,l];case 1:return c.sent(),a.forEach(function(u){var d=s._buffer.get(u);d!=null&&u._metricStorages.forEach(function(m){m.record(d,e);});}),[2]}})})})},r.prototype._findCallback=function(e,t){return this._callbacks.findIndex(function(n){return n.callback===e&&n.instrument===t})},r.prototype._findBatchCallback=function(e,t){return this._batchCallbacks.findIndex(function(n){return n.callback===e&&gB(n.instruments,t)})},r}();var nie=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o;}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i]);},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e;}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n);}}(),yz=function(r){nie(e,r);function e(t,n,o,i,a){var s=r.call(this,t)||this;return s._attributesProcessor=o,s._aggregationCardinalityLimit=a,s._deltaMetricStorage=new wS(n,s._aggregationCardinalityLimit),s._temporalMetricStorage=new AS(n,i),s}return e.prototype.record=function(t,n,o,i){n=this._attributesProcessor.process(n,o),this._deltaMetricStorage.record(t,n,o,i);},e.prototype.collect=function(t,n){var o=this._deltaMetricStorage.collect();return this._temporalMetricStorage.buildMetrics(t,this._instrumentDescriptor,o,n)},e}(CS);var Sz=function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o;}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i]);},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function n(){this.constructor=e;}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n);}}(),Qu=function(){function r(){}return r.Noop=function(){return iie},r}();var oie=function(r){Sz(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.process=function(t,n){return t},e}(Qu);var bz=function(r){Sz(e,r);function e(t){var n=r.call(this)||this;return n._allowedAttributeNames=t,n}return e.prototype.process=function(t,n){var o=this,i={};return Object.keys(t).filter(function(a){return o._allowedAttributeNames.includes(a)}).forEach(function(a){return i[a]=t[a]}),i},e}(Qu);var iie=new oie;var aie=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},sie=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},lie=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},Ez=function(){function r(e,t){this._meterProviderSharedState=e,this._instrumentationScope=t,this.metricStorageRegistry=new uz,this.observableRegistry=new gz,this.meter=new az(this);}return r.prototype.registerMetricStorage=function(e){var t=this._registerMetricStorage(e,yz);return t.length===1?t[0]:new dz(t)},r.prototype.registerAsyncMetricStorage=function(e){var t=this._registerMetricStorage(e,cz);return t},r.prototype.collect=function(e,t,n){return aie(this,void 0,void 0,function(){var o,i,a;return sie(this,function(s){switch(s.label){case 0:return [4,this.observableRegistry.observe(t,n?.timeoutMillis)];case 1:return o=s.sent(),i=this.metricStorageRegistry.getStorages(e),i.length===0?[2,null]:(a=i.map(function(l){return l.collect(e,t)}).filter(mB),a.length===0?[2,{errors:o}]:[2,{scopeMetrics:{scope:this._instrumentationScope,metrics:a},errors:o}])}})})},r.prototype._registerMetricStorage=function(e,t){var n=this,o=this._meterProviderSharedState.viewRegistry.findViews(e,this._instrumentationScope),i=o.map(function(l){var c=bB(l,e),u=n.metricStorageRegistry.findOrUpdateCompatibleStorage(c);if(u!=null)return u;var d=l.aggregation.createAggregator(c),m=new t(c,d,l.attributesProcessor,n._meterProviderSharedState.metricCollectors,l.aggregationCardinalityLimit);return n.metricStorageRegistry.register(m),m});if(i.length===0){var a=this._meterProviderSharedState.selectAggregations(e.type),s=a.map(function(l){var c=lie(l,2),u=c[0],d=c[1],m=n.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(u,e);if(m!=null)return m;var p=d.createAggregator(e),f=u.selectCardinalityLimit(e.type),h=new t(e,p,Qu.Noop(),[u],f);return n.metricStorageRegistry.registerForCollector(u,h),h});i=i.concat(s);}return i},r}();var cie=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return {next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")},Tz=function(){function r(e){this.resource=e,this.viewRegistry=new ZB,this.metricCollectors=[],this.meterSharedStates=new Map;}return r.prototype.getMeterSharedState=function(e){var t=pB(e),n=this.meterSharedStates.get(t);return n==null&&(n=new Ez(this,e),this.meterSharedStates.set(t,n)),n},r.prototype.selectAggregations=function(e){var t,n,o=[];try{for(var i=cie(this.metricCollectors),a=i.next();!a.done;a=i.next()){var s=a.value;o.push([s,s.selectAggregation(e)]);}}catch(l){t={error:l};}finally{try{a&&!a.done&&(n=i.return)&&n.call(i);}finally{if(t)throw t.error}}return o},r}();var RS=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},xS=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},uie=function(r,e){var t=typeof Symbol=="function"&&r[Symbol.iterator];if(!t)return r;var n=t.call(r),o,i=[],a;try{for(;(e===void 0||e-- >0)&&!(o=n.next()).done;)i.push(o.value);}catch(s){a={error:s};}finally{try{o&&!o.done&&(t=n.return)&&t.call(n);}finally{if(a)throw a.error}}return i},die=function(r,e,t){if(t||arguments.length===2)for(var n=0,o=e.length,i;n<o;n++)(i||!(n in e))&&(i||(i=Array.prototype.slice.call(e,0,n)),i[n]=e[n]);return r.concat(i||Array.prototype.slice.call(e))},vz=function(){function r(e,t){this._sharedState=e,this._metricReader=t;}return r.prototype.collect=function(e){return RS(this,void 0,void 0,function(){var t,n,o,i,a=this;return xS(this,function(s){switch(s.label){case 0:return t=jl(Date.now()),n=[],o=[],i=Array.from(this._sharedState.meterSharedStates.values()).map(function(l){return RS(a,void 0,void 0,function(){var c;return xS(this,function(u){switch(u.label){case 0:return [4,l.collect(this,t,e)];case 1:return c=u.sent(),c?.scopeMetrics!=null&&n.push(c.scopeMetrics),c?.errors!=null&&o.push.apply(o,die([],uie(c.errors),!1)),[2]}})})}),[4,Promise.all(i)];case 1:return s.sent(),[2,{resourceMetrics:{resource:this._sharedState.resource,scopeMetrics:n},errors:o}]}})})},r.prototype.forceFlush=function(e){return RS(this,void 0,void 0,function(){return xS(this,function(t){switch(t.label){case 0:return [4,this._metricReader.forceFlush(e)];case 1:return t.sent(),[2]}})})},r.prototype.shutdown=function(e){return RS(this,void 0,void 0,function(){return xS(this,function(t){switch(t.label){case 0:return [4,this._metricReader.shutdown(e)];case 1:return t.sent(),[2]}})})},r.prototype.selectAggregationTemporality=function(e){return this._metricReader.selectAggregationTemporality(e)},r.prototype.selectAggregation=function(e){return this._metricReader.selectAggregation(e)},r.prototype.selectCardinalityLimit=function(e){var t,n,o;return (o=(n=(t=this._metricReader).selectCardinalityLimit)===null||n===void 0?void 0:n.call(t,e))!==null&&o!==void 0?o:2e3},r}();var Cz=function(r,e,t,n){function o(i){return i instanceof t?i:new t(function(a){a(i);})}return new(t||(t=Promise))(function(i,a){function s(u){try{c(n.next(u));}catch(d){a(d);}}function l(u){try{c(n.throw(u));}catch(d){a(d);}}function c(u){u.done?i(u.value):o(u.value).then(s,l);}c((n=n.apply(r,e||[])).next());})},wz=function(r,e){var t={label:0,sent:function(){if(i[0]&1)throw i[1];return i[1]},trys:[],ops:[]},n,o,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(c){return function(u){return l([c,u])}}function l(c){if(n)throw new TypeError("Generator is already executing.");for(;t;)try{if(n=1,o&&(i=c[0]&2?o.return:c[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,c[1])).done)return i;switch(o=0,i&&(c=[c[0]&2,i.value]),c[0]){case 0:case 1:i=c;break;case 4:return t.label++,{value:c[1],done:!1};case 5:t.label++,o=c[1],c=[0];continue;case 7:c=t.ops.pop(),t.trys.pop();continue;default:if(i=t.trys,!(i=i.length>0&&i[i.length-1])&&(c[0]===6||c[0]===2)){t=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]<i[3])){t.label=c[1];break}if(c[0]===6&&t.label<i[1]){t.label=i[1],i=c;break}if(i&&t.label<i[2]){t.label=i[2],t.ops.push(c);break}i[2]&&t.ops.pop(),t.trys.pop();continue}c=e.call(r,t);}catch(u){c=[6,u],o=0;}finally{n=i=0;}if(c[0]&5)throw c[1];return {value:c[0]?c[1]:void 0,done:!0}}},Az=function(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],n=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return {next:function(){return r&&n>=r.length&&(r=void 0),{value:r&&r[n++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")};function mie(r,e){var t=e??ES.empty();return r?ES.default().merge(t):t}var bR=function(){function r(e){var t,n,o,i,a;if(this._shutdown=!1,this._sharedState=new Tz(mie((a=e?.mergeResourceWithDefaults)!==null&&a!==void 0?a:!0,e?.resource)),e?.views!=null&&e.views.length>0)try{for(var s=Az(e.views),l=s.next();!l.done;l=s.next()){var c=l.value;this._sharedState.viewRegistry.addView(c);}}catch(p){t={error:p};}finally{try{l&&!l.done&&(n=s.return)&&n.call(s);}finally{if(t)throw t.error}}if(e?.readers!=null&&e.readers.length>0)try{for(var u=Az(e.readers),d=u.next();!d.done;d=u.next()){var m=d.value;this.addMetricReader(m);}}catch(p){o={error:p};}finally{try{d&&!d.done&&(i=u.return)&&i.call(u);}finally{if(o)throw o.error}}}return r.prototype.getMeter=function(e,t,n){return t===void 0&&(t=""),n===void 0&&(n={}),this._shutdown?(he.warn("A shutdown MeterProvider cannot provide a Meter"),wA()):this._sharedState.getMeterSharedState({name:e,version:t,schemaUrl:n.schemaUrl}).meter},r.prototype.addMetricReader=function(e){var t=new vz(this._sharedState,e);e.setMetricProducer(t),this._sharedState.metricCollectors.push(t);},r.prototype.shutdown=function(e){return Cz(this,void 0,void 0,function(){return wz(this,function(t){switch(t.label){case 0:return this._shutdown?(he.warn("shutdown may only be called once per MeterProvider"),[2]):(this._shutdown=!0,[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.shutdown(e)}))]);case 1:return t.sent(),[2]}})})},r.prototype.forceFlush=function(e){return Cz(this,void 0,void 0,function(){return wz(this,function(t){switch(t.label){case 0:return this._shutdown?(he.warn("invalid attempt to force flush after MeterProvider shutdown"),[2]):[4,Promise.all(this._sharedState.metricCollectors.map(function(n){return n.forceFlush(e)}))];case 1:return t.sent(),[2]}})})},r}();var pie=/[\^$\\.+?()[\]{}|]/g,MS=function(){function r(e){e==="*"?(this._matchAll=!0,this._regexp=/.*/):(this._matchAll=!1,this._regexp=new RegExp(r.escapePattern(e)));}return r.prototype.match=function(e){return this._matchAll?!0:this._regexp.test(e)},r.escapePattern=function(e){return "^"+e.replace(pie,"\\$&").replace("*",".*")+"$"},r.hasWildcard=function(e){return e.includes("*")},r}();var ed=function(){function r(e){this._matchAll=e===void 0,this._pattern=e;}return r.prototype.match=function(e){return !!(this._matchAll||e===this._pattern)},r}();var Rz=function(){function r(e){var t;this._nameFilter=new MS((t=e?.name)!==null&&t!==void 0?t:"*"),this._type=e?.type,this._unitFilter=new ed(e?.unit);}return r.prototype.getType=function(){return this._type},r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getUnitFilter=function(){return this._unitFilter},r}();var xz=function(){function r(e){this._nameFilter=new ed(e?.name),this._versionFilter=new ed(e?.version),this._schemaUrlFilter=new ed(e?.schemaUrl);}return r.prototype.getNameFilter=function(){return this._nameFilter},r.prototype.getVersionFilter=function(){return this._versionFilter},r.prototype.getSchemaUrlFilter=function(){return this._schemaUrlFilter},r}();function fie(r){return r.instrumentName==null&&r.instrumentType==null&&r.instrumentUnit==null&&r.meterName==null&&r.meterVersion==null&&r.meterSchemaUrl==null}var bf=function(){function r(e){var t;if(fie(e))throw new Error("Cannot create view with no selector arguments supplied");if(e.name!=null&&(e?.instrumentName==null||MS.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 bz(e.attributeKeys):this.attributesProcessor=Qu.Noop(),this.name=e.name,this.description=e.description,this.aggregation=(t=e.aggregation)!==null&&t!==void 0?t:Ao.Default(),this.instrumentSelector=new Rz({name:e.instrumentName,type:e.instrumentType,unit:e.instrumentUnit}),this.meterSelector=new xz({name:e.meterName,version:e.meterVersion,schemaUrl:e.meterSchemaUrl}),this.aggregationCardinalityLimit=e.aggregationCardinalityLimit;}return r}();Pt();function gie(){return new cB({url:"https://us-west.metrics.momentic.ai/v1/metrics",headers:{"x-momentic-metrics-api-key":"c60c6a0f-60da-41a7-a61b-07969a0aa303"},temporalityPreference:Vl.DELTA})}var yie=[new bf({instrumentName:"test_event_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new bf({instrumentName:"test_step_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)}),new bf({instrumentName:"test_mobile_step_duration",instrumentType:tt.HISTOGRAM,aggregation:new Zu([100,500,1e3,2e3,3e3,4e3,5e3,7500,1e4,15e3,2e4],!1)})],_S=class{globalAttributes;provider;meter;counterCache=new Map;histogramCache=new Map;observableGaugeCache=new Map;gaugeValues=new Map;getCounter(e){let t=this.counterCache.get(e);if(t)return t;let n=this.meter.createCounter(e);return this.counterCache.set(e,n),n}getHistogram(e){let t=this.histogramCache.get(e);if(t)return t;let n=this.meter.createHistogram(e);return this.histogramCache.set(e,n),n}ensureObservableGauge(e){let t=this.observableGaugeCache.get(e);if(t)return t;let n=this.meter.createObservableGauge(e);return n.addCallback(o=>{let i=this.gaugeValues.get(e);i!==void 0&&o.observe(i,this.globalAttributes);}),this.observableGaugeCache.set(e,n),n}constructor(e){this.globalAttributes={...e.globalAttributes??{}};let t=typeof process<"u"?"production":"unknown",n=new VA({[Ky]:e.serviceName,[iU]:t,[sU]:typeof process<"u"&&process.env.SERVICE_INSTANCE_ID?process.env.SERVICE_INSTANCE_ID:v4$1()}),o=gie(),i=new mR({exporter:o,exportIntervalMillis:e.exportIntervalMs??6e4});this.provider=new bR({resource:n,readers:[i],views:yie}),jy.setGlobalMeterProvider(this.provider),this.meter=jy.getMeter("momentic-serverless");}increment(e,t,n){try{let o=gA(n,this.globalAttributes);this.getCounter(e).add(typeof t=="number"?t:1,o);}catch{}}gauge(e,t){try{this.ensureObservableGauge(e),this.gaugeValues.set(e,t);}catch{}}distribution(e,t,n){try{let o=gA(n,this.globalAttributes);this.getHistogram(e).record(t,o);}catch{}}async flush(){try{await this.provider.forceFlush();}catch{}}async recordDuration({fn:e,name:t,tags:n}){let o=Date.now();try{return await Promise.resolve(e())}finally{this.distribution(t,Date.now()-o,n);}}};var Et=new $y;function Mz(r){r.disabled||(Et=new _S(r));}var bie=1e4;async function Ef(r){return new Promise(e=>{exec(r,{timeout:bie},(t,n,o)=>{e({command:r,stdout:n,stderr:o,error:t?.message??null,timedOut:t?.killed??!1});});})}async function Eie(r){if(platform()==="win32")return Ef(`tracert ${r}`);let t=await Ef(`traceroute ${r}`);return t.stderr.includes("not found")||t.error?.includes("not found")?Ef(`tracepath ${r}`):t}async function td(r){let t=platform()==="win32",n=t?`ping -n 3 ${r}`:`ping -c 3 ${r}`,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 ${t?"NUL":"/dev/null"} -s ${r}`,[a,s,l]=await Promise.all([Ef(n),Eie(r),Ef(i)]);return {ping:a,traceroute:s,curl:l}}var ER;function Pz(r){ER=r;}function PS(r){r instanceof Wr||ER&&ER(r);}var TR=!1;try{let r=await import('@sentry/node');r.init({dsn:"https://67a6ef469598f8880478f33863d05873@o4506426201800704.ingest.us.sentry.io/4510914396291072",environment:"production",dist:"production",release:"mobile-cli-0.88.2",tracesSampleRate:0,sendDefaultPii:!0}),Pz(r.captureException),TR=!0;}catch{}var wie=!1,Iz=(()=>{try{return statSync("/.dockerenv"),!0}catch{return !1}})();async function rd(r){return Fl||wie||Iz?!0:(await N.flush(),await new Promise(t=>setTimeout(t,100)),await confirm({message:r}))}async function Oz(r,e){return Fl||Iz?e:(await input({message:r,default:e})).trim()||e}var vR=class extends Error{constructor(e,t,n){let o=Error.stackTraceLimit;n&&(Error.stackTraceLimit=Math.max(n,o||10)),super(e),Error.captureStackTrace&&Error.captureStackTrace(this,t),Error.stackTraceLimit=o;}},IS=class r extends Console{_buffer=[];_groupDepth=0;Console=Console;constructor(){super({write:e=>(r.write(this._buffer,"log",e),!0)});}static write(e,t,n,o=2){let i=new vR(void 0,r.write).stack;if(!i)return e;let a=i.split(`
|
|
170
170
|
`).slice(o).filter(Boolean).join(`
|
|
171
171
|
`);return e.push({message:n,origin:a,type:t}),e}_log(e,t){r.write(this._buffer,e," ".repeat(this._groupDepth)+t,3);}debug(e,...t){this._log("debug",format(e,...t));}error(e,...t){this._log("error",format(e,...t));}info(e,...t){this._log("info",format(e,...t));}log(e,...t){this._log("log",format(e,...t));}warn(e,...t){this._log("warn",format(e,...t));}getBuffer(){return this._buffer.length>0?this._buffer:void 0}};function Lz(r){let e=globalThis.console,t=new IS;globalThis.console=t;try{r();}finally{let o=t.getBuffer()?.map(i=>i.message).join(`
|
|
172
172
|
`);process.stderr.write(`${o}
|
|
173
|
-
`),globalThis.console=e;}}var vf=" ".repeat(6);var mr=Fu({app:"cli",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:"0.88.
|
|
173
|
+
`),globalThis.console=e;}}var vf=" ".repeat(6);var mr=Fu({app:"cli",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:"0.88.2"});function CR(r){if(!r)return;r=r.toLowerCase();let e=xy.safeParse(r);if(e.success)return N.setMinLevel(e.data),e.data}function Dz({results:r,startTime:e,entity:t,getDisplayLine:n,onFailed:o}){let i=r.filter(u=>u.status==="PASSED"&&u.quarantined),a=r.filter(u=>u.status==="PASSED"&&!u.quarantined),s=r.filter(u=>u.status==="FAILED"&&u.quarantined),l=r.filter(u=>u.status==="FAILED"&&!u.quarantined),c=r.filter(u=>u.status==="CANCELLED");return Lz(()=>{if(l.forEach(u=>{N.log(""),o(u);}),l.length){N.log("");let u=l.length===1?"":"s";N.error(`${l.length} ${t}${u} failed:`),l.forEach(d=>{N.dimmed(n(d));});}if(c.length){N.log("");let u=c.length===1?"":"s";N.warn(`${c.length} ${t}${u} cancelled:`),c.forEach(d=>{N.dimmed(n(d));});}if(a.length){N.log("");let u=a.length===1?"":"s";N.success(`${a.length} ${t}${u} passed:`),a.forEach(d=>{N.dimmed(n(d));});}if(s.length){N.log("");let u=s.length===1?"":"s";N.warn(`${s.length} quarantined ${t}${u} failed:`),s.forEach(d=>{N.dimmed(n(d));});}if(i.length){N.log("");let u=i.length===1?"":"s";N.warn(`${i.length} quarantined ${t}${u} passed:`),i.forEach(d=>{N.dimmed(n(d));});}N.log(""),N.dimmed(`Total time: ${Math.round((Date.now()-e)/1e3)}s`);}),{quarantinedPassed:i.length,passed:a.length,quarantinedFailed:s.length,failed:l.length,cancelled:c.length}}var Cf=({status:r,testLogRef:e,getRunningTestsCount:t,getTotalTestsCount:n,additionalText:o})=>{r=r.toUpperCase();let i=r,a;r.includes("FAIL")?(i=xi.bgRgb(139,0,0).white("FAIL"),a=3):r.includes("PASS")?(i=xi.bgGreen.white("PASS"),a=3):r.includes("START")?(i=xi.bgBlue.white("START"),a=2):r.includes("CANCEL")?(i=xi.bgRgb(191,68,11).white("CANCEL"),a=1):r.includes("RETRY")?(i=xi.bgRgb(255,140,0).white("RETRY"),a=2):r.includes("RUN")||r.includes("PROG")?(i=xi.bgMagenta.white("RUNNING"),a=0):(N.warn(`Unknown status tried to be logged in run test locally: ${r}`),a=0),supportsColor||(i=`${i}`),N.log(`${i}${" ".repeat(a)} ${e} ${o?`${o} `:""}(${t()}/${n()})`);};var Fz=xr__default.join(tmpdir(),"momenticBrowserInstallation");var OS=["chrome","chromium","chrome-for-testing","ffmpeg"];[...OS.filter(r=>r!=="ffmpeg")];var Oie={Chromium:"chromium","Google Chrome":"chrome","Chrome for Testing":"chrome-for-testing"};var Uz={chrome:"chrome",chromium:"chromium","chrome-for-testing":"chromium-headless-shell",ffmpeg:"ffmpeg"};function Bz(r){if(r==="Org Default")return !1;let e=Uz[Oie[r]??""]??"",t=registry.findExecutable(e);return !t||t.installType==="none"?!1:wR(t)}function wR(r){let e=r.executablePath();return Tr.existsSync(e)}function Nie(r,e){let t=Uz[r];if(!t)throw new Error(`Requested install of unknown browser type ${r}`);let n=registry.findExecutable(t);if(!n||n.installType==="none")throw new Error(`Requested install of unknown browser type ${r}`);if(!(!e&&wR(n)))return n}async function Lie({browser:r,force:e}){let t=Nie(r,e);if(!t){N.info(`Browser '${r}' is already installed, skipping...`);return}N.info(`Installing browser '${r}'...`);try{await registry.installDeps([t],!1),await registry.install([t],!1);}catch(n){if(n.message.includes("Lock file is already being held")){N.warn("Another process is installing Playwright browsers. Waiting for completion before proceeding..");let o=registry.findExecutable(r),i=5*60*1e3,a=Date.now();for(;Date.now()-a<i&&!wR(o);)N.info("Waiting for browser to finish installing..."),await new Promise(s=>setTimeout(s,5e3));}else throw n}}async function Die(){if(platform()==="win32"){N.info("Installing Windows dependencies for Playwright...");try{await program.parseAsync(["","","install","winldd"]);}catch(r){N.warn(`Failed to install Windows dependencies: ${r}. Continuing with browser installation...`);}}}async function NS({rawBrowsers:r,force:e=!1,all:t=!1}){await Die();let n=t?OS:Array.from(new Set(r));try{await kz.lock(Fz,{stale:1e3*60*5,update:1e3*60,realpath:!1,retries:{retries:30,factor:2,maxTimeout:15e3,minTimeout:500}});}catch(i){N.warn(`Failed to acquire lock to install browsers. Please ensure that any other process installing browsers completes within 5 minutes: ${i}. Continuing without installation...`);return}let o;try{for(let i of n)try{await Lie({browser:i,force:e});}catch(a){o=a,N.error(`Failed to install the ${i} browser: ${a}`);}}finally{await kz.unlock(Fz,{realpath:!1});}if(o)throw o}async function Es(r,e,t=30){for(let n=0;n<t;n+=1){let o=r+n;if(await LS(o))return o}N.error(`Could not find an available port for ${e} starting from ${r} after ${t} attempts`),process.exit(1);}async function LS(r){return new Promise((e,t)=>{let n=createServer();n.once("error",o=>{o.code==="EADDRINUSE"?e(!1):(N.warn({err:o},"Unexpected error checking for open ports, continuing..."),n.close(),e(!0));}),n.once("listening",()=>{n.close(()=>{e(!0);});}),n.listen(r);})}function zz(r){let e=r?.shardIndex??1,t=r?.shardCount??1;if(e<1)throw new Error("Shard index must be greater than 0.");if(t<1)throw new Error("Shard count must be greater than 0.");if(e>t)throw new Error("Shard index cannot be greater than shard count")}function Fie(r,e,t,n){if(t>r.length&&(N.warn(`Shard count ${t} is greater than the number of tests ${r.length}! Some workers won't have any tests to run.`),t=Math.max(t,r.length),e>t))return [];let o=Math.floor((e-1)*(r.length/t)),i=Math.floor(e*(r.length/t));return (n?[...r].sort((s,l)=>n(s).localeCompare(n(l))):[...r].sort()).filter((s,l)=>l>=o&&l<i)}function $z(r){let{items:e,shardIndex:t,shardCount:n,sortKey:o}=r;return n>1?Fie(e,t,n,o):e}function Uie({regenerateCache:r,alwaysSaveCache:e,noCache:t}){if(t){if(r)throw new Error("--disable-cache and --regenerate-cache cannot be used together.");if(e)throw new Error("--disable-cache and --save-cache cannot be used together.")}}function DS({disableCache:r,saveCache:e,regenerateCache:t,bustOldestCachePercentage:n}){let o={regenerateCache:t??!1,alwaysSaveCache:e??!1,noCache:r??!1,bustOldestCachePercentage:n};return Uie(o),o}function Vz(r,e,t){return r instanceof $c?(r.zodIssues.forEach(n=>{t.push({file:e,stepIndex:typeof n.path[0]=="number"?n.path[0]:void 0,field:n.path.slice(1).join(".")||n.path.join("."),issue:n.message});}),!0):!1}function AR({parsingErrors:r,parsingErrorDetails:e,failedTestFilePaths:t,failedModuleFilePaths:n}){if(N.error(`
|
|
174
174
|
Found ${r} file(s) with validation errors that must be fixed manually:
|
|
175
175
|
`),e.length>0){let o=new Map;e.forEach(i=>{let a=o.get(i.file)||[];a.push(i),o.set(i.file,a);}),o.forEach((i,a)=>{N.error(` ${a}`),i.forEach(({stepIndex:s,field:l,issue:c})=>{let u=s!==void 0?`Step ${s}`:"File",d=l?`, field "${l}"`:"";N.error(` ${u}${d}:`),N.error(` \u2192 ${c}`);});});}else t.size>0&&N.error(`Failed test files:
|
|
176
176
|
${[...t].map(o=>`${vf}- ${o}`).join(`
|
|
@@ -191,7 +191,7 @@ ${JSON.stringify(t)}`);return {key:Jie(r.id,e.join(":")),organizationId:r.orgId,
|
|
|
191
191
|
${t}`:t}var uae="[FAILED]";async function KS(r,e,t,{numStepsWithScreenshots:n=5,addIndices:o=!0,includeBeforeScreenshots:i=!1,screenshotMediaType:a="image/png",includeUserFacingStepReference:s,flatten:l=!0,maxItemsFromEnd:c=20}){let u=await C1(r,e,t,{addIndices:o,includeUserFacingStepReference:s,flatten:l,maxItemsFromEnd:c,indexOffset:0}),{results:d}=u,{failureIndex:m}=u;m!==void 0&&d.length>0&&(d=d.slice(0,m+1));let p=[],f=0;if(c!==void 0&&d.length>c&&(f=d.length-c),m!==void 0&&m<d.length-1&&r.warn({failureIndex:m,flattenedResultsLength:d.length,lastIndex:d.length-1,isLastIndex:m===d.length-1,offset:f},"PROCESS_RESULTS_FOR_LLM: Failure index check - should not be possible"),m!==void 0&&f>m)throw new Error("Failure index is out of bounds");for(let h=f;h<d.length;h++){let g=d[h],y={description:g.description,startTime:g.startTime,endTime:g.endTime,status:g.status,userFacingStepReference:g.userFacingStepReference,message:g.message,index:g.index},S,b;e&&(n===void 0||n>0&&h>=d.length-n)&&(g.afterSnapshot&&(b=await v1(e,g.afterSnapshot,a)),i&&g.beforeSnapshot&&(S=await v1(e,g.beforeSnapshot,a))),y.beforeScreenshot=S,y.afterScreenshot=b,p.push(y);}return {results:p,failureIndex:m!==void 0?m-f:void 0}}async function C1(r,e,t,{addIndices:n=!0,flatten:o=!0,maxItemsFromEnd:i=15,indexOffset:a=0,includeUserFacingStepReference:s,parentStep:l}){let c,u=[];for(let d=0;d<t.length;d++){let m=t[d];switch(m.type){case"MOBILE_PRESET_STEP":{m.status==="FAILED"&&(c=a+u.length),u.push(qS(m,{index:a+u.length,addIndices:n,includeUserFacingStepReference:s,unflattenedIndex:d,parentStep:l}));break}case"MOBILE_AI_ACTION_STEP":case"MOBILE_CONDITIONAL_STEP":case"MOBILE_MODULE_STEP":{let p=m.type==="MOBILE_CONDITIONAL_STEP"&&m.assertionResult?[m.assertionResult,...m.steps]:m.steps;if(o){let f=a+u.length;u.push(qS(m,{index:f,addIndices:n,includeUserFacingStepReference:s,unflattenedIndex:d,parentStep:l,header:"start"}));let{failureIndex:h,results:g}=await C1(r,e,p,{addIndices:n,includeUserFacingStepReference:s,flatten:o,maxItemsFromEnd:i,indexOffset:a+u.length,parentStep:m});u.push(...g),h!==void 0?c=h:m.status==="FAILED"&&(c=f),a+=g.length,u.push(qS(m,{index:a+u.length,addIndices:n,includeUserFacingStepReference:s,parentStep:l,header:"end"}));}else u.push(qS(m,{index:a+u.length,addIndices:n,includeUserFacingStepReference:s,parentStep:l}));break}default:return (f=>{throw new Error("You missed a case in the switch above")})()}}return {results:u,failureIndex:c}}function qS(r,e={}){let{index:t,addIndices:n=!0,unflattenedIndex:o,parentStep:i,header:a,includeUserFacingStepReference:s}=e,c=T1({header:a,typeLabel:dae(r),content:Ni(r)});r.status==="FAILED"&&(c=`${uae} ${c}`);let u={description:c,startTime:r.startTime,endTime:r.endTime,status:r.status,beforeSnapshot:r.beforeSnapshot,afterSnapshot:r.afterSnapshot,message:r.message,index:n?t:void 0};return s&&(u.userFacingStepReference=mae(r,{parentStep:i,unflattenedIndex:o})),u}function dae(r){switch(r.type){case"MOBILE_AI_ACTION_STEP":return "AI action";case"MOBILE_CONDITIONAL_STEP":return "Conditional";case"MOBILE_PRESET_STEP":return "Preset action";case"MOBILE_MODULE_STEP":return "Module";default:throw new Error("Missing case in switch within getMobileResultTypeDescription")}}function mae(r,{unflattenedIndex:e,parentStep:t}){if(t){let n=`sub-step ${e}`;switch(t.type){case"MOBILE_MODULE_STEP":return `${n} within module '${t.name??t.moduleId}'`;case"MOBILE_AI_ACTION_STEP":return `${n} within AI action`;case"MOBILE_CONDITIONAL_STEP":return `${n} within conditional`;default:return n}}return `step ${e}`}async function v1(r,e,t="image/png"){if(e){let n=await r.getScreenshot(e);if(n)return `data:${t};base64,${n.toString("base64")}`}}function Xl({json:r,keysToRedact:e,maxJsonStringSize:t}){try{if(r==null)return r;if(typeof r=="string")return tr(r,t??2e4);if(typeof r=="bigint")return r.toString();if(typeof r=="function")return `[Function ${r.name||"anonymous"}]`;if(typeof r=="symbol")return r.toString();if(typeof r=="object"){let n=new WeakSet,o=(()=>{try{return JSON.stringify(r,(a,s)=>{if(e?.includes(a)||typeof s=="string"&&s.length>3e4)return "REDACTED";if(typeof s=="bigint")return s.toString();if(typeof s=="function")return `[Function ${s.name||"anonymous"}]`;if(typeof s=="symbol")return s.toString();if(typeof s=="object"&&s!==null){if(n.has(s))return "[Circular]";n.add(s);}return s})}catch{return}})();if(o===void 0)return;let{jsonString:i}=a0(o,t??2e4);return JSON.parse(i)}return r}catch{return "[unserializable value omitted]"}}async function VR({promiseGenerator:r,signal:e,codePath:t,logger:n}){let i=Date.now(),a=setInterval(()=>{if(e?.aborted){clearInterval(a);return}n?.warn({codePath:t,startTime:i,elapsedMilliseconds:Date.now()-i},`Asynchronous operation is taking a long time (${t})`);},5e3);return new Promise((s,l)=>{function c(){clearInterval(a),e?.removeEventListener("abort",c),l(e?.reason);}if(e?.aborted){l(e?.reason),clearInterval(a);return}e?.addEventListener("abort",c,{once:!0}),(async()=>{try{s(await r());}catch(u){l(u);}finally{clearInterval(a),e?.removeEventListener("abort",c);}})();})}async function If({promiseGenerator:r,timeoutMs:e,codePath:t,logger:n,signal:o}){let i=!1,a=new AbortController,s=()=>{a.abort();},l=setTimeout(()=>{o?.removeEventListener("abort",s),!i&&a.abort();},e);o?.addEventListener("abort",s,{once:!0});try{return await VR({promiseGenerator:r,signal:a.signal,codePath:t,logger:n})}finally{i=!0,o?.removeEventListener("abort",s),clearTimeout(l);}}function XS(r){let e;return r>10*60*1e3?e=2*60*1e3:r>60*1e3?e=20*1e3:r>10*1e3?e=2*1e3:e=1e3,e}function w1(r,e){let t=Math.max(1,e),n=r/t;return Math.max(n,1e3)}var YS=(r,e,t)=>{t?.caseInsensitive&&(r=r.toLowerCase());let n;switch(e.type){case"SUBSTRING":{let o=t?.caseInsensitive?e.url.toLowerCase():e.url;n=r.includes(o);break}case"GLOB":{let o=t?.caseInsensitive?e.glob.toLowerCase():e.glob;n=r===e.glob||fae(o)(r);break}case"REGEX":{n=new RegExp(e.regex).test(r);break}case"DOMAIN":{let o=t?.caseInsensitive?e.domain.toLowerCase():e.domain;n=new URL(r).hostname===o;break}}return t?.negated?!n:n},JS=(r,e)=>{try{let{hostname:t,pathname:n}=new URL(r),{hostname:o,pathname:i}=new URL(e);return t!==o||n!==i}catch{return !1}},ld=r=>{try{return new URL(r),!0}catch{return !1}},A1=r=>!r.toLowerCase().startsWith("http"),cd=(r,e)=>{try{return new URL(r,e),!0}catch{return !1}};function Cs(r,e){try{return !!new URL(r).origin.trim()}catch(t){return e?.warn({url:r,err:t},"Invalid URL in check"),!1}}function R1(r,e,t){let{organizationId:n="local",runKey:o=e,createdBy:i="local-user",runGroupMetadata:a,runAttempts:s=[]}=t??{},l=r.trigger===So.CLI;return {id:e,runKey:o,organizationId:n,executionType:r.executionType,createdAt:r.startedAt??new Date,createdBy:i,flake:r.flake??null,scheduledAt:null,startedAt:r.startedAt??null,updatedAt:r.finishedAt??null,finishedAt:r.finishedAt??null,resolvedBaseUrl:r.resolvedBaseUrl??null,environmentName:r.environmentName??null,gitBranchName:a?.gitBranchName??null,githubRepository:a?.githubRepository??null,gitlabProjectPath:a?.gitlabProjectPath??null,labels:r.labels??[],gitOriginUrl:a?.gitOriginUrl??null,gitCommitSha:a?.gitCommitSha??null,gitCommitShaShort:a?.gitCommitShaShort??null,gitCommitAuthorName:a?.gitCommitAuthorName??null,gitCommitTimestamp:a?.gitCommitTimestamp??null,gitCommitMessage:a?.gitCommitMessage??null,cliVersion:r.cliVersion??a?.cliVersion??null,status:r.status,trigger:r.trigger,attempts:r.attempts,runAttempts:s,videos:[],failureReason:r.failureReason??null,failureDetails:r.failureDetails??null,failureRecoveryDetails:r.failureRecoveryDetails??null,pipelineId:a?.pipelineId??null,resolvedInputs:r.resolvedInputs??null,quarantined:r.quarantined??!1,quarantinedReason:r.quarantinedReason??null,...l?{localTestId:r.testId??null,testName:r.testName??r.testDescription??null,test:null}:{testId:r.testId??null,test:r.testId?{id:r.testId,name:r.testName??r.testDescription??"Unknown Test"}:null},description:r.testDescription??null,suiteId:void 0,aiSettings:r.aiSettings??void 0,stepsSnapshot:r.stepsSnapshot??void 0,beforeStepsSnapshot:r.beforeStepsSnapshot??void 0,afterStepsSnapshot:r.afterStepsSnapshot??void 0}}function ZS(r,e){return {...r,testId:e?.testId??"",testName:e?.testName??"",suiteId:e?.suiteId??"",suiteName:e?.suiteName??""}}function hae(r){return r!=="CONDITIONAL"&&r!=="SECTION"&&r!=="MODULE"&&r!=="RESOLVED_MODULE"&&r!=="MOBILE_MODULE_STEP"&&r!=="MOBILE_CONDITIONAL_STEP"&&r!=="RESOLVED_MOBILE_MODULE"}var Di=class{reporter;asyncWork;metadata;isInteractive;creditsUsedV1=0;creditsUsedV2=0;stepsExecuted=0;constructor({logger:e,reporter:t,runType:n,runId:o,testMetadata:i,suiteMetadata:a,isInteractive:s=!1}){this.reporter=t,this.isInteractive=s,this.metadata={testId:i.id,testName:i.name,suiteId:a?.id,suiteName:a?.name},this.asyncWork=[],s||this.asyncWork.push(t.reportBillableEvents(e,[{event:n,timestamp:new Date().toISOString(),transactionId:o,properties:ZS({isInteractive:this.isInteractive},this.metadata)}]).catch(l=>e.error({err:l},"Failed to report billable event")));}trackStepExecution(e){if(hae(e.type)&&(this.stepsExecuted+=1),this.isInteractive)return;if(LD(e.type)){this.creditsUsedV2+=1;return}let t=HD(e.type);if(this.creditsUsedV1+=t??0,e.type==="PRESET_ACTION"){this.creditsUsedV2+=1;let n=jD(e.command);this.creditsUsedV1+=n??0;}}async flush(e){let t=this.creditsUsedV1;this.creditsUsedV1=0;let n=this.creditsUsedV2;this.creditsUsedV2=0;let o=this.stepsExecuted;this.stepsExecuted=0,!this.isInteractive&&t>0&&this.asyncWork.push(this.reporter.reportBillableEvents(e,[{event:"credits-used",timestamp:new Date().toISOString(),transactionId:v4$1(),properties:ZS({isInteractive:this.isInteractive,creditsUsed:t},this.metadata)}]).catch(i=>e.error({err:i},"Failed to report credits used"))),!this.isInteractive&&n>0&&this.asyncWork.push(this.reporter.reportBillableEvents(e,[{event:"credits-used-v2",timestamp:new Date().toISOString(),transactionId:v4$1(),properties:ZS({isInteractive:this.isInteractive,creditsUsed:n},this.metadata)}]).catch(i=>e.error({err:i},"Failed to report credits used"))),o>0&&this.asyncWork.push(this.reporter.reportBillableEvents(e,[{event:"steps-executed",timestamp:new Date().toISOString(),transactionId:v4$1(),properties:ZS({isInteractive:this.isInteractive,stepsExecuted:o},this.metadata)}]).catch(i=>e.error({err:i},"Failed to report steps executed"))),await Promise.allSettled(this.asyncWork);}};function ws(r,e){let t=e.hooks?.postSave;if(!t)return;let n;t.includes("$1")?n=t.replaceAll("$1",r):n=`${t} ${r}`,N.debug({postSaveCommand:n},"Executing post-save hook command");try{execSync(n,{encoding:"utf-8"});}catch(o){N.warn({err:o,postSaveCommand:n},"Failed to execute post-save hook command, continuing...");}}var x1=new Map;function xa(r){let e=xr__default.resolve(r),t=statSync(e),n=x1.get(e);if(n&&n.mtimeMs===t.mtimeMs&&n.size===t.size)return {parsed:structuredClone(n.parsed),stats:t};let i=readFileSync(e,"utf-8").replace(/\r\n|\r/g,`
|
|
192
192
|
`),a=YR.parse(i);return x1.set(e,{mtimeMs:t.mtimeMs,size:t.size,parsed:a}),{parsed:structuredClone(a),stats:t}}function QS(r,e){let t=[];for(let n of r.config.environments??[]){if(n.baseUrl)continue;let o=Yl(n.name,r,e);o.variables[UC]||t.push(o);}return t}function Cae(r){return r.includes("${")?r.replace(/\$\{([^}]+)\}/g,(e,t)=>{let n=t.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:(:-|-)([\s\S]*))?$/);if(!n)return process.env[t]||"";let o=n[1];if(!o)return "";let i=n[2],a=n[3],s=process.env[o];return i===":-"?s&&s!==""?s:a||"":i==="-"?s!==void 0?s:a||"":s||""}):r}function wae(r){let{envVariables:e,project:t}=r;if(!e)return {};let n={};for(let[o,i]of Object.entries(e)){if(typeof i=="string"){let s=Cae(i);s&&(n[o]=s);continue}let a;try{a=Tr.readFileSync(xr__default.resolve(t.rootDir,i.fromFile),"utf-8");}catch(s){throw new Error(`Failed to read environment variable '${o}' from file '${i.fromFile}': ${s}`)}if(i.json)try{n[o]=JSON.parse(a);}catch(s){throw new Error(`Failed to parse environment variable '${o}' from file '${i.fromFile}' as JSON: ${s}`)}else n[o]=a;}return Object.keys(n).length>0&&N.debug(n,"Set environment variables with interpolation from project configuration"),n}function Aae(r){let{project:e,envFile:t,logger:n}=r,o={};if(!t)return o;let i=Tae.config({path:xr__default.resolve(e.rootDir,t),processEnv:o,logLevel:"error",quiet:!0});if(i.error)throw new Error(`Failed to load .env file: ${i.error.message}`);return n.debug("Set environment variables from .env file"),o}function Yl(r,e,t){let n=(e.config.environments??[]).find(l=>l.name===r);if(!n)throw new Error(`Environment ${r} not found in local project configuration file`);let o={},i=wae({envVariables:n.envVariables,project:e});Object.assign(o,i);let a=Aae({project:e,envFile:n.envFile,logger:t});return Object.assign(o,a),n.inheritFromShell&&(t.debug(process.env,"Inheriting environment variables from shell"),Object.assign(o,process.env)),{name:r,variables:o}}var jR=["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"],Mae=jR.map(r=>`**/${r}`);function _ae(r){return r.map(e=>(e.endsWith("/")&&(e=e.slice(0,-1)),xr__default.join(e)))}async function ud(r,e){let t=await glob(r,{cwd:e.cwd,ignore:Mae.concat(e.ignore??[]),deep:e.maxDepth,onlyFiles:e.nodir,signal:e.signal});return _ae(t)}var eb=["**/*.test.yaml","**/*.module.yaml"],GR=v__default.string().refine(r=>/^[a-zA-Z0-9-]+$/.test(r)),tb=15;var As="momentic.config.yaml",qR="momentic.workspace.yaml",kae=z.object({projects:z.string().array().describe("list of glob patterns to find project (momentic.config.yaml) files")}),Fae=z.union([z.string(),z.object({fromFile:z.string(),json:z.boolean().optional()})]),Uae=z.object({name:GR,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(),Fae).optional(),inheritFromShell:z.boolean().optional().describe("inherit all environment variables from the shell - might be noisy"),browser:Tl.optional().describe("NB: most things should use project-level configuration only")}),Bae=z.object({postSave:z.string().optional()}),zae=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."),$ae=z.object({name:GR,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:tF.optional().describe("file format version to use"),goldenFileDir:z.string().optional(),reporterDir:z.string().optional(),outputDir:z.string().optional(),recordVideo:zae.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(Uae).optional(),gitMainBranch:z.string().optional().readonly(),gitProtectedBranches:z.string().array().optional().readonly(),ai:ua.optional(),browser:Tl.optional(),emulator:Uw.optional(),advanced:qC.optional(),displayRoot:z.string().optional().describe("relative path from project root to use as the Repository root"),hooks:Bae.optional()});function I1(r,e){let t;try{t=readFileSync(r,"utf-8");}catch(o){N.warn(`Could not read possible Momentic ${e} file at ${r}: ${o}`);return}let n;try{if(n=YR.parse(t),typeof n!="object"||n===null)throw new Error(`The ${e} file should parse as a map with key-value pairs, but is type ${typeof n} instead`)}catch(o){N.warn(`Possible Momentic ${e} file at ${r} does not parse as valid YAML: ${o}`);return}return n}function O1(r,e){let t=[];for(let[n,o]of Object.entries(r)){let a=/^\d+$/.test(n)?`${e}[${n}]`:e?`${e}.${n}`:n;o!==null&&typeof o=="object"?t.push(...O1(o,a)):t.push(a);}return t}function KR(r){let e=I1(r,"project configuration");if(e===void 0)return;let t;try{t=$ae.parse(e);}catch(i){N.warn(`Possible Momentic project configuration file at ${r} does not adhere to the required schema: ${i}`);return}let n=deletedDiff(e,t),o=O1(n,"");return o.length>0&&N.warn(`Momentic config file at ${r} contains unrecognized keys: ${o.join(", ")}. These keys will be ignored.`),t}function Vae(r){let e=I1(r,"workspace configuration");if(e!==void 0)try{return kae.parse(e)}catch(t){N.warn(`Possible Momentic workspace configuration file at ${r} does not adhere to the required schema: ${t}`);return}}function Hae(){let r=[],e=cwd(),t=xr__default.parse(e).root,n=15,o=0;for(;o<n;){o++;let i=xr__default.basename(e);if(jR.includes(i))return N.warn(`Stopping search for Momentic projects since the current directory name (${i}) is likely a system artifact folder.`),r;for(let a of readdirSync(e))if(a.endsWith(As)){let s=xr__default.join(e,a),l=KR(s);l&&r.push({configFilePath:s,config:l,rootDir:dirname(s)});}if(r.length)return r;if(e=xr__default.dirname(e),e===t)break}return r}async function ki(r={}){let{configFilePath:e,nameFilter:t,skipExitOnError:n}=r,o=await Gae(e,n);if(t&&(o=o.filter(i=>i.config.name===t)),o.length>1)throw new Error(`Multiple valid projects were found in the same directory. Please use the '-c / --config' flag to disambiguate:
|
|
193
193
|
${o.map(i=>i.configFilePath)}`);if(o.length===0)throw new Error("No valid Momentic project file available.");return N.debug(`Found valid project configuration at ${o[0].configFilePath}`),o[0]}async function jae(r){let e=Vae(r);if(!e||!e.projects||!e.projects.length)return;let t=e.projects.map(a=>(a.endsWith("/")||(a+="/"),`${a}*${As}`)),n=AbortSignal.timeout(2e3),o;try{o=await ud(t,{cwd:cwd(),maxDepth:tb,ignore:[],nodir:!0,signal:n});}catch(a){throw N.error({err:a},`Failed to list the available Momentic projects in the current directory. This usually indicates the 'include' or 'exclude' option in your ${qR} is misconfigured.`),a}let i=[];for(let a of o){let s=xr__default.join(cwd(),a),l=KR(s);l&&i.push({configFilePath:s,config:l,rootDir:dirname(s)});}return i}async function Gae(r,e){if(r){r=xr__default.resolve(r);let n=KR(r);return n?[{config:n,configFilePath:r,rootDir:xr__default.dirname(r)}]:(console.error(`No valid Momentic project file found at ${r}.`),e||process.exit(1),[])}if(existsSync(qR)){let n=await jae(qR);if(n)return n}return Hae()}function dd(r,e){let t=YR.stringify(r);writeFileSync(e,t);}var k1=!1,Wae=z.object({fileType:z.nativeEnum(et)});async function It(r,e=!1){let t={project:r,tests:{},modules:{},mobileTests:{},mobileModules:{},duplicateEntities:{}},n=r.config.include??eb,o=r.config.exclude??[],i=AbortSignal.timeout(5e3),a;try{a=await ud(n,{cwd:r.rootDir,ignore:o,maxDepth:tb,nodir:!0,signal:i});}catch(s){throw N.error({err:s},"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:s})}for(let s of a){let l=qae(r.rootDir,s,t,e?Dl:N);l&&(t.duplicateEntities[l.id]=l.paths);}return k1=!0,t}function qae(r,e,t,n){let o=xr__default.join(r,e),i=Kae(o,n);if(!i)return;let{entityJs:a,stats:s}=i,l=Wae.safeParse(a);if(l.success===!1){n.warn(`Possible Momentic file at ${o} does not have a 'fileType', skipping: ${l.error}`);return}let c=l.data.fileType,u=Xae(e,o,s);switch(c){case et.TEST:try{return L1(a,c,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic test metadata: ${d}`);return}case et.TEST_V2:try{return L1(a,c,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic v2 test metadata: ${d}`);return}case et.MODULE:try{return D1(a,c,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic module metadata: ${d}`);return}case et.MODULE_V2:try{return D1(a,c,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic v2 module metadata: ${d}`);return}case et.MOBILE_TEST:try{return Jae(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic mobile test metadata: ${d}`);return}case et.MOBILE_MODULE:try{return Yae(a,t,u,o,n)}catch(d){n.warn(`Skipping file '${o}' because it is missing Momentic mobile module metadata: ${d}`);return}default:{return}}}function Kae(r,e){try{let{parsed:t,stats:n}=xa(r);if(typeof t!="object"||t===null)throw new Error("The YAML document should parse as a map with key-value pairs");return {entityJs:t,stats:n}}catch(t){e.warn(`Could not parse possible Momentic file at ${r}, skipping: ${t}`);return}}function Xae(r,e,t){return {relativePath:r,fullFilePath:e,platformSep:xr__default.sep,fullPathSegments:e.split(xr__default.sep),relativePathSegments:r.split(xr__default.sep),fileName:xr__default.basename(e),lastModified:t.mtime,createdAt:t.birthtime}}function L1(r,e,t,n,o,i){let a=n.fileName.replace(".test.yaml",""),s,l;e===et.TEST_V2?(s=dA.parse(r),l=a):(s=yp.parse(r),l=s.name);let c;if(t.tests[s.id]){let u=t.tests[s.id].fullFilePath;c={id:s.id,paths:[u,o]};}return t.tests[s.id]={type:e,name:l,id:s.id,description:s.description??void 0,labels:s.labels,...n},c}function D1(r,e,t,n,o,i){let a=e===et.MODULE_V2?ky.parse(r):yi.parse(r),s=a.moduleId,l;if(t.modules[s]){let u=t.modules[s].fullFilePath;l={id:s,paths:[u,o]};}t.modules[s]={type:e,name:a.name,id:s,description:a.description??void 0,...n};let c=n.fileName.replace(".module.yaml","");return !k1&&Ko(a.name)!==c&&i.warn(`The module with ID ${a.moduleId} has a name (${a.name}) that does not match its file name (${c}). We recommend renaming the module or the file to be consistent to avoid confusion and issues with module resolution.`),l}function Yae(r,e,t,n,o){let i=Fp.parse(r),a;if(e.mobileModules[i.moduleId]){let l=e.mobileModules[i.moduleId].fullFilePath;a={id:i.moduleId,paths:[l,n]};}let s=t.fileName.replace(".module.yaml","");return e.mobileModules[i.moduleId]={type:et.MOBILE_MODULE,name:s,id:i.moduleId,description:i.description??void 0,...t},a}function Jae(r,e,t,n,o){let i=Ru.parse(r),a;if(e.mobileTests[i.id]){let l=e.mobileTests[i.id].fullFilePath;a={id:i.id,paths:[l,n]};}let s=t.fileName.replace(".test.yaml","");return e.mobileTests[i.id]={type:et.MOBILE_TEST,name:s,id:i.id,description:i.description??void 0,labels:i.labels,...t},a}var F1="test-results";var U1=3e3,vt=B1(),ese=promisify(execFile);async function Mo(r){let{logger:e,operation:t,fn:n,context:o}=r,i=Date.now();try{return await n()}finally{let a=Date.now()-i;a>U1&&!process.env.CI&&e.warn({operation:t,durationMs:a,thresholdMs:U1,...o??{}},"[timing] slow git metadata operation");}}function Fi(r){if(r)try{let e=new Date(r);return isNaN(e.getTime())?void 0:e}catch{return}}async function tse(r){let e=await Ct(r,vt.raw(["config","--list"])),t={};if(!e)return t;for(let n of e.split(`
|
|
194
|
-
`)){let o=n.indexOf("=");if(o===-1)continue;let i=n.slice(0,o),a=n.slice(o+1).trim();t[i]=a;}return t}async function rse(r,e,t){try{let o=t["github.user"]||void 0;if(o)return o}catch{}let n;try{if(e?.startsWith("http://")||e?.startsWith("https://"))n=new URL(e).host;else if(e?.startsWith("git@")){let o=e.indexOf("@"),i=e.indexOf(":",o+1);o!==-1&&i!==-1&&(n=e.slice(o+1,i));}}catch{}if(n=n?.toLowerCase(),!!n&&e?.startsWith("git@")&&n.includes("github"))try{let{stdout:o,stderr:i}=await ese("ssh",["-T","-o","BatchMode=yes",`git@${n}`],{timeout:5e3}),s=`${o??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}catch{return}}async function nse(r,e,t){let n=e?.includes("github.com"),o=e?.includes("gitlab.com");try{if(n)return rse(r,e,t);if(o)return}catch{}}function Nf(r){if(r.startsWith("git@")){let e=r.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let n=t[0],o=t[1];return `${n}/${o}`}}}else if(r.startsWith("http")||r.startsWith("https")){let t=new URL(r).pathname.split("/").filter(Boolean);if(t.length>=2){let n=t[0],o=t[1].replace(".git","");return `${n}/${o}`}}}function ose(r){if(!(r instanceof Error))return !1;let e=r.message;return e.includes("not a git repository")||e.includes("ENOENT")}async function Ct(r,e){try{return (await e).trim()}catch(t){if(ose(t))return;r.error({err:t},"Failed to run git command");return}}function ise(){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 ase(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=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?Fi(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function sse(r){let[e,t,n]=await Promise.all([Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.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?Fi(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:n,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function lse(r){let[e,t,n,o]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),i=process.env.CIRCLE_REPOSITORY_URL??t,a=i?.includes("github.com"),s=i?.includes("gitlab.com"),l=i?Nf(i):void 0;return {ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:i,gitCommitMessage:n,gitCommitAuthorName:o,githubRepository:a?l:void 0,gitlabProjectPath:s?l:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function cse(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Nf(o):void 0;return {ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,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 use(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Nf(o):void 0;return {ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function dse(r,e,t){let[n,o,i,a,s,l,c,u,d]=await Promise.all([Ct(r,vt.revparse(["HEAD"])),Ct(r,vt.revparse(["--short","HEAD"])),Ct(r,vt.revparse(["--abbrev-ref","HEAD"])),Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"])),e?Ct(r,vt.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),tse(r)]),m=u||(e?await Ct(r,vt.raw(["merge-base",e,"HEAD"])):void 0),p=m?await Ct(r,vt.show(["--no-patch","--format=%ci",m])):void 0,f=a?.includes("github.com"),h=a?.includes("gitlab.com"),g=a?Nf(a):void 0,y=d["user.email"]||void 0,S=d["user.name"]||void 0,b=d["user.username"]||void 0,C=d["github.user"]||void 0,M=(t?.includeHostingUsername??!0?await nse(r,a,d):void 0)??b??C??void 0;return {ciProvider:"none",gitCommitSha:n,gitCommitShaShort:o,gitBranchName:i,gitOriginUrl:a,gitCommitTimestamp:s?Fi(s):void 0,gitCommitMessage:l,gitCommitAuthorName:c,gitLocalUsername:M,gitLocalEmail:y,gitLocalName:S,lastCommitOnMainSha:m,lastCommitOnMainTimestamp:p?Fi(p):void 0,githubRepository:f?g:void 0,gitlabProjectPath:h?g:void 0,pipelineId:void 0}}async function mse(r){let[e,t]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),n=process.env.GIT_REPOSITORY_URL,o=n?.includes("github.com"),i=n?.includes("gitlab.com"),a=n?Nf(n):void 0;return {ciProvider:"Bitrise",gitCommitSha:process.env.BITRISE_GIT_COMMIT,gitCommitShaShort:process.env.BITRISE_GIT_COMMIT?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.BITRISE_GIT_BRANCH,gitOriginUrl:n,gitCommitMessage:process.env.BITRISE_GIT_MESSAGE,gitCommitAuthorName:t,githubRepository:o?a:void 0,gitlabProjectPath:i?a:void 0,pipelineId:`${process.env.BITRISE_APP_SLUG}:${process.env.BITRISE_BUILD_SLUG}`}}async function pse(){let r=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:r?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:r?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}function fse(){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:Fi(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:Fi(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 hse(r){let e=[...r.config.gitProtectedBranches??[]];return r.config.gitMainBranch&&e.push(r.config.gitMainBranch),{gitMainBranch:r.config.gitMainBranch,gitProtectedBranches:e}}async function Lf(r,e,t){let n=ise();if(!n)return dse(r,e,t);switch(n){case"GithubActions":return ase(r);case"GitlabCI":return sse(r);case"CircleCI":return lse(r);case"Buildkite":return cse(r);case"AzureDevOps":return use(r);case"GCPCloudBuild":return pse();case"Bitrise":return mse(r);case"Custom":return fse()}}async function gse(r,e,t,n){let o=n,i=n.gitCommitSha;if(!i)return o;let a=n.gitMainBranch;if(a&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp))try{let s=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getMergeBaseCommitFromGitlab",fn:()=>e.getMergeBaseCommitFromGitlab(t,a,i),context:{projectPath:t,mainBranch:a}});o={...o,lastCommitOnMainSha:s.sha,lastCommitOnMainTimestamp:s.committer.date};}catch(s){r.warn({err:s},"Failed to get merge base commit from Gitlab");}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName)try{let s=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getCommitFromGitlab",fn:()=>e.getCommitFromGitlab(t,i),context:{projectPath:t,gitCommitSha:i}});s&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??s.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??s.author.name,gitCommitMessage:o.gitCommitMessage??s.message});}catch(s){r.warn({err:s},"Failed to get commit from Gitlab");}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!o.mergedGitBranchName){let s=n.gitBranchName;try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getMergedBranchFromGitlab",fn:()=>e.getMergedBranchFromGitlab(t,s,i),context:{projectPath:t,branchName:s,gitCommitSha:i}});l.mergedBranch&&(o={...o,mergedGitBranchName:l.mergedBranch});}catch(l){r.warn({err:l},"Failed to get merged branch from Gitlab");}}return o}async function yse(r,e,t,n,o){let i=o,a=o.gitCommitSha;if(!a)return i;let s=o.gitMainBranch;if(s&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getMergeBaseCommitFromGithub",fn:()=>e.getMergeBaseCommitFromGithub(t,n,s,a),context:{owner:t,repo:n,mainBranch:s}});i={...i,lastCommitOnMainSha:l.sha,lastCommitOnMainTimestamp:l.committer.date};}catch(l){r.warn({err:l},"Failed to get merge base commit from GitHub");}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getCommitFromGithub",fn:()=>e.getCommitFromGithub(t,n,a),context:{owner:t,repo:n,gitCommitSha:a}});l&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??l.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??l.author.name,gitCommitMessage:i.gitCommitMessage??l.message});}catch(l){r.warn({err:l},"Failed to get commit from GitHub");}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!i.mergedGitBranchName){let l=o.gitBranchName;try{let c=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getMergedBranchFromGithub",fn:()=>e.getMergedBranchFromGithub(t,n,l,a),context:{owner:t,repo:n,branchName:l,gitCommitSha:a}});c.mergedBranch&&(i={...i,mergedGitBranchName:c.mergedBranch});}catch(c){r.warn({err:c},"Failed to get merged branch from GitHub");}}return i}async function Sse(r,e,t){try{if(t.githubRepository){let[n,o]=t.githubRepository.split("/");return await Mo({logger:r,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitHub",fn:()=>yse(r,e,n,o,t),context:{githubRepository:t.githubRepository}})}else if(t.gitlabProjectPath){let n=t.gitlabProjectPath;return await Mo({logger:r,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitlab",fn:()=>gse(r,e,n,t),context:{gitlabProjectPath:n}})}}catch(n){r.warn({err:n},"Failed to get remote git metadata");}return t}async function bse(r,e,t,n){let o={},i={gitMainBranch:t.config.gitMainBranch};return Mo({logger:r,operation:"getGitMetadata.total",fn:async()=>{let[a,s]=await Promise.all([Mo({logger:r,operation:"getGitMetadata.getConfiguredGitMetadata",fn:()=>hse(t),context:{projectConfigPath:t.configFilePath}}),Mo({logger:r,operation:"getGitMetadata.getEnvironmentGitMetadata",fn:async()=>{let u=await Lf(r,t.config.gitMainBranch,n);return i.ciProvider=u.ciProvider,u},context:i})]),l={...a,...s};o.gitBranchName=l.gitBranchName,o.githubRepository=l.githubRepository,o.gitlabProjectPath=l.gitlabProjectPath,(!l.lastCommitOnMainSha||!l.lastCommitOnMainTimestamp)&&l.gitBranchName===a.gitMainBranch&&(l.lastCommitOnMainSha=l.gitCommitSha,l.lastCommitOnMainTimestamp=l.gitCommitTimestamp);let c=await Mo({logger:r,operation:"getGitMetadata.getRemoteMetadataIfNeeded",fn:()=>Sse(r,e,l),context:{githubRepository:l.githubRepository,gitlabProjectPath:l.gitlabProjectPath,gitBranchName:l.gitBranchName}});return {...a,...s,...c}},context:o})}async function z1(r){try{let e=await B1(r).remote(["show","origin"]);return e?e.match(/HEAD branch: (.*)$/m)?.[1]?.trim():void 0}catch{return}}var XR=new Map;async function Ese(r,e,t){let n,o;try{[n,o]=await Promise.all([Ct(r,vt.raw(["symbolic-ref","--short","-q","HEAD"]).then(s=>s.trim())),Ct(r,vt.revparse(["--verify","HEAD"]).then(s=>s.trim()))]);}catch{return}if(!n||!o)return;let i=`${e.configFilePath}:${e.config.gitMainBranch}:${e.config.gitProtectedBranches?.join(",")}`,a=`${t?.includeHostingUsername}`;return `${n}:${o}:${i}:${a}`}async function Lr(r,e,t,n){let o=await Ese(r,t,n);if(o&&XR.has(o))return r.debug("Using cached git metadata"),XR.get(o);let i=await bse(r,e,t,n);return o&&XR.set(o,i),i}function V1(r,e){let t=`${Ko(e)}.module.yaml`,n=xr__default.join(xr__default.dirname(r),t);if(Tr.existsSync(n))throw new Error(`A conflicting file already exists at the following path: ${n}`);return Tr.renameSync(r,n),n}function pd({content:r,schemaVersion:e,momenticFiles:t,project:n,forceSaveOnNoDiffs:o}){let i=t.mobileModules[r.moduleId]?.fullFilePath,a=t.mobileModules[r.moduleId]?.name;if(!i||!Tr.existsSync(i))throw new Error(`Tried to update mobile module ${r.moduleId} that could not be found on disk`);let{parsed:s}=xa(i),l={...s,...r,schemaVersion:e},c=Kl({fileType:et.MOBILE_MODULE,...Fp.parse(l),steps:Ea(r.platform).array().parse(r.steps)}),u=!!r.name&&r.name!==a,d=diff(c,s);if(d&&Object.keys(d).length===0&&!o&&!u)return;let m=YR.stringify(c);Tr.writeFileSync(i,m,"utf-8");let p;u&&(p=V1(i,r.name)),ws(p||i,n.config);}function H1({moduleId:r,patch:e,momenticFiles:t,project:n,logger:o}){let i=t.mobileModules[r]?.fullFilePath;if(!i)throw new Error(`Tried to update mobile module ${r} that could not be found on disk`);let a=Df(i,o),s={...a,...e},l=Kl({fileType:et.MOBILE_MODULE,...my.parse(s)}),c=diff(l,a);if(c&&Object.keys(c).length===0)return;let u=YR.stringify(l);Tr.writeFileSync(i,u,"utf-8");let d;e.name&&(d=V1(i,e.name)),ws(d||i,n.config);}async function kf({name:r,description:e,enabled:t,platform:n,steps:o,folder:i,project:a}){let s=Ko(r),l=xr__default.join(i,`${s}.module.yaml`),c=v4$1(),{stepsToSave:{steps:u}}=await Dn({platform:n,stepLists:{steps:o}}),d={schemaVersion:Wc,platform:n,moduleId:c,description:e,enabled:t},m={fileType:et.MOBILE_MODULE,...d,steps:u},p=YR.stringify(PD.parse(m));switch(Tr.writeFileSync(l,p,"utf-8"),ws(l,a.config),n){case"ANDROID":return {moduleId:c,platform:n,name:r,description:e||void 0,steps:o};case"IOS":return {moduleId:c,platform:n,name:r,description:e||void 0,steps:o}}}function Df(r,e){let{parsed:t}=xa(r);try{return {...my.parse(t),name:xr__default.basename(r,".module.yaml")}}catch(n){throw e.error({err:n,moduleFilePath:r,existingModule:t},`${r} does not parse as a valid Momentic mobile module`),n}}async function Ql(r,e,t,n){let o=Df(r.fullFilePath,t),i=o.platform==="ANDROID"?n?.android:n?.ios,{resolvedSteps:a}=await HS({platform:o.platform,rawSteps:o.steps,resolvedModuleCache:i||{},onFetchModule:async l=>{let c=e.mobileModules[l]?.fullFilePath;if(!c)throw new Error(`Could not find mobile module with id ${l}`);return Df(c,t)},logger:t,metadata:{id:o.moduleId,schemaVersion:o.schemaVersion}}),s=o.platform==="ANDROID"?{...o,platform:"ANDROID",name:r.name,description:o.description||void 0,steps:a}:{...o,platform:"IOS",name:r.name,description:o.description||void 0,steps:a};return i&&(i[r.id]=cloneDeep(s)),s}async function j1(r,e){let t={},n={};return await Promise.all(Object.values(r.mobileModules).map(async o=>{await Ql(o,r,e,{ios:t,android:n});})),[...Object.values(t),...Object.values(n)]}var nb=v__default.discriminatedUnion("platform",[vy.extend({beforeSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional(),steps:v__default.record(v__default.string(),v__default.unknown()).array(),afterSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional()}),Cy.extend({beforeSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional(),steps:v__default.record(v__default.string(),v__default.unknown()).array(),afterSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional()})]);function ob({name:r,description:e="",settings:t,folder:n,platform:o}){try{yo(r);}catch(d){throw new dn(`${d} when validating the test entity name`)}let a=`${Ko(r)}.test.yaml`,s=xr__default.join(n,a);if(Tr.existsSync(s))throw new Error(`A test named '${r}' already exists at path '${s}'. Choose a different name.`);let l=randomUUID(),c={fileType:et.MOBILE_TEST,id:l,description:e,schemaVersion:_n,platform:o,settings:t,steps:[]},u=YR.stringify(m0.parse(c));return Tr.writeFileSync(s,u,"utf-8"),{fullPath:s,testId:l}}function wse(r){if(!Tr.existsSync(r))throw new Error(`Test file not found: ${r}`);let{parsed:e}=xa(r);if(!e.steps||!Array.isArray(e.steps))throw new Error(`Test ${r} is missing steps`);return e}async function br(r,e,t){let n=wse(r),o;try{o=Ru.parse(n);}catch(a){throw new Error(`Mobile test ${r} is missing metadata or has invalid metadata: ${a}`,{cause:a})}let i={rawStepLists:{steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps},logger:e,testMetadata:o,onFetchModule:async a=>{let s=t.mobileModules[a]?.fullFilePath;if(!s)throw new Error(`Mobile module ${a} not found`);return Df(s,e)}};switch(o.platform){case"ANDROID":{let{resolvedStepLists:a}=await UR({...i,platform:o.platform});return {...o,steps:a.steps,...a.beforeSteps?.length&&{beforeSteps:a.beforeSteps},...a.afterSteps?.length&&{afterSteps:a.afterSteps}}}case"IOS":{let{resolvedStepLists:a}=await UR({...i,platform:o.platform});return {...o,steps:a.steps,...a.beforeSteps?.length&&{beforeSteps:a.beforeSteps},...a.afterSteps?.length&&{afterSteps:a.afterSteps}}}}}async function fd({platform:r,filePath:e,steps:t,beforeSteps:n,afterSteps:o,settings:i,labels:a,folder:s,project:l,momenticFiles:c,schemaVersion:u}){let d=xr__default.isAbsolute(e)?e:xr__default.join(s,e);if(!Tr.existsSync(d))throw new Error(`Test file not found: ${d}`);let{parsed:m}=xa(d),p=nb.parse({...m,schemaVersion:u});if(p.fileType!==et.MOBILE_TEST)throw new Error(`File at '${d}' is not a mobile test (fileType=${p.fileType}).`);if(p.platform!==r)throw new Error(`Platform mismatch. Test at '${d}' is for platform ${p.platform}, but update is for platform ${r}.`);let h=t||n||o?await Dn({platform:p.platform,stepLists:{steps:t??[],beforeSteps:n,afterSteps:o}}):void 0,g=h?.moduleUpdates??[],y={...p,...t?{steps:h?.stepsToSave.steps??[]}:{steps:p.steps},...a!==void 0?{labels:a}:{}};if(n){let b=h?.stepsToSave.beforeSteps;b&&b.length>0?y.beforeSteps=b:delete y.beforeSteps;}else p.beforeSteps&&p.beforeSteps.length>0&&(y.beforeSteps=p.beforeSteps);if(o){let b=h?.stepsToSave.afterSteps;b&&b.length>0?y.afterSteps=b:delete y.afterSteps;}else p.afterSteps&&p.afterSteps.length>0&&(y.afterSteps=p.afterSteps);i&&(y.settings=i);let S=YR.stringify(nb.parse(y));for(let b of g)pd({content:b,schemaVersion:_n,momenticFiles:c,project:l});Tr.writeFileSync(d,S,"utf-8"),ws(d,l.config);}function G1(r,e,t){let n=xr__default.join(t.rootDir,r);if(!Tr.existsSync(n))throw new Error(`Test not found at path '${r}' in project '${t.rootDir}'`);let{parsed:o}=xa(n),i=nb.parse(o),a=xr__default.basename(r,".test.yaml"),s,l;if(e.name&&e.name!==a){let d=`${Ko(e.name)}.test.yaml`;if(s=xr__default.join(xr__default.dirname(r),d),l=xr__default.join(t.rootDir,s),Tr.existsSync(l))throw new Error(`Test with name '${e.name}' already exists at path '${l}'`)}let c={...i,...e};if(delete c.name,c.fileType!==et.MOBILE_TEST)throw new Error(`File at '${n}' is not a mobile test (fileType=${c.fileType}).`);let u=YR.stringify(nb.parse(c));return Tr.writeFileSync(n,u,"utf-8"),l&&l!==n?(Tr.renameSync(n,l),ws(l,t.config)):ws(n,t.config),{newRelativeTestPath:s}}var W1=new Set([".DS_Store","__MACOSX"]),q1={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return "FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return "CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return "RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return "RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return "PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function Rse(r,e,t){if(q1[t]){let i=q1[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var ZR=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. 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(n),this.name="InvalidMomenticResultsPathError";}};function K1(r,e){try{let t=xr__default.join(e,"metadata.json");return Du.parse(JSON.parse(Tr.readFileSync(t,"utf-8")))}catch{throw new ZR(r,e)}}function X1(r,e,t){let n=randomUUID(),o=r.child({runGroupId:n});Tr.rmSync(e,{recursive:!0,force:!0});let i=Tr.readdirSync(t).filter(l=>!W1.has(l)).map(l=>xr__default.join(t,l));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);Tr.mkdirSync(e,{recursive:!0});let a={...K1(t,i[0]),id:n};for(let l of i){let c=xr__default.join(l,"runs");if(!Tr.existsSync(c))continue;let u=K1(t,l);o.info({oldRunGroupId:u.id},"Merging run groups");for(let m in u){if(m==="id")continue;let p=m;a[p]=Rse(a,u,p);}let d=Tr.readdirSync(c);for(let m of d){if(W1.has(m))continue;let p=xr__default.join(c,m),f=xr__default.join(e,"runs",m);Tr.cpSync(p,f,{recursive:!0});}}let s=xr__default.join(e,"metadata.json");Tr.writeFileSync(s,JSON.stringify(a,null,2));}var W="v1",QR="mobile-cli",ec="0.88.1";var xse=9e4,Mse=3,_se=1500,Pse=15e3,kn=class extends Error{status;rawError;constructor(e,t,n,o={}){super(n,o),this.status=e,this.rawError=t;}};async function Ise(r){return r.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var ex=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger;}getHeaders(){let e={"Content-Type":"application/json"};return (e[Py]=ec),(e[ok]=QR),e}async sendRequest(e,t){let{retries:n=Mse,requestTimeoutMs:o=xse,initialRetryDelayMs:i=_se,maxRetryDelayMs:a=Pse,onFailedRequest:s}=t,l=n,c=n,u,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;l>0;)try{return l--,await this.sendSingleRequestHelper(e,t,o)}catch(m){u=m;try{s?.(u);}catch{}if(m instanceof kn&&m.status>=400&&m.status<500)throw m;if(m instanceof Error&&m.name==="AbortError"&&(u=new ms),l===0)throw u;let p=c-l,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 sendSingleRequestHelper(e,t,n){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),n),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s,{once:!0});let l=Date.now(),c={...this.getHeaders(),...t.extraHeaders};try{let u=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:c,signal:i.signal});if(!u.ok){let p=await Ise(u);throw new kn(u.status,p,`Request to ${t.method} ${e} failed with status ${u.status}: ${p}`)}let d;if(u.status===204)d={};else if(t.responseType==="buffer"){let p=await u.arrayBuffer();d=Buffer.from(p);}else {let p=await u.text();try{d=JSON.parse(p);}catch{d=p;}}this.logger&&t.logResponse===!0&&d&&this.logger.debug({result:d,status:u.status,durationMs:Date.now()-l,...o},"Got response from Momentic server");let m=t.responseHeadersObject;return m&&u.headers.forEach((p,f)=>{m[f.toLowerCase()]=p;}),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s);}}},Ui=class extends ex{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode;}getHeaders(){return {...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[nk]:this.mode??""}}};var w$="vercel.ai.error",Ose=Symbol.for(w$),Y1,J1,Lt=class A$ extends(J1=Error,Y1=Ose,J1){constructor({name:e,message:t,cause:n}){super(t),this[Y1]=!0,this.name=e,this.cause=n;}static isInstance(e){return A$.hasMarker(e,w$)}static hasMarker(e,t){let n=Symbol.for(t);return e!=null&&typeof e=="object"&&n in e&&typeof e[n]=="boolean"&&e[n]===!0}},R$="AI_APICallError",x$=`vercel.ai.error.${R$}`,Nse=Symbol.for(x$),Z1,Q1,Zr=class extends(Q1=Lt,Z1=Nse,Q1){constructor({message:r,url:e,requestBodyValues:t,statusCode:n,responseHeaders:o,responseBody:i,cause:a,isRetryable:s=n!=null&&(n===408||n===409||n===429||n>=500),data:l}){super({name:R$,message:r,cause:a}),this[Z1]=!0,this.url=e,this.requestBodyValues=t,this.statusCode=n,this.responseHeaders=o,this.responseBody=i,this.isRetryable=s,this.data=l;}static isInstance(r){return Lt.hasMarker(r,x$)}},M$="AI_EmptyResponseBodyError",_$=`vercel.ai.error.${M$}`,Lse=Symbol.for(_$),e$,t$,P$=class extends(t$=Lt,e$=Lse,t$){constructor({message:r="Empty response body"}={}){super({name:M$,message:r}),this[e$]=!0;}static isInstance(r){return Lt.hasMarker(r,_$)}};function I$(r){return r==null?"unknown error":typeof r=="string"?r:r instanceof Error?r.message:JSON.stringify(r)}var O$="AI_InvalidArgumentError",N$=`vercel.ai.error.${O$}`,Dse=Symbol.for(N$),r$,n$,ib=class extends(n$=Lt,r$=Dse,n$){constructor({message:r,cause:e,argument:t}){super({name:O$,message:r,cause:e}),this[r$]=!0,this.argument=t;}static isInstance(r){return Lt.hasMarker(r,N$)}},L$="AI_InvalidPromptError",D$=`vercel.ai.error.${L$}`,kse=Symbol.for(D$),o$,i$,k$=class extends(i$=Lt,o$=kse,i$){constructor({prompt:r,message:e,cause:t}){super({name:L$,message:`Invalid prompt: ${e}`,cause:t}),this[o$]=!0,this.prompt=r;}static isInstance(r){return Lt.hasMarker(r,D$)}},F$="AI_InvalidResponseDataError",U$=`vercel.ai.error.${F$}`,Fse=Symbol.for(U$),a$,s$,ab=class extends(s$=Lt,a$=Fse,s$){constructor({data:r,message:e=`Invalid response data: ${JSON.stringify(r)}.`}){super({name:F$,message:e}),this[a$]=!0,this.data=r;}static isInstance(r){return Lt.hasMarker(r,U$)}},B$="AI_JSONParseError",z$=`vercel.ai.error.${B$}`,Use=Symbol.for(z$),l$,c$,Ff=class extends(c$=Lt,l$=Use,c$){constructor({text:r,cause:e}){super({name:B$,message:`JSON parsing failed: Text: ${r}.
|
|
194
|
+
`)){let o=n.indexOf("=");if(o===-1)continue;let i=n.slice(0,o),a=n.slice(o+1).trim();t[i]=a;}return t}async function rse(r,e,t){try{let o=t["github.user"]||void 0;if(o)return o}catch{}let n;try{if(e?.startsWith("http://")||e?.startsWith("https://"))n=new URL(e).host;else if(e?.startsWith("git@")){let o=e.indexOf("@"),i=e.indexOf(":",o+1);o!==-1&&i!==-1&&(n=e.slice(o+1,i));}}catch{}if(n=n?.toLowerCase(),!!n&&e?.startsWith("git@")&&n.includes("github"))try{let{stdout:o,stderr:i}=await ese("ssh",["-T","-o","BatchMode=yes",`git@${n}`],{timeout:5e3}),s=`${o??""}${i??""}`.trim().match(/Hi\s+([A-Za-z0-9_-]+)!/);if(s?.[1])return s[1]}catch{return}}async function nse(r,e,t){let n=e?.includes("github.com"),o=e?.includes("gitlab.com");try{if(n)return rse(r,e,t);if(o)return}catch{}}function Nf(r){if(r.startsWith("git@")){let e=r.split(":");if(e.length===2){let t=e[1].replace(".git","").split("/");if(t.length===2){let n=t[0],o=t[1];return `${n}/${o}`}}}else if(r.startsWith("http")||r.startsWith("https")){let t=new URL(r).pathname.split("/").filter(Boolean);if(t.length>=2){let n=t[0],o=t[1].replace(".git","");return `${n}/${o}`}}}function ose(r){if(!(r instanceof Error))return !1;let e=r.message;return e.includes("not a git repository")||e.includes("ENOENT")}async function Ct(r,e){try{return (await e).trim()}catch(t){if(ose(t))return;r.error({err:t},"Failed to run git command");return}}function ise(){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 ase(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=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?Fi(e):void 0,gitBranchName:process.env.GITHUB_HEAD_REF||process.env.GITHUB_REF_NAME,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:process.env.GITHUB_REPOSITORY,pipelineId:process.env.GITHUB_RUN_ID}}async function sse(r){let[e,t,n]=await Promise.all([Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.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?Fi(process.env.CI_COMMIT_TIMESTAMP):void 0,gitBranchName:process.env.CI_COMMIT_BRANCH||process.env.CI_COMMIT_REF_NAME,gitOriginUrl:e,gitCommitMessage:t,gitCommitAuthorName:n,gitlabProjectPath:process.env.CI_PROJECT_PATH,pipelineId:`${process.env.CI_PIPELINE_ID}:${process.env.CI_JOB_ID}`}}async function lse(r){let[e,t,n,o]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),i=process.env.CIRCLE_REPOSITORY_URL??t,a=i?.includes("github.com"),s=i?.includes("gitlab.com"),l=i?Nf(i):void 0;return {ciProvider:"CircleCI",gitCommitSha:process.env.CIRCLE_SHA1,gitCommitShaShort:process.env.CIRCLE_SHA1?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.CIRCLE_BRANCH,gitOriginUrl:i,gitCommitMessage:n,gitCommitAuthorName:o,githubRepository:a?l:void 0,gitlabProjectPath:s?l:void 0,pipelineId:process.env.CIRCLE_PIPELINE_ID}}async function cse(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=process.env.BUILDKITE_REPO,i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Nf(o):void 0;return {ciProvider:"Buildkite",gitCommitSha:process.env.BUILDKITE_COMMIT,gitCommitShaShort:process.env.BUILDKITE_COMMIT?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.BUILDKITE_BRANCH,gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,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 use(r){let[e,t,n]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),o=process.env["Build.Repository.Uri"],i=o?.includes("github.com"),a=o?.includes("gitlab.com"),s=o?Nf(o):void 0;return {ciProvider:"AzureDevOps",gitCommitSha:process.env["Build.SourceVersion"],gitCommitShaShort:process.env["Build.SourceVersion"]?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env["System.PullRequest.SourceBranch"]??process.env["Build.SourceBranchName"],gitOriginUrl:o,gitCommitMessage:t,gitCommitAuthorName:n,githubRepository:i?s:void 0,gitlabProjectPath:a?s:void 0,pipelineId:`${process.env["System.JobId"]}:${process.env["System.JobAttempt"]}`}}async function dse(r,e,t){let[n,o,i,a,s,l,c,u,d]=await Promise.all([Ct(r,vt.revparse(["HEAD"])),Ct(r,vt.revparse(["--short","HEAD"])),Ct(r,vt.revparse(["--abbrev-ref","HEAD"])),Ct(r,vt.listRemote(["--get-url","origin"])),Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%B"])),Ct(r,vt.show(["-s","--pretty=%an"])),e?Ct(r,vt.raw(["merge-base","--fork-point",e])):Promise.resolve(void 0),tse(r)]),m=u||(e?await Ct(r,vt.raw(["merge-base",e,"HEAD"])):void 0),p=m?await Ct(r,vt.show(["--no-patch","--format=%ci",m])):void 0,f=a?.includes("github.com"),h=a?.includes("gitlab.com"),g=a?Nf(a):void 0,y=d["user.email"]||void 0,S=d["user.name"]||void 0,b=d["user.username"]||void 0,C=d["github.user"]||void 0,M=(t?.includeHostingUsername??!0?await nse(r,a,d):void 0)??b??C??void 0;return {ciProvider:"none",gitCommitSha:n,gitCommitShaShort:o,gitBranchName:i,gitOriginUrl:a,gitCommitTimestamp:s?Fi(s):void 0,gitCommitMessage:l,gitCommitAuthorName:c,gitLocalUsername:M,gitLocalEmail:y,gitLocalName:S,lastCommitOnMainSha:m,lastCommitOnMainTimestamp:p?Fi(p):void 0,githubRepository:f?g:void 0,gitlabProjectPath:h?g:void 0,pipelineId:void 0}}async function mse(r){let[e,t]=await Promise.all([Ct(r,vt.show(["--no-patch","--format=%ci"])),Ct(r,vt.show(["-s","--pretty=%an"]))]),n=process.env.GIT_REPOSITORY_URL,o=n?.includes("github.com"),i=n?.includes("gitlab.com"),a=n?Nf(n):void 0;return {ciProvider:"Bitrise",gitCommitSha:process.env.BITRISE_GIT_COMMIT,gitCommitShaShort:process.env.BITRISE_GIT_COMMIT?.slice(0,6),gitCommitTimestamp:e?Fi(e):void 0,gitBranchName:process.env.BITRISE_GIT_BRANCH,gitOriginUrl:n,gitCommitMessage:process.env.BITRISE_GIT_MESSAGE,gitCommitAuthorName:t,githubRepository:o?a:void 0,gitlabProjectPath:i?a:void 0,pipelineId:`${process.env.BITRISE_APP_SLUG}:${process.env.BITRISE_BUILD_SLUG}`}}async function pse(){let r=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:r?process.env._HEAD_REPO_URL:void 0,gitCommitTimestamp:void 0,gitCommitMessage:void 0,gitCommitAuthorName:void 0,githubRepository:r?process.env.REPO_FULL_NAME:void 0,pipelineId:`${process.env.PROJECT_ID}:${process.env.BUILD_ID}`}}function fse(){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:Fi(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:Fi(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 hse(r){let e=[...r.config.gitProtectedBranches??[]];return r.config.gitMainBranch&&e.push(r.config.gitMainBranch),{gitMainBranch:r.config.gitMainBranch,gitProtectedBranches:e}}async function Lf(r,e,t){let n=ise();if(!n)return dse(r,e,t);switch(n){case"GithubActions":return ase(r);case"GitlabCI":return sse(r);case"CircleCI":return lse(r);case"Buildkite":return cse(r);case"AzureDevOps":return use(r);case"GCPCloudBuild":return pse();case"Bitrise":return mse(r);case"Custom":return fse()}}async function gse(r,e,t,n){let o=n,i=n.gitCommitSha;if(!i)return o;let a=n.gitMainBranch;if(a&&(!o.lastCommitOnMainSha||!o.lastCommitOnMainTimestamp))try{let s=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getMergeBaseCommitFromGitlab",fn:()=>e.getMergeBaseCommitFromGitlab(t,a,i),context:{projectPath:t,mainBranch:a}});o={...o,lastCommitOnMainSha:s.sha,lastCommitOnMainTimestamp:s.committer.date};}catch(s){r.warn({err:s},"Failed to get merge base commit from Gitlab");}if(!o.gitCommitTimestamp||!o.gitCommitAuthorName||!o.gitCommitMessage||!o.gitCommitAuthorName)try{let s=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getCommitFromGitlab",fn:()=>e.getCommitFromGitlab(t,i),context:{projectPath:t,gitCommitSha:i}});s&&(o={...o,gitCommitTimestamp:o.gitCommitTimestamp??s.committer.date,gitCommitAuthorName:o.gitCommitAuthorName??s.author.name,gitCommitMessage:o.gitCommitMessage??s.message});}catch(s){r.warn({err:s},"Failed to get commit from Gitlab");}if(n.gitBranchName&&n.gitBranchName===n.gitMainBranch&&!o.mergedGitBranchName){let s=n.gitBranchName;try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitlab.getMergedBranchFromGitlab",fn:()=>e.getMergedBranchFromGitlab(t,s,i),context:{projectPath:t,branchName:s,gitCommitSha:i}});l.mergedBranch&&(o={...o,mergedGitBranchName:l.mergedBranch});}catch(l){r.warn({err:l},"Failed to get merged branch from Gitlab");}}return o}async function yse(r,e,t,n,o){let i=o,a=o.gitCommitSha;if(!a)return i;let s=o.gitMainBranch;if(s&&(!i.lastCommitOnMainSha||!i.lastCommitOnMainTimestamp))try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getMergeBaseCommitFromGithub",fn:()=>e.getMergeBaseCommitFromGithub(t,n,s,a),context:{owner:t,repo:n,mainBranch:s}});i={...i,lastCommitOnMainSha:l.sha,lastCommitOnMainTimestamp:l.committer.date};}catch(l){r.warn({err:l},"Failed to get merge base commit from GitHub");}if(!i.gitCommitTimestamp||!i.gitCommitAuthorName||!i.gitCommitMessage||!i.gitCommitAuthorName)try{let l=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getCommitFromGithub",fn:()=>e.getCommitFromGithub(t,n,a),context:{owner:t,repo:n,gitCommitSha:a}});l&&(i={...i,gitCommitTimestamp:i.gitCommitTimestamp??l.committer.date,gitCommitAuthorName:i.gitCommitAuthorName??l.author.name,gitCommitMessage:i.gitCommitMessage??l.message});}catch(l){r.warn({err:l},"Failed to get commit from GitHub");}if(o.gitBranchName&&o.gitBranchName===o.gitMainBranch&&!i.mergedGitBranchName){let l=o.gitBranchName;try{let c=await Mo({logger:r,operation:"getRemoteMetadataFromGitHub.getMergedBranchFromGithub",fn:()=>e.getMergedBranchFromGithub(t,n,l,a),context:{owner:t,repo:n,branchName:l,gitCommitSha:a}});c.mergedBranch&&(i={...i,mergedGitBranchName:c.mergedBranch});}catch(c){r.warn({err:c},"Failed to get merged branch from GitHub");}}return i}async function Sse(r,e,t){try{if(t.githubRepository){let[n,o]=t.githubRepository.split("/");return await Mo({logger:r,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitHub",fn:()=>yse(r,e,n,o,t),context:{githubRepository:t.githubRepository}})}else if(t.gitlabProjectPath){let n=t.gitlabProjectPath;return await Mo({logger:r,operation:"getRemoteMetadataIfNeeded.getRemoteMetadataFromGitlab",fn:()=>gse(r,e,n,t),context:{gitlabProjectPath:n}})}}catch(n){r.warn({err:n},"Failed to get remote git metadata");}return t}async function bse(r,e,t,n){let o={},i={gitMainBranch:t.config.gitMainBranch};return Mo({logger:r,operation:"getGitMetadata.total",fn:async()=>{let[a,s]=await Promise.all([Mo({logger:r,operation:"getGitMetadata.getConfiguredGitMetadata",fn:()=>hse(t),context:{projectConfigPath:t.configFilePath}}),Mo({logger:r,operation:"getGitMetadata.getEnvironmentGitMetadata",fn:async()=>{let u=await Lf(r,t.config.gitMainBranch,n);return i.ciProvider=u.ciProvider,u},context:i})]),l={...a,...s};o.gitBranchName=l.gitBranchName,o.githubRepository=l.githubRepository,o.gitlabProjectPath=l.gitlabProjectPath,(!l.lastCommitOnMainSha||!l.lastCommitOnMainTimestamp)&&l.gitBranchName===a.gitMainBranch&&(l.lastCommitOnMainSha=l.gitCommitSha,l.lastCommitOnMainTimestamp=l.gitCommitTimestamp);let c=await Mo({logger:r,operation:"getGitMetadata.getRemoteMetadataIfNeeded",fn:()=>Sse(r,e,l),context:{githubRepository:l.githubRepository,gitlabProjectPath:l.gitlabProjectPath,gitBranchName:l.gitBranchName}});return {...a,...s,...c}},context:o})}async function z1(r){try{let e=await B1(r).remote(["show","origin"]);return e?e.match(/HEAD branch: (.*)$/m)?.[1]?.trim():void 0}catch{return}}var XR=new Map;async function Ese(r,e,t){let n,o;try{[n,o]=await Promise.all([Ct(r,vt.raw(["symbolic-ref","--short","-q","HEAD"]).then(s=>s.trim())),Ct(r,vt.revparse(["--verify","HEAD"]).then(s=>s.trim()))]);}catch{return}if(!n||!o)return;let i=`${e.configFilePath}:${e.config.gitMainBranch}:${e.config.gitProtectedBranches?.join(",")}`,a=`${t?.includeHostingUsername}`;return `${n}:${o}:${i}:${a}`}async function Lr(r,e,t,n){let o=await Ese(r,t,n);if(o&&XR.has(o))return r.debug("Using cached git metadata"),XR.get(o);let i=await bse(r,e,t,n);return o&&XR.set(o,i),i}function V1(r,e){let t=`${Ko(e)}.module.yaml`,n=xr__default.join(xr__default.dirname(r),t);if(Tr.existsSync(n))throw new Error(`A conflicting file already exists at the following path: ${n}`);return Tr.renameSync(r,n),n}function pd({content:r,schemaVersion:e,momenticFiles:t,project:n,forceSaveOnNoDiffs:o}){let i=t.mobileModules[r.moduleId]?.fullFilePath,a=t.mobileModules[r.moduleId]?.name;if(!i||!Tr.existsSync(i))throw new Error(`Tried to update mobile module ${r.moduleId} that could not be found on disk`);let{parsed:s}=xa(i),l={...s,...r,schemaVersion:e},c=Kl({fileType:et.MOBILE_MODULE,...Fp.parse(l),steps:Ea(r.platform).array().parse(r.steps)}),u=!!r.name&&r.name!==a,d=diff(c,s);if(d&&Object.keys(d).length===0&&!o&&!u)return;let m=YR.stringify(c);Tr.writeFileSync(i,m,"utf-8");let p;u&&(p=V1(i,r.name)),ws(p||i,n.config);}function H1({moduleId:r,patch:e,momenticFiles:t,project:n,logger:o}){let i=t.mobileModules[r]?.fullFilePath;if(!i)throw new Error(`Tried to update mobile module ${r} that could not be found on disk`);let a=Df(i,o),s={...a,...e},l=Kl({fileType:et.MOBILE_MODULE,...my.parse(s)}),c=diff(l,a);if(c&&Object.keys(c).length===0)return;let u=YR.stringify(l);Tr.writeFileSync(i,u,"utf-8");let d;e.name&&(d=V1(i,e.name)),ws(d||i,n.config);}async function kf({name:r,description:e,enabled:t,platform:n,steps:o,folder:i,project:a}){let s=Ko(r),l=xr__default.join(i,`${s}.module.yaml`),c=v4$1(),{stepsToSave:{steps:u}}=await Dn({platform:n,stepLists:{steps:o}}),d={schemaVersion:Wc,platform:n,moduleId:c,description:e,enabled:t},m={fileType:et.MOBILE_MODULE,...d,steps:u},p=YR.stringify(PD.parse(m));switch(Tr.writeFileSync(l,p,"utf-8"),ws(l,a.config),n){case"ANDROID":return {moduleId:c,platform:n,name:r,description:e||void 0,steps:o};case"IOS":return {moduleId:c,platform:n,name:r,description:e||void 0,steps:o}}}function Df(r,e){let{parsed:t}=xa(r);try{return {...my.parse(t),name:xr__default.basename(r,".module.yaml")}}catch(n){throw e.error({err:n,moduleFilePath:r,existingModule:t},`${r} does not parse as a valid Momentic mobile module`),n}}async function Ql(r,e,t,n){let o=Df(r.fullFilePath,t),i=o.platform==="ANDROID"?n?.android:n?.ios,{resolvedSteps:a}=await HS({platform:o.platform,rawSteps:o.steps,resolvedModuleCache:i||{},onFetchModule:async l=>{let c=e.mobileModules[l]?.fullFilePath;if(!c)throw new Error(`Could not find mobile module with id ${l}`);return Df(c,t)},logger:t,metadata:{id:o.moduleId,schemaVersion:o.schemaVersion}}),s=o.platform==="ANDROID"?{...o,platform:"ANDROID",name:r.name,description:o.description||void 0,steps:a}:{...o,platform:"IOS",name:r.name,description:o.description||void 0,steps:a};return i&&(i[r.id]=cloneDeep(s)),s}async function j1(r,e){let t={},n={};return await Promise.all(Object.values(r.mobileModules).map(async o=>{await Ql(o,r,e,{ios:t,android:n});})),[...Object.values(t),...Object.values(n)]}var nb=v__default.discriminatedUnion("platform",[vy.extend({beforeSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional(),steps:v__default.record(v__default.string(),v__default.unknown()).array(),afterSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional()}),Cy.extend({beforeSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional(),steps:v__default.record(v__default.string(),v__default.unknown()).array(),afterSteps:v__default.record(v__default.string(),v__default.unknown()).array().optional()})]);function ob({name:r,description:e="",settings:t,folder:n,platform:o}){try{yo(r);}catch(d){throw new dn(`${d} when validating the test entity name`)}let a=`${Ko(r)}.test.yaml`,s=xr__default.join(n,a);if(Tr.existsSync(s))throw new Error(`A test named '${r}' already exists at path '${s}'. Choose a different name.`);let l=randomUUID(),c={fileType:et.MOBILE_TEST,id:l,description:e,schemaVersion:_n,platform:o,settings:t,steps:[]},u=YR.stringify(m0.parse(c));return Tr.writeFileSync(s,u,"utf-8"),{fullPath:s,testId:l}}function wse(r){if(!Tr.existsSync(r))throw new Error(`Test file not found: ${r}`);let{parsed:e}=xa(r);if(!e.steps||!Array.isArray(e.steps))throw new Error(`Test ${r} is missing steps`);return e}async function br(r,e,t){let n=wse(r),o;try{o=Ru.parse(n);}catch(a){throw new Error(`Mobile test ${r} is missing metadata or has invalid metadata: ${a}`,{cause:a})}let i={rawStepLists:{steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps},logger:e,testMetadata:o,onFetchModule:async a=>{let s=t.mobileModules[a]?.fullFilePath;if(!s)throw new Error(`Mobile module ${a} not found`);return Df(s,e)}};switch(o.platform){case"ANDROID":{let{resolvedStepLists:a}=await UR({...i,platform:o.platform});return {...o,steps:a.steps,...a.beforeSteps?.length&&{beforeSteps:a.beforeSteps},...a.afterSteps?.length&&{afterSteps:a.afterSteps}}}case"IOS":{let{resolvedStepLists:a}=await UR({...i,platform:o.platform});return {...o,steps:a.steps,...a.beforeSteps?.length&&{beforeSteps:a.beforeSteps},...a.afterSteps?.length&&{afterSteps:a.afterSteps}}}}}async function fd({platform:r,filePath:e,steps:t,beforeSteps:n,afterSteps:o,settings:i,labels:a,folder:s,project:l,momenticFiles:c,schemaVersion:u}){let d=xr__default.isAbsolute(e)?e:xr__default.join(s,e);if(!Tr.existsSync(d))throw new Error(`Test file not found: ${d}`);let{parsed:m}=xa(d),p=nb.parse({...m,schemaVersion:u});if(p.fileType!==et.MOBILE_TEST)throw new Error(`File at '${d}' is not a mobile test (fileType=${p.fileType}).`);if(p.platform!==r)throw new Error(`Platform mismatch. Test at '${d}' is for platform ${p.platform}, but update is for platform ${r}.`);let h=t||n||o?await Dn({platform:p.platform,stepLists:{steps:t??[],beforeSteps:n,afterSteps:o}}):void 0,g=h?.moduleUpdates??[],y={...p,...t?{steps:h?.stepsToSave.steps??[]}:{steps:p.steps},...a!==void 0?{labels:a}:{}};if(n){let b=h?.stepsToSave.beforeSteps;b&&b.length>0?y.beforeSteps=b:delete y.beforeSteps;}else p.beforeSteps&&p.beforeSteps.length>0&&(y.beforeSteps=p.beforeSteps);if(o){let b=h?.stepsToSave.afterSteps;b&&b.length>0?y.afterSteps=b:delete y.afterSteps;}else p.afterSteps&&p.afterSteps.length>0&&(y.afterSteps=p.afterSteps);i&&(y.settings=i);let S=YR.stringify(nb.parse(y));for(let b of g)pd({content:b,schemaVersion:_n,momenticFiles:c,project:l});Tr.writeFileSync(d,S,"utf-8"),ws(d,l.config);}function G1(r,e,t){let n=xr__default.join(t.rootDir,r);if(!Tr.existsSync(n))throw new Error(`Test not found at path '${r}' in project '${t.rootDir}'`);let{parsed:o}=xa(n),i=nb.parse(o),a=xr__default.basename(r,".test.yaml"),s,l;if(e.name&&e.name!==a){let d=`${Ko(e.name)}.test.yaml`;if(s=xr__default.join(xr__default.dirname(r),d),l=xr__default.join(t.rootDir,s),Tr.existsSync(l))throw new Error(`Test with name '${e.name}' already exists at path '${l}'`)}let c={...i,...e};if(delete c.name,c.fileType!==et.MOBILE_TEST)throw new Error(`File at '${n}' is not a mobile test (fileType=${c.fileType}).`);let u=YR.stringify(nb.parse(c));return Tr.writeFileSync(n,u,"utf-8"),l&&l!==n?(Tr.renameSync(n,l),ws(l,t.config)):ws(n,t.config),{newRelativeTestPath:s}}var W1=new Set([".DS_Store","__MACOSX"]),q1={status:(r,e)=>{if(r.status===e.status)return r.status;if(r.status==="FAILED"||e.status==="FAILED")return "FAILED";if(r.status==="CANCELLED"||e.status==="CANCELLED")return "CANCELLED";if(r.status==="RETRYING"||e.status==="RETRYING")return "RETRYING";if(r.status==="RUNNING"||e.status==="RUNNING")return "RUNNING";if(r.status==="PENDING"||e.status==="PENDING")return "PENDING";throw new Error(`Invalid run status merge: ${r.status} and ${e.status}`)},startedAt:(r,e)=>r.startedAt<e.startedAt?r.startedAt:e.startedAt,updatedAt:(r,e)=>r.updatedAt>e.updatedAt?r.updatedAt:e.updatedAt,finishedAt:(r,e)=>!r.finishedAt||!e.finishedAt?new Date:r.finishedAt>e.finishedAt?r.finishedAt:e.finishedAt,gitCommitTimestamp:(r,e)=>{if(!(!r&&!e)){if(!r.gitCommitTimestamp||!e.gitCommitTimestamp||r.gitCommitTimestamp.getTime()!==e.gitCommitTimestamp.getTime())throw new Error(`Git commit timestamps must match to be merged: ${r.gitCommitTimestamp} and ${e.gitCommitTimestamp}`);return r.gitCommitTimestamp}},pipelineId:(r,e)=>r.pipelineId===e.pipelineId?r.pipelineId:!r.pipelineId&&e.pipelineId?e.pipelineId:!e.pipelineId&&r.pipelineId?r.pipelineId:r.startedAt<e.startedAt?e.pipelineId:r.pipelineId,labels:(r,e)=>{let t=new Set([...r.labels??[],...e.labels??[]]);return Array.from(t)}};function Rse(r,e,t){if(q1[t]){let i=q1[t];return i(r,e)}let n=r[t],o=e[t];if(n!==o)throw new Error(`Metadata values for key "${t}" do not match: "${n}" vs "${o}"`);return n}var ZR=class extends Error{constructor(e,t){let n=`${e} contains invalid Momentic results: ${t}. 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(n),this.name="InvalidMomenticResultsPathError";}};function K1(r,e){try{let t=xr__default.join(e,"metadata.json");return Du.parse(JSON.parse(Tr.readFileSync(t,"utf-8")))}catch{throw new ZR(r,e)}}function X1(r,e,t){let n=randomUUID(),o=r.child({runGroupId:n});Tr.rmSync(e,{recursive:!0,force:!0});let i=Tr.readdirSync(t).filter(l=>!W1.has(l)).map(l=>xr__default.join(t,l));if(i.length===0)throw new Error(`No run groups found in results path: ${t}`);Tr.mkdirSync(e,{recursive:!0});let a={...K1(t,i[0]),id:n};for(let l of i){let c=xr__default.join(l,"runs");if(!Tr.existsSync(c))continue;let u=K1(t,l);o.info({oldRunGroupId:u.id},"Merging run groups");for(let m in u){if(m==="id")continue;let p=m;a[p]=Rse(a,u,p);}let d=Tr.readdirSync(c);for(let m of d){if(W1.has(m))continue;let p=xr__default.join(c,m),f=xr__default.join(e,"runs",m);Tr.cpSync(p,f,{recursive:!0});}}let s=xr__default.join(e,"metadata.json");Tr.writeFileSync(s,JSON.stringify(a,null,2));}var W="v1",QR="mobile-cli",ec="0.88.2";var xse=9e4,Mse=3,_se=1500,Pse=15e3,kn=class extends Error{status;rawError;constructor(e,t,n,o={}){super(n,o),this.status=e,this.rawError=t;}};async function Ise(r){return r.text().then(e=>{try{return JSON.parse(e).error}catch{return e}})}var ex=class{baseUrl;logger;constructor(e){this.baseUrl=e.baseUrl,this.logger=e.logger;}getHeaders(){let e={"Content-Type":"application/json"};return (e[Py]=ec),(e[ok]=QR),e}async sendRequest(e,t){let{retries:n=Mse,requestTimeoutMs:o=xse,initialRetryDelayMs:i=_se,maxRetryDelayMs:a=Pse,onFailedRequest:s}=t,l=n,c=n,u,d={path:e,baseUrl:this.baseUrl,method:t.method};for(;l>0;)try{return l--,await this.sendSingleRequestHelper(e,t,o)}catch(m){u=m;try{s?.(u);}catch{}if(m instanceof kn&&m.status>=400&&m.status<500)throw m;if(m instanceof Error&&m.name==="AbortError"&&(u=new ms),l===0)throw u;let p=c-l,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 sendSingleRequestHelper(e,t,n){let o={path:e,baseUrl:this.baseUrl,method:t.method},i=new AbortController,a=setTimeout(()=>i.abort(),n),s=()=>i.abort();t.signal&&t.signal.addEventListener("abort",s,{once:!0});let l=Date.now(),c={...this.getHeaders(),...t.extraHeaders};try{let u=await fetch(`${this.baseUrl}${e}`,{method:t.method,body:t.body?JSON.stringify(t.body):void 0,headers:c,signal:i.signal});if(!u.ok){let p=await Ise(u);throw new kn(u.status,p,`Request to ${t.method} ${e} failed with status ${u.status}: ${p}`)}let d;if(u.status===204)d={};else if(t.responseType==="buffer"){let p=await u.arrayBuffer();d=Buffer.from(p);}else {let p=await u.text();try{d=JSON.parse(p);}catch{d=p;}}this.logger&&t.logResponse===!0&&d&&this.logger.debug({result:d,status:u.status,durationMs:Date.now()-l,...o},"Got response from Momentic server");let m=t.responseHeadersObject;return m&&u.headers.forEach((p,f)=>{m[f.toLowerCase()]=p;}),d}finally{clearTimeout(a),t.signal&&t.signal.removeEventListener("abort",s);}}},Ui=class extends ex{apiKey;mode;constructor(e){super(e),this.apiKey=e.apiKey,this.mode=e.mode;}getHeaders(){return {...super.getHeaders(),Authorization:`Bearer ${this.apiKey}`,[nk]:this.mode??""}}};var w$="vercel.ai.error",Ose=Symbol.for(w$),Y1,J1,Lt=class A$ extends(J1=Error,Y1=Ose,J1){constructor({name:e,message:t,cause:n}){super(t),this[Y1]=!0,this.name=e,this.cause=n;}static isInstance(e){return A$.hasMarker(e,w$)}static hasMarker(e,t){let n=Symbol.for(t);return e!=null&&typeof e=="object"&&n in e&&typeof e[n]=="boolean"&&e[n]===!0}},R$="AI_APICallError",x$=`vercel.ai.error.${R$}`,Nse=Symbol.for(x$),Z1,Q1,Zr=class extends(Q1=Lt,Z1=Nse,Q1){constructor({message:r,url:e,requestBodyValues:t,statusCode:n,responseHeaders:o,responseBody:i,cause:a,isRetryable:s=n!=null&&(n===408||n===409||n===429||n>=500),data:l}){super({name:R$,message:r,cause:a}),this[Z1]=!0,this.url=e,this.requestBodyValues=t,this.statusCode=n,this.responseHeaders=o,this.responseBody=i,this.isRetryable=s,this.data=l;}static isInstance(r){return Lt.hasMarker(r,x$)}},M$="AI_EmptyResponseBodyError",_$=`vercel.ai.error.${M$}`,Lse=Symbol.for(_$),e$,t$,P$=class extends(t$=Lt,e$=Lse,t$){constructor({message:r="Empty response body"}={}){super({name:M$,message:r}),this[e$]=!0;}static isInstance(r){return Lt.hasMarker(r,_$)}};function I$(r){return r==null?"unknown error":typeof r=="string"?r:r instanceof Error?r.message:JSON.stringify(r)}var O$="AI_InvalidArgumentError",N$=`vercel.ai.error.${O$}`,Dse=Symbol.for(N$),r$,n$,ib=class extends(n$=Lt,r$=Dse,n$){constructor({message:r,cause:e,argument:t}){super({name:O$,message:r,cause:e}),this[r$]=!0,this.argument=t;}static isInstance(r){return Lt.hasMarker(r,N$)}},L$="AI_InvalidPromptError",D$=`vercel.ai.error.${L$}`,kse=Symbol.for(D$),o$,i$,k$=class extends(i$=Lt,o$=kse,i$){constructor({prompt:r,message:e,cause:t}){super({name:L$,message:`Invalid prompt: ${e}`,cause:t}),this[o$]=!0,this.prompt=r;}static isInstance(r){return Lt.hasMarker(r,D$)}},F$="AI_InvalidResponseDataError",U$=`vercel.ai.error.${F$}`,Fse=Symbol.for(U$),a$,s$,ab=class extends(s$=Lt,a$=Fse,s$){constructor({data:r,message:e=`Invalid response data: ${JSON.stringify(r)}.`}){super({name:F$,message:e}),this[a$]=!0,this.data=r;}static isInstance(r){return Lt.hasMarker(r,U$)}},B$="AI_JSONParseError",z$=`vercel.ai.error.${B$}`,Use=Symbol.for(z$),l$,c$,Ff=class extends(c$=Lt,l$=Use,c$){constructor({text:r,cause:e}){super({name:B$,message:`JSON parsing failed: Text: ${r}.
|
|
195
195
|
Error message: ${I$(e)}`,cause:e}),this[l$]=!0,this.text=r;}static isInstance(r){return Lt.hasMarker(r,z$)}},$$="AI_LoadAPIKeyError",V$=`vercel.ai.error.${$$}`,Bse=Symbol.for(V$),u$,d$,Uf=class extends(d$=Lt,u$=Bse,d$){constructor({message:r}){super({name:$$,message:r}),this[u$]=!0;}static isInstance(r){return Lt.hasMarker(r,V$)}},X$="AI_TooManyEmbeddingValuesForCallError",Y$=`vercel.ai.error.${X$}`,Hse=Symbol.for(Y$),S$,b$,J$=class extends(b$=Lt,S$=Hse,b$){constructor(r){super({name:X$,message:`Too many values for a single embedding call. The ${r.provider} model "${r.modelId}" can only embed up to ${r.maxEmbeddingsPerCall} values per call, but ${r.values.length} values were provided.`}),this[S$]=!0,this.provider=r.provider,this.modelId=r.modelId,this.maxEmbeddingsPerCall=r.maxEmbeddingsPerCall,this.values=r.values;}static isInstance(r){return Lt.hasMarker(r,Y$)}},Z$="AI_TypeValidationError",Q$=`vercel.ai.error.${Z$}`,jse=Symbol.for(Q$),E$,T$,Ms=class tx extends(T$=Lt,E$=jse,T$){constructor({value:e,cause:t}){super({name:Z$,message:`Type validation failed: Value: ${JSON.stringify(e)}.
|
|
196
196
|
Error message: ${I$(t)}`,cause:t}),this[E$]=!0,this.value=e;}static isInstance(e){return Lt.hasMarker(e,Q$)}static wrap({value:e,cause:t}){return tx.isInstance(t)&&t.value===e?t:new tx({value:e,cause:t})}},eV="AI_UnsupportedFunctionalityError",tV=`vercel.ai.error.${eV}`,Gse=Symbol.for(tV),v$,C$,Fn=class extends(C$=Lt,v$=Gse,C$){constructor({functionality:r,message:e=`'${r}' functionality not supported.`}){super({name:eV,message:e}),this[v$]=!0,this.functionality=r;}static isInstance(r){return Lt.hasMarker(r,tV)}};var sb=class extends Error{constructor(e,t){super(e),this.name="ParseError",this.type=t.type,this.field=t.field,this.value=t.value,this.line=t.line;}};function rx(r){}function rV(r){if(typeof r=="function")throw new TypeError("`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?");let{onEvent:e=rx,onError:t=rx,onRetry:n=rx,onComment:o}=r,i="",a=!0,s,l="",c="";function u(h){let g=a?h.replace(/^\xEF\xBB\xBF/,""):h,[y,S]=Wse(`${i}${g}`);for(let b of y)d(b);i=S,a=!1;}function d(h){if(h===""){p();return}if(h.startsWith(":")){o&&o(h.slice(h.startsWith(": ")?2:1));return}let g=h.indexOf(":");if(g!==-1){let y=h.slice(0,g),S=h[g+1]===" "?2:1,b=h.slice(g+S);m(y,b,h);return}m(h,"",h);}function m(h,g,y){switch(h){case"event":c=g;break;case"data":l=`${l}${g}
|
|
197
197
|
`;break;case"id":s=g.includes("\0")?void 0:g;break;case"retry":/^\d+$/.test(g)?n(parseInt(g,10)):t(new sb(`Invalid \`retry\` value: "${g}"`,{type:"invalid-retry",value:g,line:y}));break;default:t(new sb(`Unknown field "${h.length>20?`${h.slice(0,20)}\u2026`:h}"`,{type:"unknown-field",field:h,value:g,line:y}));break}}function p(){l.length>0&&e({id:s,event:c||void 0,data:l.endsWith(`
|
|
@@ -5207,7 +5207,7 @@ ${r}`;case"ELEMENT_CHECK":return `${UG}
|
|
|
5207
5207
|
${r}`;default:return r}}async function Do({frameConfig:r,action:e,browser:t}){let n=t.getActiveFrameConfig();r?t.setActiveFrameConfig(r):n?.type==="auto"&&t.setActiveFrameConfig(void 0);try{return await e()}finally{t.setActiveFrameConfig(n);}}var lhe=["NAVIGATE","NEW_TAB","CLOSE_TAB","TAB","REFRESH","WAIT_FOR_URL"];async function $G({beforeUrl:r,beforePages:e,browser:t,command:n,logger:o}){if(lhe.includes(n.type))return;await ur().startAsyncSpan("AUTO_FOLLOW_NEW_TABS",async a=>{let c=("cache"in n&&n.cache&&"target"in n.cache?n.cache.target:void 0)?.nodeOnlySerializedHtml?.includes("<a")??!1?300:3e3,u=Date.now(),d=0;for(o.info({command:n.type,beforePages:e,beforeUrl:r,timeout:c},"Checking for new tabs to auto-follow");d===0||Date.now()-u<c;){await te(250),d++;let m=(await t.getOpenPages()).map(f=>f.url),p=t.url();if(m.length!==e.length)for(let f=m.length-1;f>=e.length;f--){let h=m[f];if(Cs(h,o)&&h!==r&&h!==p){o.info({beforePages:e,afterPages:m,beforeUrl:r},"Auto-following new tab after preset action"),await t.switchToPage({type:"INDEX",index:String(f)}),a.result={followed:!0};return}}}a.result={followed:!1};});}async function Hs(r,e={}){let t=await r.getBrowserState(e);return {serializedTree:t.serialize(e.serializationOpts),tree:t}}var VG=r=>!!r&&Lc(r),HG=r=>{let{cache:e,description:t,disableSecondaryCacheResolution:n,logger:o}=r,i=e,a=!1,s;return i&&n&&i.targetSource==="HEURISTIC_HEALED"&&(a=!0,s="Heuristic healed cache incompatible",i=void 0),i?.inputDescription&&!BG(t,i.inputDescription)&&(o.warn({old:i.inputDescription,new:t},"Target cache was generated with a different description, clearing it automatically"),a=!0,s="Description changed",i=void 0),{cache:i,cacheBustedBeforeAction:a,cacheBustReason:s}};var GG={minChunkTokenCount:1e4,acceptableChunkTokenCount:25e3,maxChunkTokenCount:5e4,maxLineLength:4e3},jG=/<(\S+) id="(\d+)".*?>/g,che=/(<\/(\S+)>)|(<(\S+).*?\/>)/g,WG=["h1","h2","section","footer","nav","aside","form","label","dialog"],uhe=[...WG,"span","div","h3"],dhe=["table","select","form","ul","ol","menu","pre","code","dialog"],mhe=["table","form","dialog","nav","section","ul","select"];function qG(r){return phe(r)}function phe({logger:r,serializedTree:e,options:t}){let{minChunkTokenCount:n,acceptableChunkTokenCount:o,maxChunkTokenCount:i,maxLineLength:a}=t,s=[],l=e.split(`
|
|
5208
5208
|
`),c=0,u=[],d=0,m=[],p=[],f=!1;for(;c<l.length;){f&&(s.push({ids:m,content:u.join(`
|
|
5209
5209
|
`),tokenLength:d}),u=[],d=0,m=p.length?[p[p.length-1].id]:[],f=!1);let h=l[c],g=At(h);d+=g,h.length>a&&(h=h.slice(0,a));let b=Array.from(h.matchAll(jG)).map(L=>L&&L.length>=3?{tagName:L[1],id:L[2]}:void 0).filter(L=>!!L),A=Array.from(h.matchAll(che)).map(L=>L&&(L[2]||L[4])).filter(L=>!!L);A.reverse();let O=h.replace(/ id="[0-9]+"/g,"");u.push(O);for(let L of b)m.push(L.id),p.push(L);for(let L of A){let F=p[p.length-1];F&&F.tagName===L&&p.pop();}let M=p.some(L=>dhe.includes(L.tagName)),R=l[c+1]??"",_=At(R),B=Array.from(R.matchAll(jG)).map(L=>L&&L.length>2?L[1]:void 0).filter(L=>!!L),J=B.some(L=>WG.includes(L)),z=B.some(L=>uhe.includes(L));d+_>=i&&(f=!0),d>=n&&(J&&!M||A.some(L=>mhe.includes(L)))&&(f=!0),d>=o&&z&&!M&&(f=!0),c++;}return u.length&&s.push({ids:m,content:u.join(`
|
|
5210
|
-
`),tokenLength:d}),s.forEach((h,g)=>{let y=h.ids[0],S=h.ids[h.ids.length-1];r.debug({tokenLength:h.tokenLength,minId:y,maxId:S},`Chunk for page filtering (index ${g+1}/${s.length})`);}),{chunks:s}}var KG=5e6,hhe=15e4;async function sc(r){let{fixtures:e}=r,{logger:t}=e,n=r.tree,o=r.serializedTree,i=At(o);if(i>KG)throw new w("UserConfigurationError",`Page accessibility tree is too large for AI page filtering (${i} tokens). Maximum supported size is ${KG} tokens.`);if(i>hhe){let a=qG({serializedTree:o,options:GG,logger:t}),s=randomUUID();n=await ghe({...r,chunks:a.chunks,callId:s}),o=n.serialize();let l=At(o);t.info({oldTokens:i,newTokens:l,langfuseCallId:s},"Filtered page using AI chunk ranking");}return o}async function ghe({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:l}=o,c=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:3e4,mediumTokenLimit:6e4,hardTokenLimit:18e4,callId:e},{abortSignal:s,logger:l,loggerTags:we(l)}),u=[];return t.forEach((m,p)=>{c.indices.includes(p)&&(u=u.concat(m.ids));}),i.pruneUsingRelevantIds(new Set(u))}async function EM(r,e){if(!r.description)throw new w("UserConfigurationError","Cannot locate element with empty description");return Do({action:async()=>She(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function She(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,logger:l,allowNotActionableNodesOverride:c,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,skipSavingVisualAttributes:m,isAutoHeal:p,cacheBustReason:f,acceptElementMovedError:h}=r,{orgId:g,browser:y,localCodeEvalTools:S,generator:b,abortSignal:C}=e,A=r.description,O=ur(),M=r.useMemory&&!t;n&&(A=await Ia({orgId:g,s:A,context:n,localTools:S,signal:C,logger:l})),a&&(A=zG(A,a));let{serializedTree:R,tree:_}=await O.startAsyncSpan("GET_PAGE_STATE",async()=>Hs(y,{allowNotActionableNodesOverride:c,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,filterByViewport:o,abortSignal:C,skipWait:i,logger:l}),{}),k=await O.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let fe,le=Date.now(),ae;for(;!fe&&Date.now()-le<3e3;){C.throwIfAborted();try{fe=await y.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(_e){ae=_e;}}if(!fe)throw new w("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${ae?.message}`);return fe}),B=R,J=!1,L=`data:image/jpeg;base64,${k.toString("base64")}`;B=await sc({type:"locator",description:A,screenshot:L,serializedTree:R,tree:_,fixtures:{generator:b,signal:C,logger:l,orgId:g}}),B!==R&&(J=!0);let F=await O.startAsyncSpan("AI_LOCATOR_CALL",async fe=>{p&&(fe.attributes.isAutoHeal=!0),f&&(fe.attributes.cacheBustReason=f);let le=await b.getElementLocation({browserState:B,goal:A,screenshot:L,source:a,memory:M?s:void 0},{disableCache:t,abortSignal:C,loggerTags:we(l),useMemory:M});if(fe.result=le,O.storeTraceAsset){let ae=randomUUID();O.storeTraceAsset({snapshotId:ae,data:k}),fe.screenshotSnapshotId=ae;}return le});if(l.debug({usedRag:J,result:F},"Got locator result"),!(F.id>0))throw new hi(`Could not find any relevant element: ${F.thoughts}`,F.updatedMemory?{type:"GCS_TRACES",traces:F.updatedMemory}:void 0);let{resolution:D,target:j,frameConfig:Q}=await O.startAsyncSpan("TARGET_RESOLUTION",async fe=>{let le=await y.createTargetFromA11yId({id:F.id,requirements:F.requirements,additionalElements:F.additionalElements,description:A,targetSource:"AI",logger:l,skipSavingVisualAttributes:m,acceptElementMovedError:h});return fe.result={serializedElement:le.target.nodeOnlySerializedHtml??"Unknown HTML element"},le});if(D.a11yNode?.properties?.hidden&&D.a11yNode?.properties?.hidden!=="false")throw new w("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: ${D.displayString}`);return M&&(F.updatedMemory?j.memory={type:"GCS_TRACES",traces:F.updatedMemory}:s&&(j.memory=s)),{thoughts:F.thoughts,target:j,resolution:D,frameConfig:Q,screenshot:L}}var bhe=15;async function tE({command:r,logger:e,fixtures:t,useMemory:n,maxRetries:o=bhe}){if(!r.assertion.trim())throw new w("ActionFailureError","Assertion command is missing the assertion content");let i=JC.optional().catch(void 0).parse(r.source);r.source&&!i&&e.warn(`Invalid source ${r.source} for AI assertion, ignoring...`);let a=ur();return a.startAsyncSpan("AI_ASSERTION_CALL",async s=>{let{browser:l}=t,c=r.timeout?r.timeout*1e3:l.smartWaitingTimeout,u=w1(c,o-1),d=0,m=Date.now(),p=m+c,f=m,h,g,y;try{await Do({action:()=>l.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:l,logger:e});}catch(C){e.warn({err:C},"Failed to clear highlights before AI check, continuing...");}for(;d<o;){t.abortSignal.throwIfAborted();let C=Date.now();if(d>0){if(C>=p)break;let M=p-C,R=f-C,_=Math.min(R,M);_>0&&await te(_,t.abortSignal);}let A=Date.now();if(d>0&&A>=p)break;let O=!1;try{if(h=await Do({action:async()=>{let R=await YG(l,e,t.abortSignal);return g&&g.serializedTree===R.serializedTree&&g.screenshotBuff.equals(R.screenshotBuff)?(O=!0,h):(g=R,JG({command:r,state:R,fixtures:t,useMemory:n,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:d,logger:e,source:i}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:e,browser:l}),h?.success){h?.updatedMemory&&Af(r,h.updatedMemory,e);break}else throw h?.thoughts?new w("AssertionFailureError",h.thoughts):new w("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(M){t.abortSignal.throwIfAborted(),y=M instanceof Error?M:new Error(`${M}`),O?e.info(`AI check attempt ${d} failed (re-used previous result)`):e.info({err:M},`AI check assert attempt ${d} failed, retrying...`);}finally{d++,f=A+u;}}if(!h?.success){let C=p-Date.now();C>0&&await te(C,t.abortSignal);}if(!h?.success)try{h=await Do({action:async()=>JG({command:r,state:await YG(l,e,t.abortSignal),fixtures:t,useMemory:n,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:d,logger:e}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:e,browser:l});}catch(C){t.abortSignal.throwIfAborted(),y=C instanceof Error?C:new Error(`${C}`);}finally{d++;}h?.updatedMemory&&Af(r,h.updatedMemory,e);let S=h?.afterScreenshotOverride;if(S&&a.storeTraceAsset){let C=randomUUID();a.storeTraceAsset({snapshotId:C,data:S}),s.screenshotSnapshotId=C;}let b=h?.elementScreenshotOverride;if(b&&a.storeTraceAsset){let C=randomUUID();a.storeTraceAsset({snapshotId:C,data:b}),s.elementScreenshotSnapshotId=C;}if(!h?.success){s.result={thoughts:y?.message??"AI check failed after all attempts",result:!1};let C=`AI check still failing after ${d} attempts.`;throw y&&(C+=` Latest result: ${y.message}`),new w("AssertionFailureError",C)}return s.result={thoughts:h.thoughts,result:!0},{...h,succeedImmediately:!1,urlAfterCommand:l.url()}})}async function YG(r,e,t){await r.waitForPageLoad({signal:t});let[n,o]=await Promise.all([Hs(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return {...n,screenshotBuff:o}}async function JG({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,attemptNumber:a,source:s,logger:l}){let {browser:c,generator:u,abortSignal:d}=t,{serializedTree:p,tree:f}=e,h=e.screenshotBuff,g=h.toString("base64"),y=c.url(),S=r.contextChoice??"MULTIMODAL",b=p;S!=="VISION_ONLY"&&(b=await sc({type:"assertion",serializedTree:p,tree:f,description:r.assertion,screenshot:g,fixtures:{generator:u,signal:d,logger:l,orgId:t.orgId}}),b);let C={goal:r.assertion,url:y,memory:o?r.cache?.memory:void 0,browserState:b,screenshot:g,contextChoice:S,source:s},O=await(S==="VISION_ONLY"?(R,_)=>u.getVisualAssertionResult(R,_):(R,_)=>u.getAssertionResult(R,_))(C,{useConsensus:n,attemptNumber:a,useMemory:o,disableCache:!!r.disableCache,abortSignal:d,logger:l,loggerTags:we(l)}),M;if((O.result||i)&&O.relevantElements?.length){O.relevantElements.map(R=>c.getSerializedFormFromA11yId(R)).filter(R=>!!R);try{let R=O.relevantElements[0],{resolution:_}=await c.createTargetFromA11yId({id:R,description:null,targetSource:"AI",skipSaveToCache:!0});M=await c.screenshot({locator:_.locator,clearHighlights:!0,respectActiveFrame:!0});}catch(R){l.debug({err:R},"Failed to capture element screenshot for trace, continuing...");}await Ehe(O.relevantElements,c,l);}return {success:O.result,thoughts:O.thoughts,afterScreenshotOverride:h,elementScreenshotOverride:M,updatedMemory:o?O.updatedMemory:void 0}}async function Ehe(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await q(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}});}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}async function QG(r){let{command:e,logger:t,fixtures:n,disableCache:o}=r,{browser:i,generator:a,abortSignal:s}=n;if(!e.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(e.schema){let d=Lu(e.schema);if(d)throw new w("UserConfigurationError",d)}let l=await i.getCondensedHtml(),c=await i.screenshot({retries:2}),u=ur();try{return await u.startAsyncSpan("AI_EXTRACTION_CALL",async d=>{let m=await a.getTextExtraction({goal:e.goal,browserState:l,returnSchema:e.schema,screenshot:`data:image/jpeg;base64,${c.toString("base64")}`},{disableCache:o,abortSignal:s,loggerTags:we(t)});if(d.result=m,The({tracer:u,span:d,screenshot:c,htmlState:l,logger:t}),m.result==="NOT_FOUND")throw new w("ActionFailureError","No relevant data found for extraction goal on this page");if(m.thoughts?.includes("MaxGenerationLengthExceededError"))throw new w("UserConfigurationError",m.thoughts);return {thoughts:m.thoughts||void 0,data:m.result,succeedImmediately:!1,urlAfterCommand:i.url()}})}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 The(r){let{tracer:e,span:t,screenshot:n,htmlState:o,logger:i}=r;if(e.storeTraceAsset)try{let a=randomUUID();e.storeTraceAsset({snapshotId:a,data:n}),t.screenshotSnapshotId=a;let s=randomUUID();e.storeTraceAsset({snapshotId:s,data:Buffer.from(o),extension:"html"}),t.browserStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}async function eW(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await vhe(i,r,e);}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await te(s,n);}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete");}}async function vhe(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await te(o.smartWaitingTimeout,n);return}if(!e.description)throw new w("UserConfigurationError","Cannot locate element with empty description");await q(Che(r,e,t),{milliseconds:o.smartWaitingTimeout});}async function Che(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await Do({action:async()=>whe(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function whe(r,e){let{testContext:t,logger:n}=r,{browser:o,abortSignal:i,localCodeEvalTools:a,orgId:s,generator:l}=e,c=r.description;t&&(c=await Ia({orgId:s,s:c,context:t,localTools:a,signal:i,logger:n})),i.throwIfAborted();let u;try{u=await o.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(f){throw new w("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 l.getSmartWaitingDecision({description:c,screenshot:m},{abortSignal:i,loggerTags:we(n)});return n.debug({result:p},"Got smart waiting result"),p.isPageReady}async function nW(r){return ur().startAsyncSpan("ELEMENT_ASSERTION",async t=>Ahe(r,t),{name:"Element check"})}async function Ahe(r,e){let{command:t,timeoutMs:n,fixtures:o,disableCache:i}=r,{abortSignal:a}=o,s=()=>fC(t.cache)?t.cache:void 0,l=s(),c=!i&&!!l?.target&&Lc(l.target),u=cloneDeep(l),d=(S=!1)=>{if(l=s(),!!l)if(S){let b=r1(u,l);l.target=b.target,l.updatedAt=b.updatedAt;}else {if(!u){l=void 0;return}l.target=u.target,l.updatedAt=u.updatedAt;}},m=Date.now(),p=0,f,h=500,g=!1;for(;p<2||Date.now()-m<n;){p++,p>1&&await te(h,a),a?.throwIfAborted(),l=s();let S=p===1,{result:b,elementWasFound:C}=await tW({cacheToUse:l,skipAISmartWaiting:!S,useAIIfCacheFails:!c,params:r});if(f=b,g=g||C,b.success)break;d(),h=Math.min(h*1.25,1e4);}if(!f)throw new w("InternalPlatformError",`Failed to evaluate manual element assertion in ${n}ms.`);if(a?.throwIfAborted(),!f.success){let S=s(),b=S?.target?.memory?{target:{id:-1,memory:S.target.memory}}:void 0,{result:C,elementWasFound:A}=await tW({cacheToUse:b,skipAISmartWaiting:!0,useAIIfCacheFails:!0,params:r});f=C,g=g||A,f.success||d(!0);}let y=s();return f.success&&y?.target&&!g&&(y.target=IR(y.target),y.updatedAt=new Date),e.result={success:f.success,message:f.err?.message},f}async function tW({cacheToUse:r,skipAISmartWaiting:e,useAIIfCacheFails:t,params:n}){let{command:o,disableCache:i,fixtures:a,tracer:s,targetingWrapper:l}=n,{logger:c}=a;if(o.target&&!Ja(o.target))throw new Error("Element assertion with x/y is not supported yet");let u=ad(o.assertion),d=Rhe(o.assertion),m,p=!1,f=cloneDeep(r);try{let{elementInteractedDisplayString:h,result:g,thoughts:y}=await l({tracer:s,command:o,target:o.target,cache:f?.target,action:async S=>xhe(S.locator,n),options:{...o,allowNotActionableNodesOverride:d,allowIneligibleTagRedirect:d,showZeroOpacityElementsOverride:!0,disableCache:i,memory:f?.target?.memory,disableGlobalLocatorRedirect:!0,source:lp(o),skipAISmartWaiting:e,targetName:"target"},retriesWithAI:t?1:0});return m={success:g.success,data:g.data,err:g.err,elementInteractedDisplayString:h,thoughts:y},p=!0,g.success||(c.warn({aiThoughts:y,elementString:h,err:g.err},"Element check found an element but failed"),m={...g,thoughts:y}),{result:m,elementWasFound:p}}catch(h){if(u)return m={success:!0,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 w)||h.reason!="ActionFailureError")throw h;return m={success:!1,err:h,data:void 0,thoughts:void 0},c.warn({err:h},"Element check did not find an element and failed"),{result:m,elementWasFound:p}}}function Rhe(r){return !(r.type==="ELEMENT_EXISTENCE"&&r.condition==="VISIBLE"&&!r.negated)}async function xhe(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await Mhe(r,e.assertion)}async function Mhe(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:tr(a,500,!0)},!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,n=new w("AssertionFailureError",`The content ${s} '${e.value}': ${a}`);}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:tr(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a=null;try{a=await r.getAttribute(e.attr,{timeout:3e3});}catch(s){n=new w("AssertionFailureError",ne(s)),t=!1;break}if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,e.operation==="EXISTS"?n=new w("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new w("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`);}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,l)=>{let c=Date.now();for(;Date.now()-c<l;){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 !0}return !1},yr*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:yr*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:yr*1e3});break}case"FOCUSED":{t=await r.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(t=e.negated?!t:t,!t){let a=wr(e);n=new w("AssertionFailureError",`The element ${a}`);}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=wr(e);t=!1,n=new w("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`);}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,l)=>window.getComputedStyle(s).getPropertyValue(l),e.property);if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,e.operation==="EXISTS"?n=new w("AssertionFailureError",`The style property ${e.property} ${s}`):n=new w("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:t,data:o,err:n}}function oW(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}async function Yf(r,e){let t=await r.screenshot(e),n=await Jimp.fromBuffer(t);return {buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}async function aW({tracer:r,command:e,disableCache:t,browser:n,targetingWrapper:o,logger:i,screenshotStorage:a}){if(e.target&&!Ja(e.target))throw new Error("Visual Diff with x/y is not supported yet");await n.waitForStability({logger:i});let s={clearHighlights:!0,hideCaret:!0},l;e.target?.elementDescriptor?l=(await o({tracer:r,command:e,target:e.target,cache:e.cache?.target,action:async k=>Yf(n,{locator:k.locator,...s}),options:{...e,disableCache:t,disableGlobalLocatorRedirect:!0,memory:e.cache?.target?.memory,targetName:"target"}})).result:l=await Yf(n,s);let c=await a.prepareGoldenScreenshotForComparison(i,e,l);if((l.height!==c.height||l.width!==c.width)&&i.warn({currHeight:l.height,currWidth:l.width,savedHeight:c.height,savedWidth:c.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-c.height)>10||Math.abs(l.width-c.width)>10){let _=`${l.width}x${l.height}`,k=`${c.width}x${c.height}`;return {fail:!0,thoughts:`Current screenshot (${_}) does not match saved screenshot dimensions (${k}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:c.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:n.url()}}let u=await Jimp.fromBuffer(l.buffer),d={width:l.width,height:l.height},m=await Jimp.fromBuffer(c.buffer),p={width:c.width,height:c.height},f,h=d.width*d.height,g=p.width*p.height,y=Math.abs(d.height-p.height),S=Math.abs(d.width-p.width);if(h>g){let _=u.cover({w:p.width,h:p.height});l.buffer=await _.getBuffer("image/jpeg"),f="current",l.width=p.width,l.height=p.height;}else if(g>h){let _=m.cover({w:d.width,h:d.height});c.buffer=await _.getBuffer("image/jpeg"),f="saved";}let b={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},C=e.threshold??.1,O=gde(TM.decode(c.buffer).data,TM.decode(l.buffer).data,b.data,l.width,l.height,{threshold:C,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,M=O>C*100,R=`Visual diff of ${O.toFixed(2)}% detected, which is ${M?"over":"under"} the threshold of ${C*100}%.`;if(f&&(R+=` The ${f} screenshot was cropped since it was taller by ${y} pixels and wider by ${S} pixels.`),M)throw new w("ActionFailureError",R);return {fail:M,thoughts:R,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:TM.encode(b,75).data,succeedImmediately:!1,urlAfterCommand:n.url()}}var Ihe=3e4;function Ohe(r){if(!r.body)return {};switch(r.body.type){case"json":return {content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n);}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function Id({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Ihe/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([f,h])=>f&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([f,h])=>f&&h).forEach(([f,h])=>{a.append(f,h);});let s=a.toString(),l;if(ld(r.url)&&(l=r.url),t&&cd(r.url,t)&&(l=new URL(r.url,t).toString()),!l)throw new w("ActionFailureError",`Invalid URL: ${r.url}`);let c=l;e.info({url:c,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let d=await q((async()=>{let f=s?`${c}?${s}`:c;try{let h=Ohe(r),g=new Headers(i);return h.contentType&&!g.has("Content-Type")&&g.set("Content-Type",h.contentType),await n(f,{headers:g,method:r.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:o*1e3,fallback:()=>{throw new w("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let f;try{f=await d.text();}catch(h){f=`Failed to read response body: ${h}`;}throw new w("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:r.method,headers:i}};if(r.body?.type==="json"&&r.body.content)try{p.request.json=JSON.parse(r.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 Nhe=5e3;async function cW({timeout:r=yr,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let l=Date.now();i=await sW(e),a=Date.now();let c=a-l;if(c>1e3&&e.logger.warn({pageAssertDuration:c},"Page assertion took longer than expected"),!i.success)await te(s,e.signal),s=Math.min(Math.floor(s*1.5),Nhe);else return i}return i=await sW(e),i}async function sW(r){return ur().startAsyncSpan("PAGE_ASSERTION",async t=>{let n=await vM(r);return t.result={success:n.success,message:n.err?.message},n},{name:"Page check"})}async function vM({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let l=await e.evaluateFunctionInAllFrames(lW,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?l.every(c=>c.evaluation):l.some(c=>c.evaluation),s=l.find(c=>c.pageHtml)?.pageHtml;}else ({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(lW,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let l=r.negated?wa.CONTAINS:Aa.CONTAINS;a=new w("AssertionFailureError",`The page ${l} '${r.value}'.`),o=s;}}catch(s){a=new w("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`);}return {success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return (o=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}}function lW({value:r,negated:e,returnHtml:t}){let n=document.body.innerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var Lhe=3e4;async function uW({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Lhe/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,m])=>d&&m));a["Content-Type"]="application/json";let s;if(ld(r.url)&&(s=r.url),t&&cd(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new w("ActionFailureError",`Invalid URL: ${r.url}`);let c=await q((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:o*1e3});if(!c)throw new w("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!c.ok){let d,m=await c.text();try{d=JSON.parse(m);}catch{throw new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${m}`)}throw d?.errors?.length&&d?.errors[0]?.message?new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${d.errors[0].message}`):new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${m}`)}let u={};return c.headers.forEach((d,m)=>{u[m]=d;}),{status:c.status,headers:u,json:await c.json()}}var rE=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;executionOptionsStack=[];recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:l,options:c}){this.orgId=i,this.options=c,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=l,this.localCodeEvalTools=a,this.generator=t,this.logger=n;}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,t){this.executionOptionsStack.push(e);try{return await t()}finally{this.executionOptionsStack.pop();}}getCurrentExecutionOptions(){return this.executionOptionsStack[this.executionOptionsStack.length-1]??{}}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[l,c]=await Promise.all([Hs(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${c.toString("base64")}`,d=await sc({type:"ai-action",description:e,screenshot:u,serializedTree:l.serializedTree,tree:l.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),m={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(m,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...we(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let l=this.browser.url(),[c,u]=await Promise.all([Hs(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,m=await sc({type:"ai-action",description:e,screenshot:d,serializedTree:c.serializedTree,tree:c.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),p={url:l,browserState:m,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(p,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...we(a)},langfuseSessionId:s})}catch(f){throw new w("InternalWebAgentError",`Error generating command: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}}async getBrowserState(e){return Hs(this.browser,e)}async locateElement(e){return await EM(e,this.getControllerFixtures())}async locateElementWithSelector(e,t){return Do({action:async()=>{let n=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:n}},frameConfig:t?{type:"url",url:t}: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??!0}async wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:n,descriptions:o,caches:i,action:a,options:s,retriesWithAI:l=1}){let c=[];for(let u=0;u<o.length;u++){let d=o[u],m=await this.wrapElementTargetingCommand({tracer:e,command:t,target:d,cache:i[u],action:async p=>p,options:{...s,targetName:n[u]}});c.push(m);}try{let u=await a(...c.map(p=>p.result)),d=p=>p==="fromTarget"?"From Target":p==="toTarget"?"To Target":"Target",m=c.map((p,f)=>p.thoughts?`${d(n[f])}: ${p.thoughts}`:void 0).filter(p=>!!p).join(" -------------- ")||void 0;return {result:u,elementInteractedDisplayStrings:c.map(p=>p.elementInteractedDisplayString),thoughts:m}}catch(u){if(this.throwIfClosed(),l>0)return this.logger.warn({err:u},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:n,descriptions:o,caches:o.map(()=>{}),action:a,options:s,retriesWithAI:l-1});throw new w("ActionFailureError",u.message,{errOptions:{cause:u}})}}async wrapHardcodedCssTargetingCommandHelper({target:e,action:t,options:n,command:o}){let i=this.logger.child({commandId:o.id}),{targetName:a}=n;if(e.type!=="description")throw new w("ActionFailureError","Cannot use selector with non-description target");let s,l=Date.now(),c=Date.now();for(;Date.now()-c<this.browser.smartWaitingTimeout;){l=Date.now();try{let u=await this.browser.resolveHardcodedCssSelector({selector:e.elementDescriptor,targetName:a,logger:i});return {result:await t({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()-l<500&&await te(500);}}throw s}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:t,disableGlobalLocatorRedirect:n,logger:o}=e,i=ur(),a=!n&&this.browser.userBrowserSettings.globalLocatorRedirect!==!1;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(t.locator);});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async l=>{let{targetingResult:c,metadata:u}=await this.browser.performTargetRedirection(t,o);if(l.result=u,u.outcome==="redirected to new element"&&c&&i.storeTraceAsset&&!this.browser.userBrowserSettings.disableBrowserMonitoring){let d=randomUUID();(async()=>{try{let m=await this.browser.screenshot({locator:c.locator,clearHighlights:!0,boundingBoxOverride:c.serverSideBoundingBox??void 0});i.storeTraceAsset?.({snapshotId:d,data:m});}catch(m){o.debug({err:m},"Failed to capture element screenshot for redirect trace");}})(),l.elementScreenshotSnapshotId=d;}return c})),s||(s={locator:t.locator,serverSideBoundingBox:await t.locator.boundingBox({timeout:Ae}),originalElementLocationResult:t.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{cache:t,options:n,logger:o}=e,a=await ur().startAsyncSpan("CACHE_RESOLUTION",async l=>{l.targetSource=t.targetSource;try{let c=await this.browser.resolveTarget(t,{allowNotActionableNodesOverride:n.allowNotActionableNodesOverride,logger:o,signal:this.executeAbortController.signal,...n.resolveTargetOptions,acceptElementMovedError:n.force});l.attributes.targetDisplayString=c.displayString,l.attributes.decisions=c.decisions;let u=c.decisions.find(d=>d.matched);return u&&(l.resolutionMethod=u.type),c}catch(c){throw c instanceof Ee&&(l.cacheMissReason=c.cacheMissReason,l.attributes.decisions=c.decisions),c}}),s=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:a,disableGlobalLocatorRedirect:n.disableGlobalLocatorRedirect,logger:o});return n.force||await a.revalidator?.(),{resolutionResult:a,finalTarget:s}}async wrapElementTargetingCommand(e){return await Do({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:t,target:n,action:o,options:i,command:a,finalAttempt:s=!1,originalCache:l=e.cache}=e,{retriesWithAI:c=1}=e,{disableCache:u,useSelector:d,targetName:m}=i,p=ur(),f=this.logger.child({commandId:a.id}),h=this.shouldUseMemory(),g=cloneDeep(e.cache);if((!g||u)&&!BO(n))throw new w("ActionFailureError","Cannot target element with no cached data or element descriptor");if(d)return this.wrapHardcodedCssTargetingCommandHelper(e);let y=!1,S;u&&(f.info("Cache explicitly disabled for this step"),y=!0,S="Cache explicitly disabled",g=void 0);let b=HG({cache:g,description:n.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:f});g=b.cache,y=y||b.cacheBustedBeforeAction,!S&&b.cacheBustReason&&(S=b.cacheBustReason);let C=!0;if(!VG(g))return c--,C=!1,this.executeTargetingCommandWithAI({tracer:p,stepTracer:t,target:n,options:i,command:a,action:o,originalCache:l,logger:f,useMemory:h,cacheBustedBeforeAction:y,cacheBustReason:S});try{let{resolutionResult:A,finalTarget:O}=await this.resolveCachedTargetForAction({cache:g,options:i,logger:f}),M=await o(O);if(Et.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!g.requirements}`,`hasAdditionalElements:${!!g.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.88.1"]),US({cmd:a,key:m,newTarget:g,logger:f,updatedWithAI:!1}),C){let R=A.decisions.filter(_=>_.matched);if(R.length!==1)f.warn({decisions:A.decisions},"Expected exactly 1 matching method for element location, got more or less");else {let _=R[0].type;t.recordTargetAutoHeal({healType:_});}}return {result:M,elementInteractedDisplayString:A.displayString}}catch(A){this.throwIfClosed();let O=xC(A);if(O&&!s)return f.warn({err:A},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({tracer:t,command:a,target:n,action:o,cache:l,originalCache:l,retriesWithAI:c,finalAttempt:!0,options:i});if(A instanceof w&&!O)throw f.warn({err:A},"Failed to execute command with target (fatal)"),A;if(c>0&&n){f.info({err:A},"Failed to execute action with cached target, retrying with AI"),Et.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!g.requirements}`,`hasAdditionalElements:${!!g.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.88.1",`missReason:${A instanceof Ee?A.cacheMissReason:"unknown"}`]);let M;return g.memory&&zO(g.memory)&&(M=g.memory),this.wrapElementTargetingCommandHelper({tracer:t,command:a,target:n,cache:void 0,action:o,originalCache:l,retriesWithAI:c,finalAttempt:!0,options:{...i,memory:M,targetHealingInProgress:!0}})}throw new w("ActionFailureError",`Failed to execute interactive command: ${A instanceof Error?A.message:`${A}`}`,{errOptions:{cause:A}})}}async executeTargetingCommandWithAI(e){let{tracer:t,stepTracer:n,target:o,options:i,command:a,action:s,originalCache:l,logger:c,useMemory:u,cacheBustedBeforeAction:d,cacheBustReason:m}=e;c.info({description:o.elementDescriptor,targetHealingInProgress:i.targetHealingInProgress,cacheBustedBeforeAction:d,memory:i.memory,useMemory:u},"Prompting AI for an updated element location");let p=!1;(d||!l)&&!this.getCurrentExecutionOptions().skipAISmartWaiting&&!i.skipAISmartWaiting?(await t.startAsyncSpan("SMART_WAITING",async()=>await eW({description:o.elementDescriptor,iframeUrl:i.iframeUrl,source:i.source,logger:c,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride},this.getControllerFixtures())),p=!0):(d||!l)&&(i.skipAISmartWaiting?c.debug("Skipping AI smart waiting for this targeting attempt"):c.debug("Skipping AI smart waiting due to controller execution options"));let f=2;for(let h=1;h<=f;h++){let g=!1,y=this.browser.getActiveFrameConfig(),S=i.force||h>1;try{let b;try{b=await EM({description:o.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:c,skipWait:p,isAutoHeal:!!i.targetHealingInProgress,cacheBustReason:m,acceptElementMovedError:S},this.getControllerFixtures());}catch(O){if(O instanceof hi&&O.updatedLocatorMemory){let M={id:-1,...l,memory:O.updatedLocatorMemory};US({cmd:a,key:i.targetName,newTarget:M,logger:c,updatedWithAI:!0});}throw O}b.frameConfig&&(this.browser.setActiveFrameConfig(b.frameConfig),g=!0);let C=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:b.resolution,disableGlobalLocatorRedirect:i.disableGlobalLocatorRedirect,logger:c}),A=await s(C);return US({cmd:a,key:i.targetName,newTarget:b.target,logger:c,updatedWithAI:!0}),i.targetHealingInProgress&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=we(c)),{result:A,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}catch(b){if(g&&this.browser.setActiveFrameConfig(y),this.throwIfClosed(),h<f&&xC(b)){c.warn({err:b,aiAttempt:h},"Encountered retryable AI targeting error; retrying with AI once");continue}throw b instanceof w?b:new w("ActionFailureError",b.message)}}throw new w("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return Yf(this.browser,e)}async executePresetCommand(e,t,n,o){this.options?.slowMoMs&&await te(this.options.slowMoMs);let i=await this.browser.getOpenPages(),a=this.browser.url(),s;try{s=await this.resolveCommandTemplateStrings(t,n);}catch(l){throw this.throwIfClosed(),new w("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o);return this.options?.autoFollowNewTabs&&await $G({beforeUrl:a,command:t,beforePages:i.map(c=>c.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{Rd(t,s);}}createCallbacksForBrowser(e){return {createIsolatedFolder:()=>Hx(e)}}async traceBrowserInteraction(e,t,n){return ur().startAsyncSpan("BROWSER_INTERACTION",async()=>t(),{name:e,...n})}async resolveCommandTemplateStrings(e,t){return Ad({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o){o=o||"disableCache"in t&&!!t.disableCache;let i=this.logger.child({commandId:t.id});switch(t.type){case"SUCCESS":{let a=t.condition;return a?.assertion.trim()?tE({command:a,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:i}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AI_ASSERTION":{if(!t.assertion.trim())throw new w("ActionFailureError","Missing assertion");if(t.timeout&&t.timeout>1800)throw new w("AssertionFailureError",`AI check timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);return tE({command:t,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:i})}case"AI_EXTRACT":return QG({command:t,logger:i,fixtures:this.getControllerFixtures(),disableCache:o});case"NAVIGATE":if(!ld(t.url)&&!cd(t.url,this.browser.baseUrl))throw new w("ActionFailureError",`Invalid URL provided to navigate command: ${t.url}`);await this.traceBrowserInteraction("Navigate",()=>this.browser.navigate({url:t.url,loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0}));break;case"DIALOG":this.browser.registerDialogHandler(t.action);break;case"CAPTCHA":throw new w("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 a,s;if(t.target&&fi(t.target))await this.browser.hoverUsingVisualCoordinates(t.target.pixels);else if(t.target&&t.target.elementDescriptor.trim()){let{elementInteractedDisplayString:u,thoughts:d}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:m=>this.browser.hover(m),options:{...t,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:o}});a=u,s=d;}let l=this.browser.getViewport()?.height??es.height,c=this.browser.getViewport()?.width??es.width;switch(t.type){case"SCROLL_UP":await this.traceBrowserInteraction("Scroll up",()=>this.browser.scrollVertical(-(t.deltaY??l)));break;case"SCROLL_DOWN":await this.traceBrowserInteraction("Scroll down",()=>this.browser.scrollVertical(t.deltaY??l));break;case"SCROLL_LEFT":await this.traceBrowserInteraction("Scroll left",()=>this.browser.scrollHorizontal(-(t.deltaX??c)));break;case"SCROLL_RIGHT":await this.traceBrowserInteraction("Scroll right",()=>this.browser.scrollHorizontal(t.deltaX??c));break}return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"WAIT_FOR_URL":{if(t.timeout&&t.timeout>1800)throw new w("UserConfigurationError",`Wait for URL timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);let a=t.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:a},{timeout:t.timeout?t.timeout*1e3:void 0,negated:t.negated,caseInsensitive:t.caseInsensitive});break}case"WAIT":{if(t.delay>1800)throw new w("UserConfigurationError",`Wait timeout of ${t.delay} seconds exceeds the maximum allowed value of 30 minutes`);let a=t.delay*1e3;await te(a,this.executeAbortController.signal);break}case"REFRESH":await this.traceBrowserInteraction("Refresh",()=>this.browser.refresh({loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0}));break;case"CLICK":{if(fi(t.target)){let{pixels:d}=t.target;await this.traceBrowserInteraction("Click",()=>this.browser.clickUsingVisualCoordinates(d,t),{coordinates:d});break}let a=this.browser.url(),{elementInteractedDisplayString:s,result:l,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,target:t.target,command:t,cache:t.cache?.target,action:d=>this.traceBrowserInteraction("Click",()=>this.browser.click(d,this.createCallbacksForBrowser(this.orgId),t),{selector:d.locator.toString()}),options:{...t,targetName:"target",disableCache:o}}),u={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:s,thoughts:c,data:l.downloadedFile?{downloadedFile:l.downloadedFile}:void 0};return JS(a,u.urlAfterCommand)&&(u.succeedImmediately=!0,u.succeedImmediatelyReason="URL changed"),u}case"COPY":return await this.browser.copy(t.value),{succeedImmediately:!1,data:t.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(fi(t.fromTarget)&&fi(t.toTarget)){let l=t.fromTarget.pixels,c=t.toTarget.pixels;await this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDropUsingVisualCoordinates(l,c,{hoverDurationMs:t.hoverSeconds?t.hoverSeconds*1e3:void 0}),{coordinates:l});break}if(fi(t.fromTarget)||fi(t.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:a,thoughts:s}=await this.wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:["fromTarget","toTarget"],descriptions:[t.fromTarget,t.toTarget],caches:[t.cache?.fromTarget,t.cache?.toTarget],action:(l,c)=>this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDrop(l,c,{hoverDurationMs:t.hoverSeconds?t.hoverSeconds*1e3:void 0,steps:t.steps})),options:{...t,disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a[0],thoughts:s}}case"MOUSE_DRAG":{let a=parseInt(t.deltaX),s=parseInt(t.deltaY),l=t.steps??5;if(isNaN(a)||isNaN(s))throw new w("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${t.deltaX}, ${t.deltaY})`);if(t.target&&fi(t.target)){let d=t.target.pixels;await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDragUsingVisualCoordinates({deltaX:a,deltaY:s,steps:l,fromTarget:d}),{coordinates:d});break}let c,u;if(t.target?.elementDescriptor){let{elementInteractedDisplayString:d,thoughts:m}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async p=>this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(a,s,l,p.locator,{force:t.force})),options:{...t,targetName:"target",disableCache:o}});c=d,u=m;}else await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(a,s,l,void 0,{force:t.force}));return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:c,thoughts:u}}case"SELECT_OPTION":{if(!Ja(t.target))throw new Error("Select with x/y is not supported yet");let a=t.target.elementDescriptor,s=t.choice,{elementInteractedDisplayString:l,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:{type:"description",elementDescriptor:a},cache:t.cache?.target,action:u=>this.traceBrowserInteraction("Select option",()=>this.browser.selectOption(u,s,t.force),{value:s.type==="LABEL"?s.label:s.type==="VALUE"?s.value:s.index}),options:{...t,targetName:"target",disableCache:o,source:lp(t)}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:c}}case"TAB":{let a={loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(t.action,a);break}case"NEW_TAB":await this.browser.createNewTab(t.url,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"CLOSE_TAB":await this.browser.closePage(t.action,{retry:!0});break;case"COOKIE":{if(!t.value)break;let a=await this.browser.setCookie(t.value);i.debug({results:a},"Set cookies");break}case"LOCAL_STORAGE":if(!t.value||!t.key)break;await this.browser.setLocalStorage(t.key,t.value);break;case"JAVASCRIPT":{let a;try{t.environment==="BROWSER"?(a=await this.browser.evaluateCodeInPage({code:t.code,fragment:t.fragment??!1,context:n.toObjectCopy(),timeoutMs:t.timeout?t.timeout*1e3:void 0}),i.info({result:a},"Executed JavaScript in browser")):a=await Oo({orgId:this.orgId,code:t.code,fragment:!!t.fragment,context:n,timeoutMs:t.timeout?t.timeout*1e3:void 0,logger:i,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async s=>{if(!this.options?.scratchPadId){i.warn({updates:s},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:s,logger:i});}}});}catch(s){throw this.throwIfClosed(),new w("ActionFailureError",s instanceof Error?s.message:`${s}`,{errOptions:{cause:s}})}try{JSON.stringify(a);}catch(s){throw new w("ActionFailureError",`Return value is not serializable: ${s instanceof Error?s.message:`${s}`}`,{errOptions:{cause:s}})}return {urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:a}}case"TYPE":{if(t.target&&fi(t.target)){await this.browser.clickUsingVisualCoordinates(t.target.pixels,t),await this.traceBrowserInteraction("Type",()=>this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter},!0),{value:t.value});break}let a=this.browser.url(),s,l,c=cloneDeep(t.target),u=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(c){let{elementInteractedDisplayString:m,thoughts:p}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:c,cache:t.cache?.target,action:f=>this.traceBrowserInteraction("Type",()=>this.browser.typeIntoTarget(t.value,f,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter,relativePosition:t.relativePosition}),{value:t.value,selector:f.locator.toString()}),options:{...t,targetName:"target",disableCache:o,disableGlobalLocatorRedirect:!u,source:lp(t)}});s=m,l=p;}else await this.traceBrowserInteraction("Type",()=>this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter},!0),{value:t.value});let d={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:s,thoughts:l};return JS(a,d.urlAfterCommand)&&(d.succeedImmediately=!0,d.succeedImmediatelyReason="URL changed"),d}case"HOVER":{if(fi(t.target)){let{pixels:l}=t.target;await this.traceBrowserInteraction("Hover",()=>this.browser.hoverUsingVisualCoordinates(l),{coordinates:l});break}let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:l=>this.traceBrowserInteraction("Hover",()=>this.browser.hover(l,{relativePosition:t.relativePosition}),{selector:l.locator.toString()}),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"FOCUS":{if(!Ja(t.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:l=>this.browser.focus(l),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"BLUR":{if(t.target&&!Ja(t.target))throw new Error("Blur with x/y is not supported yet");if(!t.target||!t.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,target:t.target,command:t,cache:t.cache?.target,action:l=>this.browser.blur(l),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"PRESS":{let a=this.browser.url();await this.traceBrowserInteraction("Press key",()=>this.browser.press(t.value,{repeat:t.repeat,convertMeta:t.convertMeta??!0,delayMs:t.delayMs}),{value:t.value});let s={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return JS(a,s.urlAfterCommand)&&(s.succeedImmediately=!0,s.succeedImmediatelyReason="URL changed"),s}case"KEY_DOWN":return await this.browser.keyDown(t.value,{convertMeta:t.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(t.value,{convertMeta:t.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let a=new CookieJar,s=khe(fetch,a),l;try{l=new URL(t.url).hostname;}catch{}let c=await Id({command:t,baseUrl:this.browser.baseUrl,logger:i,fetchImplementation:s});return {data:Bc.parse({...c,cookies:gu(a,l)}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return {data:await uW({command:t,baseUrl:this.browser.baseUrl,logger:i}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return aW({tracer:e,command:t,disableCache:o,browser:this.browser,logger:i,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:a=>this.wrapElementTargetingCommand(a)});case"FILE_UPLOAD":{let a,s;if(t.fileSource.type==="URL"?(s=t.fileSource.url,a=await aj({uri:t.fileSource.url,logger:i,orgId:this.orgId})):t.fileSource.type==="USER_FILE"&&(s=t.fileSource.name,a=await this.uploadedFileStorage?.getFileForUpload(t.fileSource.name,this.orgId)),!a)throw new w("UserConfigurationError",`Attempted to use non-existent file for upload step: ${s}`);await this.browser.setFileChooserHandler({...a,filename:t.filename});break}case"AUTH_SAVE":return {data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let a;if(!t.storageState.trim())a=void 0;else if(a=await Oo({orgId:this.orgId,code:t.storageState,fragment:!1,context:n,logger:i,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof a!="object")throw new w("ActionFailureError",`Credentials must evaluate to an object (received ${typeof a} instead)`);let s;try{s=GD.optional().parse(a);}catch(l){throw new w("ActionFailureError",`Credentials provided do not follow the required format: ${l}`)}await this.browser.loadAuthState(s);break}case"ELEMENT_CHECK":{let a=(t.timeout??yr)*1e3,s=this.generator.getAgentConfig()?.assertion;if(oW(t.assertion)&&!t.useSelector&&t.target.type==="description"&&s&&s!=="v1"){let c={id:t.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: ${t.target.elementDescriptor}`,iframeUrl:t.iframeUrl,timeout:t.timeout,source:"NEGATED_CHECK",cache:t.cache&&"memory"in t.cache?{memory:t.cache?.memory}:void 0};try{let u=await tE({command:c,logger:i,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory()});return {succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${u.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:u.afterScreenshotOverride}}finally{c.cache?.memory&&Af(t,c.cache?.memory.traces,i);}}let l=await nW({command:t,tracer:e,timeoutMs:a,targetingWrapper:c=>this.wrapElementTargetingCommand(c),fixtures:this.getControllerFixtures(),disableCache:o});return {fail:!l.success,data:l.data,elementInteracted:l.elementInteractedDisplayString,thoughts:l.err?.message??l.thoughts??`Element assertion ${l.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let a=await Do({action:async()=>cW({assertion:t.assertion,browser:this.browser,logger:i,timeout:t.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:this.browser,logger:i});return {fail:!a.success,data:a.data,thoughts:a.success?"Page assertion passed.":a.err?.message??`Page assertion still failing after ${t.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let a=new zs(t.requestMatcher),s=this.browser.registerRequestListener(a);return this.registeredListeners[t.key]=s.then(async l=>await qx(l)).catch(l=>{i.error({err:l},"Failed to get request listener response");}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let a=this.registeredListeners[t.key];if(!a)throw new w("ActionFailureError",`No listener registered with key: ${t.key}`);let s=t.timeout??10;return {data:await q(a,{milliseconds:s*1e3,message:`Request listener timed out after ${s} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let a=new zs(t.requestMatcher);return this.recordedRequests[t.key]={},this.browser.registerRequestRecorder(t.key,{matches:s=>a.matches({url:s.request.url,method:s.request.method}),onRequestStart:(s,l)=>{this.recordedRequests[t.key][s]=$b(l);},onRequestComplete:(s,l)=>{this.recordedRequests[t.key]?.[s]&&(this.recordedRequests[t.key][s]=$b(l));}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let a=this.recordedRequests[t.key];if(!a)throw new w("ActionFailureError",`No recorder registered with key: ${t.key}`);return delete this.recordedRequests[t.key],{data:Object.values(a),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let a;return t.requestMatcher&&(a=new zs(t.requestMatcher)),this.browser.setHeader(t.name,t.value,a),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return {data:{key:this.browser.registerMock(t.key,new zs(t.requestMatcher),async(s,l)=>{let c=await Oo({orgId:this.orgId,code:t.responseGenerator,fragment:!1,context:n,timeoutMs:void 0,logger:i,localTools:this.localCodeEvalTools,mock:{request:s,response:l},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),u=b0.parse(c);return new Response(u.body,{status:u.status,headers:u.headers})},t.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(t.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(t.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return (s=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}return {succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return (await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:we(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights();}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Yb({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:we(this.logger)})}async getFailureRecoveryPlan(e,t){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:we(t??this.logger)})}};function yt({text:r,section:e}){if(!e)return [{type:"text",text:r}];let t=`### ${e}`;return r.length===0?[{type:"text",text:t}]:[{type:"text",text:`${t}
|
|
5210
|
+
`),tokenLength:d}),s.forEach((h,g)=>{let y=h.ids[0],S=h.ids[h.ids.length-1];r.debug({tokenLength:h.tokenLength,minId:y,maxId:S},`Chunk for page filtering (index ${g+1}/${s.length})`);}),{chunks:s}}var KG=5e6,hhe=15e4;async function sc(r){let{fixtures:e}=r,{logger:t}=e,n=r.tree,o=r.serializedTree,i=At(o);if(i>KG)throw new w("UserConfigurationError",`Page accessibility tree is too large for AI page filtering (${i} tokens). Maximum supported size is ${KG} tokens.`);if(i>hhe){let a=qG({serializedTree:o,options:GG,logger:t}),s=randomUUID();n=await ghe({...r,chunks:a.chunks,callId:s}),o=n.serialize();let l=At(o);t.info({oldTokens:i,newTokens:l,langfuseCallId:s},"Filtered page using AI chunk ranking");}return o}async function ghe({type:r,callId:e,chunks:t,description:n,fixtures:o,tree:i}){let{generator:a,signal:s,logger:l}=o,c=await a.rankChunksWithAi({chunks:t,description:n,type:r,softTokenLimit:3e4,mediumTokenLimit:6e4,hardTokenLimit:18e4,callId:e},{abortSignal:s,logger:l,loggerTags:we(l)}),u=[];return t.forEach((m,p)=>{c.indices.includes(p)&&(u=u.concat(m.ids));}),i.pruneUsingRelevantIds(new Set(u))}async function EM(r,e){if(!r.description)throw new w("UserConfigurationError","Cannot locate element with empty description");return Do({action:async()=>She(r,e),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:e.browser,logger:r.logger})}async function She(r,e){let{disableCache:t,testContext:n,filterByViewport:o,skipWait:i,source:a,memory:s,logger:l,allowNotActionableNodesOverride:c,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,skipSavingVisualAttributes:m,isAutoHeal:p,cacheBustReason:f,acceptElementMovedError:h}=r,{orgId:g,browser:y,localCodeEvalTools:S,generator:b,abortSignal:C}=e,A=r.description,O=ur(),M=r.useMemory&&!t;n&&(A=await Ia({orgId:g,s:A,context:n,localTools:S,signal:C,logger:l})),a&&(A=zG(A,a));let{serializedTree:R,tree:_}=await O.startAsyncSpan("GET_PAGE_STATE",async()=>Hs(y,{allowNotActionableNodesOverride:c,allowIneligibleTagRedirect:u,showZeroOpacityElementsOverride:d,filterByViewport:o,abortSignal:C,skipWait:i,logger:l}),{}),k=await O.startAsyncSpan("GET_PAGE_SCREENSHOT",async()=>{let fe,le=Date.now(),ae;for(;!fe&&Date.now()-le<3e3;){C.throwIfAborted();try{fe=await y.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(_e){ae=_e;}}if(!fe)throw new w("ActionFailureError",`Failed to take screenshot of page to locate element. The page may be unresponsive, or your machine might be severely resource constrained. Error: ${ae?.message}`);return fe}),B=R,J=!1,L=`data:image/jpeg;base64,${k.toString("base64")}`;B=await sc({type:"locator",description:A,screenshot:L,serializedTree:R,tree:_,fixtures:{generator:b,signal:C,logger:l,orgId:g}}),B!==R&&(J=!0);let F=await O.startAsyncSpan("AI_LOCATOR_CALL",async fe=>{p&&(fe.attributes.isAutoHeal=!0),f&&(fe.attributes.cacheBustReason=f);let le=await b.getElementLocation({browserState:B,goal:A,screenshot:L,source:a,memory:M?s:void 0},{disableCache:t,abortSignal:C,loggerTags:we(l),useMemory:M});if(fe.result=le,O.storeTraceAsset){let ae=randomUUID();O.storeTraceAsset({snapshotId:ae,data:k}),fe.screenshotSnapshotId=ae;}return le});if(l.debug({usedRag:J,result:F},"Got locator result"),!(F.id>0))throw new hi(`Could not find any relevant element: ${F.thoughts}`,F.updatedMemory?{type:"GCS_TRACES",traces:F.updatedMemory}:void 0);let{resolution:D,target:j,frameConfig:Q}=await O.startAsyncSpan("TARGET_RESOLUTION",async fe=>{let le=await y.createTargetFromA11yId({id:F.id,requirements:F.requirements,additionalElements:F.additionalElements,description:A,targetSource:"AI",logger:l,skipSavingVisualAttributes:m,acceptElementMovedError:h});return fe.result={serializedElement:le.target.nodeOnlySerializedHtml??"Unknown HTML element"},le});if(D.a11yNode?.properties?.hidden&&D.a11yNode?.properties?.hidden!=="false")throw new w("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: ${D.displayString}`);return M&&(F.updatedMemory?j.memory={type:"GCS_TRACES",traces:F.updatedMemory}:s&&(j.memory=s)),{thoughts:F.thoughts,target:j,resolution:D,frameConfig:Q,screenshot:L}}var bhe=15;async function tE({command:r,logger:e,fixtures:t,useMemory:n,maxRetries:o=bhe}){if(!r.assertion.trim())throw new w("ActionFailureError","Assertion command is missing the assertion content");let i=JC.optional().catch(void 0).parse(r.source);r.source&&!i&&e.warn(`Invalid source ${r.source} for AI assertion, ignoring...`);let a=ur();return a.startAsyncSpan("AI_ASSERTION_CALL",async s=>{let{browser:l}=t,c=r.timeout?r.timeout*1e3:l.smartWaitingTimeout,u=w1(c,o-1),d=0,m=Date.now(),p=m+c,f=m,h,g,y;try{await Do({action:()=>l.clearHighlights(),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,browser:l,logger:e});}catch(C){e.warn({err:C},"Failed to clear highlights before AI check, continuing...");}for(;d<o;){t.abortSignal.throwIfAborted();let C=Date.now();if(d>0){if(C>=p)break;let M=p-C,R=f-C,_=Math.min(R,M);_>0&&await te(_,t.abortSignal);}let A=Date.now();if(d>0&&A>=p)break;let O=!1;try{if(h=await Do({action:async()=>{let R=await YG(l,e,t.abortSignal);return g&&g.serializedTree===R.serializedTree&&g.screenshotBuff.equals(R.screenshotBuff)?(O=!0,h):(g=R,JG({command:r,state:R,fixtures:t,useMemory:n,useConsensus:!1,highlightElementsOnFailure:!1,attemptNumber:d,logger:e,source:i}))},frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:e,browser:l}),h?.success){h?.updatedMemory&&Af(r,h.updatedMemory,e);break}else throw h?.thoughts?new w("AssertionFailureError",h.thoughts):new w("InternalPlatformError","No thoughts were provided for AI assertion failure")}catch(M){t.abortSignal.throwIfAborted(),y=M instanceof Error?M:new Error(`${M}`),O?e.info(`AI check attempt ${d} failed (re-used previous result)`):e.info({err:M},`AI check assert attempt ${d} failed, retrying...`);}finally{d++,f=A+u;}}if(!h?.success){let C=p-Date.now();C>0&&await te(C,t.abortSignal);}if(!h?.success)try{h=await Do({action:async()=>JG({command:r,state:await YG(l,e,t.abortSignal),fixtures:t,useMemory:n,useConsensus:!0,highlightElementsOnFailure:!0,attemptNumber:d,logger:e}),frameConfig:r.iframeUrl?{type:"url",url:r.iframeUrl}:void 0,logger:e,browser:l});}catch(C){t.abortSignal.throwIfAborted(),y=C instanceof Error?C:new Error(`${C}`);}finally{d++;}h?.updatedMemory&&Af(r,h.updatedMemory,e);let S=h?.afterScreenshotOverride;if(S&&a.storeTraceAsset){let C=randomUUID();a.storeTraceAsset({snapshotId:C,data:S}),s.screenshotSnapshotId=C;}let b=h?.elementScreenshotOverride;if(b&&a.storeTraceAsset){let C=randomUUID();a.storeTraceAsset({snapshotId:C,data:b}),s.elementScreenshotSnapshotId=C;}if(!h?.success){s.result={thoughts:y?.message??"AI check failed after all attempts",result:!1};let C=`AI check still failing after ${d} attempts.`;throw y&&(C+=` Latest result: ${y.message}`),new w("AssertionFailureError",C)}return s.result={thoughts:h.thoughts,result:!0},{...h,succeedImmediately:!1,urlAfterCommand:l.url()}})}async function YG(r,e,t){await r.waitForPageLoad({signal:t});let[n,o]=await Promise.all([Hs(r,{abortSignal:t,skipWait:!0,skipWaitForPageLoad:!0,logger:e}),r.screenshot({retries:1,respectActiveFrame:!0})]);return {...n,screenshotBuff:o}}async function JG({command:r,state:e,fixtures:t,useConsensus:n,useMemory:o,highlightElementsOnFailure:i,attemptNumber:a,source:s,logger:l}){let {browser:c,generator:u,abortSignal:d}=t,{serializedTree:p,tree:f}=e,h=e.screenshotBuff,g=h.toString("base64"),y=c.url(),S=r.contextChoice??"MULTIMODAL",b=p;S!=="VISION_ONLY"&&(b=await sc({type:"assertion",serializedTree:p,tree:f,description:r.assertion,screenshot:g,fixtures:{generator:u,signal:d,logger:l,orgId:t.orgId}}),b);let C={goal:r.assertion,url:y,memory:o?r.cache?.memory:void 0,browserState:b,screenshot:g,contextChoice:S,source:s},O=await(S==="VISION_ONLY"?(R,_)=>u.getVisualAssertionResult(R,_):(R,_)=>u.getAssertionResult(R,_))(C,{useConsensus:n,attemptNumber:a,useMemory:o,disableCache:!!r.disableCache,abortSignal:d,logger:l,loggerTags:we(l)}),M;if((O.result||i)&&O.relevantElements?.length){O.relevantElements.map(R=>c.getSerializedFormFromA11yId(R)).filter(R=>!!R);try{let R=O.relevantElements[0],{resolution:_}=await c.createTargetFromA11yId({id:R,description:null,targetSource:"AI",skipSaveToCache:!0});M=await c.screenshot({locator:_.locator,clearHighlights:!0,respectActiveFrame:!0});}catch(R){l.debug({err:R},"Failed to capture element screenshot for trace, continuing...");}await Ehe(O.relevantElements,c,l);}return {success:O.result,thoughts:O.thoughts,afterScreenshotOverride:h,elementScreenshotOverride:M,updatedMemory:o?O.updatedMemory:void 0}}async function Ehe(r,e,t){let n=Date.now();for(let o of r){if(Date.now()-n>2e3){t.debug("Highlighting relevant elements took over 2s, aborting...");return}try{let i=new AbortController;await q(e.highlightA11yId(o),{milliseconds:1e3,fallback:()=>{throw i.abort(),new Error("Timed out waiting for highlighting to complete")}});}catch(i){t.debug({err:i},"Failed to highlight relevant element after assertion, continuing...");return}}}async function QG(r){let{command:e,logger:t,fixtures:n,disableCache:o}=r,{browser:i,generator:a,abortSignal:s}=n;if(!e.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(e.schema){let d=Lu(e.schema);if(d)throw new w("UserConfigurationError",d)}let l=await i.getCondensedHtml(),c=await i.screenshot({retries:2}),u=ur();try{return await u.startAsyncSpan("AI_EXTRACTION_CALL",async d=>{let m=await a.getTextExtraction({goal:e.goal,browserState:l,returnSchema:e.schema,screenshot:`data:image/jpeg;base64,${c.toString("base64")}`},{disableCache:o,abortSignal:s,loggerTags:we(t)});if(d.result=m,The({tracer:u,span:d,screenshot:c,htmlState:l,logger:t}),m.result==="NOT_FOUND")throw new w("ActionFailureError","No relevant data found for extraction goal on this page");if(m.thoughts?.includes("MaxGenerationLengthExceededError"))throw new w("UserConfigurationError",m.thoughts);return {thoughts:m.thoughts||void 0,data:m.result,succeedImmediately:!1,urlAfterCommand:i.url()}})}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 The(r){let{tracer:e,span:t,screenshot:n,htmlState:o,logger:i}=r;if(e.storeTraceAsset)try{let a=randomUUID();e.storeTraceAsset({snapshotId:a,data:n}),t.screenshotSnapshotId=a;let s=randomUUID();e.storeTraceAsset({snapshotId:s,data:Buffer.from(o),extension:"html"}),t.browserStateSnapshotId=s;}catch(a){i.debug({err:a},"Failed to store extraction trace assets");}}async function eW(r,e){let{logger:t}=r,{abortSignal:n,browser:o}=e,i=Date.now();try{await vhe(i,r,e);}catch(a){if(a instanceof Error&&(a.name==="AbortError"||a.name==="TimeoutError")||n.aborted)return;t.warn({err:a},"Unexpected error occurred during AI smart waiting");let s=o.smartWaitingTimeout-(Date.now()-i);s>0&&await te(s,n);}finally{t.debug({durationMs:Date.now()-i},"AI smart waiting complete");}}async function vhe(r,e,t){let{abortSignal:n,browser:o}=t;if(o.smartWaitingTimeout<3e3){await te(o.smartWaitingTimeout,n);return}if(!e.description)throw new w("UserConfigurationError","Cannot locate element with empty description");await q(Che(r,e,t),{milliseconds:o.smartWaitingTimeout});}async function Che(r,e,t){let{logger:n,iframeUrl:o}=e,{browser:i}=t;for(;Date.now()-r<i.smartWaitingTimeout;)if(await Do({action:async()=>whe(e,t),frameConfig:o?{type:"url",url:o}:void 0,browser:i,logger:n}))return}async function whe(r,e){let{testContext:t,logger:n}=r,{browser:o,abortSignal:i,localCodeEvalTools:a,orgId:s,generator:l}=e,c=r.description;t&&(c=await Ia({orgId:s,s:c,context:t,localTools:a,signal:i,logger:n})),i.throwIfAborted();let u;try{u=await o.screenshot({clearHighlights:!0,respectActiveFrame:!0,retries:2});}catch(f){throw new w("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 l.getSmartWaitingDecision({description:c,screenshot:m},{abortSignal:i,loggerTags:we(n)});return n.debug({result:p},"Got smart waiting result"),p.isPageReady}async function nW(r){return ur().startAsyncSpan("ELEMENT_ASSERTION",async t=>Ahe(r,t),{name:"Element check"})}async function Ahe(r,e){let{command:t,timeoutMs:n,fixtures:o,disableCache:i}=r,{abortSignal:a}=o,s=()=>fC(t.cache)?t.cache:void 0,l=s(),c=!i&&!!l?.target&&Lc(l.target),u=cloneDeep(l),d=(S=!1)=>{if(l=s(),!!l)if(S){let b=r1(u,l);l.target=b.target,l.updatedAt=b.updatedAt;}else {if(!u){l=void 0;return}l.target=u.target,l.updatedAt=u.updatedAt;}},m=Date.now(),p=0,f,h=500,g=!1;for(;p<2||Date.now()-m<n;){p++,p>1&&await te(h,a),a?.throwIfAborted(),l=s();let S=p===1,{result:b,elementWasFound:C}=await tW({cacheToUse:l,skipAISmartWaiting:!S,useAIIfCacheFails:!c,params:r});if(f=b,g=g||C,b.success)break;d(),h=Math.min(h*1.25,1e4);}if(!f)throw new w("InternalPlatformError",`Failed to evaluate manual element assertion in ${n}ms.`);if(a?.throwIfAborted(),!f.success){let S=s(),b=S?.target?.memory?{target:{id:-1,memory:S.target.memory}}:void 0,{result:C,elementWasFound:A}=await tW({cacheToUse:b,skipAISmartWaiting:!0,useAIIfCacheFails:!0,params:r});f=C,g=g||A,f.success||d(!0);}let y=s();return f.success&&y?.target&&!g&&(y.target=IR(y.target),y.updatedAt=new Date),e.result={success:f.success,message:f.err?.message},f}async function tW({cacheToUse:r,skipAISmartWaiting:e,useAIIfCacheFails:t,params:n}){let{command:o,disableCache:i,fixtures:a,tracer:s,targetingWrapper:l}=n,{logger:c}=a;if(o.target&&!Ja(o.target))throw new Error("Element assertion with x/y is not supported yet");let u=ad(o.assertion),d=Rhe(o.assertion),m,p=!1,f=cloneDeep(r);try{let{elementInteractedDisplayString:h,result:g,thoughts:y}=await l({tracer:s,command:o,target:o.target,cache:f?.target,action:async S=>xhe(S.locator,n),options:{...o,allowNotActionableNodesOverride:d,allowIneligibleTagRedirect:d,showZeroOpacityElementsOverride:!0,disableCache:i,memory:f?.target?.memory,disableGlobalLocatorRedirect:!0,source:lp(o),skipAISmartWaiting:e,targetName:"target"},retriesWithAI:t?1:0});return m={success:g.success,data:g.data,err:g.err,elementInteractedDisplayString:h,thoughts:y},p=!0,g.success||(c.warn({aiThoughts:y,elementString:h,err:g.err},"Element check found an element but failed"),m={...g,thoughts:y}),{result:m,elementWasFound:p}}catch(h){if(u)return m={success:!0,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 w)||h.reason!="ActionFailureError")throw h;return m={success:!1,err:h,data:void 0,thoughts:void 0},c.warn({err:h},"Element check did not find an element and failed"),{result:m,elementWasFound:p}}}function Rhe(r){return !(r.type==="ELEMENT_EXISTENCE"&&r.condition==="VISIBLE"&&!r.negated)}async function xhe(r,{command:e,fixtures:t}){return await t.browser.highlight(r),await Mhe(r,e.assertion)}async function Mhe(r,e){let t=!0,n,o;switch(e.type){case"ELEMENT_CONTENT":{let a=await r.textContent()??"";if(o={elementTextContent:tr(a,500,!0)},!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,n=new w("AssertionFailureError",`The content ${s} '${e.value}': ${a}`);}break}case"ELEMENT_ATTRIBUTE":{o={elementOuterHtml:tr(await r.evaluate(s=>s.cloneNode(!1).outerHTML),500,!0)};let a=null;try{a=await r.getAttribute(e.attr,{timeout:3e3});}catch(s){n=new w("AssertionFailureError",ne(s)),t=!1;break}if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,e.operation==="EXISTS"?n=new w("AssertionFailureError",`The attribute ${e.attr} ${s}`):n=new w("AssertionFailureError",`The attribute ${e.attr} ${s} '${e.value}': ${a}`);}break}case"ELEMENT_EXISTENCE":{switch(e.condition){case"VISIBLE":{t=await r.evaluate(async(s,l)=>{let c=Date.now();for(;Date.now()-c<l;){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 !0}return !1},yr*1e3);break}case"EDITABLE":{t=await r.isEditable({timeout:yr*1e3});break}case"EXISTS":{t=!0;break}case"ENABLED":{t=await r.isEnabled({timeout:yr*1e3});break}case"FOCUSED":{t=await r.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(t=e.negated?!t:t,!t){let a=wr(e);n=new w("AssertionFailureError",`The element ${a}`);}break}case"ELEMENT_NAME":{let a=await r.evaluate(s=>s.tagName);if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})){let s=wr(e);t=!1,n=new w("AssertionFailureError",`The element tag name ${s} '${e.value}': ${a}`);}break}case"ELEMENT_STYLE":{let a=await r.evaluate((s,l)=>window.getComputedStyle(s).getPropertyValue(l),e.property);if(!gn(a,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let s=wr(e);t=!1,e.operation==="EXISTS"?n=new w("AssertionFailureError",`The style property ${e.property} ${s}`):n=new w("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:t,data:o,err:n}}function oW(r){return r.type==="ELEMENT_EXISTENCE"&&r.negated&&r.condition==="EXISTS"}async function Yf(r,e){let t=await r.screenshot(e),n=await Jimp.fromBuffer(t);return {buffer:t,width:Math.ceil(n.bitmap.width??0),height:Math.ceil(n.bitmap.height??0)}}async function aW({tracer:r,command:e,disableCache:t,browser:n,targetingWrapper:o,logger:i,screenshotStorage:a}){if(e.target&&!Ja(e.target))throw new Error("Visual Diff with x/y is not supported yet");await n.waitForStability({logger:i});let s={clearHighlights:!0,hideCaret:!0},l;e.target?.elementDescriptor?l=(await o({tracer:r,command:e,target:e.target,cache:e.cache?.target,action:async k=>Yf(n,{locator:k.locator,...s}),options:{...e,disableCache:t,disableGlobalLocatorRedirect:!0,memory:e.cache?.target?.memory,targetName:"target"}})).result:l=await Yf(n,s);let c=await a.prepareGoldenScreenshotForComparison(i,e,l);if((l.height!==c.height||l.width!==c.width)&&i.warn({currHeight:l.height,currWidth:l.width,savedHeight:c.height,savedWidth:c.width},"Mismatched before and after visual diff screenshot sizes"),Math.abs(l.height-c.height)>10||Math.abs(l.width-c.width)>10){let _=`${l.width}x${l.height}`,k=`${c.width}x${c.height}`;return {fail:!0,thoughts:`Current screenshot (${_}) does not match saved screenshot dimensions (${k}) - did you change the size of the target or the viewport?`,beforeScreenshotOverride:c.buffer,afterScreenshotOverride:l.buffer,succeedImmediately:!1,urlAfterCommand:n.url()}}let u=await Jimp.fromBuffer(l.buffer),d={width:l.width,height:l.height},m=await Jimp.fromBuffer(c.buffer),p={width:c.width,height:c.height},f,h=d.width*d.height,g=p.width*p.height,y=Math.abs(d.height-p.height),S=Math.abs(d.width-p.width);if(h>g){let _=u.cover({w:p.width,h:p.height});l.buffer=await _.getBuffer("image/jpeg"),f="current",l.width=p.width,l.height=p.height;}else if(g>h){let _=m.cover({w:d.width,h:d.height});c.buffer=await _.getBuffer("image/jpeg"),f="saved";}let b={data:Buffer.alloc(l.width*l.height*4),width:l.width,height:l.height},C=e.threshold??.1,O=gde(TM.decode(c.buffer).data,TM.decode(l.buffer).data,b.data,l.width,l.height,{threshold:C,diffColorAlt:[0,255,0]})/(l.width*l.height)*100,M=O>C*100,R=`Visual diff of ${O.toFixed(2)}% detected, which is ${M?"over":"under"} the threshold of ${C*100}%.`;if(f&&(R+=` The ${f} screenshot was cropped since it was taller by ${y} pixels and wider by ${S} pixels.`),M)throw new w("ActionFailureError",R);return {fail:M,thoughts:R,beforeScreenshotOverride:l.buffer,afterScreenshotOverride:TM.encode(b,75).data,succeedImmediately:!1,urlAfterCommand:n.url()}}var Ihe=3e4;function Ohe(r){if(!r.body)return {};switch(r.body.type){case"json":return {content:r.body.content,contentType:"application/json"};case"form-urlencoded":{let e=new URLSearchParams;return Object.entries(r.body.content).forEach(([t,n])=>{e.append(t,n);}),{content:e.toString(),contentType:"application/x-www-form-urlencoded;charset=UTF-8"}}}}async function Id({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Ihe/1e3,i=Object.fromEntries(Object.entries(r.headers||{}).filter(([f,h])=>f&&h)),a=new URLSearchParams;Object.entries(r.params||{}).filter(([f,h])=>f&&h).forEach(([f,h])=>{a.append(f,h);});let s=a.toString(),l;if(ld(r.url)&&(l=r.url),t&&cd(r.url,t)&&(l=new URL(r.url,t).toString()),!l)throw new w("ActionFailureError",`Invalid URL: ${r.url}`);let c=l;e.info({url:c,searchParams:s,headers:i,body:r.body,method:r.method},"Making HTTP request");let d=await q((async()=>{let f=s?`${c}?${s}`:c;try{let h=Ohe(r),g=new Headers(i);return h.contentType&&!g.has("Content-Type")&&g.set("Content-Type",h.contentType),await n(f,{headers:g,method:r.method,body:h.content})}catch(h){throw new Error(`Failed to make HTTP request: ${h}`,{cause:h})}})(),{milliseconds:o*1e3,fallback:()=>{throw new w("ActionFailureError",`Fetch request timed out after ${o} seconds`)}});if(!d.ok){let f;try{f=await d.text();}catch(h){f=`Failed to read response body: ${h}`;}throw new w("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:r.method,headers:i}};if(r.body?.type==="json"&&r.body.content)try{p.request.json=JSON.parse(r.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 Nhe=5e3;async function cW({timeout:r=yr,...e}){let t=Date.now(),n=r*1e3,o=n+1e4,i,a=0,s=500;for(;a-t<n;){if(Date.now()-t>o){e.logger.warn("Exceeded max system timeout for page assertion, exiting...");break}e.signal?.throwIfAborted();let l=Date.now();i=await sW(e),a=Date.now();let c=a-l;if(c>1e3&&e.logger.warn({pageAssertDuration:c},"Page assertion took longer than expected"),!i.success)await te(s,e.signal),s=Math.min(Math.floor(s*1.5),Nhe);else return i}return i=await sW(e),i}async function sW(r){return ur().startAsyncSpan("PAGE_ASSERTION",async t=>{let n=await vM(r);return t.result={success:n.success,message:n.err?.message},n},{name:"Page check"})}async function vM({assertion:r,browser:e,autoExpandIframes:t}){switch(r.type){case"CONTENT":case"CONTENT":{let o,i=!1,a;try{let s;if(t){let l=await e.evaluateFunctionInAllFrames(lW,{value:r.value,negated:!!r.negated,returnHtml:!1});i=r.negated?l.every(c=>c.evaluation):l.some(c=>c.evaluation),s=l.find(c=>c.pageHtml)?.pageHtml;}else ({evaluation:i,pageHtml:s}=await e.evaluateFunctionInPage(lW,{value:r.value,negated:!!r.negated,returnHtml:!0},"checking page content"));if(!i){let l=r.negated?wa.CONTAINS:Aa.CONTAINS;a=new w("AssertionFailureError",`The page ${l} '${r.value}'.`),o=s;}}catch(s){a=new w("AssertionFailureError",`Failed to evaluate page content assertion: ${s instanceof Error?s.message:`${s}`}`);}return {success:i,err:a,data:i||!o?void 0:{pageContent:o}}}default:return (o=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}}function lW({value:r,negated:e,returnHtml:t}){let n=document.body.innerHTML,o=n.includes(r)===!e;return n.length>1e4&&(n=n.slice(0,1e4)+"...TRUNCATED"),{evaluation:o,pageHtml:!o&&t?n:void 0}}var Lhe=3e4;async function uW({command:r,logger:e,baseUrl:t,fetchImplementation:n=fetch}){let o=r.timeout??Lhe/1e3,i=new AbortController,a=Object.fromEntries(Object.entries(r.headers||{}).filter(([d,m])=>d&&m));a["Content-Type"]="application/json";let s;if(ld(r.url)&&(s=r.url),t&&cd(r.url,t)&&(s=new URL(r.url,t).toString()),!s)throw new w("ActionFailureError",`Invalid URL: ${r.url}`);let c=await q((async()=>{try{return await n(s,{headers:a,method:"POST",body:JSON.stringify({query:r.query,variables:r.variables?JSON.parse(r.variables):void 0}),signal:i.signal})}catch(d){throw new Error(`Failed to make HTTP request: ${d}`,{cause:d})}})(),{milliseconds:o*1e3});if(!c)throw new w("ActionFailureError",`GraphQL request timed out after ${o} seconds`);if(!c.ok){let d,m=await c.text();try{d=JSON.parse(m);}catch{throw new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${m}`)}throw d?.errors?.length&&d?.errors[0]?.message?new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${d.errors[0].message}`):new w("ActionFailureError",`GraphQL request failed with status ${c.status}: ${m}`)}let u={};return c.headers.forEach((d,m)=>{u[m]=d;}),{status:c.status,headers:u,json:await c.json()}}var rE=class{orgId;options;storage;localCodeEvalTools;uploadedFileStorage;visualDiffScreenshotStorage;browser;generator;executeAbortController=new AbortController;logger;executionOptionsStack=[];recordAbortController=null;registeredListeners={};recordedRequests={};constructor({browser:e,generator:t,logger:n,storage:o,orgId:i,localCodeEvalTools:a,uploadedFileStorage:s,visualDiffScreenshotStorage:l,options:c}){this.orgId=i,this.options=c,this.browser=e,this.browser.registerAbortSignal(this.executeAbortController.signal),this.storage=o,this.uploadedFileStorage=s,this.visualDiffScreenshotStorage=l,this.localCodeEvalTools=a,this.generator=t,this.logger=n;}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,t){this.executionOptionsStack.push(e);try{return await t()}finally{this.executionOptionsStack.pop();}}getCurrentExecutionOptions(){return this.executionOptionsStack[this.executionOptionsStack.length-1]??{}}async evaluateAiAction({goal:e,startingScreenshot:t,history:n,disableCache:o,langfuseSessionId:i,lastError:a,logger:s=this.logger}){let[l,c]=await Promise.all([Hs(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:s}),this.browser.screenshot({retries:1,clearHighlights:!0})]),u=`data:image/jpeg;base64,${c.toString("base64")}`,d=await sc({type:"ai-action",description:e,screenshot:u,serializedTree:l.serializedTree,tree:l.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:s,orgId:this.orgId}}),m={url:this.browser.url(),browserState:d,startingScreenshot:t,history:n,goal:e,screenshot:u,lastError:a};return await this.generator.getMultiturnAiActionEvaluation(m,{disableCache:o,abortSignal:this.executeAbortController.signal,loggerTags:{...we(s)},langfuseSessionId:i})}async promptToCommand({goal:e,startingScreenshot:t,history:n,actionHint:o,disableCache:i,logger:a=this.logger,langfuseSessionId:s}){let l=this.browser.url(),[c,u]=await Promise.all([Hs(this.browser,{abortSignal:this.executeAbortController.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:a}),this.browser.screenshot({retries:1,clearHighlights:!0})]),d=`data:image/jpeg;base64,${u.toString("base64")}`,m=await sc({type:"ai-action",description:e,screenshot:d,serializedTree:c.serializedTree,tree:c.tree,fixtures:{generator:this.generator,signal:this.executeAbortController.signal,logger:a,orgId:this.orgId}}),p={url:l,browserState:m,startingScreenshot:t,history:n,goal:e,actionHint:o,screenshot:d};try{return await this.generator.getMultiturnAiActionCommand(p,{disableCache:i,abortSignal:this.executeAbortController.signal,loggerTags:{...we(a)},langfuseSessionId:s})}catch(f){throw new w("InternalWebAgentError",`Error generating command: ${f instanceof Error?f.message:f}`,{errOptions:{cause:f}})}}async getBrowserState(e){return Hs(this.browser,e)}async locateElement(e){return await EM(e,this.getControllerFixtures())}async locateElementWithSelector(e,t){return Do({action:async()=>{let n=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:n}},frameConfig:t?{type:"url",url:t}: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??!0}async wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:n,descriptions:o,caches:i,action:a,options:s,retriesWithAI:l=1}){let c=[];for(let u=0;u<o.length;u++){let d=o[u],m=await this.wrapElementTargetingCommand({tracer:e,command:t,target:d,cache:i[u],action:async p=>p,options:{...s,targetName:n[u]}});c.push(m);}try{let u=await a(...c.map(p=>p.result)),d=p=>p==="fromTarget"?"From Target":p==="toTarget"?"To Target":"Target",m=c.map((p,f)=>p.thoughts?`${d(n[f])}: ${p.thoughts}`:void 0).filter(p=>!!p).join(" -------------- ")||void 0;return {result:u,elementInteractedDisplayStrings:c.map(p=>p.elementInteractedDisplayString),thoughts:m}}catch(u){if(this.throwIfClosed(),l>0)return this.logger.warn({err:u},"Failed to execute action with multiple cached targets, retrying with AI"),this.wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:n,descriptions:o,caches:o.map(()=>{}),action:a,options:s,retriesWithAI:l-1});throw new w("ActionFailureError",u.message,{errOptions:{cause:u}})}}async wrapHardcodedCssTargetingCommandHelper({target:e,action:t,options:n,command:o}){let i=this.logger.child({commandId:o.id}),{targetName:a}=n;if(e.type!=="description")throw new w("ActionFailureError","Cannot use selector with non-description target");let s,l=Date.now(),c=Date.now();for(;Date.now()-c<this.browser.smartWaitingTimeout;){l=Date.now();try{let u=await this.browser.resolveHardcodedCssSelector({selector:e.elementDescriptor,targetName:a,logger:i});return {result:await t({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()-l<500&&await te(500);}}throw s}async scrollIntoViewAndResolveFinalTarget(e){let{resolutionResult:t,disableGlobalLocatorRedirect:n,logger:o}=e,i=ur(),a=!n&&this.browser.userBrowserSettings.globalLocatorRedirect!==!1;(this.browser.userBrowserSettings.visualActions||a)&&await i.startAsyncSpan("SCROLL_ELEMENT_INTO_VIEW",async()=>{await this.browser.scrollIntoViewIfNeeded(t.locator);});let s;return a&&(s=await i.startAsyncSpan("LOCATOR_REDIRECT",async l=>{let{targetingResult:c,metadata:u}=await this.browser.performTargetRedirection(t,o);if(l.result=u,u.outcome==="redirected to new element"&&c&&i.storeTraceAsset&&!this.browser.userBrowserSettings.disableBrowserMonitoring){let d=randomUUID();(async()=>{try{let m=await this.browser.screenshot({locator:c.locator,clearHighlights:!0,boundingBoxOverride:c.serverSideBoundingBox??void 0});i.storeTraceAsset?.({snapshotId:d,data:m});}catch(m){o.debug({err:m},"Failed to capture element screenshot for redirect trace");}})(),l.elementScreenshotSnapshotId=d;}return c})),s||(s={locator:t.locator,serverSideBoundingBox:await t.locator.boundingBox({timeout:Ae}),originalElementLocationResult:t.originalElementLocationResult}),s}async resolveCachedTargetForAction(e){let{cache:t,options:n,logger:o}=e,a=await ur().startAsyncSpan("CACHE_RESOLUTION",async l=>{l.targetSource=t.targetSource;try{let c=await this.browser.resolveTarget(t,{allowNotActionableNodesOverride:n.allowNotActionableNodesOverride,logger:o,signal:this.executeAbortController.signal,...n.resolveTargetOptions,acceptElementMovedError:n.force});l.attributes.targetDisplayString=c.displayString,l.attributes.decisions=c.decisions;let u=c.decisions.find(d=>d.matched);return u&&(l.resolutionMethod=u.type),c}catch(c){throw c instanceof Ee&&(l.cacheMissReason=c.cacheMissReason,l.attributes.decisions=c.decisions),c}}),s=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:a,disableGlobalLocatorRedirect:n.disableGlobalLocatorRedirect,logger:o});return n.force||await a.revalidator?.(),{resolutionResult:a,finalTarget:s}}async wrapElementTargetingCommand(e){return await Do({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:t,target:n,action:o,options:i,command:a,finalAttempt:s=!1,originalCache:l=e.cache}=e,{retriesWithAI:c=1}=e,{disableCache:u,useSelector:d,targetName:m}=i,p=ur(),f=this.logger.child({commandId:a.id}),h=this.shouldUseMemory(),g=cloneDeep(e.cache);if((!g||u)&&!BO(n))throw new w("ActionFailureError","Cannot target element with no cached data or element descriptor");if(d)return this.wrapHardcodedCssTargetingCommandHelper(e);let y=!1,S;u&&(f.info("Cache explicitly disabled for this step"),y=!0,S="Cache explicitly disabled",g=void 0);let b=HG({cache:g,description:n.elementDescriptor,disableSecondaryCacheResolution:!!this.browser.userBrowserSettings.disableSecondaryCacheResolution,logger:f});g=b.cache,y=y||b.cacheBustedBeforeAction,!S&&b.cacheBustReason&&(S=b.cacheBustReason);let C=!0;if(!VG(g))return c--,C=!1,this.executeTargetingCommandWithAI({tracer:p,stepTracer:t,target:n,options:i,command:a,action:o,originalCache:l,logger:f,useMemory:h,cacheBustedBeforeAction:y,cacheBustReason:S});try{let{resolutionResult:A,finalTarget:O}=await this.resolveCachedTargetForAction({cache:g,options:i,logger:f}),M=await o(O);if(Et.increment("cache_target_resolution_v2",1,["outcome:hit","platform:web",`hasRequirements:${!!g.requirements}`,`hasAdditionalElements:${!!g.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.88.2"]),US({cmd:a,key:m,newTarget:g,logger:f,updatedWithAI:!1}),C){let R=A.decisions.filter(_=>_.matched);if(R.length!==1)f.warn({decisions:A.decisions},"Expected exactly 1 matching method for element location, got more or less");else {let _=R[0].type;t.recordTargetAutoHeal({healType:_});}}return {result:M,elementInteractedDisplayString:A.displayString}}catch(A){this.throwIfClosed();let O=xC(A);if(O&&!s)return f.warn({err:A},"Encountered error that is retryable with cache"),this.wrapElementTargetingCommandHelper({tracer:t,command:a,target:n,action:o,cache:l,originalCache:l,retriesWithAI:c,finalAttempt:!0,options:i});if(A instanceof w&&!O)throw f.warn({err:A},"Failed to execute command with target (fatal)"),A;if(c>0&&n){f.info({err:A},"Failed to execute action with cached target, retrying with AI"),Et.increment("cache_target_resolution_v2",1,["outcome:miss","platform:web",`hasRequirements:${!!g.requirements}`,`hasAdditionalElements:${!!g.additionalElements}`,`orgId:${this.orgId}`,"cliVersion:0.88.2",`missReason:${A instanceof Ee?A.cacheMissReason:"unknown"}`]);let M;return g.memory&&zO(g.memory)&&(M=g.memory),this.wrapElementTargetingCommandHelper({tracer:t,command:a,target:n,cache:void 0,action:o,originalCache:l,retriesWithAI:c,finalAttempt:!0,options:{...i,memory:M,targetHealingInProgress:!0}})}throw new w("ActionFailureError",`Failed to execute interactive command: ${A instanceof Error?A.message:`${A}`}`,{errOptions:{cause:A}})}}async executeTargetingCommandWithAI(e){let{tracer:t,stepTracer:n,target:o,options:i,command:a,action:s,originalCache:l,logger:c,useMemory:u,cacheBustedBeforeAction:d,cacheBustReason:m}=e;c.info({description:o.elementDescriptor,targetHealingInProgress:i.targetHealingInProgress,cacheBustedBeforeAction:d,memory:i.memory,useMemory:u},"Prompting AI for an updated element location");let p=!1;(d||!l)&&!this.getCurrentExecutionOptions().skipAISmartWaiting&&!i.skipAISmartWaiting?(await t.startAsyncSpan("SMART_WAITING",async()=>await eW({description:o.elementDescriptor,iframeUrl:i.iframeUrl,source:i.source,logger:c,allowNotActionableNodesOverride:i.allowNotActionableNodesOverride},this.getControllerFixtures())),p=!0):(d||!l)&&(i.skipAISmartWaiting?c.debug("Skipping AI smart waiting for this targeting attempt"):c.debug("Skipping AI smart waiting due to controller execution options"));let f=2;for(let h=1;h<=f;h++){let g=!1,y=this.browser.getActiveFrameConfig(),S=i.force||h>1;try{let b;try{b=await EM({description:o.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:c,skipWait:p,isAutoHeal:!!i.targetHealingInProgress,cacheBustReason:m,acceptElementMovedError:S},this.getControllerFixtures());}catch(O){if(O instanceof hi&&O.updatedLocatorMemory){let M={id:-1,...l,memory:O.updatedLocatorMemory};US({cmd:a,key:i.targetName,newTarget:M,logger:c,updatedWithAI:!0});}throw O}b.frameConfig&&(this.browser.setActiveFrameConfig(b.frameConfig),g=!0);let C=await this.scrollIntoViewAndResolveFinalTarget({resolutionResult:b.resolution,disableGlobalLocatorRedirect:i.disableGlobalLocatorRedirect,logger:c}),A=await s(C);return US({cmd:a,key:i.targetName,newTarget:b.target,logger:c,updatedWithAI:!0}),i.targetHealingInProgress&&(n.recordTargetAutoHeal({healType:"AI"}),b.target.targetSource="AI_HEALED",b.target.targetUpdateTime=new Date().toUTCString(),b.target.targetUpdateLoggerTags=we(c)),{result:A,elementInteractedDisplayString:b.resolution.displayString,thoughts:b.thoughts}}catch(b){if(g&&this.browser.setActiveFrameConfig(y),this.throwIfClosed(),h<f&&xC(b)){c.warn({err:b,aiAttempt:h},"Encountered retryable AI targeting error; retrying with AI once");continue}throw b instanceof w?b:new w("ActionFailureError",b.message)}}throw new w("ActionFailureError","Failed to execute AI targeting after retry")}async screenshotWithDimensions(e){return Yf(this.browser,e)}async executePresetCommand(e,t,n,o){this.options?.slowMoMs&&await te(this.options.slowMoMs);let i=await this.browser.getOpenPages(),a=this.browser.url(),s;try{s=await this.resolveCommandTemplateStrings(t,n);}catch(l){throw this.throwIfClosed(),new w("ActionFailureError",`Failed to substitute template strings in command: ${l.message}`,{errOptions:{cause:l}})}try{let l=await this.executePresetCommandHelper(e,t,n,o);return this.options?.autoFollowNewTabs&&await $G({beforeUrl:a,command:t,beforePages:i.map(c=>c.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{Rd(t,s);}}createCallbacksForBrowser(e){return {createIsolatedFolder:()=>Hx(e)}}async traceBrowserInteraction(e,t,n){return ur().startAsyncSpan("BROWSER_INTERACTION",async()=>t(),{name:e,...n})}async resolveCommandTemplateStrings(e,t){return Ad({obj:e,context:t,bannedKeys:["type","a11yData","thoughts","cache","code"],orgId:this.orgId,logger:this.logger,signal:this.executeAbortController.signal,localTools:this.localCodeEvalTools})}async executePresetCommandHelper(e,t,n,o){o=o||"disableCache"in t&&!!t.disableCache;let i=this.logger.child({commandId:t.id});switch(t.type){case"SUCCESS":{let a=t.condition;return a?.assertion.trim()?tE({command:a,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:i}):{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AI_ASSERTION":{if(!t.assertion.trim())throw new w("ActionFailureError","Missing assertion");if(t.timeout&&t.timeout>1800)throw new w("AssertionFailureError",`AI check timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);return tE({command:t,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory(),logger:i})}case"AI_EXTRACT":return QG({command:t,logger:i,fixtures:this.getControllerFixtures(),disableCache:o});case"NAVIGATE":if(!ld(t.url)&&!cd(t.url,this.browser.baseUrl))throw new w("ActionFailureError",`Invalid URL provided to navigate command: ${t.url}`);await this.traceBrowserInteraction("Navigate",()=>this.browser.navigate({url:t.url,loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0}));break;case"DIALOG":this.browser.registerDialogHandler(t.action);break;case"CAPTCHA":throw new w("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 a,s;if(t.target&&fi(t.target))await this.browser.hoverUsingVisualCoordinates(t.target.pixels);else if(t.target&&t.target.elementDescriptor.trim()){let{elementInteractedDisplayString:u,thoughts:d}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:m=>this.browser.hover(m),options:{...t,targetName:"target",disableGlobalLocatorRedirect:!0,disableCache:o}});a=u,s=d;}let l=this.browser.getViewport()?.height??es.height,c=this.browser.getViewport()?.width??es.width;switch(t.type){case"SCROLL_UP":await this.traceBrowserInteraction("Scroll up",()=>this.browser.scrollVertical(-(t.deltaY??l)));break;case"SCROLL_DOWN":await this.traceBrowserInteraction("Scroll down",()=>this.browser.scrollVertical(t.deltaY??l));break;case"SCROLL_LEFT":await this.traceBrowserInteraction("Scroll left",()=>this.browser.scrollHorizontal(-(t.deltaX??c)));break;case"SCROLL_RIGHT":await this.traceBrowserInteraction("Scroll right",()=>this.browser.scrollHorizontal(t.deltaX??c));break}return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"WAIT_FOR_URL":{if(t.timeout&&t.timeout>1800)throw new w("UserConfigurationError",`Wait for URL timeout of ${t.timeout} exceeds the maximum allowed value of 30 minutes.`);let a=t.matcher;await this.browser.waitForUrl({beforeUrl:this.browser.url(),matcher:a},{timeout:t.timeout?t.timeout*1e3:void 0,negated:t.negated,caseInsensitive:t.caseInsensitive});break}case"WAIT":{if(t.delay>1800)throw new w("UserConfigurationError",`Wait timeout of ${t.delay} seconds exceeds the maximum allowed value of 30 minutes`);let a=t.delay*1e3;await te(a,this.executeAbortController.signal);break}case"REFRESH":await this.traceBrowserInteraction("Refresh",()=>this.browser.refresh({loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0}));break;case"CLICK":{if(fi(t.target)){let{pixels:d}=t.target;await this.traceBrowserInteraction("Click",()=>this.browser.clickUsingVisualCoordinates(d,t),{coordinates:d});break}let a=this.browser.url(),{elementInteractedDisplayString:s,result:l,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,target:t.target,command:t,cache:t.cache?.target,action:d=>this.traceBrowserInteraction("Click",()=>this.browser.click(d,this.createCallbacksForBrowser(this.orgId),t),{selector:d.locator.toString()}),options:{...t,targetName:"target",disableCache:o}}),u={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:s,thoughts:c,data:l.downloadedFile?{downloadedFile:l.downloadedFile}:void 0};return JS(a,u.urlAfterCommand)&&(u.succeedImmediately=!0,u.succeedImmediatelyReason="URL changed"),u}case"COPY":return await this.browser.copy(t.value),{succeedImmediately:!1,data:t.value,urlAfterCommand:this.browser.url()};case"PASTE":{await this.browser.paste();break}case"DRAG":{if(fi(t.fromTarget)&&fi(t.toTarget)){let l=t.fromTarget.pixels,c=t.toTarget.pixels;await this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDropUsingVisualCoordinates(l,c,{hoverDurationMs:t.hoverSeconds?t.hoverSeconds*1e3:void 0}),{coordinates:l});break}if(fi(t.fromTarget)||fi(t.toTarget))throw new Error("Drag and drop targets must be both coordinates or both descriptions");let{elementInteractedDisplayStrings:a,thoughts:s}=await this.wrapMultiElementTargetingCommand({tracer:e,command:t,targetNames:["fromTarget","toTarget"],descriptions:[t.fromTarget,t.toTarget],caches:[t.cache?.fromTarget,t.cache?.toTarget],action:(l,c)=>this.traceBrowserInteraction("Drag",()=>this.browser.dragAndDrop(l,c,{hoverDurationMs:t.hoverSeconds?t.hoverSeconds*1e3:void 0,steps:t.steps})),options:{...t,disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a[0],thoughts:s}}case"MOUSE_DRAG":{let a=parseInt(t.deltaX),s=parseInt(t.deltaY),l=t.steps??5;if(isNaN(a)||isNaN(s))throw new w("ActionFailureError",`Invalid pixel values passed to mouse drag command: (${t.deltaX}, ${t.deltaY})`);if(t.target&&fi(t.target)){let d=t.target.pixels;await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDragUsingVisualCoordinates({deltaX:a,deltaY:s,steps:l,fromTarget:d}),{coordinates:d});break}let c,u;if(t.target?.elementDescriptor){let{elementInteractedDisplayString:d,thoughts:m}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:async p=>this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(a,s,l,p.locator,{force:t.force})),options:{...t,targetName:"target",disableCache:o}});c=d,u=m;}else await this.traceBrowserInteraction("Mouse drag",()=>this.browser.mouseDrag(a,s,l,void 0,{force:t.force}));return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:c,thoughts:u}}case"SELECT_OPTION":{if(!Ja(t.target))throw new Error("Select with x/y is not supported yet");let a=t.target.elementDescriptor,s=t.choice,{elementInteractedDisplayString:l,thoughts:c}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:{type:"description",elementDescriptor:a},cache:t.cache?.target,action:u=>this.traceBrowserInteraction("Select option",()=>this.browser.selectOption(u,s,t.force),{value:s.type==="LABEL"?s.label:s.type==="VALUE"?s.value:s.index}),options:{...t,targetName:"target",disableCache:o,source:lp(t)}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:l,thoughts:c}}case"TAB":{let a={loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0,retry:!0};await this.browser.switchToPage(t.action,a);break}case"NEW_TAB":await this.browser.createNewTab(t.url,{loadTimeoutMs:t.loadTimeout?t.loadTimeout*1e3:void 0});break;case"CLOSE_TAB":await this.browser.closePage(t.action,{retry:!0});break;case"COOKIE":{if(!t.value)break;let a=await this.browser.setCookie(t.value);i.debug({results:a},"Set cookies");break}case"LOCAL_STORAGE":if(!t.value||!t.key)break;await this.browser.setLocalStorage(t.key,t.value);break;case"JAVASCRIPT":{let a;try{t.environment==="BROWSER"?(a=await this.browser.evaluateCodeInPage({code:t.code,fragment:t.fragment??!1,context:n.toObjectCopy(),timeoutMs:t.timeout?t.timeout*1e3:void 0}),i.info({result:a},"Executed JavaScript in browser")):a=await Oo({orgId:this.orgId,code:t.code,fragment:!!t.fragment,context:n,timeoutMs:t.timeout?t.timeout*1e3:void 0,logger:i,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal,callbacks:{onPersistentVariableUpdates:async s=>{if(!this.options?.scratchPadId){i.warn({updates:s},"Got persistent variable updates but scratch pad is not available");return}await this.storage.savePersistentVariables?.({scratchPadId:this.options?.scratchPadId,orgId:this.orgId,updates:s,logger:i});}}});}catch(s){throw this.throwIfClosed(),new w("ActionFailureError",s instanceof Error?s.message:`${s}`,{errOptions:{cause:s}})}try{JSON.stringify(a);}catch(s){throw new w("ActionFailureError",`Return value is not serializable: ${s instanceof Error?s.message:`${s}`}`,{errOptions:{cause:s}})}return {urlAfterCommand:this.browser.url(),succeedImmediately:!1,data:a}}case"TYPE":{if(t.target&&fi(t.target)){await this.browser.clickUsingVisualCoordinates(t.target.pixels,t),await this.traceBrowserInteraction("Type",()=>this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter},!0),{value:t.value});break}let a=this.browser.url(),s,l,c=cloneDeep(t.target),u=this.browser.userBrowserSettings.globalLocatorRedirect===void 0||this.browser.userBrowserSettings.globalLocatorRedirect==="always";if(c){let{elementInteractedDisplayString:m,thoughts:p}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:c,cache:t.cache?.target,action:f=>this.traceBrowserInteraction("Type",()=>this.browser.typeIntoTarget(t.value,f,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter,relativePosition:t.relativePosition}),{value:t.value,selector:f.locator.toString()}),options:{...t,targetName:"target",disableCache:o,disableGlobalLocatorRedirect:!u,source:lp(t)}});s=m,l=p;}else await this.traceBrowserInteraction("Type",()=>this.browser.type(t.value,{force:t.force,clearContent:t.clearContent,forceClearContent:t.forceClearContent,delay:t.delay,pressEnter:t.pressEnter},!0),{value:t.value});let d={urlAfterCommand:this.browser.url(),succeedImmediately:!1,elementInteracted:s,thoughts:l};return JS(a,d.urlAfterCommand)&&(d.succeedImmediately=!0,d.succeedImmediatelyReason="URL changed"),d}case"HOVER":{if(fi(t.target)){let{pixels:l}=t.target;await this.traceBrowserInteraction("Hover",()=>this.browser.hoverUsingVisualCoordinates(l),{coordinates:l});break}let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:l=>this.traceBrowserInteraction("Hover",()=>this.browser.hover(l,{relativePosition:t.relativePosition}),{selector:l.locator.toString()}),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"FOCUS":{if(!Ja(t.target))throw new Error("Focus with x/y is not supported yet");let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,command:t,target:t.target,cache:t.cache?.target,action:l=>this.browser.focus(l),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"BLUR":{if(t.target&&!Ja(t.target))throw new Error("Blur with x/y is not supported yet");if(!t.target||!t.target.elementDescriptor)return await this.browser.blur(null),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};let{elementInteractedDisplayString:a,thoughts:s}=await this.wrapElementTargetingCommand({tracer:e,target:t.target,command:t,cache:t.cache?.target,action:l=>this.browser.blur(l),options:{...t,targetName:"target",disableCache:o}});return {succeedImmediately:!1,urlAfterCommand:this.browser.url(),elementInteracted:a,thoughts:s}}case"PRESS":{let a=this.browser.url();await this.traceBrowserInteraction("Press key",()=>this.browser.press(t.value,{repeat:t.repeat,convertMeta:t.convertMeta??!0,delayMs:t.delayMs}),{value:t.value});let s={urlAfterCommand:this.browser.url(),succeedImmediately:!1};return JS(a,s.urlAfterCommand)&&(s.succeedImmediately=!0,s.succeedImmediatelyReason="URL changed"),s}case"KEY_DOWN":return await this.browser.keyDown(t.value,{convertMeta:t.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"KEY_UP":return await this.browser.keyUp(t.value,{convertMeta:t.convertMeta??!0}),{urlAfterCommand:this.browser.url(),succeedImmediately:!1};case"REQUEST":{let a=new CookieJar,s=khe(fetch,a),l;try{l=new URL(t.url).hostname;}catch{}let c=await Id({command:t,baseUrl:this.browser.baseUrl,logger:i,fetchImplementation:s});return {data:Bc.parse({...c,cookies:gu(a,l)}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GRAPHQL_REQUEST":return {data:await uW({command:t,baseUrl:this.browser.baseUrl,logger:i}),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"VISUAL_DIFF":return aW({tracer:e,command:t,disableCache:o,browser:this.browser,logger:i,screenshotStorage:this.visualDiffScreenshotStorage,targetingWrapper:a=>this.wrapElementTargetingCommand(a)});case"FILE_UPLOAD":{let a,s;if(t.fileSource.type==="URL"?(s=t.fileSource.url,a=await aj({uri:t.fileSource.url,logger:i,orgId:this.orgId})):t.fileSource.type==="USER_FILE"&&(s=t.fileSource.name,a=await this.uploadedFileStorage?.getFileForUpload(t.fileSource.name,this.orgId)),!a)throw new w("UserConfigurationError",`Attempted to use non-existent file for upload step: ${s}`);await this.browser.setFileChooserHandler({...a,filename:t.filename});break}case"AUTH_SAVE":return {data:await this.browser.saveAuthState(),succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"AUTH_LOAD":{let a;if(!t.storageState.trim())a=void 0;else if(a=await Oo({orgId:this.orgId,code:t.storageState,fragment:!1,context:n,logger:i,localTools:this.localCodeEvalTools,signal:this.executeAbortController.signal}),typeof a!="object")throw new w("ActionFailureError",`Credentials must evaluate to an object (received ${typeof a} instead)`);let s;try{s=GD.optional().parse(a);}catch(l){throw new w("ActionFailureError",`Credentials provided do not follow the required format: ${l}`)}await this.browser.loadAuthState(s);break}case"ELEMENT_CHECK":{let a=(t.timeout??yr)*1e3,s=this.generator.getAgentConfig()?.assertion;if(oW(t.assertion)&&!t.useSelector&&t.target.type==="description"&&s&&s!=="v1"){let c={id:t.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: ${t.target.elementDescriptor}`,iframeUrl:t.iframeUrl,timeout:t.timeout,source:"NEGATED_CHECK",cache:t.cache&&"memory"in t.cache?{memory:t.cache?.memory}:void 0};try{let u=await tE({command:c,logger:i,fixtures:this.getControllerFixtures(),useMemory:this.shouldUseMemory()});return {succeedImmediately:!1,thoughts:`The element described does not exist on the page: ${u.thoughts}`,urlAfterCommand:this.browser.url(),afterScreenshotOverride:u.afterScreenshotOverride}}finally{c.cache?.memory&&Af(t,c.cache?.memory.traces,i);}}let l=await nW({command:t,tracer:e,timeoutMs:a,targetingWrapper:c=>this.wrapElementTargetingCommand(c),fixtures:this.getControllerFixtures(),disableCache:o});return {fail:!l.success,data:l.data,elementInteracted:l.elementInteractedDisplayString,thoughts:l.err?.message??l.thoughts??`Element assertion ${l.success?"succeeded":"failed"}.`,succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"PAGE_CHECK":{let a=await Do({action:async()=>cW({assertion:t.assertion,browser:this.browser,logger:i,timeout:t.timeout,signal:this.executeAbortController.signal,autoExpandIframes:!!this.browser.userBrowserSettings.autoExpandIframes}),frameConfig:t.iframeUrl?{type:"url",url:t.iframeUrl}:void 0,browser:this.browser,logger:i});return {fail:!a.success,data:a.data,thoughts:a.success?"Page assertion passed.":a.err?.message??`Page assertion still failing after ${t.timeout} seconds.`,urlAfterCommand:this.browser.url(),succeedImmediately:!1}}case"REGISTER_REQUEST_LISTENER":{let a=new zs(t.requestMatcher),s=this.browser.registerRequestListener(a);return this.registeredListeners[t.key]=s.then(async l=>await qx(l)).catch(l=>{i.error({err:l},"Failed to get request listener response");}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"AWAIT_LISTENER":{let a=this.registeredListeners[t.key];if(!a)throw new w("ActionFailureError",`No listener registered with key: ${t.key}`);let s=t.timeout??10;return {data:await q(a,{milliseconds:s*1e3,message:`Request listener timed out after ${s} seconds`}),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"RECORD_REQUESTS":{let a=new zs(t.requestMatcher);return this.recordedRequests[t.key]={},this.browser.registerRequestRecorder(t.key,{matches:s=>a.matches({url:s.request.url,method:s.request.method}),onRequestStart:(s,l)=>{this.recordedRequests[t.key][s]=$b(l);},onRequestComplete:(s,l)=>{this.recordedRequests[t.key]?.[s]&&(this.recordedRequests[t.key][s]=$b(l));}}),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"GET_RECORDED_REQUESTS":{let a=this.recordedRequests[t.key];if(!a)throw new w("ActionFailureError",`No recorder registered with key: ${t.key}`);return delete this.recordedRequests[t.key],{data:Object.values(a),succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"SET_HEADER":{let a;return t.requestMatcher&&(a=new zs(t.requestMatcher)),this.browser.setHeader(t.name,t.value,a),{succeedImmediately:!1,urlAfterCommand:this.browser.url()}}case"MOCK_ROUTE":return {data:{key:this.browser.registerMock(t.key,new zs(t.requestMatcher),async(s,l)=>{let c=await Oo({orgId:this.orgId,code:t.responseGenerator,fragment:!1,context:n,timeoutMs:void 0,logger:i,localTools:this.localCodeEvalTools,mock:{request:s,response:l},disallowVariableUpdates:!0,responseSerialization:"RESPONSE"}),u=b0.parse(c);return new Response(u.body,{status:u.status,headers:u.headers})},t.fetchOriginalResponse??!1)},succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"REMOVE_ROUTE_MOCK":return this.browser.removeMock(t.key),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};case"OFFLINE_MODE":return await this.browser.setOfflineMode(t.enable),{succeedImmediately:!1,urlAfterCommand:this.browser.url()};default:return (s=>{throw "If Typescript complains about the line below, you missed a case or break in the switch above"})()}return {succeedImmediately:!1,urlAfterCommand:this.browser.url()}}async getReverseMappedDescription({browserState:e,targetId:t,disableCache:n,screenshot:o}){return (await this.generator.getReverseMappedDescription({browserState:e,target:t,screenshot:o},{disableCache:n,abortSignal:this.executeAbortController.signal,loggerTags:we(this.logger)})).phrase}async stopRecordMode(){this.recordAbortController?.abort(),await this.browser.clearAllCdpHighlights();}async startRecordMode({params:e,abortController:t,isClickToRecord:n}){this.recordAbortController=t;let o=new Yb({signal:t.signal,...e});return await this.browser.startRecording(this.recordAbortController.signal,o,n),o}async runSectionAutohealing(e){return this.generator.getAutohealingProposal(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:we(this.logger)})}async getFailureRecoveryPlan(e,t){return this.generator.getFailureRecoveryPlan(e,{disableCache:!0,abortSignal:this.executeAbortController.signal,loggerTags:we(t??this.logger)})}};function yt({text:r,section:e}){if(!e)return [{type:"text",text:r}];let t=`### ${e}`;return r.length===0?[{type:"text",text:t}]:[{type:"text",text:`${t}
|
|
5211
5211
|
${r}`}]}function wM({base64Data:r,mediaType:e,section:t}){return t?[{type:"text",text:`### ${t}`},{type:"media",data:r,mediaType:e}]:[{type:"media",data:r,mediaType:e}]}function Jf(r){if(r.length===0)throw new dn("No content parts provided to construct the tool response content.");return {type:"content",value:r}}function mW({projectRoot:r,filePath:e,pathLabel:t="path"}){if(!e||!xr__default.isAbsolute(e))return e;let n=xr__default.relative(r,e);if(n.startsWith("..")||xr__default.isAbsolute(n))throw new Error(`Error: ${t} "${e}" must be inside project root "${r}".`);return n}function pW(r){return r.map(e=>{switch(e.type){case"text":return e;case"media":return {type:"image",data:e.data,mimeType:e.mediaType};default:return (n=>{throw new Error("Unhandled content part")})()}})}var AM="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 nE(r){return `${AM} ${r}`}function js(r,e){if(r===e)return !0;let t=n=>n.startsWith(AM)?n.slice(AM.length).trim():n;return t(r)===t(e)}var Uhe=[401,403,408,409,413,429,498,500,502,503,504],Bhe=["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","server_error","you can retry your request","429","500","502","503","504"];function fW(r){if(r&&typeof r=="object"&&"statusCode"in r){let t=r.statusCode;if(typeof t=="number"&&(Uhe.includes(t)||t>500))return !0}let e=hW(r).toLowerCase();return Bhe.some(t=>e.includes(t))}function hW(r){if(r instanceof Error){let e="cause"in r?r.cause:void 0,t="code"in r&&typeof r.code=="string"?r.code:"";return `${r.name} ${r.message} ${t} ${hW(e)}`}if(typeof r=="string")return r;if(r&&typeof r=="object")try{return JSON.stringify(r)}catch{return ""}return ""}function yW(r){return new RM(r)}var RM=class{specificationVersion="v2";settings;retryAfterOutput;models;constructor(e){if(this.settings=e,this.models=[...e.models],this.retryAfterOutput=e.retryAfterOutput??!0,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 t=await this.currentModel.doStream(e);return {...t,stream:this.createRetryingStream({stream:t.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):fW(e)}async notifyError(e){await this.settings.onError?.(e,this.modelId);}async retry(e){let t=this.models.length;for(let n=0;n<t;n++)try{return await e()}catch(o){if(!this.shouldRetry(o)||(await this.notifyError(o),this.moveCurrentModelToBack(),n===t-1))throw o}throw new Error("No models available in settings")}createRetryingStream(e){let{stream:t,options:n}=e,o={hasStreamedAny:!1,hasEmittedClientExecutedToolCall:!1,remainingFallbackAttempts:this.models.length-1};return new ReadableStream({start:async i=>{let a;try{a=t.getReader(),await this.pipeStreamToController({reader:a,controller:i,retryState:o}),i.close();}catch(s){await this.retryStreamAfterError({error:s,options:n,controller:i,retryState:o});}finally{gW(a);}}})}async pipeStreamToController(e){let{reader:t,controller:n,retryState:o}=e,i=await t.read();for(;!i.done;){let a=i.value;if(o&&a.type==="error"&&this.shouldRetry(a.error))throw a.error;n.enqueue(a),o&&(o.hasStreamedAny||=a.type!=="stream-start",a.type==="tool-call"&&a.providerExecuted!==!0&&(o.hasEmittedClientExecutedToolCall=!0)),i=await t.read();}}async retryStreamAfterError(e){let{error:t,options:n,controller:o,retryState:i}=e;if(!this.shouldRetry(t)){o.error(t);return}if(await this.notifyError(t),i.hasEmittedClientExecutedToolCall||i.hasStreamedAny&&!this.retryAfterOutput||i.remainingFallbackAttempts<=0){o.error(t);return}this.moveCurrentModelToBack(),i.remainingFallbackAttempts-=1;let a;try{a=(await this.currentModel.doStream(n)).stream.getReader(),await this.pipeStreamToController({reader:a,controller:o,retryState:i}),o.close();}catch(s){await this.retryStreamAfterError({error:s,options:n,controller:o,retryState:i});}finally{gW(a);}}};function gW(r){try{r?.releaseLock();}catch{}}var $he=new Set(["itemId","reasoningEncryptedContent"]);function SW({model:r,logger:e,logMessage:t}){return wrapLanguageModel({model:r,middleware:{transformParams:async({params:o})=>{let{messages:i,wasPruned:a}=Vhe(o.prompt);return a&&e.info({messageCount:i.length,fallbackModel:r.modelId},t),{...o,prompt:i}}}})}function Vhe(r){let e=!1,t=[];for(let n of r){let{message:o,wasPruned:i}=Hhe(n);e=e||i,o&&t.push(o);}return {messages:t,wasPruned:e}}function Hhe(r){let e=bW(r.providerOptions),t=e.wasPruned;switch(r.role){case"system":return {message:{...r,providerOptions:e.providerOptions},wasPruned:t};case"assistant":{let n=[];for(let i of r.content){if(i.type==="reasoning"){t=!0;continue}n.push(i);}let o=xM(n);return t=t||o.wasPruned,o.parts.length===0?{message:void 0,wasPruned:!0}:{message:{...r,content:o.parts,providerOptions:e.providerOptions},wasPruned:t}}case"user":{let n=xM(r.content);return t=t||n.wasPruned,{message:{...r,content:n.parts,providerOptions:e.providerOptions},wasPruned:t}}case"tool":{let n=xM(r.content);return t=t||n.wasPruned,{message:{...r,content:n.parts,providerOptions:e.providerOptions},wasPruned:t}}}}function bW(r){if(!r)return {providerOptions:r,wasPruned:!1};let e=!1,t={};for(let[n,o]of Object.entries(r)){let i={};for(let[a,s]of Object.entries(o)){if($he.has(a)){e=!0;continue}i[a]=s;}Object.keys(i).length>0&&(t[n]=i);}return {providerOptions:Object.keys(t).length>0?t:void 0,wasPruned:e}}function xM(r){let e=!1;return {parts:r.map(t=>{let n=jhe(t);return e=e||n.wasPruned,n.part}),wasPruned:e}}function jhe(r){let e=bW(r.providerOptions);return e.wasPruned?{part:{...r,providerOptions:e.providerOptions},wasPruned:!0}:{part:r,wasPruned:!1}}var Zf="openai-websocket";function EW(r){if(!r||typeof r!="object"||!("modelId"in r))return !1;let e=r.modelId;return typeof e=="string"&&e.startsWith(`${Zf}/`)}function vW(){let r=new Map;return {get(e){return r.get(e)},set(e,t){r.set(e,t);}}}var Xhe=vW();function oE(r){let{providerFallback:e,prepareStep:t,onChunk:n,streamTelemetry:o,...i}=r,a=wW(e);return streamText({...i,prepareStep:ege(t),onChunk:Yhe({logger:e.logger,onChunk:n,telemetry:o}),model:a})}async function CW(r){let{providerFallback:e,...t}=r,n={...e,websocketFirst:void 0},o=wW(n),i=streamObject({...t,model:o,output:"object"});return await consumeStream({stream:i.fullStream,onError(a){throw a}}),i.object}function Yhe(r){let{logger:e,onChunk:t,telemetry:n}=r;if(!n)return t;let o=new Map;return async i=>{Jhe({logger:e,buffers:o,telemetry:n,chunk:i.chunk}),await t?.(i);}}function Jhe(r){let{logger:e,buffers:t,telemetry:n,chunk:o}=r;if(o.type==="text-delta"&&n.textDeltas){TW({logger:e,buffers:t,telemetry:n,chunk:o});return}if(o.type==="reasoning-delta"&&n.reasoningDeltas){TW({logger:e,buffers:t,telemetry:n,chunk:o});return}if(o.type==="text-end"||o.type==="reasoning-end"){_M({logger:e,buffers:t,telemetry:n,id:o.id,kind:o.type==="text-end"?"text-delta":"reasoning-delta",flushReason:"end"});return}(o.type==="finish"||o.type==="abort"||o.type==="error")&&Qhe({logger:e,buffers:t,telemetry:n,flushReason:o.type});}function TW(r){let{logger:e,buffers:t,telemetry:n,chunk:o}=r,i=`${o.type}:${o.id}`,s=t.get(i)??{id:o.id,kind:o.type,text:"",deltaCount:0,timer:void 0};s.timer&&clearTimeout(s.timer),s.text+=o.text,s.deltaCount+=1,s.timer=setTimeout(()=>{_M({logger:e,buffers:t,telemetry:n,id:o.id,kind:o.type,flushReason:"debounce"});},n.debounceMs??2e3),Zhe(s.timer),t.set(i,s);}function Zhe(r){if(typeof r!="object"||r===null||!("unref"in r))return;let e=r.unref;typeof e=="function"&&e.call(r);}function _M(r){let{logger:e,buffers:t,telemetry:n,id:o,kind:i,flushReason:a}=r,s=`${i}:${o}`,l=t.get(s);if(!l)return;l.timer&&clearTimeout(l.timer),t.delete(s);let c=n.maxLoggedChars,u=typeof c=="number"&&l.text.length>c?l.text.slice(0,c):l.text;e.info({...n.attributes,chunkId:l.id,chunkType:l.kind,deltaCount:l.deltaCount,flushReason:a,text:u,textLength:l.text.length,truncated:u.length!==l.text.length},`streamText ${i}`);}function Qhe(r){let{logger:e,buffers:t,telemetry:n,flushReason:o}=r;for(let i of Array.from(t.values()))_M({logger:e,buffers:t,telemetry:n,id:i.id,kind:i.kind,flushReason:o});}function ege(r){if(r)return e=>{if(!EW(e.model))return r(e)}}function wW(r){let e=r.scopeKey,t=e?r.state??Xhe:vW(),n=tge({...r,scopeKey:e,state:t});if(n.length===0)throw new Error("No streamText fallback providers configured");return yW({models:n.map(o=>o.model),retryAfterOutput:!0,onError:async(o,i)=>{let a=n.find(s=>s.model.modelId===i)?.id??i;r.logger.warn({err:o,modelId:i,providerId:a},"streamText provider failed, trying next fallback"),await r.onError?.({error:IN(o),failedProviderId:a,failedModelId:i});}})}function tge(r){let e=r.scopeKey?r.state.get(r.scopeKey):void 0;if(r.websocketFirst?.enabled&&(!e||e===r.websocketFirst.provider.id))return [MM({candidate:r.websocketFirst.provider,config:r,pruneProviderState:!1}),...r.providers.map(i=>MM({candidate:i,config:r,pruneProviderState:!0}))];let t=e?r.providers.findIndex(i=>i.id===e):-1,n=t>=0?t:0;return [...r.providers.slice(n),...r.providers.slice(0,n)].map((i,a)=>MM({candidate:i,config:r,pruneProviderState:a>0}))}function MM(r){let{candidate:e,config:t,pruneProviderState:n}=r,o=rge({model:e.model,providerId:e.id,scopeKey:t.scopeKey,state:t.state});return n&&(o=SW({model:o,logger:t.logger,logMessage:"Stripped provider-local state from streamText fallback step"})),{...e,model:o}}function rge(r){let{model:e,providerId:t,scopeKey:n,state:o}=r;return wrapLanguageModel({model:e,middleware:{overrideModelId:()=>`${t}/${e.modelId}`,wrapGenerate:async({doGenerate:i})=>{let a=await i();return n&&o.set(n,t),a},wrapStream:async({doStream:i})=>{let a=await i();return {...a,stream:nge({stream:a.stream,providerId:t,scopeKey:n,state:o})}}}})}function nge(r){let{stream:e,providerId:t,scopeKey:n,state:o}=r,i=!1,a,s=!1;return new ReadableStream({async start(l){a=e.getReader();try{for(;;){let{done:c,value:u}=await a.read();if(c)break;!i&&u.type!=="stream-start"&&u.type!=="error"&&(i=!0,n&&o.set(n,t)),l.enqueue(u);}s||l.close();}catch(c){s||l.error(c);}finally{a.releaseLock(),a=void 0;}},cancel(l){return s=!0,a?.cancel(l)}})}async function oge(r){let{agentConfig:e,streamResponseMessages:t,userMessage:n,...o}=r,i={role:"user",content:n};return CW({...o,providerFallback:e.providerFallback,system:e.system,providerOptions:e.providerOptions,messages:[...e.messages??[],...t,i]})}async function Qf({validate:r,maxAttempts:e,logger:t,...n}){let o;for(let i=1;i<=e;i++){n.abortSignal?.throwIfAborted();try{let a=await oge(n);return await r(a),a}catch(a){if(n.abortSignal?.aborted||(o=a,i===e))throw a;t.warn({err:a,attempt:i,nextAttempt:i+1},"Failed to validate generated object to repair missing submission tool call, retrying");}}throw o}var AW=z.object({type:z.literal("tool-call"),toolCallId:z.string(),toolName:z.string(),input:z.unknown()}).passthrough(),ige=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()})]))}),age=z.discriminatedUnion("type",[z.object({type:z.literal("text"),value:z.string()}),z.object({type:z.literal("json"),value:z.unknown()}),z.object({type:z.literal("error-text"),value:z.string()}),z.object({type:z.literal("error-json"),value:z.unknown()}),ige]),RW=z.object({type:z.literal("tool-result"),toolCallId:z.string(),toolName:z.string(),output:age}).passthrough(),xW=z.object({text:z.string()}).passthrough();var MW=2,sge=1600,lge=.3,lc="[trimmed: omitted due to context budget]",IW="[screenshot truncated]",OW="[browser state truncated]",NW={_momenticTrimmed:!0,summary:lc},LW={type:"text",value:lc},cge=z.object({type:z.literal("text"),value:z.literal(lc)}),uge=["reasoning","tool-result","image","tool-call","text"];function DW(r){let{messages:e,phase1:t,phase2:n,logger:o}=r,i=dge(e,t.toolResultPruningRules??[],{trimReasoning:t.trimReasoning??!1});if(typeof t.numScreenshots=="number"&&(i=mge(i,t.numScreenshots)),typeof t.numBrowserStates=="number"&&t.browserStateMarkers&&t.browserStateMarkers.length>0&&(i=yge(i,t.numBrowserStates,t.browserStateMarkers)),!n)return i;let a=At(i);return a<=n.tokensThreshold||(o.info({totalTokens:a,threshold:n.tokensThreshold,target:n.targetTokens,messageCount:i.length,breakdown:PW(i)},"Phase 2 triggered \u2014 token breakdown before compaction"),i=Lge(i,n.targetTokens,o),o.info({totalTokens:At(i),messageCount:i.length,breakdown:PW(i)},"Phase 2 complete \u2014 token breakdown after compaction")),i}function dge(r,e,t){let n=r;t.trimReasoning&&(n=n.map((o,i)=>o.role!=="assistant"?o:Pge(o,i===r.length-1)));for(let o of e)n=vge(n,o);return n}function mge(r,e){let t={count:e},n=[...r];for(let o=n.length-1;o>=0;o--)n[o]=pge(n[o],t);return n}function pge(r,e){if(r.role==="user"){if(typeof r.content=="string")return r;let t=fge(r.content,e);return {...r,content:t}}if(r.role==="tool"){let t=hge(r.content,e);return {...r,content:t}}return r}function fge(r,e){let t=[...r];for(let n=t.length-1;n>=0;n--)if(t[n].type==="image"){if(e.count>0){e.count--;continue}t[n]={type:"text",text:IW};}return t}function hge(r,e){let t=[...r];for(let n=t.length-1;n>=0;n--){let o=t[n];if(o.output.type!=="content")continue;let i=gge(o.output.value,e);i!==o.output.value&&(t[n]={...o,output:{...o.output,value:i}});}return t}function gge(r,e){let t=[...r],n=!1;for(let o=t.length-1;o>=0;o--)if(t[o].type==="media"){if(e.count>0){e.count--;continue}t[o]={type:"text",text:IW},n=!0;}return n?t:r}function yge(r,e,t){let n={count:e},o=[...r];for(let i=o.length-1;i>=0;i--)o[i]=Sge(o[i],n,t);return o}function Sge(r,e,t){if(r.role==="user"){if(typeof r.content=="string")return r;let n=bge(r.content,e,t);return {...r,content:n}}if(r.role==="tool"){let n=Ege(r.content,e,t);return {...r,content:n}}return r}function bge(r,e,t){let n=[...r];for(let o=n.length-1;o>=0;o--){let i=n[o];if(!(i.type!=="text"||!kW(i.text,t))){if(e.count>0){e.count--;continue}n[o]={type:"text",text:OW};}}return n}function Ege(r,e,t){let n=[...r];for(let o=n.length-1;o>=0;o--){let i=n[o];if(i.output.type!=="content")continue;let a=Tge(i.output.value,e,t);a!==i.output.value&&(n[o]={...i,output:{...i.output,value:a}});}return n}function Tge(r,e,t){let n=[...r],o=!1;for(let i=n.length-1;i>=0;i--){let a=n[i];if(!(a.type!=="text"||!kW(a.text,t))){if(e.count>0){e.count--;continue}n[i]={type:"text",text:OW},o=!0;}}return o?n:r}function kW(r,e){for(let t of e)if(r.includes(t))return !0;return !1}function vge(r,e){let t=new Set;for(let n of r.slice(-e.keepLastMessages))if(typeof n.content!="string")for(let o of n.content)Cge(o)&&e.tools.includes(o.toolName)&&t.add(o.toolCallId);return r.map((n,o)=>o>=r.length-e.keepLastMessages?n:Nge(n,e,t))}function iE(r){return AW.safeParse(r).success}function OM(r){return RW.safeParse(r).success}function Cge(r){return iE(r)||OM(r)}function wge(r){return xW.safeParse(r).success}function FW(r){return !r||typeof r!="object"||Array.isArray(r)?!1:r._momenticTrimmed===!0}function UW(r){return cge.safeParse(r).success}function IM(r){return r.text===lc?{part:r,trimmedTokens:0}:{part:{...r,text:lc},trimmedTokens:At(r.text)}}function Age(r){return r.input===void 0||FW(r.input)?{part:r,trimmedTokens:0}:{part:{...r,input:NW},trimmedTokens:At(r.input)}}function BW(r){return r.output===void 0||UW(r.output)?{part:r,trimmedTokens:0}:{part:{...r,output:LW},trimmedTokens:At(r.output)}}function Rge(r,e,t){let n=0,o=[];for(let i of r){if(n>=e){o.push(i);continue}switch(i.role){case"assistant":{let a=xge(i,e-n,t);n+=a.trimmedTokens,o.push(a.message);continue}case"tool":{let a=_ge(i,e-n,t);n+=a.trimmedTokens,o.push(a.message);continue}case"user":{let a=Mge(i,e-n,t);n+=a.trimmedTokens,o.push(a.message);continue}default:o.push(i);}}return {messages:o,trimmedTokens:n}}function xge(r,e,t){if(typeof r.content=="string")return {message:r,trimmedTokens:0};let n=[],o=0;for(let i of r.content){if(o>=e){n.push(i);continue}if(t==="image"){n.push(i);continue}if(t==="reasoning"){if(i.type!=="reasoning"){n.push(i);continue}let s=IM(i);o+=s.trimmedTokens,n.push(s.part);continue}if(t==="text"){if(i.type!=="text"){n.push(i);continue}let s=IM(i);o+=s.trimmedTokens,n.push(s.part);continue}if(t==="tool-call"){if(!iE(i)){n.push(i);continue}let s=Age(i);o+=s.trimmedTokens,n.push(s.part);continue}if(!OM(i)){n.push(i);continue}let a=BW(i);o+=a.trimmedTokens,n.push(a.part);}return {message:{...r,content:n},trimmedTokens:o}}function Mge(r,e,t){if(typeof r.content=="string")return {message:r,trimmedTokens:0};let n=[],o=0;for(let i of r.content){if(o>=e){n.push(i);continue}if(t==="image"){if(i.type!=="image"){n.push(i);continue}o+=sge;continue}if(t!=="text"||!wge(i)){n.push(i);continue}let a=IM(i);o+=a.trimmedTokens,n.push(a.part);}return {message:{...r,content:n},trimmedTokens:o}}function _ge(r,e,t){if(t!=="tool-result")return {message:r,trimmedTokens:0};let n=[],o=0;for(let i of r.content){if(o>=e){n.push(i);continue}let a=BW(i);o+=a.trimmedTokens,n.push(a.part);}return {message:{...r,content:n},trimmedTokens:o}}function Pge(r,e){return e||typeof r.content=="string"?r:{...r,content:r.content.map(t=>t.type!=="reasoning"||t.text===lc?t:{...t,text:lc})}}function Ige(r,e,t){return !e.tools.includes(r.toolName)||t.has(r.toolCallId)||r.input===void 0||FW(r.input)?r:{...r,input:NW}}function zW(r,e,t){return !e.tools.includes(r.toolName)||t.has(r.toolCallId)||r.output===void 0||UW(r.output)?r:{...r,output:LW}}function Oge(r,e,t){return iE(r)?Ige(r,e,t):OM(r)?zW(r,e,t):r}function Nge(r,e,t){return r.role==="assistant"&&typeof r.content!="string"?{...r,content:r.content.map(n=>Oge(n,e,t))}:r.role==="tool"?{...r,content:r.content.map(n=>zW(n,e,t))}:r}function eh(r,e,t){let n=[...r];for(let o of uge){let i=At(n);if(i<=e)break;let a=i-e,s=Rge(n,a,o);n=s.messages,s.trimmedTokens>0&&t.debug({contentType:o,trimmedTokens:s.trimmedTokens,newTokenCount:At(n)},"Trimmed content");}return n}function $W(r){return r.role!=="assistant"||typeof r.content=="string"?!1:r.content.some(e=>iE(e))}function _W(r){if(r.length===0)return;let e=r[0];if($W(e)){r.shift(),r.length>0&&r[0].role==="tool"&&r.shift();return}r.shift();}function PW(r){let e={};for(let t of r)if(t.role==="system")e.system=(e.system??0)+At(t);else if(t.role==="user")e.user=(e.user??0)+At(t);else if(t.role==="assistant")if(typeof t.content=="string")e.assistant_text=(e.assistant_text??0)+At(t);else for(let n of t.content)if(n.type==="tool-call"){let o=`tool_call:${n.toolName}`;e[o]=(e[o]??0)+At(n);}else e.assistant_text=(e.assistant_text??0)+At(n);else if(t.role==="tool"){for(let n of t.content)if(n.type==="tool-result"){let o=`tool_result:${n.toolName}`;e[o]=(e[o]??0)+At(n);}}return e}function Lge(r,e,t){let n=At(r);if(n<=e||r.length<=1)return r;let o=r[0],i=[],a=[];if(r.length>MW+1){let u=r.length-MW;u>1&&r[u]?.role==="tool"&&$W(r[u-1])&&u++,i=r.slice(1,u),a=r.slice(u);}else a=r.slice(1);if(i.length>0){i=eh(i,e,t);let u=[o,...i,...a];if(n=At(u),n<=e)return u}let s=At(i),l=s/e;if(l<lge){if(a.length>1){let u=a[a.length-1],d=[...i,...a.slice(0,-1)],m=eh(d,e,t),p=[o,...m,u];if(n=At(p),n<=e)return p;let f=eh([...m,u],e,t),h=[o,...f];if(n=At(h),n<=e)return h}else if(a.length===1){let u=[...i,...a],d=eh(u,e,t),m=[o,...d];if(n=At(m),n<=e)return m}}else for(t.debug({headBudgetRatio:l,middleMsgTokens:s,targetTokens:e},"Middle exceeds 30% budget, removing messages");i.length>0;){_W(i);let u=[o,...i,...a];if(n=At(u),n<=e)return u}a=eh(a,e,t);let c=[o,...i,...a];if(n=At(c),n<=e)return c;for(;a.length>0;)if(_W(a),c=[o,...i,...a],n=At(c),n<=e)return c;return n>e&&t.warn({targetTokens:e,finalTokenCount:n,remainingMessages:c.length},"Unable to meet token target after all pruning phases"),c}var VW=5e3;async function HW(r){let{logger:e,toolName:t,logPrefix:n="",agentName:o,input:i}=r,a=r.getResultForLogging??(l=>l),s=Date.now();e.info({...o!=null&&{agentName:o},params:Xl({json:i,maxJsonStringSize:VW}),toolName:t},`${n}Tool invoked: ${t}`);try{let l=await r.execute();return e.info({...o!=null&&{agentName:o},duration:Date.now()-s,response:Xl({json:a(l),maxJsonStringSize:VW}),toolName:t},`${n}Tool completed: ${t}`),l}catch(l){throw e.error({...o!=null&&{agentName:o},duration:Date.now()-s,err:l,toolName:t},`${n}Tool failed: ${t}`),l}}var jW=".momentic-mcp",zge=30*24*60*60*1e3;function LM(r){return r?xr__default.join(r,jW):xr__default.resolve(jW)}function Na(r){let e=LM(r);mkdirSync(e,{recursive:!0});}function $ge(){return `${Date.now()}`}function La({rootDir:r,entity:e,ext:t}){return xr__default.join(LM(r),`${e}-${$ge()}.${t}`)}function Vge(r){let e=xr__default.relative(process.cwd(),r);return e.startsWith(".")?e:`./${e}`}function qi({filePath:r,title:e}){return `- [${e}](${Vge(r)})`}var rh="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 GW({projectRootAbsolutePath:r,projectConfigAbsolutePath:e,cwd:t}){return [rh,"",`- **projectRootAbsolutePath**: \`${r}\``,`- **projectConfigAbsolutePath**: \`${e}\``,`- **cwd**: \`${t}\``].join(`
|
|
5212
5212
|
`)}async function WW({projectRootAbsolutePath:r,projectConfigAbsolutePath:e,cwd:t,stepSchema:n,stepSchemaTitle:o,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.",l=[s,"","## Project context","",GW({projectRootAbsolutePath:r,projectConfigAbsolutePath:e,cwd:t}),"",`## ${o}`,"",n].join(`
|
|
5213
5213
|
`),c=[`# ${a}`,"",l].join(`
|
|
@@ -5345,19 +5345,19 @@ ${s}`}]}async function XW({rootDir:r,cutoffTime:e}){let t=await readdir(r,{withF
|
|
|
5345
5345
|
`),section:"Diffs For Recovery"})),u}return u.push(...yt({text:["",d].join(`
|
|
5346
5346
|
`),section:"Diffs For Recovery"})),u}function KX({moduleName:r,existingModuleNames:e,parameterNames:t,defaultParameters:n,parameterEnums:o,moduleInputs:i,testPath:a,startIndex:s,endIndex:l,availableSteps:c,containsNestedModuleStep:u}){if(e.includes(r))throw new Error(`Error: module with the name "${r}" already exists. Please use a different name.`);let d=t??[],m=[...Object.keys(n??{}),...Object.keys(o??{})];for(let y of m)if(!d.includes(y)){let S=d.length?d.join(", "):"none";throw new Error(`Error: Parameter metadata "${y}" is not defined in parameters. Available parameters: ${S}`)}let p=new Set(d);for(let y of Object.keys(i??{}))if(!p.has(y)){let S=p.size?Array.from(p).join(", "):"none";throw new Error(`Error: Module input "${y}" is not defined in parameters. Available parameters: ${S}`)}let f=s??0,h=l??f+1;if(l!==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(!c)throw new Error("Error: resolved steps are required to validate module extraction.");if(f<0||f>=c.length)throw new Error(`Error: startIndex ${f} is out of bounds. Test has ${c.length} steps.`);if(h<=f||h>c.length)throw new Error(`Error: endIndex ${h} is out of bounds. Must be between ${f+1} and ${c.length}.`);let g=c.slice(f,h);for(let y of g)if(u(y))throw new Error("Error: Modules cannot be nested. Please select steps that do not include module references.");return {stepsToExtract:g,startIndex:f,endIndex:h}}var HAe=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 jAe(r){let e=r.toLowerCase();return e.endsWith("webview")||HAe.has(e)}function rg(r){return !!(jAe(r.tagName)||r.getAttribute("package")==="com.android.chrome"&&r.getAttribute("content-desc")==="Web View"&&XX(r.tagName.toLowerCase()).startsWith("frame"))}function XX(r){let e=["android.widget.","android.view.","android.webkit.","android.app.","android.support.","androidx.","com.android.inputmethod."];for(let t of e)if(r.startsWith(t))return r.substring(t.length);return r}var GAe=new Set(["index","package","a11y-important","screen-reader-focusabl"]),WAe=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"]),qAe=new Set(["text","hint"]),KAe=new Set(["live-region","drawing-order"]),XAe=new Set(["displayed","enabled"]);function YAe(r,e){let t={};for(let[n,o]of Object.entries(e))GAe.has(n)||n==="class"&&r===o||n==="focusable"&&o==="true"&&e.clickable==="true"||WAe.has(n)&&o==="false"||qAe.has(n)&&o===""||XAe.has(n)&&o==="true"||KAe.has(n)&&o==="0"||n!=="id"&&(t[n]=o);return t}function YX(r,e,t){let{prunedDocument:n,idToElement:o,prunedIdToElement:i,idCounter:a,opts:s}=r,l=a.value++;t.setAttribute("id",String(l));let c={};for(let m of e.attributes){let p=m.name,f=m.value;f!=null&&(c[p]=String(f));}let u=YAe(e.tagName,c);for(let[m,p]of Object.entries(u))t.setAttribute(m,p);if(o.set(l,e),i.set(l,t),rg(e)){let m=s?.injectedWebviewContent??"";if(s?.removeWebviewContent){for(;t.firstChild;)t.removeChild(t.firstChild);return}else if(!s?.disableMomenticAccessibilityTree&&m.trim().length>0){for(;t.firstChild;)t.removeChild(t.firstChild);m.trim().length>0&&t.appendChild(n.createCDATASection(`
|
|
5347
5347
|
${m}
|
|
5348
|
-
`));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&&t.appendChild(n.createTextNode(f));continue}if(p===1){let f=m;if(!QAe(f,s?.viewportBounds))continue;let h=n.createElement(XX(f.tagName));YX(r,f,h),t.appendChild(h);}}}function JAe(r,e,t,n){let o=r.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:o,idToElement:t,prunedIdToElement:i,idCounter:{value:0},opts:n},s=o.documentElement;YX(a,e,s);let l=new XMLSerializer().serializeToString(o);return {prunedDocument:o,prunedIdToElement:i,xml:l}}async function JX(r,e,t){let n=new DOMParser,o=n.parseFromString(r,"text/xml"),i=new Map,a=o.documentElement;if(!a)throw new w("InternalWebAgentError","No root element found in XML");if(a.tagName!=="hierarchy")throw new w("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:s,prunedIdToElement:l,xml:c}=JAe(n,a,i,t),u=c;try{u=await zAe.format(c,{parser:"xml",plugins:[BAe],printWidth:120,tabWidth:1,singleAttributePerLine:!1});}catch(d){e.warn({err:d},"Failed to format XML");}return {xml:u,originalXml:r,document:o,idToElement:i,prunedDocument:s,prunedIdToElement:l}}function ZAe(r){let e=[],t=r;for(;t;){let n=t.tagName,o=t.parentElement,i=1;if(o){let a=Array.from(o.children).filter(s=>s.tagName===n);for(let s=0;s<a.length;s++)if(a[s]===t){i=s+1;break}}e.unshift(`${n}[${i}]`),t=o;}return `/${e.join("/")}`}function UT(r,e){let t=r.idToElement.get(e);if(t)return ZAe(t)}function uI(r,e){let t=r.idToElement.get(e);if(!t)return;let n=t.cloneNode(!0);for(let o of Array.from(n.children)){let i=o;for(let a of Array.from(i.children))i.removeChild(a);}return n.outerHTML}function vc(r){if(!r.hasAttribute("bounds"))return;let e=r.getAttribute("bounds");if(!e)return;let t=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(t){let n=parseInt(t[1],10),o=parseInt(t[2],10),i=parseInt(t[3],10),a=parseInt(t[4],10);if(Number.isFinite(n)&&Number.isFinite(o)&&Number.isFinite(i)&&Number.isFinite(a))return [n,o,i,a]}}function QAe(r,e){if(!e)return !0;let t=vc(r);if(!t||t.length<4)return !0;let n=t[0],o=t[1],i=t[2],a=t[3];return !(i<=e.left||n>=e.right||a<=e.top||o>=e.bottom)}function ZX(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}function e3({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=vc(e),!t))throw new w("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:r?.textRequired&&wd(e)||void 0,requiredAttributes:ZX(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t[0],y1:t[1],x2:t[2],y2:t[3],tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t[2]-t[0],height:t[3]-t[1],tolerance:r?.shapeSpecificity}:void 0}}function r3({aiResponse:r,description:e,emulatorState:t,memory:n,useMemory:o}){let i=t.graph.idToElement.get(r.id);if(!i)throw new w("InternalWebAgentError",`Could not find node with id: ${r.id}`);let a=vc(i);if(!a)throw new w("InternalWebAgentError",`Node ${r.id} has no bounding box: ${i.outerHTML}`);let s=UT(t.graph,r.id)??"",l=uI(t.graph,r.id)??"",c=e3({requirements:r.requirements,element:i}),u=[];r.additionalElements&&(u=r.additionalElements.map(({id:m,requirements:p})=>{let f=t.graph.idToElement.get(m);if(!f)return;let h=UT(t.graph,m);return h?{xPath:h,requirements:e3({requirements:p,element:f})}:void 0}).filter(m=>!!m));let d;if(rg(i)&&r.inWebview!==!1?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:l,requirements:c,requiredRelatedElements:u},o)if(r.updatedMemory){let m={type:"GCS_TRACES",traces:r.updatedMemory};d.memory=m;}else n&&(d.memory=n);return {target:d,resolvedNode:i}}function n3(r){return r?.type==="WEBVIEW"?r.browserCache?.memory:void 0}function eRe(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r[0]+r[2])/2;if(!ji(e.tolerance,n,o,Math.min(1,t)))return !1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r[1]+r[3])/2;return ji(e.tolerance,a,s,Math.min(1,i))}function tRe(r,e){return ji(e.tolerance,e.width,r[2]-r[0],Math.min(1,e.width))?ji(e.tolerance,e.height,r[3]-r[1],Math.min(1,e.height)):!1}var t3=(r,e,t)=>{if(!e)return;let{requiredAttributes:n,requiredText:o,requiredBounds:i,position:a,shape:s}=e;if(o!==void 0&&o.length>0){let l=wd(r);if(l!==o)throw new Ee(`Resolved element text mismatch: expected ${o}, got ${l}`)}if(n)for(let[l,c]of Object.entries(n)){let u=r.getAttribute(l)??void 0;if(u!==c)throw new Ee(`Attribute ${l} mismatch: expected ${c}, got ${u}`)}if(i&&t&&!t.targetBounds.every((c,u)=>c===t.newElementBounds[u]))throw new Ee(`Bounds changed from [${t.targetBounds.join(",")} ] to [${t.newElementBounds.join(",")} ]`);if(a&&t&&!eRe(t.newElementBounds,a))throw new Ee(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(t.newElementBounds)}`);if(s&&t&&!tRe(t.newElementBounds,s))throw new Ee(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(t.newElementBounds)}`)};async function om(r){let{target:e,domState:t}=r,{graph:n}=t,{document:o}=n,i=re();if(e.type==="WEBVIEW")return rRe(e,r);if(!e.xPath)throw new w("ActionFailureError","Native element cache has no XPath");let a=QX.evaluateXPathToFirstNode(e.xPath,o,null,null);if(!a)throw new Ee(`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=QX.evaluateXPathToFirstNode(p.xPath,o);if(!f)throw new Ee(`Required related element not found for XPath: ${p.xPath}`);t3(f,p.requirements);}});}let s=vc(a);if(!s)throw new Ee("Resolved native element has no bounding box");if(!e.bounds)throw new Ee("Native element cache has no bounds");t3(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let l;for(let[m,p]of n.idToElement.entries())if(p===a){l=m;break}let c=e.elementOnlySerializedXml,u=e.xPath;return l!==void 0&&(c=uI(n,l)??c,u=UT(n,l)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:c,xPath:u}}}async function rRe(r,e){let{stateManager:t,logger:n,signal:o}=e,i=re(),a=await t.getActiveWebview();if(!a||!a.browserController)throw n.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new Ee("No browser controller is attached to the requested webview");let s=a.browserController;if(!r.browserCache)throw n.error({target:r},"resolveTargetCacheInWebView: No browser target available on cache"),new Ee("No browser target available on cache");let l=r.browserCache,{finalTarget:c}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({cache:l,options:{resolveTargetOptions:{logger:n,signal:o,skipWaitForPageLoad:!0,skipSavingVisualAttributes:!0}},logger:n}));return {resolvedTarget:{...r,controller:a.browserController,browserTarget:c}}}function Cc(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;Ci(e)&&(e[t]={...e[t],[n]:iu.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=we(r.logger)));}function al(r){if(r.type==="WEBVIEW")return {type:"WEBVIEW",resolvedDescription:r.resolvedDescription,xPath:r.xPath,browserCache:r.browserCache,memory:r.memory};let{resolvedNode:e,...t}=r;return {...t}}var ao=.15,oRe=500,or=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:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,memory:a,webviewMemory:s,metadata:l,cacheBustReason:c}){let u=this.logger.child({...l}),d=await t.startAsyncSection("Get emulator state",async()=>{let y=await this.stateManager.getCurrentScreenshotPngString();return {emulatorState:await this.stateManager.getDomState({skipFetchingFullWebviewContent:n,removeWebviewContent:o}),screenshot:y}}),m;try{m=await t.startAsyncSpan("AI_LOCATOR_CALL",async y=>{c&&(y.attributes.cacheBustReason=c);let S=await this.generator.getAndroidElementLocation({description:e,screenXml:d.emulatorState.graph.xml,screenshot:d.screenshot,source:l?.source==="SCROLL_TO"?"SCROLL_TO":void 0,memory:i?a:void 0},{logger:u,loggerTags:we(u),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return y.result=S,S});}catch(y){throw this.throwIfAborted(),u.error({err:y},"Failed to locate element"),new w("InternalWebAgentError",`Failed to locate element: ${y instanceof Error?y.message:y}`,{errOptions:{cause:y}})}if(m.id===-1){let y=m.updatedMemory?{type:"GCS_TRACES",traces:m.updatedMemory}:void 0;return {success:!1,thoughts:m.thoughts??"No matching element found",updatedLocatorMemory:y}}let{target:p,resolvedNode:f}=r3({aiResponse:m,description:e,emulatorState:d.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,resolvedNode:f},thoughts:m.thoughts};let{browserLocateResult:h,browserController:g}=await t.startWebviewTrace(async()=>{let y=await this.stateManager.getActiveWebview();if(!y||!y.browserController)throw new w("InternalWebAgentError","No browser controller is attached to the requested webview");return {browserLocateResult:await y.browserController.locateElement({description:e,disableCache:!1,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:!0,skipSavingVisualAttributes:!0}),browserController:y.browserController}});return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:h.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,controller:g,browserTarget:{...h.resolution,serverSideBoundingBox:await h.resolution.locator.boundingBox({timeout:5e3})},browserCache:h.target},thoughts:h.thoughts}}async targetingActionWithAILocator(e){let{action:t,command:n,description:o,tracer:i,cacheKey:a,targetName:s,cache:l,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:d,cacheBustReason:m}=e,p=await this.findElement({description:o,tracer:i,skipFetchingFullWebviewContent:c,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(n),memory:l?.memory,webviewMemory:n3(l),metadata:d,cacheBustReason:m});if(!p.success){if(p.updatedLocatorMemory&&l){let y={...l,memory:p.updatedLocatorMemory};Cc({command:n,cacheKey:a,targetName:s,updatedCache:y,updatedWithAI:!0,logger:this.logger});}throw new w("NoMatchingElementError",p.thoughts??"No matching element found")}let f=p.thoughts,{result:h,resolvedTarget:g}=await this.executeActionWithWebviewReconstructRetry({action:t,resolvedTarget:p.resolvedTarget,reason:"webview target closed during AI-located action"});return Cc({command:n,cacheKey:a,targetName:s,updatedCache:al(g),updatedWithAI:!0,logger:this.logger}),{result:h,thoughts:f}}async wrapTargetingAction(e){let{action:t,description:n,command:o,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:l,skipFetchingFullWebviewContent:c=!1,removeWebviewContent:u=!1}=e,d,m={commandId:o.id};if(i==="cache"&&"cache"in o&&o.cache){let b=o.cache;a==="target"&&"target"in b?d=b.target:a==="fromTarget"&&"fromTarget"in b?d=b.fromTarget:a==="toTarget"&&"toTarget"in b&&(d=b.toTarget);}let p=!1,f,h=cloneDeep(d);if(o.disableCache&&(this.logger.debug({command:o},"Cache explicitly disabled for command"),p=!0,f="Cache explicitly disabled",h=void 0),s&&(p=!0,f=f??"Cache invalidated after resolution",h=void 0),h&&!js(h?.resolvedDescription??"",n)&&(this.logger.info({description:n,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=!0,f="Description mismatch",h=void 0),!h)return this.logger.info({description:n,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:l,cacheKey:i,targetName:a,cache:d,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:m,cacheBustReason:f});let g=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,y=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,S;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:b}=await l.startAsyncSpan("CACHE_RESOLUTION",async O=>{let M=Date.now(),R;for(;Date.now()-M<3e3;){S=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let _;try{_=(await om({target:h,domState:S,stateManager:this.stateManager,logger:this.logger})).resolvedTarget;}catch(J){if(R=J,J instanceof Ee){this.logger.warn({err:J},"Failed to resolve target cache, retrying"),await Li(500,this.aborter.controller?.signal);continue}throw this.logger.error({err:J},"Failed to resolve target cache"),J}let k=al(_),B=diff(h,k);return B&&Object.keys(B).length>0&&this.logger.info({cacheDiffs:B},"Successfully resolved target with cache"),O.attributes.serializedElement=_.type==="WEBVIEW"?_.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":_.elementOnlySerializedXml??"Unknown element",{resolvedTarget:_,updatedCache:k}}throw R}),{result:C,resolvedTarget:A}=await this.executeActionWithWebviewReconstructRetry({action:t,resolvedTarget:b,reason:"webview target closed during cached action"});return Cc({command:o,cacheKey:i,targetName:a,updatedCache:al(A),updatedWithAI:!1,logger:this.logger}),Et.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${g}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.88.1"]),{result:C,thoughts:"Successfully executed preset action with cache"}}catch(b){if(this.throwIfAborted(),b instanceof w&&b.reason!=="InternalWebAgentError")throw this.logger.error({err:b},"Failed to execute action with target cache (fatal)"),b;return Et.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${g}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.88.1"]),this.logger.warn({err:b},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:l,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:m})}}async executeActionWithWebviewReconstructRetry(e){let{action:t,resolvedTarget:n,reason:o}=e;try{return {result:await t(n),resolvedTarget:n}}catch(i){if(this.throwIfAborted(),n.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(o))?.browserController))throw i;let s=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0}),{resolvedTarget:l}=await om({target:al(n),domState:s,stateManager:this.stateManager,logger:this.logger,signal:this.abortSignal});return {result:await t(l),resolvedTarget:l}}}errorLooksLikeClosedWebviewTarget(e){let t=ne(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(n=>t.includes(n))}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 w("ActionFailureError","Native element cache has no bounds");let[t,n,o,i]=e.bounds;if(t===void 0||n===void 0||o===void 0||i===void 0)throw new w("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return {left:t,top:n,width:o-t,height:i-n}}calculateSwipeCoordinates({containerBounds:e,direction:t,desiredDelta:n}){let o=e.left+e.width/2,i=e.top+e.height/2;if(t==="up"||t==="down"){let a=e.height*ao,s=e.top+a,l=e.top+e.height-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u,m=t==="down"?l-d/2:s+d/2;return {startX:o,startY:m,actualDelta:u}}else {let a=e.width*ao,s=e.left+a,l=e.left+e.width-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u;return {startX:t==="right"?l-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:t,deltaPixels:n,direction:o,durationMs:i=300}){let a=Math.abs(n),s=e,l=t;o==="up"||o==="down"?l=o==="up"?t-a:t+a:s=o==="left"?e-a:e+a,await this.driver.executeInNativeContext(this.logger,async c=>{await c.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:t},{type:"pointerDown",button:0},{type:"pause",duration:250},{type:"pointerMove",duration:i,x:s,y:l},{type:"pause",duration:500},{type:"pointerUp",button:0}]}]),await c.releaseActions();},{operationName:"performRawSwipe"}),await te(oRe,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 a3(r){return "iterations"in r}function sRe(r){let e={relativePosition:r.relativePosition};if(r.iterations!==void 0&&(!Number.isInteger(r.iterations)||r.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(r.tapDelayMs!==void 0&&(!Number.isInteger(r.tapDelayMs)||r.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(r.iterations&&r.iterations>1&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(r.tapDelayMs!==void 0&&(!r.iterations||r.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(r.longPress){if(r.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return {...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}}return r.iterations!==void 0?{...e,iterations:r.iterations,tapDelayMs:r.tapDelayMs}:e}var im=class extends or{async tapOnNativeCoordinates(e){let t=e.x,n=e.y;if(this.logger.info({x:t,y:n},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeInNativeContext(this.logger,o=>o.executeScript("mobile: longClickGesture",[{x:t,y:n,duration:e.longPressDurationMs??2e3}]),{operationName:"longPress"});if(a3(e)){let o=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.executeInNativeContext(this.logger,a=>a.tap({x:t,y:n}),{operationName:"tap"}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,o));return}await this.driver.executeInNativeContext(this.logger,o=>o.tap({x:t,y:n}),{operationName:"tap"});}async tapOnNativeTarget(e,t){let[n,o,i,a]=e.bounds,s=i-n,l=a-o,c=t?.relativePosition?.x??s/2,u=t?.relativePosition?.y??l/2;c=Math.max(0,Math.min(c,s)),u=Math.max(0,Math.min(u,l));let d=n+c,m=o+u;return await this.tapOnNativeCoordinates({x:d,y:m,...t}),{x:d,y:m}}async tapOnWebviewTarget(e,t){let{controller:n}=e,o,i=1;return t&&a3(t)?(o=t.tapDelayMs,i=t.iterations):t&&"longPress"in t&&(o=t.longPressDurationMs),(await n.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),l=xr__default.join(tmpdir(),"momentic","downloads"),c=xr__default.join(l,this.orgId,s);return mkdirSync(c,{recursive:!0}),c}},{delayMs:o,relativePosition:t?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:t}){return await re().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.attributes.options=t,"type"in e&&e.type==="NATIVE"?o.attributes.point=await this.tapOnNativeTarget(e,t):(o.withinWebview=!0,o.attributes.point=await this.tapOnWebviewTarget(e,t));},{name:"Tap on target"})}async executeTap({command:e}){let t=re(),n=sRe(e);if(e.target.type==="coordinates"){let a=await this.driver.executeInNativeContext(this.logger,c=>c.getWindowSize(),{operationName:"getTapWindowSize"}),s=e.target.xPercent*a.width,l=e.target.yPercent*a.height;return await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.tapOnNativeCoordinates({...n,x:s,y:l});},{name:`Tap at coordinates ${s}, ${l}`}),{success:!0,message:`Tapped at ${s}, ${l}`}}let o=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,action:a=>this.tapOnTarget({target:a,options:n}),description:o});return {success:!0,message:i}}};var sl=class extends or{async doPress({keycode:e,longPress:t}){await re().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeInNativeContext(this.logger,o=>o.executeScript("mobile: pressKey",[{keycode:e,isLongPress:t}]),{operationName:"pressKey"}),{name:"Send key events to emulator"});}};var wc=25,s3=150,zT=class extends or{async doType(e){let t=re();if(!e.target){if(e.clearContent)throw new w("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:!0,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:t,action:async o=>{"type"in o&&o.type==="NATIVE"?await this.doNativeType(e,o):await this.doWebviewType(e,o);},description:e.target.description});return {success:!0,message:n}}async doWebviewType(e,t){await re().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.withinWebview=!0;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??wc};o.attributes.options=i;let{controller:a,browserTarget:s}=t;await a.browser.typeIntoTarget(e.text,s,i);},{name:"Typing within web view"});}async doNativeType(e,t){let n=new im(this.constructPerformerParams());e.clearContent?(await n.tapOnNativeTarget(t,{longPress:!0}),await this.clearContent()):await n.tapOnNativeTarget(t),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e);}async sendKeys(e){let t=re(),n=e.keyPressDelayMs??wc;await t.startAsyncSection("Waiting for system keyboard to open",async(o,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.executeInNativeContext(this.logger,c=>c.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;let l=Date.now()-s;l<500&&await new Promise(c=>setTimeout(c,500-l));}i.attributes.timedOut=!0;}),await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{n!==wc&&await this.driver.executeInNativeContext(this.logger,async i=>i.updateSettings({keyInjectionDelay:n}),{operationName:"updateKeyInjectionDelay"});let o=[];for(let i=0;i<e.text.length;i+=s3)o.push(e.text.slice(i,i+s3));for(let i of o)await this.driver.executeInNativeContext(this.logger,async a=>a.keys(i),{operationName:"typeWithCustomKeyDelay",attemptTimeoutMs:Nb(n,i),maxAttempts:1});}finally{n!==wc&&await this.driver.executeInNativeContext(this.logger,async o=>o.updateSettings({keyInjectionDelay:wc}),{operationName:"updateKeyInjectionDelay"});}},{name:`Typing with a ${n}ms delay`});}async clearContent(){let e=re();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper());}catch(t){this.logger.warn({err:t},"Failed to find select all button, continuing...");}}async clearContentHelper(){await this.driver.executeInNativeContext(this.logger,async t=>{let n=t.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await n.waitForExist({timeout:750}),await n.click();},{operationName:"selectAllText",maxAttempts:1}),await new sl(this.constructPerformerParams()).doPress({keycode:67});}};var l3=.8,lRe=v__default.object({navigationBar:v__default.object({visible:v__default.boolean(),x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()}),statusBar:v__default.object({visible:v__default.boolean(),x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()})});function pI(r,e){r.attributes.scrollableElementType=e.type,r.attributes.scrollableElementDisplay=ha(e),e.type==="CUSTOM"&&(r.attributes.scrollableElementDescription=e.target.description);}var am=class extends or{async getHardcodedScrollableElementBounds(e,t){let n;switch(e.type){case"SCREEN":n=this.getContainerBoundsFromViewport(t);break;case"OPEN_APP":try{let o=lRe.parse(await this.driver.executeInNativeContext(this.logger,i=>i.executeScript("mobile: getSystemBars",[]),{operationName:"getSystemBars"}));n=this.getContainerBoundsFromViewport(t),o.navigationBar.visible&&(n.height=Math.max(1,n.height-o.navigationBar.height)),o.statusBar.visible&&(n.top+=o.statusBar.height,n.height=Math.max(1,n.height-o.statusBar.height));}catch(o){this.logger.warn({err:o},"Failed to get system bars, using hardcoded bounds"),n=this.getContainerBoundsFromViewport(t);}break;case"OPEN_WEBVIEW":{let o=await this.stateManager.getActiveWebviewNodes();if(o.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),o=await this.stateManager.getActiveWebviewNodes()),o.length===0)throw new Error("No active webviews found");if(o.length>1){let a=o.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=o[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");n=this.getContainerBoundsFromBounds(i);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return n}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:Math.max(1,e.width),height:Math.max(1,e.height)}}getContainerBoundsFromBounds(e){let t=e[0],n=e[1],o=e[2],i=e[3],a=o-t,s=i-n;return {left:t,top:n,width:Math.max(1,a),height:Math.max(1,s)}}async executeSwipe(e){let t=re(),n=ha(e.scrollableElement);if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:i,startY:a,deltaPixels:s}=e.scrollableElement;return await t.startAsyncSpan("EMULATOR_INTERACTION",async l=>{pI(l,e.scrollableElement),l.attributes.startX=i,l.attributes.startY=a,l.attributes.deltaPixels=s,l.attributes.direction=e.direction,await this.performRawSwipe({startX:i,startY:a,deltaPixels:s,direction:e.direction,durationMs:e.durationMs});},{name:`Swipe ${e.direction} in ${n}`}),{success:!0,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 t.startAsyncSpan("EMULATOR_INTERACTION",async s=>{pI(s,e.scrollableElement),await this.swipeByAbsoluteCoordinates({span:s,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:a,relativePosition:e.relativePosition});},{name:`Swipe ${e.direction} in ${n}`}),{success:!0,message:"Successfully executed swipe action"}}let{thoughts:o}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async i=>re().startAsyncSpan("EMULATOR_INTERACTION",async s=>(pI(s,e.scrollableElement),"type"in i&&i.type==="NATIVE"?this.scrollInNativeContainer({span:s,cmd:e,target:i}):(s.withinWebview=!0,this.swipeInWebview({span:s,cmd:e,target:i}))),{name:`Swipe ${e.direction} in ${n}`}),tracer:t});return {success:!0,message:o}}async scrollInNativeContainer({span:e,cmd:t,target:n}){if(!n.bounds||n.bounds.length<4)throw new w("ActionFailureError","Native container cache has no bounds");let o=n.bounds,i=o[2]-o[0],a=o[3]-o[1];await this.swipeByAbsoluteCoordinates({span:e,direction:t.direction,percent:t.viewportPercent,durationMs:t.durationMs,containerBounds:{left:o[0],top:o[1],width:Math.max(1,i),height:Math.max(1,a)},relativePosition:t.relativePosition});}async swipeInWebview({span:e,cmd:t,target:n}){let{controller:o,browserTarget:i}=n;if(!o.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=t.direction==="down"||t.direction==="up",l=await i.locator.boundingBox();if(!l)throw new Error("Failed to get bounds for webview container");let c=Math.floor(l.width*ao),u=Math.floor(l.height*ao),d=Math.max(1,l.width-c*2),m=Math.max(1,l.height-u*2),p,f;t.relativePosition?(p=l.x+t.relativePosition.x,f=l.y+t.relativePosition.y):(p=l.x+l.width/2,f=l.y+l.height/2);let h={x:p,y:f},g=(s?m:d)*(t.viewportPercent??l3)*(s?t.direction==="down"?1:-1:t.direction==="right"?1:-1);e.attributes.startPoint=h,e.attributes.scrollPixelAmount=g,await o.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:g,deltaY:s?g:0,steps:10,dragDurationMs:t.durationMs,fromTarget:h});}async swipeByAbsoluteCoordinates({span:e,direction:t,percent:n=l3,durationMs:o=500,containerBounds:i,relativePosition:a}){e.attributes.containerBounds=i;let s=i.width*ao,l=i.height*ao,c,u;if(t==="up"||t==="down"?(c=(i.height-2*l)*n,u=Math.floor(c/(o/1e3))):(c=(i.width-2*s)*n,u=Math.floor(c/(o/1e3))),e.attributes.pixelDelta=c,e.attributes.pixelsPerSecond=u,a){let d=i.left+a.x,m=i.top+a.y;await this.performRawSwipe({startX:d,startY:m,deltaPixels:c,direction:t,durationMs:o});}else {let d=i.width*ao,m=i.height*ao,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:t,percent:n,speed:u}]),{operationName:"swipeGesture"});}}};var cRe=20,fI=.9,sm=.5,hI=.2;var $T=class extends am{async executeScrollTo(e){let t=e.target.description,n=e.scrollStepPercent??fI,o=await this.tryUseCachedScrollPosition(e,t);return o||this.searchForElement({cmd:e,description:t,scrollStepPercent:n})}async resolveContainer({scrollableElement:e,containerCache:t,aiMetadata:n}){let o=await this.driver.executeInNativeContext(this.logger,u=>u.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(e.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:o.width,height:o.height},diffThresholdPercent:sm};if(e.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(e,o),diffThresholdPercent:sm};let i=re(),a=e.target.description;if(t){let u=this.getBoundsFromNativeCache(t);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:t,diffThresholdPercent:Td({containerBounds:u,viewport:o,defaultThresholdPercent:sm})}}let s=await this.findElement({description:a,tracer:i,metadata:n});if(!s.success)throw new w("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:l}=s;if(l.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(l);return this.logger.info({bounds:c},"Got container bounds from AI"),{bounds:c,cache:l,diffThresholdPercent:Td({containerBounds:c,viewport:o,defaultThresholdPercent:sm})}}async tryUseCachedScrollPosition(e,t){let n=e.cache?.target;return n?n.type==="WEBVIEW"?this.tryUseWebviewCache(e,t):n.scrollDetails?this.tryUseNativeScrollCache(e,t,n):null:null}async tryUseWebviewCache(e,t){let n=re();try{let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:n,description:t,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i);}});return {success:!0,message:o}}catch(o){return this.logger.warn({err:o},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,t,n){let o=n.scrollDetails,i=re(),a=e.scrollStepPercent??fI;if(o.pixelDelta===0)return this.logger.info("Skipping cached scroll-position replay because it would not move the viewport"),null;let s=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:o.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let c=await this.tryFindElement({cmd:e,description:t,tracer:i,scrollDetails:o,useAIIfCacheFails:!0});if(c)return c;this.logger.info("Element not found at cached position, undoing scroll");}catch(c){this.logger.warn({err:c},"Error finding element at cached position, will undo scroll");}let l=o.direction==="down"?"up":"down";return this.logger.info({pixelDelta:o.pixelDelta,originalDirection:o.direction,undoDirection:l,scrollableElementType:o.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:l,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:o,useAIIfCacheFails:i=!0}){let a,s,l=!1,c=o,u=gI(e.cache?.target);if(u&&u.resolvedDescription!==void 0&&js(u.resolvedDescription,t)&&!e.disableCache){let p=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0});try{let{resolvedTarget:f}=await om({target:u,domState:p,stateManager:this.stateManager,logger:this.logger});a=f,l=!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&&l&&a.type==="NATIVE"&&o){let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:o});c=p.scrollDetails,p.resolvedTarget?a=p.resolvedTarget:(a=void 0,l=!1);}if(!a&&!i)return null;if(!a)try{let p=nE(t),f=await this.findElement({description:p,tracer:n,metadata:{commandId:e.id,source:"SCROLL_TO"}});if(!f.success)return null;a=f.resolvedTarget,s=f.thoughts;}catch(p){if(p instanceof w&&p.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:p},"Failed to find scroll-to target with AI"),p}if(a&&!l&&a.type==="NATIVE"&&o)try{let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:o});c=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=gI(al(a));return Cc({command:e,updatedCache:p,updatedWithAI:!l,logger:this.logger}),{success:!0,message:s}}let m=al(a);if(m.type!=="NATIVE")throw new Error("Expected native target cache for scroll-to");return Cc({command:e,updatedCache:gI({...m,scrollDetails:c}),updatedWithAI:!l,logger:this.logger}),{success:!0,message:s}}async correctNativeTargetIntoView({cmd:e,resolvedTarget:t,scrollDetails:n}){let o=await this.getCorrectiveScrollForTarget({resolvedTarget:t});if(!o)return {resolvedTarget:t,scrollDetails:n};this.logger.info({bounds:t.bounds,correction:o},"Repositioning scroll-to target to the preferred viewport anchor");let i=n.scrollableElement.type==="CUSTOM"?n.scrollableElement.cache:void 0,a=await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:n.scrollableElement,containerCache:i,direction:o.direction,scrollStepPercent:e.scrollStepPercent??fI,aiMetadata:{commandId:e.id},useVisualDiff:!0});if(a===0)return this.logger.info({bounds:t.bounds,correction:o},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:t,scrollDetails:n};let s={...n,pixelDelta:_b({currentPixelDelta:n.pixelDelta,baseDirection:n.direction,correctionDirection:o.direction,correctionPixels:a})},l=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0}),c;try{({resolvedTarget:c}=await om({target:t,domState:l,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(c.type!=="NATIVE")return {scrollDetails:s};let u=await this.getCorrectiveScrollForTarget({resolvedTarget:c});return u?(this.logger.warn({bounds:c.bounds,correction:u},"Corrective scroll still did not bring the scroll-to target into the preferred viewport anchor"),{resolvedTarget:c,scrollDetails:s}):{resolvedTarget:c,scrollDetails:s}}async searchForElement({cmd:e,description:t,scrollStepPercent:n}){let o=re(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch({cmd:e,description:t,tracer:o,scrollStepPercent:n,resolvedContainer:i})}async scrollAndSearch({cmd:e,description:t,tracer:n,scrollStepPercent:o,resolvedContainer:i}){let a=0,s=i.bounds,l=i.diffThresholdPercent,c=e.scrollableElement.type==="CUSTOM_COORDINATES"?e.scrollableElement:void 0,u;c?u=Math.abs(c.deltaPixels):u=this.calculateSwipeCoordinates({containerBounds:s,direction:e.direction,desiredDelta:Fs({containerBounds:s,containerInsetRatio:ao})*o}).actualDelta;let d=!0,m=e.maxScrollAttempts??cRe;for(let h=0;h<m;h++){this.throwIfAborted();let g=this.buildScrollDetails(e,a,i.cache),y=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:g});if(y)return y;if(!d)throw new Error(`ActionFailureError: Could not find element "${t}" 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:o,diffThresholdPercent:l,rawCoordinates:c}),a+=e.direction==="down"?u:-u;}let p=this.buildScrollDetails(e,a,i.cache),f=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:p});if(f)return f;throw new Error(`ActionFailureError: Could not find element "${t}" after ${m} scroll attempts`)}buildScrollDetails(e,t,n){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:t,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:n},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:t,browserTarget:n}=e;await t.browser.hover(n);}async scrollByPage({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o,rawCoordinates:i}){return re().startAsyncSpan("EMULATOR_INTERACTION",async s=>(s.attributes.containerBounds=t,s.attributes.direction=e,(await this.executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o,rawCoordinates:i})).canScrollMore),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:t,containerCache:n,direction:o,scrollStepPercent:i,aiMetadata:a,useVisualDiff:s=!1}){if(e===0)return 0;let l=re(),c,u=sm,d,m,p;if(t.type==="CUSTOM_COORDINATES")d=t.startX,m=t.startY,p=t.deltaPixels;else {c=await this.resolveContainer({scrollableElement:t,containerCache:n,aiMetadata:a});let h=c.bounds;u=c.diffThresholdPercent;let g=Fs({containerBounds:h,containerInsetRatio:ao})*i,y=this.calculateSwipeCoordinates({containerBounds:h,direction:o,desiredDelta:g});d=y.startX,m=y.startY,p=y.actualDelta;}let f=Math.ceil(Math.abs(e)/p);return this.logger.debug({pixelDelta:e,direction:o,scrollableElementType:t.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),l.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 g=this.invertDirection(o),y=0;for(let S=0;S<f;S++){this.throwIfAborted();let b=Math.abs(e)-y,C=Math.min(p,b);if(s){let A=await this.executeScrollGesture({direction:o,containerBounds:c?.bounds,scrollStepPercent:i,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:C}});if(A.didScroll&&(y+=C),!A.canScrollMore)break}else await this.performRawSwipe({startX:d,startY:m,deltaPixels:C,direction:g}),y+=C;}return h.attributes.appliedPixels=y,y},{name:`Scroll ${o} by ${Math.abs(e)}px`})}async executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o=sm,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,l,c;if(i)s=i.startX,l=i.startY,c=i.deltaPixels;else {if(!t)throw new Error("Expected container bounds for scroll gesture");let f=Fs({containerBounds:t,containerInsetRatio:ao})*n,h=this.calculateSwipeCoordinates({containerBounds:t,direction:e,desiredDelta:f});s=h.startX,l=h.startY,c=h.actualDelta;}await this.performRawSwipe({startX:s,startY:l,deltaPixels:c,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=Ds(a,u),m=d>o,p=d>o;return this.logger.debug({diffPercent:d,didScroll:m,diffThresholdPercent:o,canScrollMore:p,direction:e,actualDelta:c,rawCoordinates:i},"Scroll gesture visual diff result"),{didScroll:m,canScrollMore:p}}async getCorrectiveScrollForTarget({resolvedTarget:e}){let t=e.bounds;if(!t||t.length<4)return;let n=await this.stateManager.getViewportBounds(),o=Math.max(1,n.bottom-n.top),i=t[1],a=t[3],s=Pb({viewportTop:n.top,viewportBottom:n.bottom,elementHeight:a-t[1],targetTopRatio:hI}),l=n.top+o*hI,c=n.bottom-o*hI,u=i>=n.top&&a<=n.bottom,d=i<l||a>c,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 gI(r){return !r||r.type!=="NATIVE"?r:Ib(r)}var VT=class extends or{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:!0,message:"Installed APK."}}async installApkFromUri(e){let t=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${xr__default.resolve(t.localPath)}`),this.logger.info({uri:e,localPath:t.localPath},"Installed APK on device");}finally{t.cleanup();}}async resolveUriToLocalApk(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.href.slice(7),o;if(Tr.existsSync(n))o=n;else if(Tr.existsSync(xr__default.join("/",n)))o=xr__default.join("/",n);else throw new w("UserConfigurationError",`APK not found at path: ${n}`);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}if(t.protocol==="http:"||t.protocol==="https:"){let n=await this.fetchWithTimeout(t);if(!n.ok)throw new w("UserInfrastructureError",`Failed to download APK from ${e} (status ${n.status})`);let o=await n.arrayBuffer(),i=Buffer.from(o),a=await this.writeBufferToTempFile(i,t.pathname);return {localPath:a,cleanup:()=>{try{Tr.unlinkSync(a);}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file");}}}}throw new w("UserConfigurationError",`Unsupported URI scheme for APK installation: ${t.protocol}`)}catch(t){if(t instanceof TypeError){let n=xr__default.resolve(e);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}throw t}}assertFileExists(e){try{Tr.accessSync(e);}catch{throw new w("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let t=AbortSignal.timeout(9e4);return await fetch(e,{signal:t})}async writeBufferToTempFile(e,t){let n=xr__default.extname(t)||".apk",o=xr__default.join(tmpdir(),`momentic-apk-${randomUUID()}${n}`);return Tr.writeFileSync(o,e),o}};async function c3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,abortSignal:a}){let s=re();if(!r.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(r.schema){let u=Lu(r.schema);if(u)throw new w("UserConfigurationError",u)}let l="",c="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{l=await o(),c=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await t.getAndroidTextExtraction({goal:r.goal,emulatorState:l,returnSchema:r.schema,screenshot:`data:image/png;base64,${c}`},{disableCache:!!r.disableCache,abortSignal:a,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["android-text-extraction"]});if(u.result=d,Ob({tracer:s,span:u,screenshot:c,emulatorState:l,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 w("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 HT=class extends or{async dragNative(e,t,n){let{left:o,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:l,top:c,width:u,height:d}=this.getBoundsFromNativeCache(t),m=o+a/2,p=i+s/2,f=l+u/2,h=c+d/2,g=n?.hoverDuration??500,y=n?.dragDuration??1e3;await this.driver.executeInNativeContext(this.logger,async S=>{await S.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:m,y:p},{type:"pointerDown",button:0},{type:"pause",duration:g},{type:"pointerMove",duration:y,x:f,y:h},{type:"pointerUp",button:0}]}]),await S.releaseActions();},{operationName:"dragAndDrop"});}async dragWebview(e,t,n){let{controller:o}=e;if(e.controller!==t.controller)throw new w("UserConfigurationError","Cannot drag and drop between different webviews");let i=n?.dragDuration??1e3,a=n?.hoverDuration??1e3,s;n?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await o.browser.dragAndDrop(e.browserTarget,t.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i});}async executeDragAndDrop({command:e}){let t=re();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new w("UserConfigurationError","Drag and drop only supports description targets for now");let n=e.fromTarget.description,{result:o,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,description:n,cacheKey:"cache",targetName:"fromTarget",action:async c=>c}),a=e.toTarget.description,{result:s,thoughts:l}=await this.wrapTargetingAction({command:e,tracer:t,description:a,cacheKey:"cache",targetName:"toTarget",action:async c=>c});if(o.type!==s.type)throw new w("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${o.type}, To=${s.type}`);return await t.startAsyncSpan("EMULATOR_INTERACTION",async c=>{o.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):o.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(c.withinWebview=!0,await this.dragWebview(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}));},{name:"Drag and drop"}),{success:!0,message:`${i}
|
|
5348
|
+
`));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&&t.appendChild(n.createTextNode(f));continue}if(p===1){let f=m;if(!QAe(f,s?.viewportBounds))continue;let h=n.createElement(XX(f.tagName));YX(r,f,h),t.appendChild(h);}}}function JAe(r,e,t,n){let o=r.parseFromString("<hierarchy/>","text/xml"),i=new Map,a={prunedDocument:o,idToElement:t,prunedIdToElement:i,idCounter:{value:0},opts:n},s=o.documentElement;YX(a,e,s);let l=new XMLSerializer().serializeToString(o);return {prunedDocument:o,prunedIdToElement:i,xml:l}}async function JX(r,e,t){let n=new DOMParser,o=n.parseFromString(r,"text/xml"),i=new Map,a=o.documentElement;if(!a)throw new w("InternalWebAgentError","No root element found in XML");if(a.tagName!=="hierarchy")throw new w("InternalWebAgentError","No hierarchy element found in XML");let{prunedDocument:s,prunedIdToElement:l,xml:c}=JAe(n,a,i,t),u=c;try{u=await zAe.format(c,{parser:"xml",plugins:[BAe],printWidth:120,tabWidth:1,singleAttributePerLine:!1});}catch(d){e.warn({err:d},"Failed to format XML");}return {xml:u,originalXml:r,document:o,idToElement:i,prunedDocument:s,prunedIdToElement:l}}function ZAe(r){let e=[],t=r;for(;t;){let n=t.tagName,o=t.parentElement,i=1;if(o){let a=Array.from(o.children).filter(s=>s.tagName===n);for(let s=0;s<a.length;s++)if(a[s]===t){i=s+1;break}}e.unshift(`${n}[${i}]`),t=o;}return `/${e.join("/")}`}function UT(r,e){let t=r.idToElement.get(e);if(t)return ZAe(t)}function uI(r,e){let t=r.idToElement.get(e);if(!t)return;let n=t.cloneNode(!0);for(let o of Array.from(n.children)){let i=o;for(let a of Array.from(i.children))i.removeChild(a);}return n.outerHTML}function vc(r){if(!r.hasAttribute("bounds"))return;let e=r.getAttribute("bounds");if(!e)return;let t=e.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);if(t){let n=parseInt(t[1],10),o=parseInt(t[2],10),i=parseInt(t[3],10),a=parseInt(t[4],10);if(Number.isFinite(n)&&Number.isFinite(o)&&Number.isFinite(i)&&Number.isFinite(a))return [n,o,i,a]}}function QAe(r,e){if(!e)return !0;let t=vc(r);if(!t||t.length<4)return !0;let n=t[0],o=t[1],i=t[2],a=t[3];return !(i<=e.left||n>=e.right||a<=e.top||o>=e.bottom)}function ZX(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}function e3({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=vc(e),!t))throw new w("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:r?.textRequired&&wd(e)||void 0,requiredAttributes:ZX(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t[0],y1:t[1],x2:t[2],y2:t[3],tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t[2]-t[0],height:t[3]-t[1],tolerance:r?.shapeSpecificity}:void 0}}function r3({aiResponse:r,description:e,emulatorState:t,memory:n,useMemory:o}){let i=t.graph.idToElement.get(r.id);if(!i)throw new w("InternalWebAgentError",`Could not find node with id: ${r.id}`);let a=vc(i);if(!a)throw new w("InternalWebAgentError",`Node ${r.id} has no bounding box: ${i.outerHTML}`);let s=UT(t.graph,r.id)??"",l=uI(t.graph,r.id)??"",c=e3({requirements:r.requirements,element:i}),u=[];r.additionalElements&&(u=r.additionalElements.map(({id:m,requirements:p})=>{let f=t.graph.idToElement.get(m);if(!f)return;let h=UT(t.graph,m);return h?{xPath:h,requirements:e3({requirements:p,element:f})}:void 0}).filter(m=>!!m));let d;if(rg(i)&&r.inWebview!==!1?d={type:"WEBVIEW",resolvedDescription:e,xPath:s}:d={type:"NATIVE",bounds:a,resolvedDescription:e,xPath:s,elementOnlySerializedXml:l,requirements:c,requiredRelatedElements:u},o)if(r.updatedMemory){let m={type:"GCS_TRACES",traces:r.updatedMemory};d.memory=m;}else n&&(d.memory=n);return {target:d,resolvedNode:i}}function n3(r){return r?.type==="WEBVIEW"?r.browserCache?.memory:void 0}function eRe(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r[0]+r[2])/2;if(!ji(e.tolerance,n,o,Math.min(1,t)))return !1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r[1]+r[3])/2;return ji(e.tolerance,a,s,Math.min(1,i))}function tRe(r,e){return ji(e.tolerance,e.width,r[2]-r[0],Math.min(1,e.width))?ji(e.tolerance,e.height,r[3]-r[1],Math.min(1,e.height)):!1}var t3=(r,e,t)=>{if(!e)return;let{requiredAttributes:n,requiredText:o,requiredBounds:i,position:a,shape:s}=e;if(o!==void 0&&o.length>0){let l=wd(r);if(l!==o)throw new Ee(`Resolved element text mismatch: expected ${o}, got ${l}`)}if(n)for(let[l,c]of Object.entries(n)){let u=r.getAttribute(l)??void 0;if(u!==c)throw new Ee(`Attribute ${l} mismatch: expected ${c}, got ${u}`)}if(i&&t&&!t.targetBounds.every((c,u)=>c===t.newElementBounds[u]))throw new Ee(`Bounds changed from [${t.targetBounds.join(",")} ] to [${t.newElementBounds.join(",")} ]`);if(a&&t&&!eRe(t.newElementBounds,a))throw new Ee(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(t.newElementBounds)}`);if(s&&t&&!tRe(t.newElementBounds,s))throw new Ee(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(t.newElementBounds)}`)};async function om(r){let{target:e,domState:t}=r,{graph:n}=t,{document:o}=n,i=re();if(e.type==="WEBVIEW")return rRe(e,r);if(!e.xPath)throw new w("ActionFailureError","Native element cache has no XPath");let a=QX.evaluateXPathToFirstNode(e.xPath,o,null,null);if(!a)throw new Ee(`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=QX.evaluateXPathToFirstNode(p.xPath,o);if(!f)throw new Ee(`Required related element not found for XPath: ${p.xPath}`);t3(f,p.requirements);}});}let s=vc(a);if(!s)throw new Ee("Resolved native element has no bounding box");if(!e.bounds)throw new Ee("Native element cache has no bounds");t3(a,e.requirements,{targetBounds:e.bounds,newElementBounds:s});let l;for(let[m,p]of n.idToElement.entries())if(p===a){l=m;break}let c=e.elementOnlySerializedXml,u=e.xPath;return l!==void 0&&(c=uI(n,l)??c,u=UT(n,l)??u),{resolvedTarget:{...e,resolvedNode:a,bounds:s,elementOnlySerializedXml:c,xPath:u}}}async function rRe(r,e){let{stateManager:t,logger:n,signal:o}=e,i=re(),a=await t.getActiveWebview();if(!a||!a.browserController)throw n.error({webview:a?{...a,browserController:!!a.browserController}:void 0},"resolveTargetCacheInWebView: No browser controller attached"),new Ee("No browser controller is attached to the requested webview");let s=a.browserController;if(!r.browserCache)throw n.error({target:r},"resolveTargetCacheInWebView: No browser target available on cache"),new Ee("No browser target available on cache");let l=r.browserCache,{finalTarget:c}=await i.startAsyncSection("Resolve target in webview",()=>s.resolveCachedTargetForAction({cache:l,options:{resolveTargetOptions:{logger:n,signal:o,skipWaitForPageLoad:!0,skipSavingVisualAttributes:!0}},logger:n}));return {resolvedTarget:{...r,controller:a.browserController,browserTarget:c}}}function Cc(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;Ci(e)&&(e[t]={...e[t],[n]:iu.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=we(r.logger)));}function al(r){if(r.type==="WEBVIEW")return {type:"WEBVIEW",resolvedDescription:r.resolvedDescription,xPath:r.xPath,browserCache:r.browserCache,memory:r.memory};let{resolvedNode:e,...t}=r;return {...t}}var ao=.15,oRe=500,or=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:t,skipFetchingFullWebviewContent:n=!1,removeWebviewContent:o=!1,useMemory:i=!1,memory:a,webviewMemory:s,metadata:l,cacheBustReason:c}){let u=this.logger.child({...l}),d=await t.startAsyncSection("Get emulator state",async()=>{let y=await this.stateManager.getCurrentScreenshotPngString();return {emulatorState:await this.stateManager.getDomState({skipFetchingFullWebviewContent:n,removeWebviewContent:o}),screenshot:y}}),m;try{m=await t.startAsyncSpan("AI_LOCATOR_CALL",async y=>{c&&(y.attributes.cacheBustReason=c);let S=await this.generator.getAndroidElementLocation({description:e,screenXml:d.emulatorState.graph.xml,screenshot:d.screenshot,source:l?.source==="SCROLL_TO"?"SCROLL_TO":void 0,memory:i?a:void 0},{logger:u,loggerTags:we(u),abortSignal:this.aborter.controller?.signal,useMemory:i,agentConfigVersion:this.aiSettings.agentConfig?.["android-locator"]});return y.result=S,S});}catch(y){throw this.throwIfAborted(),u.error({err:y},"Failed to locate element"),new w("InternalWebAgentError",`Failed to locate element: ${y instanceof Error?y.message:y}`,{errOptions:{cause:y}})}if(m.id===-1){let y=m.updatedMemory?{type:"GCS_TRACES",traces:m.updatedMemory}:void 0;return {success:!1,thoughts:m.thoughts??"No matching element found",updatedLocatorMemory:y}}let{target:p,resolvedNode:f}=r3({aiResponse:m,description:e,emulatorState:d.emulatorState,memory:a,useMemory:i});if(p.type==="NATIVE")return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:p.elementOnlySerializedXml??"Unknown element"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,resolvedNode:f},thoughts:m.thoughts};let{browserLocateResult:h,browserController:g}=await t.startWebviewTrace(async()=>{let y=await this.stateManager.getActiveWebview();if(!y||!y.browserController)throw new w("InternalWebAgentError","No browser controller is attached to the requested webview");return {browserLocateResult:await y.browserController.locateElement({description:e,disableCache:!1,useMemory:i,memory:i?s:void 0,logger:this.logger,skipWait:!0,skipSavingVisualAttributes:!0}),browserController:y.browserController}});return t.addSpan({type:"TARGET_RESOLUTION",startTime:Date.now(),endTime:Date.now(),result:{serializedElement:h.target.nodeOnlySerializedHtml??"Unknown HTML element in webview"},attributes:{},subSpans:[]}),{success:!0,resolvedTarget:{...p,controller:g,browserTarget:{...h.resolution,serverSideBoundingBox:await h.resolution.locator.boundingBox({timeout:5e3})},browserCache:h.target},thoughts:h.thoughts}}async targetingActionWithAILocator(e){let{action:t,command:n,description:o,tracer:i,cacheKey:a,targetName:s,cache:l,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:d,cacheBustReason:m}=e,p=await this.findElement({description:o,tracer:i,skipFetchingFullWebviewContent:c,removeWebviewContent:u,useMemory:this.shouldUseMemoryForCommand(n),memory:l?.memory,webviewMemory:n3(l),metadata:d,cacheBustReason:m});if(!p.success){if(p.updatedLocatorMemory&&l){let y={...l,memory:p.updatedLocatorMemory};Cc({command:n,cacheKey:a,targetName:s,updatedCache:y,updatedWithAI:!0,logger:this.logger});}throw new w("NoMatchingElementError",p.thoughts??"No matching element found")}let f=p.thoughts,{result:h,resolvedTarget:g}=await this.executeActionWithWebviewReconstructRetry({action:t,resolvedTarget:p.resolvedTarget,reason:"webview target closed during AI-located action"});return Cc({command:n,cacheKey:a,targetName:s,updatedCache:al(g),updatedWithAI:!0,logger:this.logger}),{result:h,thoughts:f}}async wrapTargetingAction(e){let{action:t,description:n,command:o,cacheKey:i="cache",targetName:a="target",cacheIsInvalidAfterResolution:s,tracer:l,skipFetchingFullWebviewContent:c=!1,removeWebviewContent:u=!1}=e,d,m={commandId:o.id};if(i==="cache"&&"cache"in o&&o.cache){let b=o.cache;a==="target"&&"target"in b?d=b.target:a==="fromTarget"&&"fromTarget"in b?d=b.fromTarget:a==="toTarget"&&"toTarget"in b&&(d=b.toTarget);}let p=!1,f,h=cloneDeep(d);if(o.disableCache&&(this.logger.debug({command:o},"Cache explicitly disabled for command"),p=!0,f="Cache explicitly disabled",h=void 0),s&&(p=!0,f=f??"Cache invalidated after resolution",h=void 0),h&&!js(h?.resolvedDescription??"",n)&&(this.logger.info({description:n,cacheDescription:h?.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=!0,f="Description mismatch",h=void 0),!h)return this.logger.info({description:n,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:l,cacheKey:i,targetName:a,cache:d,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:m,cacheBustReason:f});let g=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements,y=h.type==="NATIVE"?!!h.requiredRelatedElements?.length:!!h.browserCache?.additionalElements?.length,S;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:b}=await l.startAsyncSpan("CACHE_RESOLUTION",async O=>{let M=Date.now(),R;for(;Date.now()-M<3e3;){S=await this.stateManager.getDomState({skipFetchingFullWebviewContent:h?.type==="NATIVE"});let _;try{_=(await om({target:h,domState:S,stateManager:this.stateManager,logger:this.logger})).resolvedTarget;}catch(J){if(R=J,J instanceof Ee){this.logger.warn({err:J},"Failed to resolve target cache, retrying"),await Li(500,this.aborter.controller?.signal);continue}throw this.logger.error({err:J},"Failed to resolve target cache"),J}let k=al(_),B=diff(h,k);return B&&Object.keys(B).length>0&&this.logger.info({cacheDiffs:B},"Successfully resolved target with cache"),O.attributes.serializedElement=_.type==="WEBVIEW"?_.browserCache?.nodeOnlySerializedHtml??"Unknown HTML element in webview":_.elementOnlySerializedXml??"Unknown element",{resolvedTarget:_,updatedCache:k}}throw R}),{result:C,resolvedTarget:A}=await this.executeActionWithWebviewReconstructRetry({action:t,resolvedTarget:b,reason:"webview target closed during cached action"});return Cc({command:o,cacheKey:i,targetName:a,updatedCache:al(A),updatedWithAI:!1,logger:this.logger}),Et.increment("cache_target_resolution_v2",1,["outcome:hit",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${g}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.88.2"]),{result:C,thoughts:"Successfully executed preset action with cache"}}catch(b){if(this.throwIfAborted(),b instanceof w&&b.reason!=="InternalWebAgentError")throw this.logger.error({err:b},"Failed to execute action with target cache (fatal)"),b;return Et.increment("cache_target_resolution_v2",1,["outcome:miss",`platform:mobile-${h.type.toLowerCase()}`,`hasRequirements:${g}`,`hasAdditionalElements:${y}`,`orgId:${this.orgId}`,"cliVersion:0.88.2"]),this.logger.warn({err:b},"Failed to execute action with target cache, retrying with AI"),this.targetingActionWithAILocator({action:t,command:o,description:n,tracer:l,cacheKey:i,targetName:a,cache:h,skipFetchingFullWebviewContent:c,removeWebviewContent:u,metadata:m})}}async executeActionWithWebviewReconstructRetry(e){let{action:t,resolvedTarget:n,reason:o}=e;try{return {result:await t(n),resolvedTarget:n}}catch(i){if(this.throwIfAborted(),n.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(o))?.browserController))throw i;let s=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0}),{resolvedTarget:l}=await om({target:al(n),domState:s,stateManager:this.stateManager,logger:this.logger,signal:this.abortSignal});return {result:await t(l),resolvedTarget:l}}}errorLooksLikeClosedWebviewTarget(e){let t=ne(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(n=>t.includes(n))}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 w("ActionFailureError","Native element cache has no bounds");let[t,n,o,i]=e.bounds;if(t===void 0||n===void 0||o===void 0||i===void 0)throw new w("ActionFailureError",`Native element cache has incomplete bounds: [${e.bounds.join(", ")}]`);return {left:t,top:n,width:o-t,height:i-n}}calculateSwipeCoordinates({containerBounds:e,direction:t,desiredDelta:n}){let o=e.left+e.width/2,i=e.top+e.height/2;if(t==="up"||t==="down"){let a=e.height*ao,s=e.top+a,l=e.top+e.height-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u,m=t==="down"?l-d/2:s+d/2;return {startX:o,startY:m,actualDelta:u}}else {let a=e.width*ao,s=e.left+a,l=e.left+e.width-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u;return {startX:t==="right"?l-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:t,deltaPixels:n,direction:o,durationMs:i=300}){let a=Math.abs(n),s=e,l=t;o==="up"||o==="down"?l=o==="up"?t-a:t+a:s=o==="left"?e-a:e+a,await this.driver.executeInNativeContext(this.logger,async c=>{await c.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:e,y:t},{type:"pointerDown",button:0},{type:"pause",duration:250},{type:"pointerMove",duration:i,x:s,y:l},{type:"pause",duration:500},{type:"pointerUp",button:0}]}]),await c.releaseActions();},{operationName:"performRawSwipe"}),await te(oRe,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 a3(r){return "iterations"in r}function sRe(r){let e={relativePosition:r.relativePosition};if(r.iterations!==void 0&&(!Number.isInteger(r.iterations)||r.iterations<1))throw new Error("UserConfigurationError: iterations must be a positive integer");if(r.tapDelayMs!==void 0&&(!Number.isInteger(r.tapDelayMs)||r.tapDelayMs<0))throw new Error("UserConfigurationError: tapDelayMs must be >= 0");if(r.iterations&&r.iterations>1&&r.longPress)throw new Error("UserConfigurationError: Cannot specify both more than one tap iteration and long press at the same time");if(r.tapDelayMs!==void 0&&(!r.iterations||r.iterations<2))throw new Error("UserConfigurationError: tapDelayMs requires iterations >= 2");if(r.longPress){if(r.tapDelayMs!==void 0)throw new Error("UserConfigurationError: tapDelayMs cannot be used with longPress");return {...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}}return r.iterations!==void 0?{...e,iterations:r.iterations,tapDelayMs:r.tapDelayMs}:e}var im=class extends or{async tapOnNativeCoordinates(e){let t=e.x,n=e.y;if(this.logger.info({x:t,y:n},"Tap at coordinates"),"longPress"in e&&e.longPress)return await this.driver.executeInNativeContext(this.logger,o=>o.executeScript("mobile: longClickGesture",[{x:t,y:n,duration:e.longPressDurationMs??2e3}]),{operationName:"longPress"});if(a3(e)){let o=e.tapDelayMs??100;for(let i=0;i<e.iterations;i++)await this.driver.executeInNativeContext(this.logger,a=>a.tap({x:t,y:n}),{operationName:"tap"}),i<e.iterations-1&&await new Promise(a=>setTimeout(a,o));return}await this.driver.executeInNativeContext(this.logger,o=>o.tap({x:t,y:n}),{operationName:"tap"});}async tapOnNativeTarget(e,t){let[n,o,i,a]=e.bounds,s=i-n,l=a-o,c=t?.relativePosition?.x??s/2,u=t?.relativePosition?.y??l/2;c=Math.max(0,Math.min(c,s)),u=Math.max(0,Math.min(u,l));let d=n+c,m=o+u;return await this.tapOnNativeCoordinates({x:d,y:m,...t}),{x:d,y:m}}async tapOnWebviewTarget(e,t){let{controller:n}=e,o,i=1;return t&&a3(t)?(o=t.tapDelayMs,i=t.iterations):t&&"longPress"in t&&(o=t.longPressDurationMs),(await n.browser.click(e.browserTarget,{createIsolatedFolder:()=>{let s=Math.random().toString(36).substring(4),l=xr__default.join(tmpdir(),"momentic","downloads"),c=xr__default.join(l,this.orgId,s);return mkdirSync(c,{recursive:!0}),c}},{delayMs:o,relativePosition:t?.relativePosition,iterations:i})).coordinates}async tapOnTarget({target:e,options:t}){return await re().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.attributes.options=t,"type"in e&&e.type==="NATIVE"?o.attributes.point=await this.tapOnNativeTarget(e,t):(o.withinWebview=!0,o.attributes.point=await this.tapOnWebviewTarget(e,t));},{name:"Tap on target"})}async executeTap({command:e}){let t=re(),n=sRe(e);if(e.target.type==="coordinates"){let a=await this.driver.executeInNativeContext(this.logger,c=>c.getWindowSize(),{operationName:"getTapWindowSize"}),s=e.target.xPercent*a.width,l=e.target.yPercent*a.height;return await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.tapOnNativeCoordinates({...n,x:s,y:l});},{name:`Tap at coordinates ${s}, ${l}`}),{success:!0,message:`Tapped at ${s}, ${l}`}}let o=e.target.description,{thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,action:a=>this.tapOnTarget({target:a,options:n}),description:o});return {success:!0,message:i}}};var sl=class extends or{async doPress({keycode:e,longPress:t}){await re().startAsyncSpan("EMULATOR_INTERACTION",async()=>this.driver.executeInNativeContext(this.logger,o=>o.executeScript("mobile: pressKey",[{keycode:e,isLongPress:t}]),{operationName:"pressKey"}),{name:"Send key events to emulator"});}};var wc=25,s3=150,zT=class extends or{async doType(e){let t=re();if(!e.target){if(e.clearContent)throw new w("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:!0,message:"Successfully executed type action"}}if(e.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Type step");let{thoughts:n}=await this.wrapTargetingAction({command:e,tracer:t,action:async o=>{"type"in o&&o.type==="NATIVE"?await this.doNativeType(e,o):await this.doWebviewType(e,o);},description:e.target.description});return {success:!0,message:n}}async doWebviewType(e,t){await re().startAsyncSpan("EMULATOR_INTERACTION",async o=>{o.withinWebview=!0;let i={clearContent:e.clearContent,forceClearContent:e.forceClearContent,delay:e.keyPressDelayMs??wc};o.attributes.options=i;let{controller:a,browserTarget:s}=t;await a.browser.typeIntoTarget(e.text,s,i);},{name:"Typing within web view"});}async doNativeType(e,t){let n=new im(this.constructPerformerParams());e.clearContent?(await n.tapOnNativeTarget(t,{longPress:!0}),await this.clearContent()):await n.tapOnNativeTarget(t),await this.stateManager.waitForPageSourceStability({timeoutMs:2e3,signal:this.aborter.controller?.signal,reason:"Waiting for keyboard to appear before typing"}),await this.sendKeys(e);}async sendKeys(e){let t=re(),n=e.keyPressDelayMs??wc;await t.startAsyncSection("Waiting for system keyboard to open",async(o,i)=>{let a=Date.now();for(;Date.now()-a<2e3;){this.throwIfAborted();let s=Date.now();if(await this.driver.executeInNativeContext(this.logger,c=>c.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;let l=Date.now()-s;l<500&&await new Promise(c=>setTimeout(c,500-l));}i.attributes.timedOut=!0;}),await t.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{n!==wc&&await this.driver.executeInNativeContext(this.logger,async i=>i.updateSettings({keyInjectionDelay:n}),{operationName:"updateKeyInjectionDelay"});let o=[];for(let i=0;i<e.text.length;i+=s3)o.push(e.text.slice(i,i+s3));for(let i of o)await this.driver.executeInNativeContext(this.logger,async a=>a.keys(i),{operationName:"typeWithCustomKeyDelay",attemptTimeoutMs:Nb(n,i),maxAttempts:1});}finally{n!==wc&&await this.driver.executeInNativeContext(this.logger,async o=>o.updateSettings({keyInjectionDelay:wc}),{operationName:"updateKeyInjectionDelay"});}},{name:`Typing with a ${n}ms delay`});}async clearContent(){let e=re();try{await e.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper());}catch(t){this.logger.warn({err:t},"Failed to find select all button, continuing...");}}async clearContentHelper(){await this.driver.executeInNativeContext(this.logger,async t=>{let n=t.$('//android.widget.LinearLayout[@content-desc="Select all" and @clickable="true"]');await n.waitForExist({timeout:750}),await n.click();},{operationName:"selectAllText",maxAttempts:1}),await new sl(this.constructPerformerParams()).doPress({keycode:67});}};var l3=.8,lRe=v__default.object({navigationBar:v__default.object({visible:v__default.boolean(),x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()}),statusBar:v__default.object({visible:v__default.boolean(),x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()})});function pI(r,e){r.attributes.scrollableElementType=e.type,r.attributes.scrollableElementDisplay=ha(e),e.type==="CUSTOM"&&(r.attributes.scrollableElementDescription=e.target.description);}var am=class extends or{async getHardcodedScrollableElementBounds(e,t){let n;switch(e.type){case"SCREEN":n=this.getContainerBoundsFromViewport(t);break;case"OPEN_APP":try{let o=lRe.parse(await this.driver.executeInNativeContext(this.logger,i=>i.executeScript("mobile: getSystemBars",[]),{operationName:"getSystemBars"}));n=this.getContainerBoundsFromViewport(t),o.navigationBar.visible&&(n.height=Math.max(1,n.height-o.navigationBar.height)),o.statusBar.visible&&(n.top+=o.statusBar.height,n.height=Math.max(1,n.height-o.statusBar.height));}catch(o){this.logger.warn({err:o},"Failed to get system bars, using hardcoded bounds"),n=this.getContainerBoundsFromViewport(t);}break;case"OPEN_WEBVIEW":{let o=await this.stateManager.getActiveWebviewNodes();if(o.length===0&&(await this.stateManager.refreshWebviewsManually("get active webview nodes"),o=await this.stateManager.getActiveWebviewNodes()),o.length===0)throw new Error("No active webviews found");if(o.length>1){let a=o.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=o[0]?.bounds;if(!i)throw new Error("No bounds found for active webview");n=this.getContainerBoundsFromBounds(i);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return n}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:Math.max(1,e.width),height:Math.max(1,e.height)}}getContainerBoundsFromBounds(e){let t=e[0],n=e[1],o=e[2],i=e[3],a=o-t,s=i-n;return {left:t,top:n,width:Math.max(1,a),height:Math.max(1,s)}}async executeSwipe(e){let t=re(),n=ha(e.scrollableElement);if(e.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:i,startY:a,deltaPixels:s}=e.scrollableElement;return await t.startAsyncSpan("EMULATOR_INTERACTION",async l=>{pI(l,e.scrollableElement),l.attributes.startX=i,l.attributes.startY=a,l.attributes.deltaPixels=s,l.attributes.direction=e.direction,await this.performRawSwipe({startX:i,startY:a,deltaPixels:s,direction:e.direction,durationMs:e.durationMs});},{name:`Swipe ${e.direction} in ${n}`}),{success:!0,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 t.startAsyncSpan("EMULATOR_INTERACTION",async s=>{pI(s,e.scrollableElement),await this.swipeByAbsoluteCoordinates({span:s,direction:e.direction,percent:e.viewportPercent,durationMs:e.durationMs,containerBounds:a,relativePosition:e.relativePosition});},{name:`Swipe ${e.direction} in ${n}`}),{success:!0,message:"Successfully executed swipe action"}}let{thoughts:o}=await this.wrapTargetingAction({command:e,description:e.scrollableElement.target.description,action:async i=>re().startAsyncSpan("EMULATOR_INTERACTION",async s=>(pI(s,e.scrollableElement),"type"in i&&i.type==="NATIVE"?this.scrollInNativeContainer({span:s,cmd:e,target:i}):(s.withinWebview=!0,this.swipeInWebview({span:s,cmd:e,target:i}))),{name:`Swipe ${e.direction} in ${n}`}),tracer:t});return {success:!0,message:o}}async scrollInNativeContainer({span:e,cmd:t,target:n}){if(!n.bounds||n.bounds.length<4)throw new w("ActionFailureError","Native container cache has no bounds");let o=n.bounds,i=o[2]-o[0],a=o[3]-o[1];await this.swipeByAbsoluteCoordinates({span:e,direction:t.direction,percent:t.viewportPercent,durationMs:t.durationMs,containerBounds:{left:o[0],top:o[1],width:Math.max(1,i),height:Math.max(1,a)},relativePosition:t.relativePosition});}async swipeInWebview({span:e,cmd:t,target:n}){let{controller:o,browserTarget:i}=n;if(!o.browser.getViewport())throw new Error("Failed to get viewport size from webview");let s=t.direction==="down"||t.direction==="up",l=await i.locator.boundingBox();if(!l)throw new Error("Failed to get bounds for webview container");let c=Math.floor(l.width*ao),u=Math.floor(l.height*ao),d=Math.max(1,l.width-c*2),m=Math.max(1,l.height-u*2),p,f;t.relativePosition?(p=l.x+t.relativePosition.x,f=l.y+t.relativePosition.y):(p=l.x+l.width/2,f=l.y+l.height/2);let h={x:p,y:f},g=(s?m:d)*(t.viewportPercent??l3)*(s?t.direction==="down"?1:-1:t.direction==="right"?1:-1);e.attributes.startPoint=h,e.attributes.scrollPixelAmount=g,await o.browser.mouseDragUsingVisualCoordinates({deltaX:s?0:g,deltaY:s?g:0,steps:10,dragDurationMs:t.durationMs,fromTarget:h});}async swipeByAbsoluteCoordinates({span:e,direction:t,percent:n=l3,durationMs:o=500,containerBounds:i,relativePosition:a}){e.attributes.containerBounds=i;let s=i.width*ao,l=i.height*ao,c,u;if(t==="up"||t==="down"?(c=(i.height-2*l)*n,u=Math.floor(c/(o/1e3))):(c=(i.width-2*s)*n,u=Math.floor(c/(o/1e3))),e.attributes.pixelDelta=c,e.attributes.pixelsPerSecond=u,a){let d=i.left+a.x,m=i.top+a.y;await this.performRawSwipe({startX:d,startY:m,deltaPixels:c,direction:t,durationMs:o});}else {let d=i.width*ao,m=i.height*ao,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:t,percent:n,speed:u}]),{operationName:"swipeGesture"});}}};var cRe=20,fI=.9,sm=.5,hI=.2;var $T=class extends am{async executeScrollTo(e){let t=e.target.description,n=e.scrollStepPercent??fI,o=await this.tryUseCachedScrollPosition(e,t);return o||this.searchForElement({cmd:e,description:t,scrollStepPercent:n})}async resolveContainer({scrollableElement:e,containerCache:t,aiMetadata:n}){let o=await this.driver.executeInNativeContext(this.logger,u=>u.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(e.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:o.width,height:o.height},diffThresholdPercent:sm};if(e.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(e,o),diffThresholdPercent:sm};let i=re(),a=e.target.description;if(t){let u=this.getBoundsFromNativeCache(t);return this.logger.info({bounds:u},"Got container bounds from native cache"),{bounds:u,cache:t,diffThresholdPercent:Td({containerBounds:u,viewport:o,defaultThresholdPercent:sm})}}let s=await this.findElement({description:a,tracer:i,metadata:n});if(!s.success)throw new w("NoMatchingElementError",s.thoughts??"No matching element found");let{resolvedTarget:l}=s;if(l.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(l);return this.logger.info({bounds:c},"Got container bounds from AI"),{bounds:c,cache:l,diffThresholdPercent:Td({containerBounds:c,viewport:o,defaultThresholdPercent:sm})}}async tryUseCachedScrollPosition(e,t){let n=e.cache?.target;return n?n.type==="WEBVIEW"?this.tryUseWebviewCache(e,t):n.scrollDetails?this.tryUseNativeScrollCache(e,t,n):null:null}async tryUseWebviewCache(e,t){let n=re();try{let{thoughts:o}=await this.wrapTargetingAction({command:e,tracer:n,description:t,action:async i=>{if(i.type==="NATIVE")throw new Error("Expected WEBVIEW target but got NATIVE");await this.scrollWebviewTargetIntoView(i);}});return {success:!0,message:o}}catch(o){return this.logger.warn({err:o},"Failed to use webview cache, falling back to search"),null}}async tryUseNativeScrollCache(e,t,n){let o=n.scrollDetails,i=re(),a=e.scrollStepPercent??fI;if(o.pixelDelta===0)return this.logger.info("Skipping cached scroll-position replay because it would not move the viewport"),null;let s=o.scrollableElement.type==="CUSTOM"?o.scrollableElement.cache:void 0;await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:o.direction,scrollStepPercent:a,aiMetadata:{commandId:e.id}});try{let c=await this.tryFindElement({cmd:e,description:t,tracer:i,scrollDetails:o,useAIIfCacheFails:!0});if(c)return c;this.logger.info("Element not found at cached position, undoing scroll");}catch(c){this.logger.warn({err:c},"Error finding element at cached position, will undo scroll");}let l=o.direction==="down"?"up":"down";return this.logger.info({pixelDelta:o.pixelDelta,originalDirection:o.direction,undoDirection:l,scrollableElementType:o.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:o.scrollableElement,containerCache:s,direction:l,scrollStepPercent:a,aiMetadata:{commandId:e.id}}),null}async tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:o,useAIIfCacheFails:i=!0}){let a,s,l=!1,c=o,u=gI(e.cache?.target);if(u&&u.resolvedDescription!==void 0&&js(u.resolvedDescription,t)&&!e.disableCache){let p=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0});try{let{resolvedTarget:f}=await om({target:u,domState:p,stateManager:this.stateManager,logger:this.logger});a=f,l=!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&&l&&a.type==="NATIVE"&&o){let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:o});c=p.scrollDetails,p.resolvedTarget?a=p.resolvedTarget:(a=void 0,l=!1);}if(!a&&!i)return null;if(!a)try{let p=nE(t),f=await this.findElement({description:p,tracer:n,metadata:{commandId:e.id,source:"SCROLL_TO"}});if(!f.success)return null;a=f.resolvedTarget,s=f.thoughts;}catch(p){if(p instanceof w&&p.reason==="NoMatchingElementError")return null;throw this.logger.warn({err:p},"Failed to find scroll-to target with AI"),p}if(a&&!l&&a.type==="NATIVE"&&o)try{let p=await this.correctNativeTargetIntoView({cmd:e,resolvedTarget:a,scrollDetails:o});c=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=gI(al(a));return Cc({command:e,updatedCache:p,updatedWithAI:!l,logger:this.logger}),{success:!0,message:s}}let m=al(a);if(m.type!=="NATIVE")throw new Error("Expected native target cache for scroll-to");return Cc({command:e,updatedCache:gI({...m,scrollDetails:c}),updatedWithAI:!l,logger:this.logger}),{success:!0,message:s}}async correctNativeTargetIntoView({cmd:e,resolvedTarget:t,scrollDetails:n}){let o=await this.getCorrectiveScrollForTarget({resolvedTarget:t});if(!o)return {resolvedTarget:t,scrollDetails:n};this.logger.info({bounds:t.bounds,correction:o},"Repositioning scroll-to target to the preferred viewport anchor");let i=n.scrollableElement.type==="CUSTOM"?n.scrollableElement.cache:void 0,a=await this.scrollByPixelDelta({pixelDelta:o.pixelDelta,scrollableElement:n.scrollableElement,containerCache:i,direction:o.direction,scrollStepPercent:e.scrollStepPercent??fI,aiMetadata:{commandId:e.id},useVisualDiff:!0});if(a===0)return this.logger.info({bounds:t.bounds,correction:o},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:t,scrollDetails:n};let s={...n,pixelDelta:_b({currentPixelDelta:n.pixelDelta,baseDirection:n.direction,correctionDirection:o.direction,correctionPixels:a})},l=await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0}),c;try{({resolvedTarget:c}=await om({target:t,domState:l,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(c.type!=="NATIVE")return {scrollDetails:s};let u=await this.getCorrectiveScrollForTarget({resolvedTarget:c});return u?(this.logger.warn({bounds:c.bounds,correction:u},"Corrective scroll still did not bring the scroll-to target into the preferred viewport anchor"),{resolvedTarget:c,scrollDetails:s}):{resolvedTarget:c,scrollDetails:s}}async searchForElement({cmd:e,description:t,scrollStepPercent:n}){let o=re(),i=await this.resolveContainer({scrollableElement:e.scrollableElement,aiMetadata:{commandId:e.id}});return this.scrollAndSearch({cmd:e,description:t,tracer:o,scrollStepPercent:n,resolvedContainer:i})}async scrollAndSearch({cmd:e,description:t,tracer:n,scrollStepPercent:o,resolvedContainer:i}){let a=0,s=i.bounds,l=i.diffThresholdPercent,c=e.scrollableElement.type==="CUSTOM_COORDINATES"?e.scrollableElement:void 0,u;c?u=Math.abs(c.deltaPixels):u=this.calculateSwipeCoordinates({containerBounds:s,direction:e.direction,desiredDelta:Fs({containerBounds:s,containerInsetRatio:ao})*o}).actualDelta;let d=!0,m=e.maxScrollAttempts??cRe;for(let h=0;h<m;h++){this.throwIfAborted();let g=this.buildScrollDetails(e,a,i.cache),y=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:g});if(y)return y;if(!d)throw new Error(`ActionFailureError: Could not find element "${t}" 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:o,diffThresholdPercent:l,rawCoordinates:c}),a+=e.direction==="down"?u:-u;}let p=this.buildScrollDetails(e,a,i.cache),f=await this.tryFindElement({cmd:e,description:t,tracer:n,scrollDetails:p});if(f)return f;throw new Error(`ActionFailureError: Could not find element "${t}" after ${m} scroll attempts`)}buildScrollDetails(e,t,n){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:t,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:n},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollWebviewTargetIntoView(e){let{controller:t,browserTarget:n}=e;await t.browser.hover(n);}async scrollByPage({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o,rawCoordinates:i}){return re().startAsyncSpan("EMULATOR_INTERACTION",async s=>(s.attributes.containerBounds=t,s.attributes.direction=e,(await this.executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o,rawCoordinates:i})).canScrollMore),{name:`Scroll ${e} by one page`})}async scrollByPixelDelta({pixelDelta:e,scrollableElement:t,containerCache:n,direction:o,scrollStepPercent:i,aiMetadata:a,useVisualDiff:s=!1}){if(e===0)return 0;let l=re(),c,u=sm,d,m,p;if(t.type==="CUSTOM_COORDINATES")d=t.startX,m=t.startY,p=t.deltaPixels;else {c=await this.resolveContainer({scrollableElement:t,containerCache:n,aiMetadata:a});let h=c.bounds;u=c.diffThresholdPercent;let g=Fs({containerBounds:h,containerInsetRatio:ao})*i,y=this.calculateSwipeCoordinates({containerBounds:h,direction:o,desiredDelta:g});d=y.startX,m=y.startY,p=y.actualDelta;}let f=Math.ceil(Math.abs(e)/p);return this.logger.debug({pixelDelta:e,direction:o,scrollableElementType:t.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),l.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 g=this.invertDirection(o),y=0;for(let S=0;S<f;S++){this.throwIfAborted();let b=Math.abs(e)-y,C=Math.min(p,b);if(s){let A=await this.executeScrollGesture({direction:o,containerBounds:c?.bounds,scrollStepPercent:i,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:C}});if(A.didScroll&&(y+=C),!A.canScrollMore)break}else await this.performRawSwipe({startX:d,startY:m,deltaPixels:C,direction:g}),y+=C;}return h.attributes.appliedPixels=y,y},{name:`Scroll ${o} by ${Math.abs(e)}px`})}async executeScrollGesture({direction:e,containerBounds:t,scrollStepPercent:n,diffThresholdPercent:o=sm,rawCoordinates:i}){let a=await this.stateManager.getRawScreenshotBase64(),s,l,c;if(i)s=i.startX,l=i.startY,c=i.deltaPixels;else {if(!t)throw new Error("Expected container bounds for scroll gesture");let f=Fs({containerBounds:t,containerInsetRatio:ao})*n,h=this.calculateSwipeCoordinates({containerBounds:t,direction:e,desiredDelta:f});s=h.startX,l=h.startY,c=h.actualDelta;}await this.performRawSwipe({startX:s,startY:l,deltaPixels:c,direction:this.invertDirection(e)});let u=await this.stateManager.getRawScreenshotBase64(),d=Ds(a,u),m=d>o,p=d>o;return this.logger.debug({diffPercent:d,didScroll:m,diffThresholdPercent:o,canScrollMore:p,direction:e,actualDelta:c,rawCoordinates:i},"Scroll gesture visual diff result"),{didScroll:m,canScrollMore:p}}async getCorrectiveScrollForTarget({resolvedTarget:e}){let t=e.bounds;if(!t||t.length<4)return;let n=await this.stateManager.getViewportBounds(),o=Math.max(1,n.bottom-n.top),i=t[1],a=t[3],s=Pb({viewportTop:n.top,viewportBottom:n.bottom,elementHeight:a-t[1],targetTopRatio:hI}),l=n.top+o*hI,c=n.bottom-o*hI,u=i>=n.top&&a<=n.bottom,d=i<l||a>c,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 gI(r){return !r||r.type!=="NATIVE"?r:Ib(r)}var VT=class extends or{async doInstallApk(e){return await this.installApkFromUri(e.uri),{success:!0,message:"Installed APK."}}async installApkFromUri(e){let t=await this.resolveUriToLocalApk(e);try{await this.stateManager.executeRawADBCommand(`install -r ${xr__default.resolve(t.localPath)}`),this.logger.info({uri:e,localPath:t.localPath},"Installed APK on device");}finally{t.cleanup();}}async resolveUriToLocalApk(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.href.slice(7),o;if(Tr.existsSync(n))o=n;else if(Tr.existsSync(xr__default.join("/",n)))o=xr__default.join("/",n);else throw new w("UserConfigurationError",`APK not found at path: ${n}`);return this.assertFileExists(o),{localPath:o,cleanup:()=>{}}}if(t.protocol==="http:"||t.protocol==="https:"){let n=await this.fetchWithTimeout(t);if(!n.ok)throw new w("UserInfrastructureError",`Failed to download APK from ${e} (status ${n.status})`);let o=await n.arrayBuffer(),i=Buffer.from(o),a=await this.writeBufferToTempFile(i,t.pathname);return {localPath:a,cleanup:()=>{try{Tr.unlinkSync(a);}catch(s){this.logger.warn({err:s,path:a},"Failed to remove temporary APK file");}}}}throw new w("UserConfigurationError",`Unsupported URI scheme for APK installation: ${t.protocol}`)}catch(t){if(t instanceof TypeError){let n=xr__default.resolve(e);return this.assertFileExists(n),{localPath:n,cleanup:()=>{}}}throw t}}assertFileExists(e){try{Tr.accessSync(e);}catch{throw new w("UserConfigurationError",`APK not found at path: ${e}`)}}async fetchWithTimeout(e){let t=AbortSignal.timeout(9e4);return await fetch(e,{signal:t})}async writeBufferToTempFile(e,t){let n=xr__default.extname(t)||".apk",o=xr__default.join(tmpdir(),`momentic-apk-${randomUUID()}${n}`);return Tr.writeFileSync(o,e),o}};async function c3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,abortSignal:a}){let s=re();if(!r.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(r.schema){let u=Lu(r.schema);if(u)throw new w("UserConfigurationError",u)}let l="",c="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{l=await o(),c=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await t.getAndroidTextExtraction({goal:r.goal,emulatorState:l,returnSchema:r.schema,screenshot:`data:image/png;base64,${c}`},{disableCache:!!r.disableCache,abortSignal:a,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["android-text-extraction"]});if(u.result=d,Ob({tracer:s,span:u,screenshot:c,emulatorState:l,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 w("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 HT=class extends or{async dragNative(e,t,n){let{left:o,top:i,width:a,height:s}=this.getBoundsFromNativeCache(e),{left:l,top:c,width:u,height:d}=this.getBoundsFromNativeCache(t),m=o+a/2,p=i+s/2,f=l+u/2,h=c+d/2,g=n?.hoverDuration??500,y=n?.dragDuration??1e3;await this.driver.executeInNativeContext(this.logger,async S=>{await S.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:m,y:p},{type:"pointerDown",button:0},{type:"pause",duration:g},{type:"pointerMove",duration:y,x:f,y:h},{type:"pointerUp",button:0}]}]),await S.releaseActions();},{operationName:"dragAndDrop"});}async dragWebview(e,t,n){let{controller:o}=e;if(e.controller!==t.controller)throw new w("UserConfigurationError","Cannot drag and drop between different webviews");let i=n?.dragDuration??1e3,a=n?.hoverDuration??1e3,s;n?.dragDuration&&(s=Math.max(1,Math.floor(i/200))),await o.browser.dragAndDrop(e.browserTarget,t.browserTarget,{hoverDurationMs:a,steps:s,dragDurationMs:i});}async executeDragAndDrop({command:e}){let t=re();if(e.fromTarget.type!=="description"||e.toTarget.type!=="description")throw new w("UserConfigurationError","Drag and drop only supports description targets for now");let n=e.fromTarget.description,{result:o,thoughts:i}=await this.wrapTargetingAction({command:e,tracer:t,description:n,cacheKey:"cache",targetName:"fromTarget",action:async c=>c}),a=e.toTarget.description,{result:s,thoughts:l}=await this.wrapTargetingAction({command:e,tracer:t,description:a,cacheKey:"cache",targetName:"toTarget",action:async c=>c});if(o.type!==s.type)throw new w("UserConfigurationError",`Drag and drop targets must be in the same context (both native or both webview). Found: From=${o.type}, To=${s.type}`);return await t.startAsyncSpan("EMULATOR_INTERACTION",async c=>{o.type==="NATIVE"&&s.type==="NATIVE"?await this.dragNative(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}):o.type==="WEBVIEW"&&s.type==="WEBVIEW"&&(c.withinWebview=!0,await this.dragWebview(o,s,{hoverDuration:e.hoverDuration,dragDuration:e.dragDuration}));},{name:"Drag and drop"}),{success:!0,message:`${i}
|
|
5349
5349
|
${l}`}}};var jT=class{async getTextContent(e){return await e.textContent()??""}async getAttribute(e,t){return await e.getAttribute(t,{timeout:3e3})??""}async getTagName(e){return await e.evaluate(t=>t.tagName)}async isEditable(e){return await e.isEditable({timeout:yr*1e3})}async isEnabled(e){return await e.isEnabled({timeout:yr*1e3})}async isFocused(e){return await e.evaluate(t=>t===document.activeElement)}async getStyleProperty(e,t){return await e.evaluate((n,o)=>window.getComputedStyle(n).getPropertyValue(o),t)}},GT=class{async getTextContent(e){return wd(e)}async getAttribute(e,t){return e.getAttribute(t)??""}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,t){throw new Error("Cannot perform computed style checks on native element")}};var mRe=5e3,WT=class extends or{async executeElementCheck(e){let t=Date.now(),n=(e.timeout??yr)*1e3,o=n+1e4,i,a=0,s=500,l=cloneDeep(e.cache);if(e.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Element check step");for(;a-t<n;){if(Date.now()-t>o){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=l,l=cloneDeep(l),await te(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),mRe);else return i}let c=await this.executeElementCheckHelper(e,{cacheIsInvalidAfterResolution:!0});if(!c.success&&l&&e.cache){let u=_f({logger:this.logger,originalTarget:bu(l)?l.target:void 0,newTarget:e.cache.target});u&&Ra(l.target,u)&&(e.cache={target:u,updatedAt:e.cache.updatedAt});}return c}async executeElementCheckHelper(e,t){let n=re();if(e.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Element check step");let o=ad(e.assertion);try{return (await this.wrapTargetingAction({...t??{},command:e,tracer:n,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 o&&(i instanceof w&&i.reason==="NoMatchingElementError"||i instanceof hi)?{success:!0}:{success:!1,message:`Failed to evaluate element content assertion: ${i instanceof Error?i.message:`${i}`}`}}}async executeNativeElementCheck(e,t){let n=re(),{assertion:o}=e,i=t.resolvedNode;return await n.startAsyncSpan("ELEMENT_ASSERTION",async a=>{let s=await this.executeElementAssertion({assertion:o,element:i,elementPropertyAccessors:new GT,span:a});return a.result=s,s},{name:"Native element check"})}async executeWebviewElementCheck(e,t){let n=re(),o=t.browserTarget.locator,i=e.assertion;return await n.startAsyncSpan("ELEMENT_ASSERTION",async a=>{await t.controller.browser.highlight(o);let s=await this.executeElementAssertion({assertion:i,element:o,elementPropertyAccessors:new jT,span:a});return a.result=s,s},{name:"Webview element check"})}async executeElementAssertion({assertion:e,element:t,elementPropertyAccessors:n,span:o}){switch(e.type){case"ELEMENT_CONTENT":{let i=await n.getTextContent(t)??"";return o.attributes.elementTextContent=tr(i,500,!0),gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})?{success:!0}:{success:!1,message:`The content ${wr(e)} '${e.value}': ${i}`}}case"ELEMENT_ATTRIBUTE":{"evaluate"in t&&(o.attributes.elementOuterHtml=tr(await t.evaluate(a=>a.cloneNode(!1).outerHTML),500,!0));let i;try{i=await n.getAttribute(t,e.attr);}catch{i=null;}if(!gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=wr(e);return {success:!1,message:`The attribute ${e.attr} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:!0}}case"ELEMENT_EXISTENCE":{let i=!1;switch(e.condition){case"EDITABLE":i=await n.isEditable(t);break;case"VISIBLE":case"EXISTS":i=!0;break;case"ENABLED":{i=await n.isEnabled(t);break}case"FOCUSED":i=await n.isFocused(t);break;default:throw e.condition,new Error("Unrecognized element condition type")}return i=e.negated?!i:i,i?{success:!0}:{success:!1,message:`The element ${wr(e)}`}}case"ELEMENT_NAME":{let i=await n.getTagName(t);return gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})?{success:!0}:{success:!1,message:`The element tag name ${wr(e)} '${e.value}': ${i}`}}case"ELEMENT_STYLE":{let i=await n.getStyleProperty(t,e.property);if(!gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=wr(e);return {success:!1,message:`The style property ${e.property} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:!0}}default:throw new Error("Unrecognized element assertion type")}}};var pRe=5e3,qT=class extends or{async executeScreenCheck(e){let{timeout:t}=e,n=Date.now(),o=(t??yr)*1e3,i=o+1e4,a=0,s=500;for(;a-n<o;){if(Date.now()-n>i){this.logger.warn("Exceeded max system timeout for screen check, exiting...");break}this.throwIfAborted();let l=await this.executeScreenCheckHelper(e);if(a=Date.now(),!l.success)await te(s,this.abortSignal),s=Math.min(Math.floor(s*1.5),pRe);else return l}return await this.executeScreenCheckHelper(e)}async executeScreenCheckHelper(e){return await re().startAsyncSection("Execute screen check",async(n,o)=>{let[i,a]=await Promise.all([this.executeNativeScreenCheckHelper({span:o,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:t}){let{assertion:n}=t;switch(n.type){case"CONTENT":try{let o=(await this.stateManager.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).graph.document.documentElement?.outerHTML;if(!o)throw new Error("Failed to get screen HTML");let i=o.includes(n.value)===!n.negated;return o.length>1e4&&(o=o.slice(0,1e4)+"...TRUNCATED"),i?{success:!0}:(e.attributes.screenContent=o,{success:!1,message:`The screen ${id({...n,negated:!n.negated})}.`})}catch(o){return {success:!1,message:`Failed to evaluate screen content assertion: ${o instanceof Error?o.message:`${o}`}`}}default:return n.type,{success:!1,message:`Unsupported screen check assertion type: ${n.type}`}}}async executeWebviewScreenCheckHelper(e){let t=await this.stateManager.getActiveWebview();if(!t||!t.browserController)return;let n=t.browserController.browser;return await vM({assertion:e.assertion,logger:this.logger,browser:n,autoExpandIframes:!!n.userBrowserSettings.autoExpandIframes})}};var KT=class extends or{async doUninstallApk(e){return await this.uninstallApkPackage(e.packageName),{success:!0,message:"Uninstalled APK."}}async uninstallApkPackage(e){let t=e.replace(/^package:/,""),n=await this.stateManager.executeRawADBCommand(`shell pm list packages | grep -E "^package:${t}$" || true`);if(!n||n.length===0)throw new w("UserConfigurationError",`Package ${t} not found`);if(n.split(`
|
|
5350
5350
|
`).filter(i=>!!i).length>1)throw new w("UserConfigurationError",`Multiple packages found for ${t}`);try{await this.stateManager.executeRawADBCommand(`uninstall ${t}`);}catch(i){throw new w("UserInfrastructureError",`Failed to uninstall package ${t}: ${i}`)}}};var d3=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()}),m3=z.object({description:z.string(),devtoolsFrontendUrl:z.string(),id:z.string(),title:z.string(),type:z.string(),url:z.string(),webSocketDebuggerUrl:z.string()}),p3=z.object({proc:z.string(),webview:z.string(),webviewName:z.string()}),f3=z.array(p3.extend({info:d3.optional(),pages:z.array(m3).optional()}));z.array(p3.extend({info:d3,pages:z.array(m3)}));var XT=class r{driver;limbarClient;device;logger;webviews=new Map;fixtures;orgId;options;aborter;constructor({driver:e,limbarClient:t,logger:n,device:o,fixtures:i,orgId:a,options:s,aborter:l}){this.driver=e,this.limbarClient=t,this.device=o,this.logger=n,this.fixtures=i,this.orgId=a,this.options=s,this.aborter=l;for(let c of ["SIGINT","SIGTERM"])process.on(c,async()=>{await this.cleanupWebviews();});}static async init({driver:e,logger:t,fixtures:n,limbarClient:o,orgId:i,adbPort:a,options:s,aborter:l,playwrightDevice:c}){let u;if(c)u=c;else {let m=(await _android.devices()).filter(p=>p._initializer?.serial?.endsWith(a.toString())||p._initializer?.serial?.endsWith((a-1).toString()));if(t.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 w("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 w("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 r({driver:e,logger:t,device:u,fixtures:n,orgId:i,options:s,aborter:l,limbarClient:o})}async getContexts(){let e=await this.driver.executeInNativeContext(this.logger,n=>n.getContexts({}),{operationName:"getContexts"}),t=Array.from(this.webviews.values());return {contexts:e,webviews:t.map(n=>({contextId:n.contextId,packageName:n.packageName,active:n.active,hasPlaywright:!!n.browserController,lastSeen:n.lastSeen,socketName:n.socketName}))}}async getRawScreenshotBase64({maxAttempts:e=3,signal:t}={}){let n=re(),o=t??this.aborter.controller?.signal,i={maxAttempts:e,signal:o,operationName:"takeScreenshot"};return await n.startAsyncSpan("EMULATOR_READ_STATE",async()=>{if(this.limbarClient){let a=this.limbarClient,s=await Ed(this.logger,async()=>a.screenshot(),i);if(s.dataUri.startsWith("data:image/png;base64,"))return s.dataUri.slice(22);throw new w("InternalWebAgentError",`Emulator provider returned unexpected screenshot URI: ${s.dataUri}`)}return this.driver.executeInNativeContext(this.logger,a=>a.takeScreenshot(),i)},{name:"Take screenshot",signal:o,timeoutMs:3e4})}async getCurrentScreenshotPngString(){return `data:image/png;base64,${await this.getRawScreenshotBase64({maxAttempts:1})}`}async waitForScreenshotStability({timeoutMs:e,signal:t,reason:n,tolerancePercent:o=1}){let i=Uu({signal:t,timeoutMs:e});await re().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=n;let s,l=!1;for(;!i.aborted;){let c=Date.now();if(s)try{let d=await this.getRawScreenshotBase64({maxAttempts:1,signal:i});if(Ds(s,d)<=o){l=!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()-c);await Li(Math.min(1e4,u),i);}l||(a.attributes.timedOut=!0,this.logger.warn({purpose:n},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({timeoutMs:e,signal:t,reason:n}){await re().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async o=>{o.attributes.reason=n;let i=Uu({signal:t,timeoutMs:e}),a,s=!1;for(;!i.aborted;){let l,c=Date.now();try{l=await this.getPageSource(i);let d=createHash("md5").update(l).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()-c);await Li(Math.min(1e4,u),i);}s||(o.attributes.timedOut=!0,this.logger.warn({purpose:n},"Timed out waiting for page source stability"));});}async getCurrentPackage(){let e=await this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: getCurrentPackage"),{operationName:"getCurrentPackage"});return typeof e=="string"?e:void 0}async getActiveWebviewNodes(){let t=(await this.getDomState({skipFetchingFullWebviewContent:!0,removeWebviewContent:!0})).graph,n=[];for(let[o,i]of t.idToElement.entries())n.some(a=>a.id===o)||rg(i)&&n.push({id:o,originalElement:i,bounds:vc(i)});return n}async getActiveWebviewContent(){let e=await this.getActiveWebview();if(!e||!e.browserController)return;this.throwIfAborted();let t=e.browserController;return (await re().startAsyncSpan("EMULATOR_READ_STATE",()=>t.getBrowserState({abortSignal:this.aborter.controller?.signal,skipWait:!0,skipWaitForPageLoad:!0,logger:this.logger,serializationOpts:{noId:!0}}),{name:"Get webview content",signal:this.aborter.controller?.signal})).serializedTree}async getDomState(e){return await re().startAsyncSection("Get emulator state XML",async()=>{let n;if(!e?.skipFetchingFullWebviewContent&&!this.options.disableMomenticAccessibilityTree)try{n=await this.getActiveWebviewContent();}catch(l){this.logger.error({err:l},"Could not get webview info to get the nested DOM state");}this.throwIfAborted();let i=e?.filterOffscreenElements??!0?await this.getViewportBounds():void 0,a=await this.getPageSource();return {graph:await JX(a,this.logger,{injectedWebviewContent:n,disableMomenticAccessibilityTree:this.options.disableMomenticAccessibilityTree,removeWebviewContent:e?.removeWebviewContent,viewportBounds:i})}},{timeoutMs:3e4})}async getPageSource(e){let t=e??this.aborter.controller?.signal;return await re().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(this.logger,o=>o.getPageSource(),{signal:t,operationName:"getPageSource"}),{name:"Get Android page source",signal:t,timeoutMs:3e4})}async getViewportBounds(){let e=await this.driver.executeInNativeContext(this.logger,t=>t.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:!0}).catch(t=>{this.logger.warn({err:t},"Error refreshing webviews, continuing...");}).finally(()=>{this.refreshPromise=void 0;}),await this.refreshPromise;}}async doRefreshWebview(e,{currentAppOnly:t}){if(this.options.disableMomenticAccessibilityTree)return;this.logger.info({reason:e,currentAppOnly:t},"Refreshing webviews"),this.throwIfAborted();let n=await this.getCurrentPackage();if(t&&n==="com.android.permissioncontroller")return;let o=await this.getDetailedContexts();if(!o){this.logger.warn("No context details, not proceeding with refreshing webviews");return}let i=Date.now(),a=new Set;for(let s of o){if(this.throwIfAborted(),s.webview==="NATIVE_APP")continue;let l=s.info["Android-Package"];if(t&&n&&l!==n&&l!=="com.android.chrome"){this.logger.debug({packageName:l,currentPkgName:n},"Skipping webview outside the active package during manual refresh");continue}a.add(s.webview);let c=!this.webviews.has(s.webview),u=!this.webviews.get(s.webview)?.active;if(c||u){let d={contextId:s.webview,packageName:l,active:!1,lastSeen:i,socketName:s.proc.startsWith("@")?s.proc.substring(1):s.proc};this.logger.info({contextId:d.contextId,packageName:d.packageName,socketName:d.socketName},c?"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=!0;}}for(let[s,l]of this.webviews.entries())t&&n&&l.packageName!==n||!a.has(s)&&l.active&&(this.logger.info(`Disconnecting dead webview ${s}`),this.disconnectPlaywrightFromWebview(l),l.active=!1);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"}),t=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},n=await t();if(n.length===0&&(await re().startAsyncSection("Refresh webviews",async()=>{await this.refreshWebviewsManually("no matching webview during getActiveWebview");}),n=await t()),n.length>1)throw new w("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let o=n[0];if(!o)return;if(this.hasUsableWebviewBrowser(o)||(this.logger.warn({contextId:o.contextId,packageName:o.packageName},"Active webview browser is unhealthy, reconstructing"),await this.reconstructWebviewBrowser(o,"active webview page or target crashed"),this.hasUsableWebviewBrowser(o)))return o;if(await re().startAsyncSection("Refresh webviews after browser reconstruction failed",async()=>{await this.refreshWebviewsManually("active webview browser reconstruction failed");}),n=await t(),n.length>1)throw new w("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let i=n[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 t=await this.driver.executeInNativeContext(this.logger,i=>i.execute("mobile: getCurrentPackage"),{operationName:"reconstructActiveWebviewCurrentPackage"});if(t!==void 0&&typeof t!="string"){this.logger.warn({currentPkg:t},"Unexpected getCurrentPackage result");return}let n=[];for(let i of this.webviews.values())i.packageName===t&&i.active&&n.push(i);if(n.length>1)throw new w("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");let o=n[0];if(o)return await this.reconstructWebviewBrowser(o,e),this.hasUsableWebviewBrowser(o)?o:void 0}hasUsableWebviewBrowser(e){let t=e.browserController;if(!t||!e.active)return !1;let n=t.browser;if(n.closed)return !1;let o;try{o=n.getActivePage();}catch(i){return this.logger.warn({err:i,contextId:e.contextId},"Failed to resolve active page for webview browser health check"),!1}return !o.isClosed()}async reconstructWebviewBrowser(e,t){this.logger.info({contextId:e.contextId,packageName:e.packageName,reason:t},"Reconstructing webview browser"),await this.disconnectPlaywrightFromWebview(e),e.active=!1;let n=await this.connectPlaywrightToAvailableWebview(e);n&&(e.browserController=n,e.active=!0);}getDeviceSerial(){let e=this.driver.capabilities,t=n=>{if(!e||typeof e!="object")return;let o=e[n];return typeof o=="string"?o:void 0};return t("deviceUDID")||t("udid")||t("appium:udid")||t("appium:deviceUDID")}async executeRawADBCommandWithArgs(e){let t=this.getDeviceSerial();this.logger.info({serial:t,args:e},"Executing ADB command");let n=await cr(e,{serial:t,timeoutMs:15e3,throwOnError:!0});return this.logger.info({result:n},"ADB command result"),n}async executeRawADBCommand(e){let t=this.getDeviceSerial(),n=e.trim().split(/\s+/).filter(i=>i.length>0);this.logger.info({serial:t,cmdArgs:n},"Executing ADB command");let o=await cr(n,{serial:t,timeoutMs:15e3,throwOnError:!0});return this.logger.info({result:o},"ADB command result"),o}async cleanupWebviews(){this.refreshInterval&&(clearInterval(this.refreshInterval),this.refreshInterval=void 0);for(let[e,t]of this.webviews.entries())this.logger.info(`Disconnecting webview ${e}`),this.disconnectPlaywrightFromWebview(t),t.active=!1;}async getDetailedContexts(){return await re().startAsyncSpan("EMULATOR_READ_STATE",async()=>{let t=await this.driver.executeInNativeContext(this.logger,o=>o.execute("mobile: getContexts"),{operationName:"getDetailedContexts"});this.aborter.controller?.signal.throwIfAborted();let n;try{n=f3.parse(t);}catch(o){throw new w("InternalWebAgentError",`Failed to parse contexts. Original error:
|
|
5351
5351
|
${o}
|
|
5352
5352
|
Raw: ${JSON.stringify(t)}`)}return n.filter(o=>o.webviewName?!o.info||!o.pages?!1:o.pages.filter(a=>{if(!a.title)return !1;let s=a.url;return !(!s||s===""||s.startsWith("about:blank")||s.startsWith("chrome-error:"))}).length?!0:(this.logger.debug({context:o},"Webview has no qualified pages, skipping"),!1):!0)},{name:"Get available contexts",signal:this.aborter.controller?.signal})}async createBrowserController({context:e,page:t}){return await re().startSection("Run remote Chrome initialization",async(o,i)=>{let a={};i.attributes.timings=a;let s=await Xf.fromExistingContext({context:e,page:t,attachTimeoutMs:8e3,logger:this.logger,timingRecorder:a,userBrowserSettings:{...this.options.browserSettings,disableBrowserMonitoring:!0},properties:{isNewHeadless:!1,allowedA11yIgnoreReasonsOverride:[],isAndroid:!0},storage:this.fixtures.storage,enricher:this.fixtures.browserEnricher});try{return new rE({browser:s,generator:this.fixtures.browserGenerator,logger:this.logger,orgId:this.orgId,storage:this.fixtures.storage,localCodeEvalTools:this.fixtures.localCodeEvalTools,visualDiffScreenshotStorage:new Iy})}catch(l){throw await s.cleanup(),l}})}async connectPlaywrightToWebview(e,t){return re().startAsyncSection("Connect headless browser client to webview",async()=>{for(let o=0;o<2;o++)try{let i=await this.connectPlaywrightToWebviewHelper(e,t);return i?{kind:"connected",browserController:i}:{kind:"failed"}}catch(i){if(i instanceof np)return {kind:"not_found"};if(this.errorLooksLikeUnattachableWebview(i))return this.logger.info({err:i,packageName:e,socketName:t},"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 t=ne(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(n=>t.includes(n))}async connectPlaywrightToAvailableWebview(e){let t=this.webviewConnectionPromises.get(e.contextId);if(t)return this.logger.debug({contextId:e.contextId},"Waiting for existing webview connection attempt"),t;let n=re().startAsyncSection("Connect Playwright to available webview",async()=>await this.connectPlaywrightToAvailableWebviewHelper(e),{signal:this.aborter.controller?.signal}).catch(o=>{this.logger.warn({err:o,contextId:e.contextId},"Failed to connect Playwright to webview, continuing...");});return this.webviewConnectionPromises.set(e.contextId,n),n.finally(()=>{this.webviewConnectionPromises.get(e.contextId)===n&&this.webviewConnectionPromises.delete(e.contextId);}),n}async connectPlaywrightToAvailableWebviewHelper(e){let{contextId:t,packageName:n}=e,o=await this.connectPlaywrightToWebview(n??"",e.socketName);if(o.kind==="connected")return this.logger.info(`Connected Playwright to webview ${t}`),o.browserController;if(n!=="com.android.chrome"||o.kind!=="not_found")return;this.logger.info({webviewInfo:e},`Connecting Playwright to Android Chrome: ${t}`);let i=await this.connectPlaywrightToChrome(e);return i&&this.logger.info(`Connected Playwright to Android Chrome: ${t}`),i}extractSocketNameFromWebview(e,t){if("_socketName"in e&&typeof e._socketName=="string")return e._socketName;if("_data"in e&&e._data?.socketName)return e._data.socketName;t.warn({pkg:e.pkg()},"Could not extract socket name from webview");}async connectPlaywrightToWebviewHelper(e,t){let n=this.device.webViews(),o=n.find(c=>!(c.pkg()!==e&&e!=="com.android.chrome"||this.extractSocketNameFromWebview(c,this.logger)!==t));if(!o)throw this.logger.warn({webviews:n.map(c=>({pkg:c.pkg,name:this.extractSocketNameFromWebview(c,this.logger)}))},"Could not find matching webview in Playwright device list"),new np(e,t);let i=await o.page(),a=i.url();if(a===""||a.startsWith("about:blank")||a.startsWith("chrome-error:")){let c=`Webview ${e} with socket ${t} is not a valid webview`;this.logger.warn({pageUrl:a},c);return}let s=i.context();return await this.createBrowserController({context:s,page:i})}async connectPlaywrightToChrome(e){return await re().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:t,socketName:n}=e,o,i=e.forwardedPort;try{this.logger.info({contextId:t,socketName:n},"Connecting to Chrome webview");let a;if(e.forwardedPort)a=`http://127.0.0.1:${e.forwardedPort}`,this.logger.info({contextId:t,endpoint:a,socketName:n},"Using existing forwarded port");else {let c=await this.forwardDevToolsSocket(e.socketName);e.forwardedPort=c,i=c,a=`http://127.0.0.1:${c}`,this.logger.info({contextId:t,endpoint:a,socketName:n},`Forwarding DevTools socket for ${e.socketName}`);}this.logger.info({endpoint:a,socketName:n},"Connecting to CDP endpoint"),o=await chromium.connectOverCDP({endpointURL:a,timeout:8e3});let s=o.contexts()[0];if(!s){this.logger.warn("No browser context available after CDP connection"),await o.close(),o=void 0;return}let l=await this.createBrowserController({context:s});return i=void 0,o=void 0,l}catch(a){this.logger.warn({err:a},`Error connecting Playwright to webview ${e.contextId}, continuing...`);return}finally{if(o)try{await o.close();}catch(a){this.logger.warn({err:a,contextId:t},"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:t,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(t){this.logger.error({err:t},`Error disconnecting Playwright from webview ${e.contextId}:`);}finally{e.browserController=void 0;}if(e.forwardedPort)try{await this.removeDevToolsForwarding(e.forwardedPort);}catch(t){this.logger.error({err:t},`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 t=1e4+Math.floor(Math.random()*1e4),n=this.getDeviceSerial();this.logger.info({deviceId:n},`Device ID from capabilities: ${n||"not found"}`);let o=e&&e.trim().length>0?`localabstract:${e}`:"localabstract:chrome_devtools_remote";return await this.executeRawADBCommand(`forward tcp:${t} ${o}`),this.logger.info(`Successfully forwarded DevTools socket to port ${t}`),t}async removeDevToolsForwarding(e){await this.executeRawADBCommand(`forward --remove tcp:${e}`),this.logger.info("Successfully removed port forwarding");}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};var ll=class r extends or{appsWithGrantedPermissions=new Set;parseInstalledPackageLines(e){return e?.split(`
|
|
5353
5353
|
`).filter(t=>t.trim().startsWith("package:")).map(t=>t.replace("package:","").trim()).filter(t=>t.length>0&&!t.startsWith("io.appium"))??[]}constructor(e){super(e);}static async init({driver:e,generator:t,logger:n,fixtures:o,orgId:i,options:a,abortController:s,adbPort:l,limbarClient:c,playwrightDevice:u,aiSettings:d}){let m={controller:s},p=await XT.init({driver:e,logger:n,fixtures:o,orgId:i,limbarClient:c,options:a?.emulator??{},aborter:m,adbPort:l,playwrightDevice:u}),f=new r({driver:e,generator:t,stateManager:p,logger:n,fixtures:o,options:a,aborter:m,orgId:i,aiSettings:d,adbPort:l});return await f.initializeSettings(),f}get emulatorSettings(){return this.options?.emulator??{}}async installApp(e){await this.stateManager.executeRawADBCommand(`install ${xr__default.resolve(e)}`);}async getInstalledApps(){let[e,t]=await Promise.all([this.executeRawADBCommand("shell pm list packages -3"),this.executeRawADBCommand("shell pm list packages")]),n=this.parseInstalledPackageLines(e).sort((a,s)=>a.localeCompare(s)),i=this.parseInstalledPackageLines(t).filter(a=>!n.includes(a)&&!FH(a)).sort((a,s)=>a.localeCompare(s));return {installedApps:n,prunedApps:i}}async executeCommand(e){let t=["type","a11yData","thoughts","cache","code"],n;try{n=await Ad({obj:e.command,context:this.fixtures.testContext,bannedKeys:t,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools});}catch(o){throw this.throwIfAborted(),new w("UserConfigurationError",`Failed to substitute template strings in command: ${o.message}`,{errOptions:{cause:o}})}try{return await this.executeCommandHelper(e)}catch(o){throw o.name!=="AbortError"&&this.logger.error({err:o},"Error thrown in action controller"),o}finally{Rd(e.command,n);}}async executeCommandHelper({command:e}){let t=re();switch(e.type){case"TAP":return new im(this.constructPerformerParams()).executeTap({command:e});case"TYPE":return await new zT(this.constructPerformerParams()).doType(e);case"AI_CHECK":{let n=this.shouldUseMemoryForCommand(e),o=15,i=e.timeoutSecs?e.timeoutSecs*1e3:5e3,a=XS(i),s=Date.now(),l=0,c,u=!1,d;for(;l<o&&!u;){this.throwIfAborted(),u||c&&c-s>=i&&(u=!0),l!==0&&await te(a,this.abortSignal),c=Date.now();try{let m="",p="";await t.startAsyncSpan("EMULATOR_READ_STATE",async()=>{m=await this.getEmulatorDomState(),p=await this.getScreenshotBase64();},{name:"Get emulator state"});let f=await t.startAsyncSpan("AI_ASSERTION_CALL",async h=>{let g=await this.generator.evaluateAndroidAssertion({assertion:e.assertion,screenXml:m,screenshot:p,memory:n?e.cache?.memory:void 0},{logger:this.logger,loggerTags:we(this.logger),agentConfigVersion:this.aiSettings.agentConfig?.["android-assertion"],useMemory:n});return h.result={thoughts:g.thoughts,result:g.result},g});if(n&&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 ${l} failed, retrying...`),d=m instanceof Error?m:new Error(`${m}`);}finally{l++;}}return {success:!1,message:d?.message}}case"AI_EXTRACT":return c3({command:e,logger:this.logger,generator:this.generator,aiSettings:this.aiSettings,getEmulatorDomState:()=>this.getEmulatorDomState(),getScreenshotBase64:()=>this.getScreenshotBase64(),abortSignal:this.abortSignal});case"SWIPE":return new am(this.constructPerformerParams()).executeSwipe(e);case"SCREEN_CHECK":return new qT(this.constructPerformerParams()).executeScreenCheck(e);case"ELEMENT_CHECK":return await new WT(this.constructPerformerParams()).executeElementCheck(e);case"DRAG_AND_DROP":return await new HT(this.constructPerformerParams()).executeDragAndDrop({command:e});case"SCROLL_TO":return new $T(this.constructPerformerParams()).executeScrollTo(e);case"JAVASCRIPT":{let n;try{n=await Oo({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(o){throw new w("ActionFailureError",o instanceof w?o.message:`${o}`,{errOptions:{cause:o}})}try{JSON.stringify(n);}catch(o){throw new w("UserConfigurationError",`Return value is not serializable: ${o instanceof Error?o.message:`${o}`}`)}return {success:!0,output:n}}case"REQUEST":{let n;try{n=new URL(e.url).hostname;}catch(c){throw new w("UserConfigurationError",`Invalid URL: ${c instanceof Error?c.message:`${c}`}`)}let o=new CookieJar,i=khe(fetch,o),a=Date.now(),s=await Id({command:e,baseUrl:void 0,logger:this.logger,fetchImplementation:i}),l=gu(o,n);return {output:Bc.parse({...s,cookies:l}),success:!0,message:`Successfully executed request in ${Date.now()-a}ms`}}case"OPEN_NOTIFICATION_DRAWER":return await new sl(this.constructPerformerParams()).doPress({keycode:83}),{success:!0};case"OPEN_APP":{let n=e.activityName,o=["-a","android.intent.action.MAIN","-c","android.intent.category.LAUNCHER"];if(!n){let a=["resolve-activity","--brief",...o,e.packageName],s=await q(this.driver.executeInNativeContext(this.logger,l=>l.execute("mobile: shell",{command:"pm",args:a}),{operationName:"resolveMainActivity"}),{signal:this.abortSignal,milliseconds:1e4});if(typeof s!="string")throw new w("UserConfigurationError",`Could not find main activity name for package ${e.packageName}. Unexpected output: ${s}`);if(s.includes("No activity found"))throw new w("UserConfigurationError",`No activity found for package ${e.packageName}.`);if(n=s.trim().split(`
|
|
5354
|
-
`).pop()?.replace(/^.*\//,""),!n)throw new w("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",...o,"-f","0x10200000"];if(e.intentExtras)try{let a=JSON.parse(e.intentExtras);for(let[s,l]of Object.entries(a))i.push("-e",s,typeof l=="string"?l:JSON.stringify(l));}catch(a){throw new w("UserConfigurationError",`Invalid intent extras does not parse as valid JSON: ${a instanceof Error?a.message:`${a}`}`)}return i.push("-n",`${e.packageName}/${n}`),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:!0}}case"PRESS":{let n=new sl(this.constructPerformerParams());switch(e.key){case"HOME":await n.doPress({keycode:3});break;case"BACK":await n.doPress({keycode:4});break;case"APP_SWITCHER":await n.doPress({keycode:187});break;case"POWER":await n.doPress({keycode:26});break;case"SEARCH":await n.doPress({keycode:84});break;case"VOLUME_UP":await n.doPress({keycode:24});break;case"VOLUME_DOWN":await n.doPress({keycode:25});break;case"VOLUME_MUTE":await n.doPress({keycode:164});break}return {success:!0}}case"PRESS_KEYBOARD":{let n=new sl(this.constructPerformerParams()),o=i=>n.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 o(66);break;case"BACKSPACE":await o(67);break;}return {success:!0}}case"WAIT":return await te(e.timeoutSecs*1e3,this.aborter.controller?.signal),{success:!0};case"INSTALL_APP":return new VT(this.constructPerformerParams()).doInstallApk(e);case"UNINSTALL_APP":return new KT(this.constructPerformerParams()).doUninstallApk(e);case"ADD_FILE":{let n=await Rb(e.file);return await this.driver.executeInNativeContext(this.logger,async o=>{await o.pushFile(e.storageLocation,n),await o.execute("mobile: shell",{command:"am",args:["broadcast","-a","android.intent.action.MEDIA_SCANNER_SCAN_FILE","-d",`file://${e.storageLocation}`]});},{operationName:"addFile",attemptTimeoutMs:12e4}),{success:!0}}case"TOGGLE_SETTINGS":return await this.driver.executeInNativeContext(this.logger,async n=>{switch(e.settingsType){case"AIRPLANE_MODE":await n.toggleAirplaneMode();break;case"DATA":await n.toggleData();break;case"WIFI":await n.toggleWiFi();break;case"LOCATION":await n.toggleLocationServices();break;default:throw e.settingsType,new w("UserConfigurationError",`Unknown settings type: ${e.settingsType}`)}},{operationName:"toggleSettings"}),{success:!0};case"ROTATE_ORIENTATION":return await this.driver.executeInNativeContext(this.logger,async n=>{await n.execute("mobile: shell",{command:"settings",args:["put","system","accelerometer_rotation","0"]}),await n.execute("mobile: shell",{command:"settings",args:["put","system","user_rotation",e.orientation==="LANDSCAPE"?"1":"0"]});},{operationName:"rotateOrientation"}),{success:!0,output:{newViewportBounds:await this.getViewportBounds()}};case"ADB_COMMAND":{let n;try{n=JSON.parse(e.jsonArgs??"[]");}catch(a){throw new w("UserConfigurationError",`Invalid JSON for ADB command arguments: ${a instanceof Error?a.message:`${a}`}`)}let o=v__default.string().array().safeParse(n);if(!o.success)throw new w("UserConfigurationError",`Invalid ADB command arguments: ${o.error.message}`);let i=await this.executeRawADBCommandWithArgs([e.command,...o.data]);return this.logger.info({output:i},"ADB command executed successfully"),{success:!0,output:i,message:"ADB command executed successfully"}}case"APPIUM_EXECUTE":{let n=JSON.parse(e.jsonArgs??"{}"),o=await this.driver.executeInNativeContext(this.logger,async i=>i.execute(e.command,n),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:o},"Appium command executed successfully"),{success:!0,output:o,message:"Appium command executed successfully"}}case"KILL_APP":{let n=await this.stateManager.getCurrentPackage();if(!n)throw new w("UserConfigurationError","No package is currently active");await this.driver.executeInNativeContext(this.logger,async o=>{await o.execute("mobile: shell",{command:"input",args:["keyevent","KEYCODE_HOME"]}),await o.terminateApp(n);},{operationName:"killApp"});try{await DH({packageName:n,driver:this.driver,abortSignal:this.abortSignal,logger:this.logger});}catch(o){this.throwIfAborted(),this.logger.warn({err:o,packageName:n},"Failed to remove package from recents, continuing...");}return {success:!0}}case"STATE":{await this.stateManager.refreshWebviewsManually("debug cmd");let n=await this.stateManager.getDomState(),o=await this.stateManager.getContexts(),i={xml:n.graph.xml,contexts:o};return this.logger.info({result:i},"State debug command output"),{output:i,success:!0}}default:{return {success:!0}}}}async initializeSettings(){let{latitude:e,longitude:t}=this.options?.emulator?.geolocation??Jc;await this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: setGeolocation",{latitude:e,longitude:t}),{operationName:"setGeolocation"}),await Promise.all([this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_COARSE_LOCATION"]}),{operationName:"grantCoarseLocationPermission"}),this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_FINE_LOCATION"]}),{operationName:"grantFineLocationPermission"}),this.driver.executeInNativeContext(this.logger,n=>n.updateSettings({keyInjectionDelay:wc}),{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 UH(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:!0,abortSignal:this.abortSignal,loggerTags:we(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 wRe=new BS(30,60*1e3),bI="https://api.momentic.ai",yI,g3,um=r=>{bI=r;},og=()=>bI;var QT=r=>{g3=r;},dm=()=>g3,Bt=()=>yI;var cm,SI,y3,S3,JT,mm=async r=>{if(yI&&cm&&JT)return cm;let e=new Er({baseUrl:bI,apiKey:r,logger:N});yI=e;try{let t=await e.getAuthInfo();return cm=t.orgId,SI=t.userId,y3=t.email,S3=t.pylonEmailHash,JT=r,cm}catch(t){throw new Error(`Error checking API key against server: ${t}`,{cause:t})}},Hr=()=>{if(!cm)throw new Error("Your organization ID is invalid.");return cm},Ac=()=>{if(!SI)throw new Error("Your user ID is invalid.");return SI},b3=()=>y3,E3=()=>S3,T3=()=>{if(!JT)throw new Error("Your API key is invalid.");return JT},EI,ZT,cl=()=>{ZT?.abort(),ZT=void 0;},ev=(r,e)=>{EI=r,cl(),ZT=new AbortController;let t=ZT.signal,n=[r.configFilePath];r.config.environments?.forEach(o=>{if(!o.envFile)return;let i=xr__default.resolve(r.rootDir,o.envFile);try{if(Tr.lstatSync(i).isSymbolicLink())return;Tr.existsSync(i)&&n.push(i);}catch(a){N.warn({err:a},`Failed to check if env file ${i} exists`);}});try{ARe({filesToWatch:n,revalidator:e,signal:t,project:r});}catch(o){N.error({err:o},"Failed to start config file watchers");}},ot=()=>EI;function ARe({filesToWatch:r,revalidator:e,signal:t,project:n}){N.debug("Starting watch on the following files:"),r.forEach(o=>{N.debug(`- ${o}`);}),r.forEach(o=>{let i=async(s,l)=>{s.mtime.getTime()!==l.mtime.getTime()&&(wRe.increment("setLocalProject")&&N.warn(`A file change under the ${n.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.`),EI=await Promise.resolve(e(n.configFilePath)));};Tr.watchFile(o,{persistent:!1},i);let a=()=>{Tr.unwatchFile(o,i),t.removeEventListener("abort",a);};t.addEventListener("abort",a);});}function Ue(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t);}}var xRe="0.88.1",Rc=Fu({app:"desktop-server",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:xRe});(async()=>{try{let r=await Lf(Rc);r.gitBranchName&&Rc.addBinding("branch",r.gitBranchName);}catch{}})();var v3=Router();v3.get("/",async(r,e)=>{let t=ot(),n=Bt();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Lr(Rc,n,t),i=o?.gitProtectedBranches&&o?.gitBranchName&&o.gitProtectedBranches.includes(o.gitBranchName),{noCache:a,alwaysSaveCache:s}=dm(),l=!a&&(s||!i);e.status(200).json({saveCaches:l,checkedOutBranch:o?.gitBranchName});});var TI=v3;var PRe=5e3;function vI(r={}){let e=Router();function t(i){let a=ot(),s=xr__default.dirname(a.configFilePath);return xr__default.join(s,...i)}function n(i){let a=ot(),s=xr__default.dirname(a.configFilePath),l=xr__default.relative(s,i);return l?l.split(xr__default.sep):[]}function o(i,a){let s=Tr.statSync(i),l=n(i);return Gw.parse({name:a,absolutePath:i,relativePath:l.join(xr__default.sep),pathSegments:l,isDirectory:s.isDirectory(),size:s.size,createdAt:s.birthtime,modifiedAt:s.mtime,accessedAt:s.atime})}return e.post("/",Ue(async(i,a,s)=>{let l;try{l=M0.parse(i.body).pathSegments;}catch(y){a.status(400).json({error:`Failed to parse folder read body: ${y}`});return}let c=t(l);if(!Tr.existsSync(c)){a.status(404).json({error:`Path not found: ${l.join(xr__default.sep)}`});return}if(!Tr.statSync(c).isDirectory()){a.status(400).json({error:`Path is not a directory: ${l.join(xr__default.sep)}`});return}let m=ot().config.exclude??[],p=AbortSignal.timeout(PRe),f;try{f=await ud(["*"],{cwd:c,ignore:m,maxDepth:1,nodir:!1,signal:p});}catch(y){if(y instanceof Error&&y.name==="TimeoutError"){a.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw y}let h=f.map(y=>{let S=xr__default.join(c,y);return o(S,y)});if(r.allowedFileTypes){let y=new Set(r.allowedFileTypes);h=(await Promise.all(h.map(async S=>{if(S.isDirectory||!(S.name.endsWith(".test.yaml")||S.name.endsWith(".module.yaml")))return S;let C=await IRe(S.absolutePath);return C!==void 0&&y.has(C)?S:null}))).filter(S=>S!==null);}let g={absolutePath:c,pathSegments:l,contents:h};a.status(200).json(g);})),e.put("/",Ue(async(i,a,s)=>{let l;try{l=_0.parse(i.body).pathSegments;}catch(d){a.status(400).json({error:`Failed to parse folder create body: ${d}`});return}let c=t(l);if(Tr.existsSync(c)){a.status(200).json({success:!0,message:`Folder already exists: ${l.join(xr__default.sep)}`,pathSegments:l});return}Tr.mkdirSync(c,{recursive:!0});let u={success:!0,message:`Folder created: ${l.join(xr__default.sep)}`,pathSegments:l};a.status(201).json(u);})),e.patch("/",Ue(async(i,a,s)=>{let l,c;try{let f=P0.parse(i.body);l=f.pathSegments,c=f.newPathSegments;}catch(f){a.status(400).json({error:`Failed to parse folder update body: ${f}`});return}let u=t(l),d=t(c);if(!Tr.existsSync(u)){a.status(400).json({error:`Folder not found: ${l.join(xr__default.sep)}`});return}if(Tr.existsSync(d)){a.status(400).json({error:`Destination already exists: ${c.join(xr__default.sep)}`});return}let m=xr__default.dirname(d);Tr.existsSync(m)||Tr.mkdirSync(m,{recursive:!0}),Tr.renameSync(u,d);let p={success:!0,message:`Folder moved from ${l.join(xr__default.sep)} to ${c.join(xr__default.sep)}`,pathSegments:c};a.status(200).json(p);})),e.delete("/",Ue(async(i,a,s)=>{let l,c=!0;try{let p=I0.parse(i.body);l=p.pathSegments,c=p.recursive??!0;}catch(p){a.status(400).json({error:`Failed to parse folder delete body: ${p}`});return}let u=t(l);if(!Tr.existsSync(u)){a.status(200).json({success:!0,message:`Folder not found: ${l.join(xr__default.sep)}`,pathSegments:l});return}if(!Tr.statSync(u).isDirectory()){a.status(400).json({error:`Path is not a directory: ${l.join(xr__default.sep)}`});return}if(c)Tr.rmSync(u,{recursive:!0,force:!0});else {if(Tr.readdirSync(u).length>0){a.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${l.join("/")}`});return}Tr.rmdirSync(u);}let m={success:!0,message:`Folder deleted: ${l.join("/")}`,pathSegments:l};a.status(200).json(m);})),e}async function IRe(r){try{let e=await Tr.promises.open(r,"r");try{let t=Buffer.alloc(4096),{bytesRead:n}=await e.read(t,0,t.length,0);return t.toString("utf-8",0,n).match(/^fileType:\s*(.+)$/m)?.[1]?.trim()}finally{await e.close();}}catch{}}var C3=Router();C3.get("/",async(r,e)=>{let t=ot(),n=Bt();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Lr(Rc,n,t);e.status(200).json(o);});var CI=C3;var tv=class r extends ks{static async init(e){let t=await ks.connectAppium(e);return new r(t)}async executeWebViewScript(e,t,n,...o){let i=await this.executeInContext(e,t,async a=>{let s=new Function("...args",`${Gf.safariUtilsLibJs};
|
|
5354
|
+
`).pop()?.replace(/^.*\//,""),!n)throw new w("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",...o,"-f","0x10200000"];if(e.intentExtras)try{let a=JSON.parse(e.intentExtras);for(let[s,l]of Object.entries(a))i.push("-e",s,typeof l=="string"?l:JSON.stringify(l));}catch(a){throw new w("UserConfigurationError",`Invalid intent extras does not parse as valid JSON: ${a instanceof Error?a.message:`${a}`}`)}return i.push("-n",`${e.packageName}/${n}`),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:!0}}case"PRESS":{let n=new sl(this.constructPerformerParams());switch(e.key){case"HOME":await n.doPress({keycode:3});break;case"BACK":await n.doPress({keycode:4});break;case"APP_SWITCHER":await n.doPress({keycode:187});break;case"POWER":await n.doPress({keycode:26});break;case"SEARCH":await n.doPress({keycode:84});break;case"VOLUME_UP":await n.doPress({keycode:24});break;case"VOLUME_DOWN":await n.doPress({keycode:25});break;case"VOLUME_MUTE":await n.doPress({keycode:164});break}return {success:!0}}case"PRESS_KEYBOARD":{let n=new sl(this.constructPerformerParams()),o=i=>n.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 o(66);break;case"BACKSPACE":await o(67);break;}return {success:!0}}case"WAIT":return await te(e.timeoutSecs*1e3,this.aborter.controller?.signal),{success:!0};case"INSTALL_APP":return new VT(this.constructPerformerParams()).doInstallApk(e);case"UNINSTALL_APP":return new KT(this.constructPerformerParams()).doUninstallApk(e);case"ADD_FILE":{let n=await Rb(e.file);return await this.driver.executeInNativeContext(this.logger,async o=>{await o.pushFile(e.storageLocation,n),await o.execute("mobile: shell",{command:"am",args:["broadcast","-a","android.intent.action.MEDIA_SCANNER_SCAN_FILE","-d",`file://${e.storageLocation}`]});},{operationName:"addFile",attemptTimeoutMs:12e4}),{success:!0}}case"TOGGLE_SETTINGS":return await this.driver.executeInNativeContext(this.logger,async n=>{switch(e.settingsType){case"AIRPLANE_MODE":await n.toggleAirplaneMode();break;case"DATA":await n.toggleData();break;case"WIFI":await n.toggleWiFi();break;case"LOCATION":await n.toggleLocationServices();break;default:throw e.settingsType,new w("UserConfigurationError",`Unknown settings type: ${e.settingsType}`)}},{operationName:"toggleSettings"}),{success:!0};case"ROTATE_ORIENTATION":return await this.driver.executeInNativeContext(this.logger,async n=>{await n.execute("mobile: shell",{command:"settings",args:["put","system","accelerometer_rotation","0"]}),await n.execute("mobile: shell",{command:"settings",args:["put","system","user_rotation",e.orientation==="LANDSCAPE"?"1":"0"]});},{operationName:"rotateOrientation"}),{success:!0,output:{newViewportBounds:await this.getViewportBounds()}};case"ADB_COMMAND":{let n;try{n=JSON.parse(e.jsonArgs??"[]");}catch(a){throw new w("UserConfigurationError",`Invalid JSON for ADB command arguments: ${a instanceof Error?a.message:`${a}`}`)}let o=v__default.string().array().safeParse(n);if(!o.success)throw new w("UserConfigurationError",`Invalid ADB command arguments: ${o.error.message}`);let i=await this.executeRawADBCommandWithArgs([e.command,...o.data]);return this.logger.info({output:i},"ADB command executed successfully"),{success:!0,output:i,message:"ADB command executed successfully"}}case"APPIUM_EXECUTE":{let n=JSON.parse(e.jsonArgs??"{}"),o=await this.driver.executeInNativeContext(this.logger,async i=>i.execute(e.command,n),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:o},"Appium command executed successfully"),{success:!0,output:o,message:"Appium command executed successfully"}}case"KILL_APP":{let n=await this.stateManager.getCurrentPackage();if(!n)throw new w("UserConfigurationError","No package is currently active");await this.driver.executeInNativeContext(this.logger,async o=>{await o.execute("mobile: shell",{command:"input",args:["keyevent","KEYCODE_HOME"]}),await o.terminateApp(n);},{operationName:"killApp"});try{await DH({packageName:n,driver:this.driver,abortSignal:this.abortSignal,logger:this.logger});}catch(o){this.throwIfAborted(),this.logger.warn({err:o,packageName:n},"Failed to remove package from recents, continuing...");}return {success:!0}}case"STATE":{await this.stateManager.refreshWebviewsManually("debug cmd");let n=await this.stateManager.getDomState(),o=await this.stateManager.getContexts(),i={xml:n.graph.xml,contexts:o};return this.logger.info({result:i},"State debug command output"),{output:i,success:!0}}default:{return {success:!0}}}}async initializeSettings(){let{latitude:e,longitude:t}=this.options?.emulator?.geolocation??Jc;await this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: setGeolocation",{latitude:e,longitude:t}),{operationName:"setGeolocation"}),await Promise.all([this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_COARSE_LOCATION"]}),{operationName:"grantCoarseLocationPermission"}),this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: shell",{command:"pm",args:["grant","io.appium.settings","android.permission.ACCESS_FINE_LOCATION"]}),{operationName:"grantFineLocationPermission"}),this.driver.executeInNativeContext(this.logger,n=>n.updateSettings({keyInjectionDelay:wc}),{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 UH(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:!0,abortSignal:this.abortSignal,loggerTags:we(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 wRe=new BS(30,60*1e3),bI="https://api.momentic.ai",yI,g3,um=r=>{bI=r;},og=()=>bI;var QT=r=>{g3=r;},dm=()=>g3,Bt=()=>yI;var cm,SI,y3,S3,JT,mm=async r=>{if(yI&&cm&&JT)return cm;let e=new Er({baseUrl:bI,apiKey:r,logger:N});yI=e;try{let t=await e.getAuthInfo();return cm=t.orgId,SI=t.userId,y3=t.email,S3=t.pylonEmailHash,JT=r,cm}catch(t){throw new Error(`Error checking API key against server: ${t}`,{cause:t})}},Hr=()=>{if(!cm)throw new Error("Your organization ID is invalid.");return cm},Ac=()=>{if(!SI)throw new Error("Your user ID is invalid.");return SI},b3=()=>y3,E3=()=>S3,T3=()=>{if(!JT)throw new Error("Your API key is invalid.");return JT},EI,ZT,cl=()=>{ZT?.abort(),ZT=void 0;},ev=(r,e)=>{EI=r,cl(),ZT=new AbortController;let t=ZT.signal,n=[r.configFilePath];r.config.environments?.forEach(o=>{if(!o.envFile)return;let i=xr__default.resolve(r.rootDir,o.envFile);try{if(Tr.lstatSync(i).isSymbolicLink())return;Tr.existsSync(i)&&n.push(i);}catch(a){N.warn({err:a},`Failed to check if env file ${i} exists`);}});try{ARe({filesToWatch:n,revalidator:e,signal:t,project:r});}catch(o){N.error({err:o},"Failed to start config file watchers");}},ot=()=>EI;function ARe({filesToWatch:r,revalidator:e,signal:t,project:n}){N.debug("Starting watch on the following files:"),r.forEach(o=>{N.debug(`- ${o}`);}),r.forEach(o=>{let i=async(s,l)=>{s.mtime.getTime()!==l.mtime.getTime()&&(wRe.increment("setLocalProject")&&N.warn(`A file change under the ${n.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.`),EI=await Promise.resolve(e(n.configFilePath)));};Tr.watchFile(o,{persistent:!1},i);let a=()=>{Tr.unwatchFile(o,i),t.removeEventListener("abort",a);};t.addEventListener("abort",a);});}function Ue(r){return function(...e){let t=e[e.length-1],n=r(...e);Promise.resolve(n).catch(t);}}var xRe="0.88.2",Rc=Fu({app:"desktop-server",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:xRe});(async()=>{try{let r=await Lf(Rc);r.gitBranchName&&Rc.addBinding("branch",r.gitBranchName);}catch{}})();var v3=Router();v3.get("/",async(r,e)=>{let t=ot(),n=Bt();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Lr(Rc,n,t),i=o?.gitProtectedBranches&&o?.gitBranchName&&o.gitProtectedBranches.includes(o.gitBranchName),{noCache:a,alwaysSaveCache:s}=dm(),l=!a&&(s||!i);e.status(200).json({saveCaches:l,checkedOutBranch:o?.gitBranchName});});var TI=v3;var PRe=5e3;function vI(r={}){let e=Router();function t(i){let a=ot(),s=xr__default.dirname(a.configFilePath);return xr__default.join(s,...i)}function n(i){let a=ot(),s=xr__default.dirname(a.configFilePath),l=xr__default.relative(s,i);return l?l.split(xr__default.sep):[]}function o(i,a){let s=Tr.statSync(i),l=n(i);return Gw.parse({name:a,absolutePath:i,relativePath:l.join(xr__default.sep),pathSegments:l,isDirectory:s.isDirectory(),size:s.size,createdAt:s.birthtime,modifiedAt:s.mtime,accessedAt:s.atime})}return e.post("/",Ue(async(i,a,s)=>{let l;try{l=M0.parse(i.body).pathSegments;}catch(y){a.status(400).json({error:`Failed to parse folder read body: ${y}`});return}let c=t(l);if(!Tr.existsSync(c)){a.status(404).json({error:`Path not found: ${l.join(xr__default.sep)}`});return}if(!Tr.statSync(c).isDirectory()){a.status(400).json({error:`Path is not a directory: ${l.join(xr__default.sep)}`});return}let m=ot().config.exclude??[],p=AbortSignal.timeout(PRe),f;try{f=await ud(["*"],{cwd:c,ignore:m,maxDepth:1,nodir:!1,signal:p});}catch(y){if(y instanceof Error&&y.name==="TimeoutError"){a.status(408).json({error:"Folder listing timed out. This directory may contain too many files."});return}throw y}let h=f.map(y=>{let S=xr__default.join(c,y);return o(S,y)});if(r.allowedFileTypes){let y=new Set(r.allowedFileTypes);h=(await Promise.all(h.map(async S=>{if(S.isDirectory||!(S.name.endsWith(".test.yaml")||S.name.endsWith(".module.yaml")))return S;let C=await IRe(S.absolutePath);return C!==void 0&&y.has(C)?S:null}))).filter(S=>S!==null);}let g={absolutePath:c,pathSegments:l,contents:h};a.status(200).json(g);})),e.put("/",Ue(async(i,a,s)=>{let l;try{l=_0.parse(i.body).pathSegments;}catch(d){a.status(400).json({error:`Failed to parse folder create body: ${d}`});return}let c=t(l);if(Tr.existsSync(c)){a.status(200).json({success:!0,message:`Folder already exists: ${l.join(xr__default.sep)}`,pathSegments:l});return}Tr.mkdirSync(c,{recursive:!0});let u={success:!0,message:`Folder created: ${l.join(xr__default.sep)}`,pathSegments:l};a.status(201).json(u);})),e.patch("/",Ue(async(i,a,s)=>{let l,c;try{let f=P0.parse(i.body);l=f.pathSegments,c=f.newPathSegments;}catch(f){a.status(400).json({error:`Failed to parse folder update body: ${f}`});return}let u=t(l),d=t(c);if(!Tr.existsSync(u)){a.status(400).json({error:`Folder not found: ${l.join(xr__default.sep)}`});return}if(Tr.existsSync(d)){a.status(400).json({error:`Destination already exists: ${c.join(xr__default.sep)}`});return}let m=xr__default.dirname(d);Tr.existsSync(m)||Tr.mkdirSync(m,{recursive:!0}),Tr.renameSync(u,d);let p={success:!0,message:`Folder moved from ${l.join(xr__default.sep)} to ${c.join(xr__default.sep)}`,pathSegments:c};a.status(200).json(p);})),e.delete("/",Ue(async(i,a,s)=>{let l,c=!0;try{let p=I0.parse(i.body);l=p.pathSegments,c=p.recursive??!0;}catch(p){a.status(400).json({error:`Failed to parse folder delete body: ${p}`});return}let u=t(l);if(!Tr.existsSync(u)){a.status(200).json({success:!0,message:`Folder not found: ${l.join(xr__default.sep)}`,pathSegments:l});return}if(!Tr.statSync(u).isDirectory()){a.status(400).json({error:`Path is not a directory: ${l.join(xr__default.sep)}`});return}if(c)Tr.rmSync(u,{recursive:!0,force:!0});else {if(Tr.readdirSync(u).length>0){a.status(409).json({error:`Cannot delete non-empty directory without recursive flag: ${l.join("/")}`});return}Tr.rmdirSync(u);}let m={success:!0,message:`Folder deleted: ${l.join("/")}`,pathSegments:l};a.status(200).json(m);})),e}async function IRe(r){try{let e=await Tr.promises.open(r,"r");try{let t=Buffer.alloc(4096),{bytesRead:n}=await e.read(t,0,t.length,0);return t.toString("utf-8",0,n).match(/^fileType:\s*(.+)$/m)?.[1]?.trim()}finally{await e.close();}}catch{}}var C3=Router();C3.get("/",async(r,e)=>{let t=ot(),n=Bt();if(!n){e.status(500).json({message:"API client not initialized"});return}let o=await Lr(Rc,n,t);e.status(200).json(o);});var CI=C3;var tv=class r extends ks{static async init(e){let t=await ks.connectAppium(e);return new r(t)}async executeWebViewScript(e,t,n,...o){let i=await this.executeInContext(e,t,async a=>{let s=new Function("...args",`${Gf.safariUtilsLibJs};
|
|
5355
5355
|
const userFn = ${n.toString()};
|
|
5356
5356
|
try {
|
|
5357
5357
|
return userFn(momenticFunctions, ...args);
|
|
5358
5358
|
} catch (e) {
|
|
5359
5359
|
return { _failed: true, _error: e.message }
|
|
5360
|
-
}`);return a.execute(s,...o)},{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 w3({logger:r,driverLogLevel:e="error",emulator:t,callbacks:n}){let{onStatusUpdate:o}=n,i=r.child({emulatorName:t.name}),a={platformName:"iOS","appium:noReset":!0,"appium:fullReset":!1,"appium:newCommandTimeout":3600,"appium:autoWebview":!1,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":!0,"appium:fullContextList":!1,"appium:additionalWebviewBundleIds":["*"],"appium:waitForIdleTimeout":0,"appium:reduceMotion":!0,"appium:settings":{customSnapshotTimeout:0,animationCoolOffTimeout:0},...t.extraCapabilities};o("Starting Appium session...");let s={capabilities:a},l=await tv.init({logger:i,logLevel:e,callbacks:{...n,restartWda:t.restartWda?async c=>{await t.restartWda?.(c);}:void 0,onFailure:async({err:c,attempt:u})=>{let d=Mb(c),m=u<3&&d;return m&&i.warn({err:c},"Appium driver manifest race detected on first attempt, restarting Appium and retrying"),{shouldRetry:m}}},wdioOpts:s});return i.info({capabilities:a,emulatorName:t.name},"Started Appium driver"),l}async function A3({wdaUrl:r,token:e}){try{let t=new AbortController;return setTimeout(()=>t.abort(),3e3),await fetch(r+"/status",{headers:{Authorization:`Bearer ${e}`},signal:t.signal}),!0}catch{return !1}}var rv={"appium:waitForIdleTimeout":2,"appium:commandTimeouts":"30000","appium:skipLogCapture":!0,"appium:disableAutomaticScreenshots":!0,"appium:simpleIsVisibleCheck":!0};var FRe=["[com.apple.","loadConfigurationForEnvironment"],URe=["com.apple.Accessibility","com.apple.news","com.apple.locationd","NewsToday","NewsTodayIntents","apsd","APSConfiguration","APSOutgoingQueue","APSCourierConnection","APSNetworkMonitor","loadConfigurationForEnvironment"],BRe=[" Df "," Db "],zRe="https://storage.googleapis.com/mobile-drivers/WebDriverAgentRunner-Build-Sim-arm64-v10.4.5.zip";function $Re(r){let e=FRe.some(n=>r.includes(n)),t=URe.some(n=>r.includes(n));return BRe.some(n=>r.includes(n))?e||t:r.includes(" I ")?t:!1}async function x3({wdaUrl:r,token:e,limbarClient:t,logger:n,onStatusUpdate:o}){await A3({wdaUrl:r,token:e})||(o("Starting WebDriverAgent..."),n.debug("WDA is not running on the iOS emulator"),await t.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),n.debug("WDA launched"));}var ig=class r{apiClient;name;extraCapabilities;limbarToken;limbarWebRtcUrl;limbarApiUrl;limbarWdaUrl;limbarRegion;limbarClient;onStatusUpdate;logStream=void 0;constructor({apiClient:e,limbarToken:t,limbarWebRtcUrl:n,limbarApiUrl:o,limbarWdaUrl:i,limbarRegion:a,emulatorName:s,limbarClient:l,onStatusUpdate:c}){this.apiClient=e,this.name=s,this.limbarToken=t,this.limbarWebRtcUrl=n,this.limbarApiUrl=o,this.limbarWdaUrl=i,this.limbarRegion=a,this.limbarClient=l,this.extraCapabilities={...rv,"appium:automationName":"@limrun/xcuitest","appium:webDriverAgentUrl":this.limbarWdaUrl,"appium:wdaLocalPort":443,"appium:useNewWDA":!1,"appium:usePreinstalledWDA":!0,"appium:limInstanceApiUrl":o,"appium:limInstanceToken":t,"appium:wdaRequestHeaders":{Authorization:`Bearer ${t}`}},this.onStatusUpdate=c;}static async init(e){let{apiClient:t,logger:n,creationOpts:o,logLevel:i,orgId:a,sessionId:s,onStatusUpdate:l,onConnectionStateChange:c}=e,u=o.appToInstall?.channel,d=o.appToInstall?.tag;l("Creating iOS emulator");let{token:m,webRtcUrl:p,wdaUrl:f,apiUrl:h,id:g,region:y,appDownloadUrl:S,appMd5:b}=await t.createIosEmulator({...o,hostname:hostname(),sessionId:s,installAppOnClient:!0});n.info({emulatorName:g,region:y,sessionId:s},"ios instance creation ok"),l("Connecting to iOS emulator...");let C;try{C=await Et.recordDuration({fn:async()=>await createInstanceClient$1({apiUrl:h,token:m,logLevel:i}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${a}`]}),c&&C.onConnectionStateChange(c),l("Installing WebDriverAgent...");let A=C;return await Et.recordDuration({fn:async()=>{await _3({limbarClient:A,url:zRe,md5:void 0,logger:n,emulatorName:g,assetLabel:"WebDriverAgent"});},name:"test_event_duration",tags:["name:limbar-wda-install","clientOs:ios",`orgId:${a}`]}),await x3({wdaUrl:f,token:m,limbarClient:A,logger:n,onStatusUpdate:l}),S&&(l(`Installing iOS app${u?` with channel ${u}`:""}${d?` and tag ${d}`:""}`),await Et.recordDuration({fn:async()=>{await _3({limbarClient:A,url:S,md5:b,logger:n,emulatorName:g,assetLabel:"iOS app"});},name:"test_event_duration",tags:["name:limbar-app-install","clientOs:ios",`orgId:${a}`]})),(async()=>{try{let[O,M]=await Promise.allSettled([td("limserver-1.limrun.net"),td("125.253.92.199")]);n.info({limserver:O.status==="fulfilled"?O.value:O.reason,ip125:M.status==="fulfilled"?M.value:M.reason},"Limbar network diagnostics");}catch(O){n.warn({err:O},"Failed to run network diagnostics");}})(),new r({apiClient:t,limbarToken:m,limbarWebRtcUrl:p,limbarApiUrl:h,limbarWdaUrl:f,limbarRegion:y,emulatorName:g,limbarClient:A,onStatusUpdate:l})}catch(A){throw n.warn({err:A,emulatorName:g},"iOS emulator init failed after creation; cleaning up remote instance"),await VRe({apiClient:t,limbarClient:C,id:g,logger:n}),A}}tap(e,t){return this.limbarClient.tap(e,t)}nativeA11yTreeJson(){return this.limbarClient.elementTree()}async screenshotPngBase64(){let e=await this.limbarClient.screenshot(),t=Buffer.from(e.base64,"base64"),n=TM.decode(t),o=new PNG({width:n.width,height:n.height});return o.data=Buffer.from(n.data),PNG.sync.write(o).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$1.Q5});}async stopScreenRecording(e){await this.limbarClient.stopRecording({localPath:e});}addSyslogListener(e){this.logStream||(this.logStream=this.limbarClient.streamSyslog());let t=n=>{$Re(n)||e(n);};return this.logStream.on("line",t),()=>{this.logStream?.off("line",t);}}async restartWda(e){await x3({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 VRe(r){let{apiClient:e,limbarClient:t,id:n,logger:o}=r;if(t)try{t.disconnect();}catch(i){o.warn({err:i,emulatorName:n},"Failed to disconnect limbar client during init cleanup");}try{await e.deleteIosEmulator(n);}catch(i){o.warn({err:i,emulatorName:n},"Failed to delete iOS emulator during init cleanup");}}var M3=12e4,nv=6,HRe=1e3;async function _3(r){let{limbarClient:e,url:t,md5:n,logger:o,emulatorName:i,assetLabel:a}=r,s;for(let l=1;l<=nv;l++)try{await q(e.installApp(t,{md5:n}),{milliseconds:M3,message:`Timed out after ${M3}ms installing ${a} on emulator ${i}`});return}catch(c){if(s=c,l===nv)break;let u=HRe*2**(l-1);o.warn({url:t,err:c,emulatorName:i,assetLabel:a,attempt:l,maxAttempts:nv,backoffMs:u},`Failed to install ${a} on Limbar emulator; retrying after backoff`),await te(u);}throw o.error({url:t,err:s,emulatorName:i,assetLabel:a,maxAttempts:nv},`Failed to install ${a} on Limbar emulator (no more retries)`),new w("UserConfigurationError",`Failed to install ${a} on emulator ${i}: ${s}`)}var jRe=v__default.array(v__default.object({bundle_id:v__default.string(),name:v__default.string()})),iv=class{constructor(e){this.udid=e;}async exec(e,t=[]){return new Promise((n,o)=>{execFile$1("idb",[...e,"--udid",this.udid,...t],(i,a)=>{i?o(i):n(a.trim());});})}async execBuffer(e,t=[]){return new Promise((n,o)=>{execFile$1("idb",[...e,"--udid",this.udid,...t],{encoding:"buffer",maxBuffer:10*1024*1024},(i,a)=>{i?o(i):n(a);});})}async describeDevice(){return this.exec(["describe"])}async tap({x:e,y:t}){await this.exec(["ui","tap"],[Math.round(e).toString(),Math.round(t).toString()]);}async elementTree(){return this.exec(["ui","describe-all"])}async listApps(){let e=await this.exec(["list-apps","--json"]),t=JSON.parse(e);return jRe.parse(t).map(n=>({bundleId:n.bundle_id,name:n.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"],["-"]),t=Buffer.from([137,80,78,71,13,10,26,10]);if(e.length<t.length||!e.subarray(0,t.length).equals(t))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 ag(r){try{return (await new Simctl().getDeviceTypes()).filter(n=>n.includes("iPhone"))}catch(e){return r.warn({err:e},"Got error listing local iPhone device types, returning empty list"),[]}}var av=class r{name;extraCapabilities;simctl;idb;constructor({name:e,simctl:t,idb:n}){this.name=e,this.simctl=t,this.idb=n,this.extraCapabilities={...rv,"appium:automationName":"XCUITest","appium:udid":t.udid??void 0};}static async init(e,t){let n=new Simctl,o=t.emulatorName??`momentic-${Date.now()}`,i=await ag(e);if(!i.includes(t.deviceType))throw new w("UserConfigurationError",`Invalid device type: ${t.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 n.createDevice(o,t.deviceType,"26.3");n.udid=s,a=async()=>{try{await n.shutdownDevice();}catch{}await n.deleteDevice();},await n.bootDevice(),await n.startBootMonitor({timeout:12e4}),t.appFilePath&&await n.installApp(t.appFilePath);let l=new iv(s);return new r({name:o,simctl:n,idb:l})}catch(s){throw await a?.(),s}}async tap(e,t){await this.idb.tap({x:e,y:t});}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 GRe=5e3;async function pm({creationOpts:r,apiClient:e,logger:t,driverLogLevel:n,orgId:o,sessionId:i,callbacks:a}){let s=Date.now();t.info("Starting ios driver creation");let{onLimbarConnectionStateChange:l,onStatusUpdate:c}=a,u=[],d=async()=>{let p=u.toReversed();for(let f of p)try{await q(f(),{milliseconds:GRe,fallback:()=>{}});}catch(h){if(zS(h))continue;t.warn({err:h},"Error running cleanup task");}};c("Starting iOS emulator creation...");let m;switch(r.type){case"remote":{m=await ig.init({apiClient:e,logger:t,creationOpts:r,orgId:o,sessionId:i,onStatusUpdate:c,onConnectionStateChange:l,logLevel:n});break}case"local":{m=await av.init(t,r);break}}u.push(async()=>{await m.close();});try{let p=await w3({logger:t,driverLogLevel:n,emulatorStart:s,emulator:m,apiClient:e,creationOpts:r,orgId:o,sessionId:i,callbacks:a});return u.push(()=>p.close()),p.executeInNativeContext(t,f=>f.getPageSource(),{operationName:"Warm up Appium cache"}).catch(()=>{}),{driver:p,emulator:m,limbarParams:m instanceof ig?{token:m.limbarToken,webRtcUrl:m.limbarWebRtcUrl,region:m.limbarRegion,osVersion:r.type==="remote"?r.osVersion:void 0}:void 0,cleanup:d}}catch(p){throw await d(),new Error(`Failed to start Appium driver: ${p}`,{cause:p})}}var KRe=100,XRe=2500,O3=4e3,YRe="...";async function sv({emulator:r,onLogs:e}){if(!r.addSyslogListener)return;let t=create({fetcher:async o=>{e(o);},resolver:()=>{},scheduler:windowedFiniteBatchScheduler({windowMs:XRe,maxBatchSize:KRe})}),n=o=>{let i=o.toString().trim();i.length!==0&&(i.length>O3&&(i=i.slice(0,O3)+YRe),t.fetch(i).catch(()=>{}));};return r.addSyslogListener(n)}var N3="NATIVE_APP";var ZRe=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),QRe=new Set([]),exe=new Set(["name","label","traits"]),txe=new Set(["live-region","drawing-order"]),rxe=new Set(["visible","enabled"]);function L3(r){let e={},t=r.tagName,n=reduce(r.attributes,(o,i)=>(o[i.name]=i.value,o),{});for(let[o,i]of Object.entries(n))ZRe.has(o)||o==="class"&&t===i||o==="focusable"&&i==="true"&&n.clickable==="true"||QRe.has(o)&&i==="false"||exe.has(o)&&i===""||rxe.has(o)&&i==="true"||txe.has(o)&&i==="0"||(e[o]=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 za(r){let e=r.getAttribute("x"),t=r.getAttribute("y"),n=r.getAttribute("width"),o=r.getAttribute("height");if(e===null||t===null||n===null||o===null)return;let i=parseFloat(e),a=parseFloat(t),s=parseFloat(n),l=parseFloat(o);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(l)))return {x1:i,y1:a,x2:i+s,y2:a+l}}function wI(r,e){let{x1:t,y1:n,x2:o,y2:i}=e;r.setAttribute("bounds",`[${t},${n},${o},${i}]`);}function nxe(r){let e=r.match(/\[([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\]/);if(!e)return;let t=parseFloat(e[1]),n=parseFloat(e[2]),o=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(t)||isNaN(n)||isNaN(o)||isNaN(i)||o<t||i<n))return {x1:t,y1:n,x2:o,y2:i}}function lv(r){let e=r.getAttribute("bounds");if(e)return nxe(e)}function D3(r,e){if(!e)return !0;let t=za(r);return t?AI(t,e):!0}function AI(r,e){if(!e)return !0;let{x1:t,y1:n,x2:o,y2:i}=r;return !(o<e.left||t>e.right||i<e.top||n>e.bottom)}function cv(r){let e=r.cloneNode(!0);for(let t of Array.from(e.children)){let n=t;for(let o of Array.from(n.children))n.removeChild(o);}return e.outerHTML}var k3=new Set(["XCUIElementTypeWebView"]);function lxe(r){if(k3.has(r.tagName))return !0;let e=r.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let t=e.match(/UUID=([A-F0-9-]+)/),n=e.match(/WebViewProcessID=(\d+)/);if(t&&n)return !0}return !1}function cxe(r){return r.startsWith("XCUIElementType")?r.substring(15):r}function F3({state:r,originalElement:e,prunedElement:t,isInWebview:n,idInWebview:o}){let{idCounter:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l}=r,c=i.value++;t.setAttribute("id",String(c)),a.set(c,t),n?l.set(c,o):s.set(c,e);}function U3(r){if(!k3.has(r.tagName)&&r.tagName==="XCUIElementTypeOther"&&r.hasAttribute("name")&&r.hasAttribute("label"))return r;for(let e of Array.from(r.children)){let t=U3(e);if(t)return t}}function uxe({webviewNativeRootBounds:r,webviewDocumentRootBounds:e}){let t=r.x1-e.x,n=r.y1-e.y;if(!Number.isFinite(t)||!Number.isFinite(n))return r;let o=r.x2-r.x1,i=r.y2-r.y1;return {x1:t,y1:n,x2:t+o,y2:n+i}}function B3(r,e,t,n){let{document:o}=t,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=n;if(e.type==="element"){let s=o.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 l=e.boundingRect,c={x1:i.x1+l.x,y1:i.y1+l.y,x2:i.x1+l.x+l.width,y2:i.y1+l.y+l.height};if(!AI(c,a))return;wI(s,c),F3({state:t,prunedElement:s,isInWebview:!0,idInWebview:e.momenticWebviewElementId}),r.appendChild(s);for(let u of e.children)B3(s,u,t,n);}else if(e.type==="text"){let s=o.createElement("text");r.appendChild(s);let l=o.createTextNode(e.text);s.appendChild(l);}}function z3(r,e,t,n){let{pruneElementsOutsideBounds:o}=n,{document:i}=t;F3({state:t,originalElement:r,prunedElement:e,isInWebview:!1});let a=L3(r);for(let[c,u]of Object.entries(a))e.setAttribute(c,u);let s=za(r);if(s&&wI(e,s),lxe(r)){let{removeWebviewContent:c,injectedWebviewContent:u}=n;if(c)return;if(u&&za(r)){let m=U3(r),p=m?za(m):void 0;if(m&&p){t.webviewRootElement=m,t.webviewRootBounds=p,B3(e,u.root,t,{parentFrameBounds:uxe({webviewNativeRootBounds:p,webviewDocumentRootBounds:u.rootBoundingBox}),pruneElementsOutsideBounds:o});return}}}let l=Array.from(r.childNodes??[]);for(let c of l){let u=c.nodeType;if(u===3){let d=c.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=c;if(!D3(d,o))continue;let m=i.createElement(cxe(d.tagName));z3(d,m,t,n),e.appendChild(m);}}}async function RI(r,e,t){let n=r.parseFromString("<AppiumAUT/>","text/xml"),o=new Map,i=new Map,a=new Map,s={document:n,idToPrunedElement:o,idToOriginalElement:i,idToIdInWebview:a,idCounter:{value:0},webviewRootElement:void 0,webviewRootBounds:void 0},l=n.documentElement;z3(e,l,s,t);let c=new XMLSerializer().serializeToString(n),u=await zAe.format(c,{parser:"xml",plugins:[BAe],printWidth:120,tabWidth:1,singleAttributePerLine:!1});return {prunedDocument:n,idToPrunedElement:o,idToOriginalElement:i,idToIdInWebview:a,webviewRootElement:s.webviewRootElement,webviewRootBounds:s.webviewRootBounds,prunedXml:u}}async function $3(r,e){let t=new DOMParser,n=t.parseFromString(r,"text/xml"),o=n.documentElement;if(!o)throw new Error("No root element found in XML");if(o.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l,webviewRootElement:c,webviewRootBounds:u}=await RI(t,o,e);return {xml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l,webviewRootElement:c,webviewRootBounds:u,originalDocument:n}}var V3=(ce=>(ce.GenericElement="GenericElement",ce.Any="Any",ce.Other="Other",ce.Application="Application",ce.Group="Group",ce.Window="Window",ce.Sheet="Sheet",ce.Drawer="Drawer",ce.Alert="Alert",ce.Dialog="Dialog",ce.Button="Button",ce.RadioButton="RadioButton",ce.RadioGroup="RadioGroup",ce.CheckBox="CheckBox",ce.DisclosureTriangle="DisclosureTriangle",ce.PopUpButton="PopUpButton",ce.ComboBox="ComboBox",ce.MenuButton="MenuButton",ce.ToolbarButton="ToolbarButton",ce.Popover="Popover",ce.Keyboard="Keyboard",ce.Key="Key",ce.NavigationBar="NavigationBar",ce.TabBar="TabBar",ce.TabGroup="TabGroup",ce.Toolbar="Toolbar",ce.StatusBar="StatusBar",ce.Table="Table",ce.TableRow="TableRow",ce.TableColumn="TableColumn",ce.Outline="Outline",ce.OutlineRow="OutlineRow",ce.Browser="Browser",ce.CollectionView="CollectionView",ce.Slider="Slider",ce.PageIndicator="PageIndicator",ce.ProgressIndicator="ProgressIndicator",ce.ActivityIndicator="ActivityIndicator",ce.SegmentedControl="SegmentedControl",ce.Picker="Picker",ce.PickerWheel="PickerWheel",ce.Switch="Switch",ce.Toggle="Toggle",ce.Link="Link",ce.Image="Image",ce.Icon="Icon",ce.SearchField="SearchField",ce.ScrollView="ScrollView",ce.ScrollBar="ScrollBar",ce.StaticText="StaticText",ce.TextField="TextField",ce.SecureTextField="SecureTextField",ce.DatePicker="DatePicker",ce.TextView="TextView",ce.Menu="Menu",ce.MenuItem="MenuItem",ce.MenuBar="MenuBar",ce.MenuBarItem="MenuBarItem",ce.Map="Map",ce.WebView="WebView",ce.IncrementArrow="IncrementArrow",ce.DecrementArrow="DecrementArrow",ce.Heading="Heading",ce.Cell="Cell",ce))(V3||{}),H3=v__default.lazy(()=>v__default.object({AXFrame:v__default.string(),AXUniqueId:v__default.string().nullable(),AXLabel:v__default.string().nullable(),AXValue:v__default.string().nullable(),frame:v__default.object({x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()}),role:v__default.string(),role_description:v__default.string(),subrole:v__default.string().nullable(),type:v__default.nativeEnum(V3),title:v__default.string().nullable(),help:v__default.string().nullable(),content_required:v__default.boolean(),custom_actions:v__default.array(v__default.string()),enabled:v__default.boolean(),children:v__default.array(H3).default([])}));function mxe(r){return v__default.array(H3).parse(JSON.parse(r))}async function uv(r,e){let t=new DOMParser,n=mxe(r),o=pxe(t,n),{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s}=await RI(t,o.documentElement,{removeWebviewContent:!1,injectedWebviewContent:void 0,pruneElementsOutsideBounds:e.pruneElementsOutsideBounds});return {xml:i,idToPrunedElement:a,idToOriginalElement:s,originalDocument:o,webviewRootElement:void 0,idToIdInWebview:new Map,webviewRootBounds:void 0}}function pxe(r,e){let t=r.parseFromString("<hierarchy/>","text/xml"),n=t.documentElement;for(let o=0;o<e.length;o++){let i=e[o],a=j3(i,t);n.appendChild(a);}return t}function j3(r,e){let t=r.type,n=e.createElement(t);if(n.setAttribute("type",t),n.setAttribute("x",String(r.frame.x.toFixed(2))),n.setAttribute("y",String(r.frame.y.toFixed(2))),n.setAttribute("width",String(r.frame.width.toFixed(2))),n.setAttribute("height",String(r.frame.height.toFixed(2))),r.AXLabel!==null&&n.setAttribute("label",r.AXLabel),r.AXValue!==null&&n.setAttribute("value",r.AXValue),r.title!==null&&n.setAttribute("title",r.title),r.help!==null&&n.setAttribute("help",r.help),n.setAttribute("enabled",String(r.enabled)),r.children)for(let o=0;o<r.children.length;o++){let i=r.children[o],a=j3(i,e);n.appendChild(a);}return n}function xc(r){let e=[],t=r;for(;t;){let n=t.parentElement;if(!n||n.tagName==="AppiumAUT"){e.unshift(`${t.tagName}[1]`);break}let o=t.tagName,i=Array.from(n.children).filter(s=>s.tagName===o),a=1;for(let s=0;s<i.length;s++)if(i[s]===t){a=s+1;break}e.unshift(`${o}[${a}]`),t=n;}return `/${e.join("/")}`}var dv=class r{driver;emulator;options;aborter;constructor({driver:e,emulator:t,aborter:n,options:o}){this.driver=e,this.emulator=t,this.aborter=n,this.options=o;}static async init({driver:e,emulator:t,aborter:n,options:o}){return new r({driver:e,aborter:n,emulator:t,options:o})}async getContexts(e){let t=await this.driver.executeInNativeContext(e,async o=>await o.getContexts({}),{operationName:"getContexts"}),n=t.filter(o=>o!==N3);return {contexts:t.map(o=>o),webviews:n}}async getRawScreenshotBase64({logger:e,totalAttempts:t=3,signal:n}){let o=re(),i=n??this.aborter.controller?.signal;return await o.startAsyncSpan("EMULATOR_READ_STATE",async()=>await Ed(e,()=>this.emulator.screenshotPngBase64(),{maxAttempts:t,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:t,signal:n,reason:o,tolerancePercent:i=1}){await re().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=o;let s=Uu({signal:n,timeoutMs:t}),l,c=!1;for(;!s.aborted;){let u=Date.now();if(l)try{let m=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});if(Ds(l,m)<=i){c=!0;break}l=m;}catch(m){e.warn({err:m},"Failed to get screenshot during stability wait");}else try{l=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 Li(Math.min(1e4,d),s);}c||(a.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({logger:e,timeoutMs:t,signal:n,reason:o}){await re().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=o;let a=Uu({signal:n,timeoutMs:t}),s,l=!1;for(;!a.aborted;){let c,u=Date.now();try{c=await q(this.emulator.nativeA11yTreeJson(),{milliseconds:1e4,signal:a,message:"Getting the native accessibility tree timed out after 10s"});let m=createHash("md5").update(c).digest("hex");if(s&&s===m){l=!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 Li(Math.min(1e4,d),a);}l||(i.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for page source stability"));});}async getActiveWebview(e){let n=(await this.getContexts(e)).webviews;if(n.length>1)throw new w("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return n[0]}async getActiveWebviewContent(e){let t=await this.getActiveWebview(e);if(!t)return;this.throwIfAborted();let n=await this.driver.executeWebViewScript(e,t,o=>o.dumpA11yTree());return {context:t,...n}}async getDomState(e,t){let o=t?.filterOffscreenElements??!0?await this.getViewportBounds(e):void 0,i;if(!t?.skipFetchingFullWebviewContent)try{i=await this.getActiveWebviewContent(e);}catch(l){e.error({err:l},"Could not get webview info to get the nested DOM state");}if(this.throwIfAborted(),!i&&this.options?.disableMomenticAccessibilityTree){let l=await this.getNativePageSource();this.throwIfAborted();let c=await uv(l,{pruneElementsOutsideBounds:o});return {sourceTree:"native",graph:c,webviewContent:void 0}}let a=await this.getAppiumPageSource(e);return this.throwIfAborted(),{graph:await $3(a,{injectedWebviewContent:i,removeWebviewContent:t?.removeWebviewContent,pruneElementsOutsideBounds:o}),sourceTree:"appium",webviewContent:i}}async getNativePageSource(){return await re().startAsyncSpan("EMULATOR_READ_STATE",async()=>this.emulator.nativeA11yTreeJson(),{name:"Get iOS page source",signal:this.aborter.controller?.signal,timeoutMs:3e4})}async getAppiumPageSource(e,t){let n=t??this.aborter.controller?.signal;return await re().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(e,i=>i.getPageSource(),{signal:n,operationName:"getPageSource"}),{name:"Get page source",signal:n,timeoutMs:3e4})}async getViewportBounds(e){let t=await this.driver.executeInNativeContext(e,async n=>n.getWindowRect(),{operationName:"getViewportBounds"});return {left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};async function W3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,throwIfAborted:a,abortSignal:s}){let l=re(),c=15,u=r.timeoutSecs?r.timeoutSecs*1e3:5e3,d=XS(u),m=Date.now(),p=0,f,h=!1,g;for(;p<c&&!h;){a(),h||f&&f-m>=u&&(h=!0),p!==0&&await te(d,s),f=Date.now();try{let y="",S="";await l.startAsyncSpan("EMULATOR_READ_STATE",async()=>{y=await o(),S=await i();},{name:"Get emulator state"});let b=await t.evaluateIosAssertion({assertion:r.assertion,screenXml:y,screenshot:S},{logger:e,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["ios-assertion"]});if(b.result)return {success:b.result,message:b.thoughts};{let C=`AssertionFailureError: ${b.thoughts}`;g=new Error(C);}}catch(y){a(),e.info({err:y},`AI check assert attempt ${p} failed, retrying...`),g=y instanceof Error?y:new Error(`${y}`);}finally{p++;}}return {success:!1,message:g?.message}}async function q3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,abortSignal:a}){if(!r.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(r.schema){let u=Lu(r.schema);if(u)throw new w("UserConfigurationError",u)}let s=re(),l="",c="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{l=await o(),c=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await t.getIosTextExtraction({goal:r.goal,emulatorState:l,returnSchema:r.schema,screenshot:`data:image/png;base64,${c}`},{disableCache:!!r.disableCache,abortSignal:a,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["ios-text-extraction"]});if(u.result=d,Ob({tracer:s,span:u,screenshot:c,emulatorState:l,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 w("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 ea="element-6066-11e4-a52e-4f735466cecf";function ta(r,e){return Math.abs(r-e)<1}function fm(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r.x1+r.x2)/2;if(!ji(e.tolerance,n,o,Math.min(1,t)))return !1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r.y1+r.y2)/2;return ji(e.tolerance,a,s,Math.min(1,i))}function hm(r,e){let t=r.x2-r.x1,n=r.y2-r.y1;return ji(e.tolerance,e.width,t,Math.min(1,e.width))?ji(e.tolerance,e.height,n,Math.min(1,e.height)):!1}function gm(r){return r.type==="WEBVIEW",r.cache}function ym(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;Ow(e)&&(e[t]={...e[t],[n]:au.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=we(r.logger)));}var sg="name";async function K3(r,e,t){return await e.executeInNativeContext(r,n=>n.isElementDisplayed(t),{operationName:"isElementRendered"})}async function Sm(r,e,t,n){return await e.executeInNativeContext(r,o=>o.getElementAttribute(t,n),{operationName:"getAttributeFromIosElement"})}async function xI(r,e,t){return await e.executeInNativeContext(r,async n=>{try{let o=await n.findElement("xpath",t);if(!o)return null;let i=o[ea];if(!i)return null;let a=await n.getElementRect(i);return {elementId:i,rect:a}}catch{return null}},{operationName:"findElementByXPath"})}async function X3(r,e,t){let n=xc(t),o=await xI(r,e,n);if(o)return {xPath:n,...o}}async function MI({logger:r,emulatorState:e,driver:t,idInWebview:n,requirements:o}){let i=e.graph.webviewRootElement?xc(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 gxe({logger:r,driver:t,webviewRootBounds:e.graph.webviewRootBounds,nodeIdInWebview:n,aiGeneratedRequirements:o,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 gxe({logger:r,driver:e,webviewRootBounds:t,nodeIdInWebview:n,aiGeneratedRequirements:o,webviewContent:i}){let a=await e.executeWebViewScript(r,i.context,(l,c,u,d)=>l.generateCacheFromWebviewElementId(c,u,d),i.generatedAt,n,{attributesToFetch:o?.attributesRequired??[]});if(!a)return;let s={x:t.x1-i.rootBoundingBox.x+a.boundingBox.x,y:t.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:o?.textRequired?a.textContent:void 0,attributes:a.attributes,boundingBox:o?.boundsRequired?s:void 0,shape:o?.shapeSpecificity?{tolerance:o.shapeSpecificity,width:a.boundingBox.width,height:a.boundingBox.height}:void 0,position:o?.positionSpecificity?{tolerance:o.positionSpecificity,x1:s.x,y1:s.y,x2:s.x+s.width,y2:s.y+s.height}:void 0}}}async function yxe(r,e,t,n){if(!n||!n.length)return;let o={};for(let i of n){let a=await Sm(r,e,t,i);a!==null&&(o[i]=a);}return Object.keys(o).length?o:void 0}async function Y3({logger:r,driver:e,node:t,requirements:n}){let o=await X3(r,e,t);if(!o){r.warn("Failed to generate valid xPath selector for element");return}let{xPath:i,rect:a,elementId:s}=o,l={x1:a.x,y1:a.y,x2:a.x+a.width,y2:a.y+a.height};return {xPath:i,bounds:[l.x1,l.y1,l.x2,l.y2],requirements:{requiredText:n?.textRequired?await Sm(r,e,s,sg)??void 0:void 0,requiredAttributes:await yxe(r,e,s,n?.attributesRequired?.filter(c=>!(n.textRequired&&c===sg))),requiredBounds:n?.boundsRequired,position:n?.positionSpecificity?{x1:l.x1,y1:l.y1,x2:l.x2,y2:l.y2,tolerance:n?.positionSpecificity}:void 0,shape:n?.shapeSpecificity?{width:l.x2-l.x1,height:l.y2-l.y1,tolerance:n?.shapeSpecificity}:void 0}}}async function J3({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o}){let i=o.graph.idToPrunedElement.get(t.id);if(!i)throw new Error(`Could not find node with id: ${t.id}`);let a=lv(i);if(!a)throw new Error(`Could not determine bounds for element with id: ${t.id}, description: ${n}`);let s=[];for(let{id:d,requirements:m}of t.additionalElements??[]){let p=o.graph.idToIdInWebview.get(d);if(p!==void 0){try{let g=await MI({logger:r,driver:e,emulatorState:o,idInWebview:p,requirements:m});s.push(g);}catch(g){r.warn({err:g},`Failed to build webview cache for related element with id: ${d}`);}continue}let f=o.graph.idToOriginalElement.get(d);if(!f){r.warn(`Could not find original element for additional element with id: ${d}`);continue}let h=await Y3({logger:r,driver:e,node:f,requirements:m});h&&s.push(h);}let l=o.graph.idToIdInWebview.get(t.id);if(l!==void 0){let d={type:"WEBVIEW",bounds:a,cache:{type:"WEBVIEW"}};try{let m=await MI({logger:r,driver:e,emulatorState:o,idInWebview:l,requirements:t.requirements});return {...d,cache:{type:"WEBVIEW",resolvedDescription:n,requiredRelatedElements:s,...m}}}catch(m){return r.warn({err:m},"Failed to build webview target cache"),d}}let c=o.graph.idToOriginalElement.get(t.id);if(!c)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${t.id}, description: ${n}`);let u=await Y3({logger:r,driver:e,node:c,requirements:t.requirements});return u?{type:"NATIVE",bounds:a,cache:{type:"NATIVE",...u,resolvedDescription:n,sourceTree:"appium",requiredRelatedElements:s,elementOnlySerializedXml:cv(c)}}:(r.warn("Failed to generate valid cache for element"),{type:"NATIVE",cache:{type:"NATIVE"},bounds:a})}async function _I({logger:r,driver:e,stateManager:t,parentWebviewBounds:n,cache:o}){if(!o||!o.generatedSelectors)throw new Ee("Cache is missing required attributes");let i=await t.getActiveWebview(r);if(!i)throw new Ee("No active webview context found");let a=await e.executeWebViewScript(r,i,(u,d)=>u.resolveWebviewTargetCache(d),{selectors:o.generatedSelectors,attributesToFetch:Object.keys(o.requirements?.attributes??{})});if(!a)throw new Ee("Failed to resolve webview target using cache");let s=n.x1-a.rootBoundingBox.x+a.boundingBox.x,l=n.y1-a.rootBoundingBox.y+a.boundingBox.y,c={x1:s,y1:l,x2:s+a.boundingBox.width,y2:l+a.boundingBox.height};return o.requirements&&Sxe(r,c,a,o.requirements),c}function Sxe(r,e,t,n){if(!n)return;let{attributes:o,text:i,position:a,shape:s}=n;if(i!==void 0&&i.length>0&&t.textContent!==i)throw new Ee(`Text content mismatch: expected "${i}", got "${t.textContent}"`);if(o)for(let[l,c]of Object.entries(o)){let u=t.attributes[l];if(u!==c)throw new Ee(`Attribute ${l} mismatch: expected "${c}", got "${u}"`)}if(a&&!fm(e,a))throw new Ee(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(e)}`);if(s&&!hm(e,s))throw new Ee(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(e)}`)}async function Z3(r,e,t,n,o){if(!n)return;let{requiredAttributes:i,requiredText:a,requiredBounds:s,position:l,shape:c}=n;if(a!==void 0&&a.length>0){let u=await Sm(r,e,t,sg);if(u!==a)throw new Ee(`Resolved element text mismatch: expected ${a}, got ${u}`)}if(i)for(let[u,d]of Object.entries(i)){let m=await Sm(r,e,t,u)??void 0;if(m!==d)throw new Ee(`Attribute ${u} mismatch: expected ${d}, got ${m}`)}if(s&&o){let{originalBounds:u,newBounds:d}=o;if(!u)throw new Ee("Cannot validate bounds requirements without original bounds in cache");if(!(ta(u.x1,d.x1)&&ta(u.y1,d.y1)&&ta(u.x2,d.x2)&&ta(u.y2,d.y2))){let p=f=>`[${f.x1},${f.y1},${f.x2},${f.y2}]`;throw new Ee(`Bounds changed from ${p(u)} to ${p(d)}`)}}if(l&&o&&!fm(o.newBounds,l))throw new Ee(`Position mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(o.newBounds)}`);if(c&&o&&!hm(o.newBounds,c))throw new Ee(`Shape mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(o.newBounds)}`)}async function Q3({logger:r,driver:e,xPath:t,elementType:n,skipVisibilityCheck:o=!1}){let i=await xI(r,e,t);if(!i)throw new Ee(`Could not resolve ${n} via XPath: ${t}`);let{elementId:a}=i;if(!o&&!await K3(r,e,a))throw new Ee(`${n} resolved via XPath is not rendered: ${t}`);return i}async function eY({target:r,driver:e,stateManager:t,logger:n}){if(!r.xPath)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);if(r.requiredRelatedElements){let s=r.requiredRelatedElements;for(let l of s){let{elementId:c,rect:u}=await Q3({logger:n,driver:e,xPath:l.xPath,elementType:"related element",skipVisibilityCheck:!!l.browserCache});if(l.browserCache){let d={x1:u.x,y1:u.y,x2:u.x+u.width,y2:u.y+u.height};await _I({logger:n,driver:e,stateManager:t,parentWebviewBounds:d,cache:l.browserCache});}else await Z3(n,e,c,l.requirements);}}let{elementId:o,rect:i}=await Q3({logger:n,driver:e,xPath:r.xPath,elementType:"element",skipVisibilityCheck:r.type==="WEBVIEW"}),a={x1:i.x,y1:i.y,x2:i.x+i.width,y2:i.y+i.height};if(r.type==="WEBVIEW"){let s=await _I({logger:n,driver:e,stateManager:t,parentWebviewBounds:a,cache:r.browserCache});return {type:"WEBVIEW",bounds:s,cache:r}}return await Z3(n,e,o,r.requirements,{originalBounds:r.bounds?{x1:r.bounds[0],y1:r.bounds[1],x2:r.bounds[2],y2:r.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...r,bounds:[a.x1,a.y1,a.x2,a.y2]}}}function rY({aiResponse:r,description:e,emulatorState:t}){let n=t.graph.idToPrunedElement.get(r.id);if(!n)throw new Error(`Could not find node with id: ${r.id}`);let o=lv(n);if(!o)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${e}`);let i=t.graph.idToOriginalElement.get(r.id);if(!i)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${r.id}, description: ${e}`);let a=xc(i),s=cv(i),l=tY({requirements:r.requirements,element:i}),c=(r.additionalElements??[]).map(({id:u,requirements:d})=>{let m=t.graph.idToOriginalElement.get(u);return m?{xPath:xc(m),requirements:tY({requirements:d,element:m})}:void 0}).filter(u=>!!u);return {type:"NATIVE",bounds:o,cache:{type:"NATIVE",bounds:[o.x1,o.y1,o.x2,o.y2],resolvedDescription:e,sourceTree:t.sourceTree,xPath:a,elementOnlySerializedXml:s,requirements:l,requiredRelatedElements:c}}}function tY({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=za(e),!t))throw new w("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:r?.textRequired?e.textContent??void 0:void 0,requiredAttributes:bxe(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2,tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t.x2-t.x1,height:t.y2-t.y1,tolerance:r?.shapeSpecificity}:void 0}}function bxe(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}async function oY(r,e,t,n){if(!t)return;let{requiredAttributes:o,requiredText:i,requiredBounds:a,position:s,shape:l}=t;if(i!==void 0&&i.length>0){let c=e.textContent;if(c!==i)throw new Ee(`Resolved element text mismatch: expected ${i}, got ${c}`)}if(o)for(let[c,u]of Object.entries(o)){let d=e.getAttribute(c)??void 0;if(d!==u)throw new Ee(`Attribute ${c} mismatch: expected ${u}, got ${d}`)}if(a&&n){let{originalBounds:c,newBounds:u}=n;if(!c)throw new Ee("Cannot validate bounds requirements without original bounds in cache");if(!(ta(c.x1,u.x1)&&ta(c.y1,u.y1)&&ta(c.x2,u.x2)&&ta(c.y2,u.y2))){let m=p=>`[${p.x1},${p.y1},${p.x2},${p.y2}]`;throw new Ee(`Bounds changed from ${m(c)} to ${m(u)}`)}}if(s&&n&&!fm(n.newBounds,s))throw new Ee(`Position mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(n.newBounds)}`);if(l&&n&&!hm(n.newBounds,l))throw new Ee(`Shape mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(n.newBounds)}`)}async function iY({target:r,logger:e,emulator:t}){if(!r.xPath)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);let n=await t.nativeA11yTreeJson(),o=await uv(n,{pruneElementsOutsideBounds:void 0});if(r.requiredRelatedElements){let s=r.requiredRelatedElements;for(let l of s){let c=QX.evaluateXPathToFirstNode(l.xPath,o.originalDocument);if(!c)throw new Ee(`Required related element not found for XPath: ${l.xPath}`);await oY(e,c,l.requirements);}}let i=QX.evaluateXPathToFirstNode(r.xPath,o.originalDocument);if(!i)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);let a=za(i);if(!a)throw new Ee(`Could not determine bounds for cached target via XPath: ${r.xPath}`);return await oY(e,i,r.requirements,{originalBounds:r.bounds?{x1:r.bounds[0],y1:r.bounds[1],x2:r.bounds[2],y2:r.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...r,bounds:[a.x1,a.y1,a.x2,a.y2]}}}async function aY({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o}){switch(o.sourceTree){case"appium":return await J3({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o});case"native":return await rY({aiResponse:t,description:n,emulatorState:o});default:{let i=o.sourceTree;throw new Error(`Unsupported source tree type for building iOS target cache: ${i}`)}}}async function sY({target:r,driver:e,stateManager:t,logger:n,emulator:o}){if(r.type==="WEBVIEW"||!r.sourceTree||r.sourceTree=="appium")return await eY({target:r,driver:e,stateManager:t,logger:n});switch(r.sourceTree){case"native":return await iY({target:r,logger:n,emulator:o});default:{let i=r.sourceTree;throw new Error(`Unsupported source tree type for resolving iOS target cache: ${i}`)}}}var hr=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:t,description:n,skipFetchingFullWebviewContent:o=!1,removeWebviewContent:i=!1,filterOffscreenElements:a=!0,useMemory:s=!1,metadata:l,cacheBustReason:c}){let u=e.child({...l});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 t.startAsyncSection("Get emulator state",async()=>{let h=await this.stateManager.getCurrentScreenshotPngString(e);return {emulatorState:await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:o,removeWebviewContent:i,filterOffscreenElements:a}),screenshot:h}}),p;try{p=await t.startAsyncSpan("AI_LOCATOR_CALL",async h=>{c&&(h.attributes.cacheBustReason=c);let g=await this.generator.getIosElementLocation({description:n,screenXml:d.graph.xml,screenshot:m,source:l?.source==="SCROLL_TO"?"SCROLL_TO":void 0},{logger:u,loggerTags:we(u),abortSignal:this.aborter.controller?.signal,useMemory:s,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]});return h.result=g,g});}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 w("NoMatchingElementError",p.thoughts??"No matching element found");let f=await aY({logger:e,driver:this.driver,aiResponse:p,description:n,emulatorState:d});return t.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:t,action:n,command:o,description:i,cacheKey:a,targetName:s,skipFetchingFullWebviewContent:l,removeWebviewContent:c,metadata:u,logger:d,cacheBustReason:m}=e,p=await this.findElement({logger:d,tracer:t,description:i,skipFetchingFullWebviewContent:l,removeWebviewContent:c,metadata:u,cacheBustReason:m}),f=p.thoughts,h=await n(p.resolvedTarget);return ym({command:o,cacheKey:a,targetName:s,updatedCache:gm(p.resolvedTarget),updatedWithAI:!0,logger:d}),{result:h,thoughts:f}}async targetingActionWithCache({logger:e,tracer:t,action:n,command:o,cacheKey:i,targetName:a,cacheCopyForAttempt:s}){this.emulatorSettings?.waitForStability!==!1&&await this.stateManager.waitForPageSourceStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let l=await this.resolveTargetCacheWithTracing({logger:e,tracer:t,cache:s}),c=await n(l);return ym({command:o,cacheKey:i,targetName:a,updatedCache:gm(l),updatedWithAI:!1,logger:e}),{result:c,thoughts:"Successfully executed preset action with cache"}}async resolveTargetCacheWithTracing({logger:e,tracer:t,cache:n,retryWithinSmartWaiting:o=!0}){let{resolvedTarget:i}=await t.startAsyncSpan("CACHE_RESOLUTION",async a=>{let s=Date.now(),l;for(;!o||Date.now()-s<3e3;)try{let c=await sY({target:n,driver:this.driver,stateManager:this.stateManager,logger:e,emulator:this.emulator});return a.attributes.serializedElement=(c.type==="NATIVE"?c.cache.elementOnlySerializedXml:void 0)??"Unknown element",{resolvedTarget:c}}catch(c){if(l=c,c instanceof Ee){if(!o)throw c;e.warn({err:c},"Failed to resolve target cache, retrying"),await Li(500,this.aborter.controller?.signal);continue}throw e.error({err:c},"Failed to resolve target cache"),c}throw l});return i}async wrapTargetingAction(e){let{tracer:t,logger:n,action:o,description:i,command:a,cacheKey:s="cache",targetName:l="target",cacheIsInvalidAfterResolution:c,skipFetchingFullWebviewContent:u=!1,removeWebviewContent:d=!1}=e,m={commandId:a.id},p=!1,f,h;if(s==="cache"&&"cache"in a&&a.cache){let g=a.cache;l==="target"&&"target"in g?h=cloneDeep(g.target):l==="fromTarget"&&"fromTarget"in g?h=cloneDeep(g.fromTarget):l==="toTarget"&&"toTarget"in g&&(h=cloneDeep(g.toTarget));}if(a.disableCache&&(n.debug({command:a},"Cache explicitly disabled for command"),p=!0,f="Cache explicitly disabled",h=void 0),c&&(p=!0,f=f??"Cache invalidated after resolution",h=void 0),h&&!js(h.resolvedDescription??"",i)&&(n.info({description:i,cacheDescription:h.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=!0,f="Description mismatch",h=void 0),h){let g=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements;try{let y=await this.targetingActionWithCache({logger:n,tracer:t,action:o,command:a,cacheKey:s,targetName:l,cacheCopyForAttempt:h});return Et.increment("cache_target_resolution_v2",1,["outcome:hit","platform:mobile-native",`hasRequirements:${g}`,`orgId:${this.orgId}`,"cliVersion:0.88.1"]),y}catch(y){if(this.throwIfAborted(),y instanceof w&&y.reason!=="InternalWebAgentError")throw n.error({err:y},"Failed to execute action with target cache (fatal)"),y;Et.increment("cache_target_resolution_v2",1,["outcome:miss","platform:mobile-native",`hasRequirements:${g}`,`orgId:${this.orgId}`,"cliVersion:0.88.1"]),n.warn({err:y},"Failed to execute action with target cache, retrying with AI");}}return n.info({description:i,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),await this.targetingActionWithAILocator({tracer:t,action:o,command:a,description:i,cacheKey:s,targetName:l,skipFetchingFullWebviewContent:u,removeWebviewContent:d,metadata:m,logger:n,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 pv=class extends hr{async doDrag(e,t,n,o,i){let{x1:a,y1:s,x2:l,y2:c}=n.bounds,u=a+(l-a)/2,d=s+(c-s)/2;t.attributes.startPoint={x:u,y:d};let{x1:m,y1:p,x2:f,y2:h}=o.bounds,g=m+(f-m)/2,y=p+(h-p)/2;t.attributes.endPoint={x:g,y};let S=i?.hoverDuration??500,b=i?.dragDuration??1e3;b===0&&(b=1);let A=Math.sqrt(Math.pow(g-u,2)+Math.pow(y-d,2))/b*1e3;await this.driver.executeInNativeContext(e,async O=>{await O.execute("mobile: dragFromToWithVelocity",{fromX:u,fromY:d,toX:g,toY:y,pressDuration:S/1e3,velocity:A,holdDuration:.5});},{operationName:"dragAndDrop"});}async executeDragAndDrop({logger:e,command:t}){let n=re();if(t.fromTarget.type!=="description"||t.toTarget.type!=="description")throw new w("UserConfigurationError","Drag and drop only supports description targets for now");let o=t.fromTarget.description,{result:i,thoughts:a}=await this.wrapTargetingAction({command:t,tracer:n,description:o,cacheKey:"cache",targetName:"fromTarget",action:async u=>u,logger:e}),s=t.toTarget.description,{result:l,thoughts:c}=await this.wrapTargetingAction({command:t,tracer:n,description:s,cacheKey:"cache",targetName:"toTarget",action:async u=>u,logger:e});return await n.startAsyncSpan("EMULATOR_INTERACTION",async u=>{await this.doDrag(e,u,i,l,{hoverDuration:t.hoverDuration,dragDuration:t.dragDuration});},{name:"Drag and drop"}),{success:!0,message:`${a}
|
|
5360
|
+
}`);return a.execute(s,...o)},{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 w3({logger:r,driverLogLevel:e="error",emulator:t,callbacks:n}){let{onStatusUpdate:o}=n,i=r.child({emulatorName:t.name}),a={platformName:"iOS","appium:noReset":!0,"appium:fullReset":!1,"appium:newCommandTimeout":3600,"appium:autoWebview":!1,"appium:webviewConnectTimeout":500,"appium:webviewConnectRetries":5,"appium:includeSafariInWebviews":!0,"appium:fullContextList":!1,"appium:additionalWebviewBundleIds":["*"],"appium:waitForIdleTimeout":0,"appium:reduceMotion":!0,"appium:settings":{customSnapshotTimeout:0,animationCoolOffTimeout:0},...t.extraCapabilities};o("Starting Appium session...");let s={capabilities:a},l=await tv.init({logger:i,logLevel:e,callbacks:{...n,restartWda:t.restartWda?async c=>{await t.restartWda?.(c);}:void 0,onFailure:async({err:c,attempt:u})=>{let d=Mb(c),m=u<3&&d;return m&&i.warn({err:c},"Appium driver manifest race detected on first attempt, restarting Appium and retrying"),{shouldRetry:m}}},wdioOpts:s});return i.info({capabilities:a,emulatorName:t.name},"Started Appium driver"),l}async function A3({wdaUrl:r,token:e}){try{let t=new AbortController;return setTimeout(()=>t.abort(),3e3),await fetch(r+"/status",{headers:{Authorization:`Bearer ${e}`},signal:t.signal}),!0}catch{return !1}}var rv={"appium:waitForIdleTimeout":2,"appium:commandTimeouts":"30000","appium:skipLogCapture":!0,"appium:disableAutomaticScreenshots":!0,"appium:simpleIsVisibleCheck":!0};var FRe=["[com.apple.","loadConfigurationForEnvironment"],URe=["com.apple.Accessibility","com.apple.news","com.apple.locationd","NewsToday","NewsTodayIntents","apsd","APSConfiguration","APSOutgoingQueue","APSCourierConnection","APSNetworkMonitor","loadConfigurationForEnvironment"],BRe=[" Df "," Db "],zRe="https://storage.googleapis.com/mobile-drivers/WebDriverAgentRunner-Build-Sim-arm64-v10.4.5.zip";function $Re(r){let e=FRe.some(n=>r.includes(n)),t=URe.some(n=>r.includes(n));return BRe.some(n=>r.includes(n))?e||t:r.includes(" I ")?t:!1}async function x3({wdaUrl:r,token:e,limbarClient:t,logger:n,onStatusUpdate:o}){await A3({wdaUrl:r,token:e})||(o("Starting WebDriverAgent..."),n.debug("WDA is not running on the iOS emulator"),await t.simctl(["launch","booted","com.facebook.WebDriverAgentRunner.xctrunner"]).wait(),n.debug("WDA launched"));}var ig=class r{apiClient;name;extraCapabilities;limbarToken;limbarWebRtcUrl;limbarApiUrl;limbarWdaUrl;limbarRegion;limbarClient;onStatusUpdate;logStream=void 0;constructor({apiClient:e,limbarToken:t,limbarWebRtcUrl:n,limbarApiUrl:o,limbarWdaUrl:i,limbarRegion:a,emulatorName:s,limbarClient:l,onStatusUpdate:c}){this.apiClient=e,this.name=s,this.limbarToken=t,this.limbarWebRtcUrl=n,this.limbarApiUrl=o,this.limbarWdaUrl=i,this.limbarRegion=a,this.limbarClient=l,this.extraCapabilities={...rv,"appium:automationName":"@limrun/xcuitest","appium:webDriverAgentUrl":this.limbarWdaUrl,"appium:wdaLocalPort":443,"appium:useNewWDA":!1,"appium:usePreinstalledWDA":!0,"appium:limInstanceApiUrl":o,"appium:limInstanceToken":t,"appium:wdaRequestHeaders":{Authorization:`Bearer ${t}`}},this.onStatusUpdate=c;}static async init(e){let{apiClient:t,logger:n,creationOpts:o,logLevel:i,orgId:a,sessionId:s,onStatusUpdate:l,onConnectionStateChange:c}=e,u=o.appToInstall?.channel,d=o.appToInstall?.tag;l("Creating iOS emulator");let{token:m,webRtcUrl:p,wdaUrl:f,apiUrl:h,id:g,region:y,appDownloadUrl:S,appMd5:b}=await t.createIosEmulator({...o,hostname:hostname(),sessionId:s,installAppOnClient:!0});n.info({emulatorName:g,region:y,sessionId:s},"ios instance creation ok"),l("Connecting to iOS emulator...");let C;try{C=await Et.recordDuration({fn:async()=>await createInstanceClient$1({apiUrl:h,token:m,logLevel:i}),name:"test_event_duration",tags:["name:limbar-client-creation","clientOs:ios",`orgId:${a}`]}),c&&C.onConnectionStateChange(c),l("Installing WebDriverAgent...");let A=C;return await Et.recordDuration({fn:async()=>{await _3({limbarClient:A,url:zRe,md5:void 0,logger:n,emulatorName:g,assetLabel:"WebDriverAgent"});},name:"test_event_duration",tags:["name:limbar-wda-install","clientOs:ios",`orgId:${a}`]}),await x3({wdaUrl:f,token:m,limbarClient:A,logger:n,onStatusUpdate:l}),S&&(l(`Installing iOS app${u?` with channel ${u}`:""}${d?` and tag ${d}`:""}`),await Et.recordDuration({fn:async()=>{await _3({limbarClient:A,url:S,md5:b,logger:n,emulatorName:g,assetLabel:"iOS app"});},name:"test_event_duration",tags:["name:limbar-app-install","clientOs:ios",`orgId:${a}`]})),(async()=>{try{let[O,M]=await Promise.allSettled([td("limserver-1.limrun.net"),td("125.253.92.199")]);n.info({limserver:O.status==="fulfilled"?O.value:O.reason,ip125:M.status==="fulfilled"?M.value:M.reason},"Limbar network diagnostics");}catch(O){n.warn({err:O},"Failed to run network diagnostics");}})(),new r({apiClient:t,limbarToken:m,limbarWebRtcUrl:p,limbarApiUrl:h,limbarWdaUrl:f,limbarRegion:y,emulatorName:g,limbarClient:A,onStatusUpdate:l})}catch(A){throw n.warn({err:A,emulatorName:g},"iOS emulator init failed after creation; cleaning up remote instance"),await VRe({apiClient:t,limbarClient:C,id:g,logger:n}),A}}tap(e,t){return this.limbarClient.tap(e,t)}nativeA11yTreeJson(){return this.limbarClient.elementTree()}async screenshotPngBase64(){let e=await this.limbarClient.screenshot(),t=Buffer.from(e.base64,"base64"),n=TM.decode(t),o=new PNG({width:n.width,height:n.height});return o.data=Buffer.from(n.data),PNG.sync.write(o).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$1.Q5});}async stopScreenRecording(e){await this.limbarClient.stopRecording({localPath:e});}addSyslogListener(e){this.logStream||(this.logStream=this.limbarClient.streamSyslog());let t=n=>{$Re(n)||e(n);};return this.logStream.on("line",t),()=>{this.logStream?.off("line",t);}}async restartWda(e){await x3({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 VRe(r){let{apiClient:e,limbarClient:t,id:n,logger:o}=r;if(t)try{t.disconnect();}catch(i){o.warn({err:i,emulatorName:n},"Failed to disconnect limbar client during init cleanup");}try{await e.deleteIosEmulator(n);}catch(i){o.warn({err:i,emulatorName:n},"Failed to delete iOS emulator during init cleanup");}}var M3=12e4,nv=6,HRe=1e3;async function _3(r){let{limbarClient:e,url:t,md5:n,logger:o,emulatorName:i,assetLabel:a}=r,s;for(let l=1;l<=nv;l++)try{await q(e.installApp(t,{md5:n}),{milliseconds:M3,message:`Timed out after ${M3}ms installing ${a} on emulator ${i}`});return}catch(c){if(s=c,l===nv)break;let u=HRe*2**(l-1);o.warn({url:t,err:c,emulatorName:i,assetLabel:a,attempt:l,maxAttempts:nv,backoffMs:u},`Failed to install ${a} on Limbar emulator; retrying after backoff`),await te(u);}throw o.error({url:t,err:s,emulatorName:i,assetLabel:a,maxAttempts:nv},`Failed to install ${a} on Limbar emulator (no more retries)`),new w("UserConfigurationError",`Failed to install ${a} on emulator ${i}: ${s}`)}var jRe=v__default.array(v__default.object({bundle_id:v__default.string(),name:v__default.string()})),iv=class{constructor(e){this.udid=e;}async exec(e,t=[]){return new Promise((n,o)=>{execFile$1("idb",[...e,"--udid",this.udid,...t],(i,a)=>{i?o(i):n(a.trim());});})}async execBuffer(e,t=[]){return new Promise((n,o)=>{execFile$1("idb",[...e,"--udid",this.udid,...t],{encoding:"buffer",maxBuffer:10*1024*1024},(i,a)=>{i?o(i):n(a);});})}async describeDevice(){return this.exec(["describe"])}async tap({x:e,y:t}){await this.exec(["ui","tap"],[Math.round(e).toString(),Math.round(t).toString()]);}async elementTree(){return this.exec(["ui","describe-all"])}async listApps(){let e=await this.exec(["list-apps","--json"]),t=JSON.parse(e);return jRe.parse(t).map(n=>({bundleId:n.bundle_id,name:n.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"],["-"]),t=Buffer.from([137,80,78,71,13,10,26,10]);if(e.length<t.length||!e.subarray(0,t.length).equals(t))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 ag(r){try{return (await new Simctl().getDeviceTypes()).filter(n=>n.includes("iPhone"))}catch(e){return r.warn({err:e},"Got error listing local iPhone device types, returning empty list"),[]}}var av=class r{name;extraCapabilities;simctl;idb;constructor({name:e,simctl:t,idb:n}){this.name=e,this.simctl=t,this.idb=n,this.extraCapabilities={...rv,"appium:automationName":"XCUITest","appium:udid":t.udid??void 0};}static async init(e,t){let n=new Simctl,o=t.emulatorName??`momentic-${Date.now()}`,i=await ag(e);if(!i.includes(t.deviceType))throw new w("UserConfigurationError",`Invalid device type: ${t.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 n.createDevice(o,t.deviceType,"26.3");n.udid=s,a=async()=>{try{await n.shutdownDevice();}catch{}await n.deleteDevice();},await n.bootDevice(),await n.startBootMonitor({timeout:12e4}),t.appFilePath&&await n.installApp(t.appFilePath);let l=new iv(s);return new r({name:o,simctl:n,idb:l})}catch(s){throw await a?.(),s}}async tap(e,t){await this.idb.tap({x:e,y:t});}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 GRe=5e3;async function pm({creationOpts:r,apiClient:e,logger:t,driverLogLevel:n,orgId:o,sessionId:i,callbacks:a}){let s=Date.now();t.info("Starting ios driver creation");let{onLimbarConnectionStateChange:l,onStatusUpdate:c}=a,u=[],d=async()=>{let p=u.toReversed();for(let f of p)try{await q(f(),{milliseconds:GRe,fallback:()=>{}});}catch(h){if(zS(h))continue;t.warn({err:h},"Error running cleanup task");}};c("Starting iOS emulator creation...");let m;switch(r.type){case"remote":{m=await ig.init({apiClient:e,logger:t,creationOpts:r,orgId:o,sessionId:i,onStatusUpdate:c,onConnectionStateChange:l,logLevel:n});break}case"local":{m=await av.init(t,r);break}}u.push(async()=>{await m.close();});try{let p=await w3({logger:t,driverLogLevel:n,emulatorStart:s,emulator:m,apiClient:e,creationOpts:r,orgId:o,sessionId:i,callbacks:a});return u.push(()=>p.close()),p.executeInNativeContext(t,f=>f.getPageSource(),{operationName:"Warm up Appium cache"}).catch(()=>{}),{driver:p,emulator:m,limbarParams:m instanceof ig?{token:m.limbarToken,webRtcUrl:m.limbarWebRtcUrl,region:m.limbarRegion,osVersion:r.type==="remote"?r.osVersion:void 0}:void 0,cleanup:d}}catch(p){throw await d(),new Error(`Failed to start Appium driver: ${p}`,{cause:p})}}var KRe=100,XRe=2500,O3=4e3,YRe="...";async function sv({emulator:r,onLogs:e}){if(!r.addSyslogListener)return;let t=create({fetcher:async o=>{e(o);},resolver:()=>{},scheduler:windowedFiniteBatchScheduler({windowMs:XRe,maxBatchSize:KRe})}),n=o=>{let i=o.toString().trim();i.length!==0&&(i.length>O3&&(i=i.slice(0,O3)+YRe),t.fetch(i).catch(()=>{}));};return r.addSyslogListener(n)}var N3="NATIVE_APP";var ZRe=new Set(["id","processId","bundleId","type","accessible","index","x","y","width","height"]),QRe=new Set([]),exe=new Set(["name","label","traits"]),txe=new Set(["live-region","drawing-order"]),rxe=new Set(["visible","enabled"]);function L3(r){let e={},t=r.tagName,n=reduce(r.attributes,(o,i)=>(o[i.name]=i.value,o),{});for(let[o,i]of Object.entries(n))ZRe.has(o)||o==="class"&&t===i||o==="focusable"&&i==="true"&&n.clickable==="true"||QRe.has(o)&&i==="false"||exe.has(o)&&i===""||rxe.has(o)&&i==="true"||txe.has(o)&&i==="0"||(e[o]=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 za(r){let e=r.getAttribute("x"),t=r.getAttribute("y"),n=r.getAttribute("width"),o=r.getAttribute("height");if(e===null||t===null||n===null||o===null)return;let i=parseFloat(e),a=parseFloat(t),s=parseFloat(n),l=parseFloat(o);if(!(isNaN(i)||isNaN(a)||isNaN(s)||isNaN(l)))return {x1:i,y1:a,x2:i+s,y2:a+l}}function wI(r,e){let{x1:t,y1:n,x2:o,y2:i}=e;r.setAttribute("bounds",`[${t},${n},${o},${i}]`);}function nxe(r){let e=r.match(/\[([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\]/);if(!e)return;let t=parseFloat(e[1]),n=parseFloat(e[2]),o=parseFloat(e[3]),i=parseFloat(e[4]);if(!(isNaN(t)||isNaN(n)||isNaN(o)||isNaN(i)||o<t||i<n))return {x1:t,y1:n,x2:o,y2:i}}function lv(r){let e=r.getAttribute("bounds");if(e)return nxe(e)}function D3(r,e){if(!e)return !0;let t=za(r);return t?AI(t,e):!0}function AI(r,e){if(!e)return !0;let{x1:t,y1:n,x2:o,y2:i}=r;return !(o<e.left||t>e.right||i<e.top||n>e.bottom)}function cv(r){let e=r.cloneNode(!0);for(let t of Array.from(e.children)){let n=t;for(let o of Array.from(n.children))n.removeChild(o);}return e.outerHTML}var k3=new Set(["XCUIElementTypeWebView"]);function lxe(r){if(k3.has(r.tagName))return !0;let e=r.getAttribute("name");if(e&&(e.startsWith("TabDocument")||e.startsWith("BrowserView"))){let t=e.match(/UUID=([A-F0-9-]+)/),n=e.match(/WebViewProcessID=(\d+)/);if(t&&n)return !0}return !1}function cxe(r){return r.startsWith("XCUIElementType")?r.substring(15):r}function F3({state:r,originalElement:e,prunedElement:t,isInWebview:n,idInWebview:o}){let{idCounter:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l}=r,c=i.value++;t.setAttribute("id",String(c)),a.set(c,t),n?l.set(c,o):s.set(c,e);}function U3(r){if(!k3.has(r.tagName)&&r.tagName==="XCUIElementTypeOther"&&r.hasAttribute("name")&&r.hasAttribute("label"))return r;for(let e of Array.from(r.children)){let t=U3(e);if(t)return t}}function uxe({webviewNativeRootBounds:r,webviewDocumentRootBounds:e}){let t=r.x1-e.x,n=r.y1-e.y;if(!Number.isFinite(t)||!Number.isFinite(n))return r;let o=r.x2-r.x1,i=r.y2-r.y1;return {x1:t,y1:n,x2:t+o,y2:n+i}}function B3(r,e,t,n){let{document:o}=t,{parentFrameBounds:i,pruneElementsOutsideBounds:a}=n;if(e.type==="element"){let s=o.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 l=e.boundingRect,c={x1:i.x1+l.x,y1:i.y1+l.y,x2:i.x1+l.x+l.width,y2:i.y1+l.y+l.height};if(!AI(c,a))return;wI(s,c),F3({state:t,prunedElement:s,isInWebview:!0,idInWebview:e.momenticWebviewElementId}),r.appendChild(s);for(let u of e.children)B3(s,u,t,n);}else if(e.type==="text"){let s=o.createElement("text");r.appendChild(s);let l=o.createTextNode(e.text);s.appendChild(l);}}function z3(r,e,t,n){let{pruneElementsOutsideBounds:o}=n,{document:i}=t;F3({state:t,originalElement:r,prunedElement:e,isInWebview:!1});let a=L3(r);for(let[c,u]of Object.entries(a))e.setAttribute(c,u);let s=za(r);if(s&&wI(e,s),lxe(r)){let{removeWebviewContent:c,injectedWebviewContent:u}=n;if(c)return;if(u&&za(r)){let m=U3(r),p=m?za(m):void 0;if(m&&p){t.webviewRootElement=m,t.webviewRootBounds=p,B3(e,u.root,t,{parentFrameBounds:uxe({webviewNativeRootBounds:p,webviewDocumentRootBounds:u.rootBoundingBox}),pruneElementsOutsideBounds:o});return}}}let l=Array.from(r.childNodes??[]);for(let c of l){let u=c.nodeType;if(u===3){let d=c.nodeValue;d&&d.trim().length>0&&e.appendChild(i.createTextNode(d));continue}if(u===1){let d=c;if(!D3(d,o))continue;let m=i.createElement(cxe(d.tagName));z3(d,m,t,n),e.appendChild(m);}}}async function RI(r,e,t){let n=r.parseFromString("<AppiumAUT/>","text/xml"),o=new Map,i=new Map,a=new Map,s={document:n,idToPrunedElement:o,idToOriginalElement:i,idToIdInWebview:a,idCounter:{value:0},webviewRootElement:void 0,webviewRootBounds:void 0},l=n.documentElement;z3(e,l,s,t);let c=new XMLSerializer().serializeToString(n),u=await zAe.format(c,{parser:"xml",plugins:[BAe],printWidth:120,tabWidth:1,singleAttributePerLine:!1});return {prunedDocument:n,idToPrunedElement:o,idToOriginalElement:i,idToIdInWebview:a,webviewRootElement:s.webviewRootElement,webviewRootBounds:s.webviewRootBounds,prunedXml:u}}async function $3(r,e){let t=new DOMParser,n=t.parseFromString(r,"text/xml"),o=n.documentElement;if(!o)throw new Error("No root element found in XML");if(o.tagName!=="AppiumAUT")throw new Error("No AppiumAUT element found in XML");let{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l,webviewRootElement:c,webviewRootBounds:u}=await RI(t,o,e);return {xml:i,idToPrunedElement:a,idToOriginalElement:s,idToIdInWebview:l,webviewRootElement:c,webviewRootBounds:u,originalDocument:n}}var V3=(ce=>(ce.GenericElement="GenericElement",ce.Any="Any",ce.Other="Other",ce.Application="Application",ce.Group="Group",ce.Window="Window",ce.Sheet="Sheet",ce.Drawer="Drawer",ce.Alert="Alert",ce.Dialog="Dialog",ce.Button="Button",ce.RadioButton="RadioButton",ce.RadioGroup="RadioGroup",ce.CheckBox="CheckBox",ce.DisclosureTriangle="DisclosureTriangle",ce.PopUpButton="PopUpButton",ce.ComboBox="ComboBox",ce.MenuButton="MenuButton",ce.ToolbarButton="ToolbarButton",ce.Popover="Popover",ce.Keyboard="Keyboard",ce.Key="Key",ce.NavigationBar="NavigationBar",ce.TabBar="TabBar",ce.TabGroup="TabGroup",ce.Toolbar="Toolbar",ce.StatusBar="StatusBar",ce.Table="Table",ce.TableRow="TableRow",ce.TableColumn="TableColumn",ce.Outline="Outline",ce.OutlineRow="OutlineRow",ce.Browser="Browser",ce.CollectionView="CollectionView",ce.Slider="Slider",ce.PageIndicator="PageIndicator",ce.ProgressIndicator="ProgressIndicator",ce.ActivityIndicator="ActivityIndicator",ce.SegmentedControl="SegmentedControl",ce.Picker="Picker",ce.PickerWheel="PickerWheel",ce.Switch="Switch",ce.Toggle="Toggle",ce.Link="Link",ce.Image="Image",ce.Icon="Icon",ce.SearchField="SearchField",ce.ScrollView="ScrollView",ce.ScrollBar="ScrollBar",ce.StaticText="StaticText",ce.TextField="TextField",ce.SecureTextField="SecureTextField",ce.DatePicker="DatePicker",ce.TextView="TextView",ce.Menu="Menu",ce.MenuItem="MenuItem",ce.MenuBar="MenuBar",ce.MenuBarItem="MenuBarItem",ce.Map="Map",ce.WebView="WebView",ce.IncrementArrow="IncrementArrow",ce.DecrementArrow="DecrementArrow",ce.Heading="Heading",ce.Cell="Cell",ce))(V3||{}),H3=v__default.lazy(()=>v__default.object({AXFrame:v__default.string(),AXUniqueId:v__default.string().nullable(),AXLabel:v__default.string().nullable(),AXValue:v__default.string().nullable(),frame:v__default.object({x:v__default.number(),y:v__default.number(),width:v__default.number(),height:v__default.number()}),role:v__default.string(),role_description:v__default.string(),subrole:v__default.string().nullable(),type:v__default.nativeEnum(V3),title:v__default.string().nullable(),help:v__default.string().nullable(),content_required:v__default.boolean(),custom_actions:v__default.array(v__default.string()),enabled:v__default.boolean(),children:v__default.array(H3).default([])}));function mxe(r){return v__default.array(H3).parse(JSON.parse(r))}async function uv(r,e){let t=new DOMParser,n=mxe(r),o=pxe(t,n),{prunedXml:i,idToPrunedElement:a,idToOriginalElement:s}=await RI(t,o.documentElement,{removeWebviewContent:!1,injectedWebviewContent:void 0,pruneElementsOutsideBounds:e.pruneElementsOutsideBounds});return {xml:i,idToPrunedElement:a,idToOriginalElement:s,originalDocument:o,webviewRootElement:void 0,idToIdInWebview:new Map,webviewRootBounds:void 0}}function pxe(r,e){let t=r.parseFromString("<hierarchy/>","text/xml"),n=t.documentElement;for(let o=0;o<e.length;o++){let i=e[o],a=j3(i,t);n.appendChild(a);}return t}function j3(r,e){let t=r.type,n=e.createElement(t);if(n.setAttribute("type",t),n.setAttribute("x",String(r.frame.x.toFixed(2))),n.setAttribute("y",String(r.frame.y.toFixed(2))),n.setAttribute("width",String(r.frame.width.toFixed(2))),n.setAttribute("height",String(r.frame.height.toFixed(2))),r.AXLabel!==null&&n.setAttribute("label",r.AXLabel),r.AXValue!==null&&n.setAttribute("value",r.AXValue),r.title!==null&&n.setAttribute("title",r.title),r.help!==null&&n.setAttribute("help",r.help),n.setAttribute("enabled",String(r.enabled)),r.children)for(let o=0;o<r.children.length;o++){let i=r.children[o],a=j3(i,e);n.appendChild(a);}return n}function xc(r){let e=[],t=r;for(;t;){let n=t.parentElement;if(!n||n.tagName==="AppiumAUT"){e.unshift(`${t.tagName}[1]`);break}let o=t.tagName,i=Array.from(n.children).filter(s=>s.tagName===o),a=1;for(let s=0;s<i.length;s++)if(i[s]===t){a=s+1;break}e.unshift(`${o}[${a}]`),t=n;}return `/${e.join("/")}`}var dv=class r{driver;emulator;options;aborter;constructor({driver:e,emulator:t,aborter:n,options:o}){this.driver=e,this.emulator=t,this.aborter=n,this.options=o;}static async init({driver:e,emulator:t,aborter:n,options:o}){return new r({driver:e,aborter:n,emulator:t,options:o})}async getContexts(e){let t=await this.driver.executeInNativeContext(e,async o=>await o.getContexts({}),{operationName:"getContexts"}),n=t.filter(o=>o!==N3);return {contexts:t.map(o=>o),webviews:n}}async getRawScreenshotBase64({logger:e,totalAttempts:t=3,signal:n}){let o=re(),i=n??this.aborter.controller?.signal;return await o.startAsyncSpan("EMULATOR_READ_STATE",async()=>await Ed(e,()=>this.emulator.screenshotPngBase64(),{maxAttempts:t,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:t,signal:n,reason:o,tolerancePercent:i=1}){await re().startAsyncSpan("WAIT_FOR_SCREENSHOT_STABILITY",async a=>{a.attributes.reason=o;let s=Uu({signal:n,timeoutMs:t}),l,c=!1;for(;!s.aborted;){let u=Date.now();if(l)try{let m=await this.getRawScreenshotBase64({logger:e,totalAttempts:1,signal:s});if(Ds(l,m)<=i){c=!0;break}l=m;}catch(m){e.warn({err:m},"Failed to get screenshot during stability wait");}else try{l=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 Li(Math.min(1e4,d),s);}c||(a.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for screenshot stability"));});}async waitForPageSourceStability({logger:e,timeoutMs:t,signal:n,reason:o}){await re().startAsyncSpan("WAIT_FOR_PAGE_STABILITY",async i=>{i.attributes.reason=o;let a=Uu({signal:n,timeoutMs:t}),s,l=!1;for(;!a.aborted;){let c,u=Date.now();try{c=await q(this.emulator.nativeA11yTreeJson(),{milliseconds:1e4,signal:a,message:"Getting the native accessibility tree timed out after 10s"});let m=createHash("md5").update(c).digest("hex");if(s&&s===m){l=!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 Li(Math.min(1e4,d),a);}l||(i.attributes.timedOut=!0,e.warn({purpose:o},"Timed out waiting for page source stability"));});}async getActiveWebview(e){let n=(await this.getContexts(e)).webviews;if(n.length>1)throw new w("UserInfrastructureError","Multiple active webviews in a single package is currently not supported");return n[0]}async getActiveWebviewContent(e){let t=await this.getActiveWebview(e);if(!t)return;this.throwIfAborted();let n=await this.driver.executeWebViewScript(e,t,o=>o.dumpA11yTree());return {context:t,...n}}async getDomState(e,t){let o=t?.filterOffscreenElements??!0?await this.getViewportBounds(e):void 0,i;if(!t?.skipFetchingFullWebviewContent)try{i=await this.getActiveWebviewContent(e);}catch(l){e.error({err:l},"Could not get webview info to get the nested DOM state");}if(this.throwIfAborted(),!i&&this.options?.disableMomenticAccessibilityTree){let l=await this.getNativePageSource();this.throwIfAborted();let c=await uv(l,{pruneElementsOutsideBounds:o});return {sourceTree:"native",graph:c,webviewContent:void 0}}let a=await this.getAppiumPageSource(e);return this.throwIfAborted(),{graph:await $3(a,{injectedWebviewContent:i,removeWebviewContent:t?.removeWebviewContent,pruneElementsOutsideBounds:o}),sourceTree:"appium",webviewContent:i}}async getNativePageSource(){return await re().startAsyncSpan("EMULATOR_READ_STATE",async()=>this.emulator.nativeA11yTreeJson(),{name:"Get iOS page source",signal:this.aborter.controller?.signal,timeoutMs:3e4})}async getAppiumPageSource(e,t){let n=t??this.aborter.controller?.signal;return await re().startAsyncSpan("EMULATOR_READ_STATE",()=>this.driver.executeInNativeContext(e,i=>i.getPageSource(),{signal:n,operationName:"getPageSource"}),{name:"Get page source",signal:n,timeoutMs:3e4})}async getViewportBounds(e){let t=await this.driver.executeInNativeContext(e,async n=>n.getWindowRect(),{operationName:"getViewportBounds"});return {left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height}}throwIfAborted(){this.aborter.controller?.signal.throwIfAborted();}};async function W3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,throwIfAborted:a,abortSignal:s}){let l=re(),c=15,u=r.timeoutSecs?r.timeoutSecs*1e3:5e3,d=XS(u),m=Date.now(),p=0,f,h=!1,g;for(;p<c&&!h;){a(),h||f&&f-m>=u&&(h=!0),p!==0&&await te(d,s),f=Date.now();try{let y="",S="";await l.startAsyncSpan("EMULATOR_READ_STATE",async()=>{y=await o(),S=await i();},{name:"Get emulator state"});let b=await t.evaluateIosAssertion({assertion:r.assertion,screenXml:y,screenshot:S},{logger:e,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["ios-assertion"]});if(b.result)return {success:b.result,message:b.thoughts};{let C=`AssertionFailureError: ${b.thoughts}`;g=new Error(C);}}catch(y){a(),e.info({err:y},`AI check assert attempt ${p} failed, retrying...`),g=y instanceof Error?y:new Error(`${y}`);}finally{p++;}}return {success:!1,message:g?.message}}async function q3({command:r,logger:e,generator:t,aiSettings:n,getEmulatorDomState:o,getScreenshotBase64:i,abortSignal:a}){if(!r.goal.trim())throw new w("ActionFailureError","Cannot perform AI extraction without goal");if(r.schema){let u=Lu(r.schema);if(u)throw new w("UserConfigurationError",u)}let s=re(),l="",c="";return await s.startAsyncSpan("EMULATOR_READ_STATE",async()=>{l=await o(),c=await i();},{name:"Get emulator state"}),await s.startAsyncSpan("AI_EXTRACTION_CALL",async u=>{try{let d=await t.getIosTextExtraction({goal:r.goal,emulatorState:l,returnSchema:r.schema,screenshot:`data:image/png;base64,${c}`},{disableCache:!!r.disableCache,abortSignal:a,loggerTags:we(e),agentConfigVersion:n.agentConfig?.["ios-text-extraction"]});if(u.result=d,Ob({tracer:s,span:u,screenshot:c,emulatorState:l,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 w("UserConfigurationError",d.thoughts);return {success:!0,output:d.result,message:d.thoughts}}catch(d){let m=ne(d);throw m.includes("MaxGenerationLengthExceededError")?new w("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 w("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 ea="element-6066-11e4-a52e-4f735466cecf";function ta(r,e){return Math.abs(r-e)<1}function fm(r,e){let t=e.x2-e.x1,n=(e.x1+e.x2)/2,o=(r.x1+r.x2)/2;if(!ji(e.tolerance,n,o,Math.min(1,t)))return !1;let i=e.y2-e.y1,a=(e.y1+e.y2)/2,s=(r.y1+r.y2)/2;return ji(e.tolerance,a,s,Math.min(1,i))}function hm(r,e){let t=r.x2-r.x1,n=r.y2-r.y1;return ji(e.tolerance,e.width,t,Math.min(1,e.width))?ji(e.tolerance,e.height,n,Math.min(1,e.height)):!1}function gm(r){return r.type==="WEBVIEW",r.cache}function ym(r){let{command:e,cacheKey:t="cache",targetName:n="target",updatedCache:o}=r;Ow(e)&&(e[t]={...e[t],[n]:au.parse(o)},r.updatedWithAI&&(e[t].updatedAt=new Date,e[t].updatedAtLoggerTags=we(r.logger)));}var sg="name";async function K3(r,e,t){return await e.executeInNativeContext(r,n=>n.isElementDisplayed(t),{operationName:"isElementRendered"})}async function Sm(r,e,t,n){return await e.executeInNativeContext(r,o=>o.getElementAttribute(t,n),{operationName:"getAttributeFromIosElement"})}async function xI(r,e,t){return await e.executeInNativeContext(r,async n=>{try{let o=await n.findElement("xpath",t);if(!o)return null;let i=o[ea];if(!i)return null;let a=await n.getElementRect(i);return {elementId:i,rect:a}}catch{return null}},{operationName:"findElementByXPath"})}async function X3(r,e,t){let n=xc(t),o=await xI(r,e,n);if(o)return {xPath:n,...o}}async function MI({logger:r,emulatorState:e,driver:t,idInWebview:n,requirements:o}){let i=e.graph.webviewRootElement?xc(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 gxe({logger:r,driver:t,webviewRootBounds:e.graph.webviewRootBounds,nodeIdInWebview:n,aiGeneratedRequirements:o,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 gxe({logger:r,driver:e,webviewRootBounds:t,nodeIdInWebview:n,aiGeneratedRequirements:o,webviewContent:i}){let a=await e.executeWebViewScript(r,i.context,(l,c,u,d)=>l.generateCacheFromWebviewElementId(c,u,d),i.generatedAt,n,{attributesToFetch:o?.attributesRequired??[]});if(!a)return;let s={x:t.x1-i.rootBoundingBox.x+a.boundingBox.x,y:t.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:o?.textRequired?a.textContent:void 0,attributes:a.attributes,boundingBox:o?.boundsRequired?s:void 0,shape:o?.shapeSpecificity?{tolerance:o.shapeSpecificity,width:a.boundingBox.width,height:a.boundingBox.height}:void 0,position:o?.positionSpecificity?{tolerance:o.positionSpecificity,x1:s.x,y1:s.y,x2:s.x+s.width,y2:s.y+s.height}:void 0}}}async function yxe(r,e,t,n){if(!n||!n.length)return;let o={};for(let i of n){let a=await Sm(r,e,t,i);a!==null&&(o[i]=a);}return Object.keys(o).length?o:void 0}async function Y3({logger:r,driver:e,node:t,requirements:n}){let o=await X3(r,e,t);if(!o){r.warn("Failed to generate valid xPath selector for element");return}let{xPath:i,rect:a,elementId:s}=o,l={x1:a.x,y1:a.y,x2:a.x+a.width,y2:a.y+a.height};return {xPath:i,bounds:[l.x1,l.y1,l.x2,l.y2],requirements:{requiredText:n?.textRequired?await Sm(r,e,s,sg)??void 0:void 0,requiredAttributes:await yxe(r,e,s,n?.attributesRequired?.filter(c=>!(n.textRequired&&c===sg))),requiredBounds:n?.boundsRequired,position:n?.positionSpecificity?{x1:l.x1,y1:l.y1,x2:l.x2,y2:l.y2,tolerance:n?.positionSpecificity}:void 0,shape:n?.shapeSpecificity?{width:l.x2-l.x1,height:l.y2-l.y1,tolerance:n?.shapeSpecificity}:void 0}}}async function J3({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o}){let i=o.graph.idToPrunedElement.get(t.id);if(!i)throw new Error(`Could not find node with id: ${t.id}`);let a=lv(i);if(!a)throw new Error(`Could not determine bounds for element with id: ${t.id}, description: ${n}`);let s=[];for(let{id:d,requirements:m}of t.additionalElements??[]){let p=o.graph.idToIdInWebview.get(d);if(p!==void 0){try{let g=await MI({logger:r,driver:e,emulatorState:o,idInWebview:p,requirements:m});s.push(g);}catch(g){r.warn({err:g},`Failed to build webview cache for related element with id: ${d}`);}continue}let f=o.graph.idToOriginalElement.get(d);if(!f){r.warn(`Could not find original element for additional element with id: ${d}`);continue}let h=await Y3({logger:r,driver:e,node:f,requirements:m});h&&s.push(h);}let l=o.graph.idToIdInWebview.get(t.id);if(l!==void 0){let d={type:"WEBVIEW",bounds:a,cache:{type:"WEBVIEW"}};try{let m=await MI({logger:r,driver:e,emulatorState:o,idInWebview:l,requirements:t.requirements});return {...d,cache:{type:"WEBVIEW",resolvedDescription:n,requiredRelatedElements:s,...m}}}catch(m){return r.warn({err:m},"Failed to build webview target cache"),d}}let c=o.graph.idToOriginalElement.get(t.id);if(!c)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${t.id}, description: ${n}`);let u=await Y3({logger:r,driver:e,node:c,requirements:t.requirements});return u?{type:"NATIVE",bounds:a,cache:{type:"NATIVE",...u,resolvedDescription:n,sourceTree:"appium",requiredRelatedElements:s,elementOnlySerializedXml:cv(c)}}:(r.warn("Failed to generate valid cache for element"),{type:"NATIVE",cache:{type:"NATIVE"},bounds:a})}async function _I({logger:r,driver:e,stateManager:t,parentWebviewBounds:n,cache:o}){if(!o||!o.generatedSelectors)throw new Ee("Cache is missing required attributes");let i=await t.getActiveWebview(r);if(!i)throw new Ee("No active webview context found");let a=await e.executeWebViewScript(r,i,(u,d)=>u.resolveWebviewTargetCache(d),{selectors:o.generatedSelectors,attributesToFetch:Object.keys(o.requirements?.attributes??{})});if(!a)throw new Ee("Failed to resolve webview target using cache");let s=n.x1-a.rootBoundingBox.x+a.boundingBox.x,l=n.y1-a.rootBoundingBox.y+a.boundingBox.y,c={x1:s,y1:l,x2:s+a.boundingBox.width,y2:l+a.boundingBox.height};return o.requirements&&Sxe(r,c,a,o.requirements),c}function Sxe(r,e,t,n){if(!n)return;let{attributes:o,text:i,position:a,shape:s}=n;if(i!==void 0&&i.length>0&&t.textContent!==i)throw new Ee(`Text content mismatch: expected "${i}", got "${t.textContent}"`);if(o)for(let[l,c]of Object.entries(o)){let u=t.attributes[l];if(u!==c)throw new Ee(`Attribute ${l} mismatch: expected "${c}", got "${u}"`)}if(a&&!fm(e,a))throw new Ee(`Position mismatch: expected ${JSON.stringify(a)}, got ${JSON.stringify(e)}`);if(s&&!hm(e,s))throw new Ee(`Shape mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(e)}`)}async function Z3(r,e,t,n,o){if(!n)return;let{requiredAttributes:i,requiredText:a,requiredBounds:s,position:l,shape:c}=n;if(a!==void 0&&a.length>0){let u=await Sm(r,e,t,sg);if(u!==a)throw new Ee(`Resolved element text mismatch: expected ${a}, got ${u}`)}if(i)for(let[u,d]of Object.entries(i)){let m=await Sm(r,e,t,u)??void 0;if(m!==d)throw new Ee(`Attribute ${u} mismatch: expected ${d}, got ${m}`)}if(s&&o){let{originalBounds:u,newBounds:d}=o;if(!u)throw new Ee("Cannot validate bounds requirements without original bounds in cache");if(!(ta(u.x1,d.x1)&&ta(u.y1,d.y1)&&ta(u.x2,d.x2)&&ta(u.y2,d.y2))){let p=f=>`[${f.x1},${f.y1},${f.x2},${f.y2}]`;throw new Ee(`Bounds changed from ${p(u)} to ${p(d)}`)}}if(l&&o&&!fm(o.newBounds,l))throw new Ee(`Position mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(o.newBounds)}`);if(c&&o&&!hm(o.newBounds,c))throw new Ee(`Shape mismatch: expected ${JSON.stringify(c)}, got ${JSON.stringify(o.newBounds)}`)}async function Q3({logger:r,driver:e,xPath:t,elementType:n,skipVisibilityCheck:o=!1}){let i=await xI(r,e,t);if(!i)throw new Ee(`Could not resolve ${n} via XPath: ${t}`);let{elementId:a}=i;if(!o&&!await K3(r,e,a))throw new Ee(`${n} resolved via XPath is not rendered: ${t}`);return i}async function eY({target:r,driver:e,stateManager:t,logger:n}){if(!r.xPath)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);if(r.requiredRelatedElements){let s=r.requiredRelatedElements;for(let l of s){let{elementId:c,rect:u}=await Q3({logger:n,driver:e,xPath:l.xPath,elementType:"related element",skipVisibilityCheck:!!l.browserCache});if(l.browserCache){let d={x1:u.x,y1:u.y,x2:u.x+u.width,y2:u.y+u.height};await _I({logger:n,driver:e,stateManager:t,parentWebviewBounds:d,cache:l.browserCache});}else await Z3(n,e,c,l.requirements);}}let{elementId:o,rect:i}=await Q3({logger:n,driver:e,xPath:r.xPath,elementType:"element",skipVisibilityCheck:r.type==="WEBVIEW"}),a={x1:i.x,y1:i.y,x2:i.x+i.width,y2:i.y+i.height};if(r.type==="WEBVIEW"){let s=await _I({logger:n,driver:e,stateManager:t,parentWebviewBounds:a,cache:r.browserCache});return {type:"WEBVIEW",bounds:s,cache:r}}return await Z3(n,e,o,r.requirements,{originalBounds:r.bounds?{x1:r.bounds[0],y1:r.bounds[1],x2:r.bounds[2],y2:r.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...r,bounds:[a.x1,a.y1,a.x2,a.y2]}}}function rY({aiResponse:r,description:e,emulatorState:t}){let n=t.graph.idToPrunedElement.get(r.id);if(!n)throw new Error(`Could not find node with id: ${r.id}`);let o=lv(n);if(!o)throw new Error(`Could not determine bounds for element with id: ${r.id}, description: ${e}`);let i=t.graph.idToOriginalElement.get(r.id);if(!i)throw new Error(`Node isn't in a webview but couldn't find original node for id: ${r.id}, description: ${e}`);let a=xc(i),s=cv(i),l=tY({requirements:r.requirements,element:i}),c=(r.additionalElements??[]).map(({id:u,requirements:d})=>{let m=t.graph.idToOriginalElement.get(u);return m?{xPath:xc(m),requirements:tY({requirements:d,element:m})}:void 0}).filter(u=>!!u);return {type:"NATIVE",bounds:o,cache:{type:"NATIVE",bounds:[o.x1,o.y1,o.x2,o.y2],resolvedDescription:e,sourceTree:t.sourceTree,xPath:a,elementOnlySerializedXml:s,requirements:l,requiredRelatedElements:c}}}function tY({requirements:r,element:e}){let t;if((r?.positionSpecificity||r?.shapeSpecificity)&&(t=za(e),!t))throw new w("ActionFailureError","Element to cache has no bounds or unexpected bounds format");return {requiredText:r?.textRequired?e.textContent??void 0:void 0,requiredAttributes:bxe(e,r?.attributesRequired),requiredBounds:r?.boundsRequired,position:r?.positionSpecificity?{x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2,tolerance:r?.positionSpecificity}:void 0,shape:r?.shapeSpecificity?{width:t.x2-t.x1,height:t.y2-t.y1,tolerance:r?.shapeSpecificity}:void 0}}function bxe(r,e){if(r&&!(!e||e.length===0))return Object.fromEntries(e.map(t=>[t,r.getAttribute(t)]).filter(([,t])=>t!==null))}async function oY(r,e,t,n){if(!t)return;let{requiredAttributes:o,requiredText:i,requiredBounds:a,position:s,shape:l}=t;if(i!==void 0&&i.length>0){let c=e.textContent;if(c!==i)throw new Ee(`Resolved element text mismatch: expected ${i}, got ${c}`)}if(o)for(let[c,u]of Object.entries(o)){let d=e.getAttribute(c)??void 0;if(d!==u)throw new Ee(`Attribute ${c} mismatch: expected ${u}, got ${d}`)}if(a&&n){let{originalBounds:c,newBounds:u}=n;if(!c)throw new Ee("Cannot validate bounds requirements without original bounds in cache");if(!(ta(c.x1,u.x1)&&ta(c.y1,u.y1)&&ta(c.x2,u.x2)&&ta(c.y2,u.y2))){let m=p=>`[${p.x1},${p.y1},${p.x2},${p.y2}]`;throw new Ee(`Bounds changed from ${m(c)} to ${m(u)}`)}}if(s&&n&&!fm(n.newBounds,s))throw new Ee(`Position mismatch: expected ${JSON.stringify(s)}, got ${JSON.stringify(n.newBounds)}`);if(l&&n&&!hm(n.newBounds,l))throw new Ee(`Shape mismatch: expected ${JSON.stringify(l)}, got ${JSON.stringify(n.newBounds)}`)}async function iY({target:r,logger:e,emulator:t}){if(!r.xPath)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);let n=await t.nativeA11yTreeJson(),o=await uv(n,{pruneElementsOutsideBounds:void 0});if(r.requiredRelatedElements){let s=r.requiredRelatedElements;for(let l of s){let c=QX.evaluateXPathToFirstNode(l.xPath,o.originalDocument);if(!c)throw new Ee(`Required related element not found for XPath: ${l.xPath}`);await oY(e,c,l.requirements);}}let i=QX.evaluateXPathToFirstNode(r.xPath,o.originalDocument);if(!i)throw new Ee(`Could not resolve cached target via XPath: ${r.xPath}`);let a=za(i);if(!a)throw new Ee(`Could not determine bounds for cached target via XPath: ${r.xPath}`);return await oY(e,i,r.requirements,{originalBounds:r.bounds?{x1:r.bounds[0],y1:r.bounds[1],x2:r.bounds[2],y2:r.bounds[3]}:void 0,newBounds:a}),{type:"NATIVE",bounds:a,cache:{...r,bounds:[a.x1,a.y1,a.x2,a.y2]}}}async function aY({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o}){switch(o.sourceTree){case"appium":return await J3({logger:r,driver:e,aiResponse:t,description:n,emulatorState:o});case"native":return await rY({aiResponse:t,description:n,emulatorState:o});default:{let i=o.sourceTree;throw new Error(`Unsupported source tree type for building iOS target cache: ${i}`)}}}async function sY({target:r,driver:e,stateManager:t,logger:n,emulator:o}){if(r.type==="WEBVIEW"||!r.sourceTree||r.sourceTree=="appium")return await eY({target:r,driver:e,stateManager:t,logger:n});switch(r.sourceTree){case"native":return await iY({target:r,logger:n,emulator:o});default:{let i=r.sourceTree;throw new Error(`Unsupported source tree type for resolving iOS target cache: ${i}`)}}}var hr=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:t,description:n,skipFetchingFullWebviewContent:o=!1,removeWebviewContent:i=!1,filterOffscreenElements:a=!0,useMemory:s=!1,metadata:l,cacheBustReason:c}){let u=e.child({...l});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 t.startAsyncSection("Get emulator state",async()=>{let h=await this.stateManager.getCurrentScreenshotPngString(e);return {emulatorState:await this.stateManager.getDomState(e,{skipFetchingFullWebviewContent:o,removeWebviewContent:i,filterOffscreenElements:a}),screenshot:h}}),p;try{p=await t.startAsyncSpan("AI_LOCATOR_CALL",async h=>{c&&(h.attributes.cacheBustReason=c);let g=await this.generator.getIosElementLocation({description:n,screenXml:d.graph.xml,screenshot:m,source:l?.source==="SCROLL_TO"?"SCROLL_TO":void 0},{logger:u,loggerTags:we(u),abortSignal:this.aborter.controller?.signal,useMemory:s,agentConfigVersion:this.aiSettings.agentConfig?.["ios-locator"]});return h.result=g,g});}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 w("NoMatchingElementError",p.thoughts??"No matching element found");let f=await aY({logger:e,driver:this.driver,aiResponse:p,description:n,emulatorState:d});return t.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:t,action:n,command:o,description:i,cacheKey:a,targetName:s,skipFetchingFullWebviewContent:l,removeWebviewContent:c,metadata:u,logger:d,cacheBustReason:m}=e,p=await this.findElement({logger:d,tracer:t,description:i,skipFetchingFullWebviewContent:l,removeWebviewContent:c,metadata:u,cacheBustReason:m}),f=p.thoughts,h=await n(p.resolvedTarget);return ym({command:o,cacheKey:a,targetName:s,updatedCache:gm(p.resolvedTarget),updatedWithAI:!0,logger:d}),{result:h,thoughts:f}}async targetingActionWithCache({logger:e,tracer:t,action:n,command:o,cacheKey:i,targetName:a,cacheCopyForAttempt:s}){this.emulatorSettings?.waitForStability!==!1&&await this.stateManager.waitForPageSourceStability({logger:e,timeoutMs:5e3,signal:this.aborter.controller?.signal,reason:"Waiting for stability before cache resolution"});let l=await this.resolveTargetCacheWithTracing({logger:e,tracer:t,cache:s}),c=await n(l);return ym({command:o,cacheKey:i,targetName:a,updatedCache:gm(l),updatedWithAI:!1,logger:e}),{result:c,thoughts:"Successfully executed preset action with cache"}}async resolveTargetCacheWithTracing({logger:e,tracer:t,cache:n,retryWithinSmartWaiting:o=!0}){let{resolvedTarget:i}=await t.startAsyncSpan("CACHE_RESOLUTION",async a=>{let s=Date.now(),l;for(;!o||Date.now()-s<3e3;)try{let c=await sY({target:n,driver:this.driver,stateManager:this.stateManager,logger:e,emulator:this.emulator});return a.attributes.serializedElement=(c.type==="NATIVE"?c.cache.elementOnlySerializedXml:void 0)??"Unknown element",{resolvedTarget:c}}catch(c){if(l=c,c instanceof Ee){if(!o)throw c;e.warn({err:c},"Failed to resolve target cache, retrying"),await Li(500,this.aborter.controller?.signal);continue}throw e.error({err:c},"Failed to resolve target cache"),c}throw l});return i}async wrapTargetingAction(e){let{tracer:t,logger:n,action:o,description:i,command:a,cacheKey:s="cache",targetName:l="target",cacheIsInvalidAfterResolution:c,skipFetchingFullWebviewContent:u=!1,removeWebviewContent:d=!1}=e,m={commandId:a.id},p=!1,f,h;if(s==="cache"&&"cache"in a&&a.cache){let g=a.cache;l==="target"&&"target"in g?h=cloneDeep(g.target):l==="fromTarget"&&"fromTarget"in g?h=cloneDeep(g.fromTarget):l==="toTarget"&&"toTarget"in g&&(h=cloneDeep(g.toTarget));}if(a.disableCache&&(n.debug({command:a},"Cache explicitly disabled for command"),p=!0,f="Cache explicitly disabled",h=void 0),c&&(p=!0,f=f??"Cache invalidated after resolution",h=void 0),h&&!js(h.resolvedDescription??"",i)&&(n.info({description:i,cacheDescription:h.resolvedDescription},"Cache description mismatch, clearing it automatically"),p=!0,f="Description mismatch",h=void 0),h){let g=h.type==="NATIVE"?!!h.requirements:!!h.browserCache?.requirements;try{let y=await this.targetingActionWithCache({logger:n,tracer:t,action:o,command:a,cacheKey:s,targetName:l,cacheCopyForAttempt:h});return Et.increment("cache_target_resolution_v2",1,["outcome:hit","platform:mobile-native",`hasRequirements:${g}`,`orgId:${this.orgId}`,"cliVersion:0.88.2"]),y}catch(y){if(this.throwIfAborted(),y instanceof w&&y.reason!=="InternalWebAgentError")throw n.error({err:y},"Failed to execute action with target cache (fatal)"),y;Et.increment("cache_target_resolution_v2",1,["outcome:miss","platform:mobile-native",`hasRequirements:${g}`,`orgId:${this.orgId}`,"cliVersion:0.88.2"]),n.warn({err:y},"Failed to execute action with target cache, retrying with AI");}}return n.info({description:i,cacheBustedBeforeAction:p},"Prompting AI for a new element location"),await this.targetingActionWithAILocator({tracer:t,action:o,command:a,description:i,cacheKey:s,targetName:l,skipFetchingFullWebviewContent:u,removeWebviewContent:d,metadata:m,logger:n,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 pv=class extends hr{async doDrag(e,t,n,o,i){let{x1:a,y1:s,x2:l,y2:c}=n.bounds,u=a+(l-a)/2,d=s+(c-s)/2;t.attributes.startPoint={x:u,y:d};let{x1:m,y1:p,x2:f,y2:h}=o.bounds,g=m+(f-m)/2,y=p+(h-p)/2;t.attributes.endPoint={x:g,y};let S=i?.hoverDuration??500,b=i?.dragDuration??1e3;b===0&&(b=1);let A=Math.sqrt(Math.pow(g-u,2)+Math.pow(y-d,2))/b*1e3;await this.driver.executeInNativeContext(e,async O=>{await O.execute("mobile: dragFromToWithVelocity",{fromX:u,fromY:d,toX:g,toY:y,pressDuration:S/1e3,velocity:A,holdDuration:.5});},{operationName:"dragAndDrop"});}async executeDragAndDrop({logger:e,command:t}){let n=re();if(t.fromTarget.type!=="description"||t.toTarget.type!=="description")throw new w("UserConfigurationError","Drag and drop only supports description targets for now");let o=t.fromTarget.description,{result:i,thoughts:a}=await this.wrapTargetingAction({command:t,tracer:n,description:o,cacheKey:"cache",targetName:"fromTarget",action:async u=>u,logger:e}),s=t.toTarget.description,{result:l,thoughts:c}=await this.wrapTargetingAction({command:t,tracer:n,description:s,cacheKey:"cache",targetName:"toTarget",action:async u=>u,logger:e});return await n.startAsyncSpan("EMULATOR_INTERACTION",async u=>{await this.doDrag(e,u,i,l,{hoverDuration:t.hoverDuration,dragDuration:t.dragDuration});},{name:"Drag and drop"}),{success:!0,message:`${a}
|
|
5361
5361
|
${c}`}}};var fv=class{driver;logger;constructor(e,t){this.driver=e,this.logger=t;}async getTextContent(e){let t=e.cache.xPath;return t?await this.driver.executeInNativeContext(this.logger,async o=>{try{let a=(await o.findElement("xpath",t))[ea];if(!a)return "";let s=await o.getElementAttribute(a,"label"),l=await o.getElementAttribute(a,"value");return [s,l].filter(u=>!!u&&u.trim().length>0).join(" ").trim()}catch{return ""}},{operationName:"getNativeElementTextContent"})??"":""}async getAttribute(e,t){let n=e.cache.xPath;return n?await this.driver.executeInNativeContext(this.logger,async i=>{try{let s=(await i.findElement("xpath",n))[ea];return s?await i.getElementAttribute(s,t)??"":""}catch{return ""}},{operationName:"getNativeElementAttribute"})??"":""}async getTagName(e){let t=e.cache.xPath;return t?await this.driver.executeInNativeContext(this.logger,async o=>{try{let a=(await o.findElement("xpath",t))[ea];return a?await o.getElementTagName(a)??"":""}catch{return ""}},{operationName:"getNativeElementTagName"})??"":""}async isEditable(e){throw new w("UserConfigurationError","Editable checks are not supported on iOS native elements")}async isEnabled(e){let t=e.cache.xPath;return t?await this.driver.executeInNativeContext(this.logger,async n=>{try{let i=(await n.findElement("xpath",t))[ea];return i?await n.isElementEnabled(i):!1}catch{return !1}},{operationName:"isNativeElementEnabled"}):!1}async isFocused(e){let t=await this.getAttribute(e,"focused");return t==="true"||t==="1"}async getStyleProperty(e,t){throw new w("UserConfigurationError","Computed style checks are not supported on iOS native elements")}},hv=class{driver;webviewContext;logger;constructor(e,t,n){this.driver=e,this.webviewContext=t,this.logger=n;}getCenter(e){let{x1:t,y1:n,x2:o,y2:i}=e.bounds;return {x:(t+o)/2,y:(n+i)/2}}async getTextContent(e){let{x:t,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let l=document.elementFromPoint(a,s);return l?l.innerText??l.textContent??"":""},t,n)??""}async getAttribute(e,t){let{x:n,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(a,s,l,c)=>{let u=document.elementFromPoint(s,l);return u?u.getAttribute(c)??"":""},n,o,t)??""}async getTagName(e){let{x:t,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let l=document.elementFromPoint(a,s);return l?l.tagName:""},t,n)??""}async isEditable(e){let{x:t,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let l=document.elementFromPoint(a,s);if(!l)return !1;let c=l.tagName;return c==="INPUT"||c==="TEXTAREA"||c==="SELECT"||l.isContentEditable},t,n)}async isEnabled(e){let{x:t,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let l=document.elementFromPoint(a,s);return l?!l.disabled:!1},t,n)}async isFocused(e){let{x:t,y:n}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(i,a,s)=>{let l=document.elementFromPoint(a,s);return l?document.activeElement===l:!1},t,n)}async getStyleProperty(e,t){let{x:n,y:o}=this.getCenter(e);return await this.driver.executeWebViewScript(this.logger,this.webviewContext,(a,s,l,c)=>{let u=document.elementFromPoint(s,l);return u?window.getComputedStyle(u).getPropertyValue(c):""},n,o,t)??""}};var Exe=5e3,gv=class extends hr{async executeElementCheck({logger:e,command:t}){let n=Date.now(),o=(t.timeout??yr)*1e3,i=o+1e4,a,s=0,l=500,c=cloneDeep(t.cache);if(t.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Element check step");for(;s-n<o;){if(Date.now()-n>i){e.warn("Exceeded max system timeout for element check, exiting...");break}if(this.throwIfAborted(),a=await this.executeElementCheckHelper({logger:e,command:t}),s=Date.now(),!a.success)t.cache=c,c=cloneDeep(c),await te(l,this.abortSignal),l=Math.min(Math.floor(l*1.5),Exe);else return a}let u=await this.executeElementCheckHelper({logger:e,command:t,cacheIsInvalidAfterResolution:!0});if(!u.success&&c&&t.cache){let d=S1({logger:e,originalTarget:Pw(c)?c.target:void 0,newTarget:t.cache.target});d&&Ra(c.target,d)&&(t.cache={target:d,updatedAt:t.cache.updatedAt});}return u}async executeElementCheckHelper({logger:e,command:t,cacheIsInvalidAfterResolution:n}){let o=re();if(t.target.type!=="description")throw new w("UserConfigurationError","x/y targets are not supported for the Element check step");let i=ad(t.assertion);try{return (await this.wrapTargetingAction({...n?{cacheIsInvalidAfterResolution:n}:{},command:t,tracer:o,action:async s=>s.type==="NATIVE"?await this.executeNativeElementCheck(e,t,s):await this.executeWebviewElementCheck(e,t,s),description:t.target.description,logger:e})).result}catch(a){return i&&(a instanceof w&&a.reason==="NoMatchingElementError"||a instanceof hi)?{success:!0}:{success:!1,message:`Failed to evaluate element content assertion: ${a instanceof Error?a.message:`${a}`}`}}}async executeNativeElementCheck(e,t,n){let o=re(),{assertion:i}=t;return await o.startAsyncSpan("ELEMENT_ASSERTION",async a=>{let s=await this.executeElementAssertion({assertion:i,element:n,elementPropertyAccessors:new fv(this.driver,e),span:a});return a.result=s,s},{name:"Native element check"})}async executeWebviewElementCheck(e,t,n){let o=re(),{assertion:i}=t,s=(await this.stateManager.getContexts(e)).webviews[0];if(!s)throw new w("UserConfigurationError","No active webview context found for element check");return await o.startAsyncSpan("ELEMENT_ASSERTION",async l=>{let c=await this.executeElementAssertion({assertion:i,element:n,elementPropertyAccessors:new hv(this.driver,s,e),span:l});return l.result=c,c},{name:"Webview element check"})}async executeElementAssertion({assertion:e,element:t,elementPropertyAccessors:n,span:o}){switch(e.type){case"ELEMENT_CONTENT":{let i=await n.getTextContent(t)??"";return o.attributes.elementTextContent=tr(i,500,!0),gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})?{success:!0}:{success:!1,message:`The content ${wr(e)} '${e.value}': ${i}`}}case"ELEMENT_ATTRIBUTE":{let i=null;try{i=await n.getAttribute(t,e.attr);}catch{i=null;}if(!gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=wr(e);return {success:!1,message:`The attribute ${e.attr} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:!0}}case"ELEMENT_EXISTENCE":{let i=!1;switch(e.condition){case"EDITABLE":i=await n.isEditable(t);break;case"VISIBLE":case"EXISTS":i=!0;break;case"ENABLED":{i=await n.isEnabled(t);break}case"FOCUSED":i=await n.isFocused(t);break;default:throw e.condition,new Error("Unrecognized element condition type")}return i=e.negated?!i:i,i?{success:!0}:{success:!1,message:`The element ${wr(e)}`}}case"ELEMENT_NAME":{let i=await n.getTagName(t);return gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!0})?{success:!0}:{success:!1,message:`The element tag name ${wr(e)} '${e.value}': ${i}`}}case"ELEMENT_STYLE":{let i=await n.getStyleProperty(t,e.property);if(!gn(i,e.value,e.operation,{negated:!!e.negated,ignoreCase:!1})){let a=wr(e);return {success:!1,message:`The style property ${e.property} ${a}${e.operation==="EXISTS"?"":` '${e.value}': ${i}`}`}}return {success:!0}}default:throw new Error("Unrecognized element assertion type")}}};async function cY({command:r,orgId:e,logger:t,fixtures:n,abortSignal:o}){let i;try{i=await Oo({orgId:e,code:r.code,fragment:!1,context:n.testContext,timeoutMs:r.timeout?r.timeout*1e3:void 0,logger:t,localTools:n.localCodeEvalTools,signal:o});}catch(a){throw new w("ActionFailureError",a instanceof w?a.message:`${a}`,{errOptions:{cause:a}})}try{JSON.stringify(i);}catch(a){throw new w("UserConfigurationError",`Return value is not serializable: ${a instanceof Error?a.message:`${a}`}`)}return {success:!0,output:i}}async function uY({command:r,emulator:e}){switch(r.key){case"ENTER":await e.pressKey("enter");break;case"BACKSPACE":await e.pressKey("backspace");break;default:{r.key;}}return {success:!0}}var dY=v__default.object({name:v__default.string(),pid:v__default.number(),bundleId:v__default.string()});var bm=class extends hr{async doPress(e,{name:t,longPress:n}){return this.driver.executeInNativeContext(e,o=>o.executeScript("mobile: pressButton",[{name:t,isLongPress:n}]),{operationName:"pressButton"})}};var Txe="com.apple.springboard",mY=5,Sv=class extends hr{async execute(e){let t;for(let n=0;n<mY;n++){this.throwIfAborted();try{let i=await this.driver.executeInNativeContext(e,s=>s.executeScript("mobile: activeAppInfo",[]),{operationName:"getActiveAppInfo"});t=dY.parse(i).bundleId;}catch(i){throw new w("UserConfigurationError",`Failed to get active app info: ${i.message}`)}if(!t)return {success:!0,message:"No active app found"};if(await new bm(this.constructPerformerParams()).doPress(e,{name:"home"}),t!==Txe)return await this.emulator.terminateApp(t),{success:!0};await te(500,this.abortSignal);}throw new w("ActionFailureError",`Failed to dismiss notification after ${mY} attempts, cannot kill the underlying app`)}};async function pY({command:r,logger:e}){let t;try{t=new URL(r.url).hostname;}catch(l){throw new w("UserConfigurationError",`Invalid URL: ${l instanceof Error?l.message:`${l}`}`)}let n=new CookieJar,o=khe(fetch,n),i=Date.now(),a=await Id({command:r,baseUrl:void 0,logger:e,fetchImplementation:o}),s=gu(n,t);return {output:Bc.parse({...a,cookies:s}),success:!0,message:`Successfully executed request in ${Date.now()-i}ms`}}async function fY({command:r,emulator:e,driver:t,logger:n,getViewportBounds:o}){return e.setOrientation?await e.setOrientation(r.orientation):await t.executeInNativeContext(n,async i=>{await i.setOrientation(r.orientation==="LANDSCAPE"?"landscape":"portrait");},{operationName:"setOrientation"}),{success:!0,output:{newViewportBounds:await o()}}}var wxe=5e3,bv=class extends hr{async executeScreenCheck(e,t){let{timeout:n}=t,o=Date.now(),i=(n??yr)*1e3,a=i+1e4,s=0,l=500;for(;s-o<i;){if(Date.now()-o>a){e.warn("Exceeded max system timeout for screen check, exiting...");break}this.throwIfAborted();let c=await this.executeScreenCheckHelper(e,t);if(s=Date.now(),!c.success)await te(l,this.abortSignal),l=Math.min(Math.floor(l*1.5),wxe);else return c}return await this.executeScreenCheckHelper(e,t)}async executeScreenCheckHelper(e,t){let n=await this.executeNativeScreenCheckHelper(e,t);if(!t.assertion.negated&&n.success)return n;let o=await this.executeWebviewScreenCheckHelper(e,t);return o?t.assertion.negated?n.success&&o.success?n:n.success?o:n:n.success?n:o:n}async executeNativeScreenCheckHelper(e,t){let{assertion:n}=t;switch(n.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(n.value)===!n.negated;return i.length>1e4&&(i=i.slice(0,1e4)+"...TRUNCATED"),a?{success:!0}:{success:!1,message:`The screen ${id({...n,negated:!n.negated})}.`}}catch(o){return {success:!1,message:`Failed to evaluate screen content assertion: ${o instanceof Error?o.message:`${o}`}`}}default:return n.type,{success:!1,message:`Unsupported screen check assertion type: ${n.type}`}}}async executeWebviewScreenCheckHelper(e,t){let n;try{if(n=await this.stateManager.getActiveWebview(e),!n)return}catch(i){e.warn({err:i},"Failed to get active webview context during screen check");return}let{assertion:o}=t;switch(o.type){case"CONTENT":try{return await this.driver.executeWebViewScript(e,n,(a,s,l)=>document.body.innerHTML.includes(s)===!l,o.value,!!o.negated)?{success:!0}:{success:!1,message:`The webview ${id({...o,negated:!o.negated})}.`}}catch(i){e.warn({err:i},"Failed to check webview content during screen check");return}default:return}}};var Axe=.9,ul=.2,Rxe=500;function II(r,e){r.attributes.scrollableElementType=e.type,r.attributes.scrollableElementDisplay=ha(e),e.type==="CUSTOM"&&(r.attributes.scrollableElementDescription=e.target.description);}var Em=class extends hr{async getHardcodedScrollableElementBounds(e,t){let n;switch(e.type){case"SCREEN":n=this.getContainerBoundsFromViewport(t);break;case"OPEN_APP":n=this.getContainerBoundsFromViewport(t);break;case"OPEN_WEBVIEW":{n=this.getContainerBoundsFromViewport(t);break}default:{throw new Error("If Typescript complains about the line above, you missed a switch case")}}return n}getContainerBoundsFromViewport(e){return {left:e.x,top:e.y,width:e.width,height:e.height}}getContainerBoundsFromBounds(e){let t=e.x1,n=e.y1,o=e.x2,i=e.y2,a=o-t,s=i-n;return {left:t,top:n,width:a,height:s}}async executeSwipe({logger:e,command:t}){let n=re(),o=ha(t.scrollableElement);if(t.scrollableElement.type==="CUSTOM_COORDINATES"){let{startX:a,startY:s,deltaPixels:l}=t.scrollableElement;return await n.startAsyncSpan("EMULATOR_INTERACTION",async c=>{II(c,t.scrollableElement),await this.performRawSwipe({logger:e,span:c,startX:a,startY:s,deltaPixels:l,direction:t.direction,durationMs:t.durationMs});},{name:`Swipe ${t.direction} in ${o}`}),{success:!0,message:"Successfully executed swipe action"}}if(t.scrollableElement.type!=="CUSTOM"){let a=await this.driver.executeInNativeContext(e,async l=>l.getWindowRect(),{operationName:"getSwipeViewportRect"}),s=await this.getHardcodedScrollableElementBounds(t.scrollableElement,a);return await n.startAsyncSpan("EMULATOR_INTERACTION",async l=>{II(l,t.scrollableElement),await this.swipeByAbsoluteCoordinates({logger:e,span:l,direction:t.direction,percent:t.viewportPercent,durationMs:t.durationMs,containerBounds:s,relativePosition:t.relativePosition});},{name:`Swipe ${t.direction} in ${o}`}),{success:!0,message:"Successfully executed swipe action"}}let{thoughts:i}=await this.wrapTargetingAction({command:t,description:t.scrollableElement.target.description,action:async a=>re().startAsyncSpan("EMULATOR_INTERACTION",async l=>(II(l,t.scrollableElement),this.scrollInNativeContainer({logger:e,span:l,cmd:t,target:a})),{name:`Swipe ${t.direction} in ${o}`}),tracer:n,logger:e});return {success:!0,message:i}}async scrollInNativeContainer({logger:e,span:t,cmd:n,target:o}){let i=o.bounds,a=this.getContainerBoundsFromBounds(i);await this.swipeByAbsoluteCoordinates({logger:e,span:t,direction:n.direction,percent:n.viewportPercent,durationMs:n.durationMs,containerBounds:a,relativePosition:n.relativePosition});}async swipeByAbsoluteCoordinates({logger:e,span:t,direction:n,percent:o=Axe,durationMs:i,containerBounds:a,relativePosition:s}){t.attributes.containerBounds=a;let l=n==="up"||n==="down",c=a.width*ul,u=a.height*ul,d=l?(a.height-2*u)*o:(a.width-2*c)*o,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(n),desiredDelta:d});m=h.startX,p=h.startY,f=h.actualDelta;}await this.performRawSwipe({logger:e,span:t,startX:m,startY:p,deltaPixels:f,direction:n,durationMs:i});}calculateSwipeCoordinates({containerBounds:e,direction:t,desiredDelta:n}){let o=e.left+e.width/2,i=e.top+e.height/2;if(t==="up"||t==="down"){let a=e.height*ul,s=e.top+a,l=e.top+e.height-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u,m=t==="down"?l-d/2:s+d/2;return {startX:o,startY:m,actualDelta:u}}else {let a=e.width*ul,s=e.left+a,l=e.left+e.width-a,c=l-s,u=Math.min(Math.abs(n),c),d=c-u;return {startX:t==="right"?l-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:t,startX:n,startY:o,deltaPixels:i,direction:a,durationMs:s=300}){let l=Math.abs(i),c=Math.max(2,Math.round(s)),u=Math.max(1,Math.min(120,Math.floor(c*.25))),d=Math.max(1,c-u),m=Math.min(l/2,Math.min(12,Math.max(l*.05,1))),p=n,f=o,h=n,g=o;a==="up"||a==="down"?(f=a==="up"?o-l:o+l,h=p,g=a==="up"?f+m:f-m):(p=a==="left"?n-l:n+l,h=a==="left"?p+m:p-m,g=f),t.attributes.pixelDelta=l,t.attributes.startPoint={x:n,y:o},t.attributes.endPoint={x:p,y:f},t.attributes.durationMs=c,await this.driver.executeInNativeContext(e,async y=>{let S={type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:n,y:o},{type:"pointerDown",button:0},{type:"pause",duration:300},{type:"pointerMove",duration:d,x:h,y:g},{type:"pointerMove",duration:u,x:p,y:f},{type:"pause",duration:300},{type:"pointerUp",button:0}]};await y.performActions([S]),await y.releaseActions();},{operationName:"performRawSwipe"}),await te(Rxe,this.abortSignal);}};var xxe=20,OI=.9,Tm=.5,NI=.2;function Mxe(r){return r.type==="NATIVE"&&r.scrollDetails!==void 0}var Ev=class extends Em{async executeScrollTo({logger:e,command:t}){let n=t.target.description,o=t.scrollStepPercent??OI,i=await this.tryUseNativeScrollCache(e,t,n);return i||this.searchForElement({logger:e,cmd:t,description:n,scrollStepPercent:o})}async resolveContainer({logger:e,scrollableElement:t,containerCache:n}){let o=await this.driver.executeInNativeContext(e,async c=>c.getWindowRect(),{operationName:"getScrollContainerViewportRect"});if(t.type==="CUSTOM_COORDINATES")return {bounds:{left:0,top:0,width:o.width,height:o.height},diffThresholdPercent:Tm};if(t.type!=="CUSTOM")return {bounds:await this.getHardcodedScrollableElementBounds(t,o),diffThresholdPercent:Tm};let i=re(),a=t.target.description;if(n){let c=this.getBoundsFromNativeCache(n);return e.info({bounds:c},"Got container bounds from native cache"),{bounds:c,cache:n,diffThresholdPercent:Td({containerBounds:c,viewport:o,defaultThresholdPercent:Tm})}}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 l=this.getBoundsFromNativeCache(s.cache);return e.info({bounds:l},"Got container bounds from AI"),{bounds:l,cache:s.cache,diffThresholdPercent:Td({containerBounds:l,viewport:o,defaultThresholdPercent:Tm})}}getBoundsFromNativeCache(e){if(!e.bounds||e.bounds.length<4)throw new w("ActionFailureError","Native target cache has no bounds");let[t,n,o,i]=e.bounds;return {left:t,top:n,width:o-t,height:i-n}}async tryUseNativeScrollCache(e,t,n){let o=t.cache?.target;if(o&&Mxe(o)&&o.scrollDetails!==void 0)return this.tryUseNativeScrollCacheHelper(e,t,n,o)}async tryUseNativeScrollCacheHelper(e,t,n,o){let i=o.scrollDetails,a=re(),s=t.scrollStepPercent??OI;if(i.pixelDelta===0){e.info("Skipping cached scroll-position replay because it would not move the viewport");return}let l;i.scrollableElement.type==="CUSTOM"&&i.scrollableElement.cache?.type==="NATIVE"&&(l=i.scrollableElement.cache),await this.scrollByPixelDelta({logger:e,pixelDelta:i.pixelDelta,scrollableElement:i.scrollableElement,containerCache:l,direction:i.direction,scrollStepPercent:s});try{let u=await this.tryFindElement({logger:e,cmd:t,description:n,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 c=i.direction==="down"?"up":"down";e.info({pixelDelta:i.pixelDelta,originalDirection:i.direction,undoDirection:c,scrollableElementType:i.scrollableElement.type},"Undoing scroll"),await this.scrollByPixelDelta({logger:e,pixelDelta:i.pixelDelta,scrollableElement:i.scrollableElement,containerCache:l,direction:c,scrollStepPercent:s});}async tryFindElement({logger:e,cmd:t,description:n,tracer:o,scrollDetails:i,useAIIfCacheFails:a=!0}){let s,l,c=!1,u=i,d=hY(t.cache?.target);if(d&&d.type==="NATIVE"&&d.resolvedDescription!==void 0&&js(d.resolvedDescription,n)&&!t.disableCache)try{s=await this.resolveTargetCacheWithTracing({logger:e,tracer:o,cache:d,retryWithinSmartWaiting:!1}),c=!0,l="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&&c&&i){let p=await this.correctNativeTargetIntoView({logger:e,tracer:o,cmd:t,resolvedTarget:s,scrollDetails:i});u=p.scrollDetails,p.resolvedTarget?s=p.resolvedTarget:(s=void 0,c=!1);}if(!s&&!a)return null;if(!s)try{let p=nE(n),f=await this.findElement({logger:e,description:p,tracer:o,metadata:{commandId:t.id,source:"SCROLL_TO"}});if(f.resolvedTarget.type!=="NATIVE")return null;s=f.resolvedTarget,l=f.thoughts;}catch(p){if(p instanceof w&&p.reason==="NoMatchingElementError")return null;throw e.warn({err:p},"Failed to find scroll-to target with AI"),p}if(s&&!c&&i)try{let p=await this.correctNativeTargetIntoView({logger:e,tracer:o,cmd:t,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 ym({command:t,updatedCache:hY({...gm(s),...u?{scrollDetails:u}:{}}),updatedWithAI:!c,logger:e}),{success:!0,message:l}}async correctNativeTargetIntoView({logger:e,tracer:t,cmd:n,resolvedTarget:o,scrollDetails:i}){let a=await this.getCorrectiveScrollForTarget({logger:e,resolvedTarget:o});if(!a)return {resolvedTarget:o,scrollDetails:i};e.info({bounds:o.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,l=await this.scrollByPixelDelta({logger:e,pixelDelta:a.pixelDelta,scrollableElement:i.scrollableElement,containerCache:s,direction:a.direction,scrollStepPercent:n.scrollStepPercent??OI,useVisualDiff:!0});if(l===0)return e.info({bounds:o.bounds,correction:a},"Skipping corrective scroll update because the viewport did not move"),{resolvedTarget:o,scrollDetails:i};let c={...i,pixelDelta:_b({currentPixelDelta:i.pixelDelta,baseDirection:i.direction,correctionDirection:a.direction,correctionPixels:l})},u;try{u=await this.resolveTargetCacheWithTracing({logger:e,tracer:t,cache:o.cache,retryWithinSmartWaiting:!1});}catch(m){return e.warn({err:m},"Failed to re-resolve scroll-to target after corrective scroll"),{scrollDetails:c}}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:c}):{resolvedTarget:u,scrollDetails:c}}async searchForElement({logger:e,cmd:t,description:n,scrollStepPercent:o}){let i=re(),a=await this.resolveContainer({logger:e,scrollableElement:t.scrollableElement});return this.scrollAndSearch({logger:e,cmd:t,description:n,tracer:i,scrollStepPercent:o,resolvedContainer:a})}async scrollAndSearch({logger:e,cmd:t,description:n,tracer:o,scrollStepPercent:i,resolvedContainer:a}){let s=0,l=a.bounds,c=a.diffThresholdPercent,u=_xe(t.scrollableElement),d=u?Math.abs(u.deltaPixels):this.calculateSwipeCoordinates({containerBounds:l,direction:t.direction,desiredDelta:Fs({containerBounds:l,containerInsetRatio:ul})*i}).actualDelta,m=!0,p=t.maxScrollAttempts??xxe;for(let g=0;g<p;g++){this.throwIfAborted();let y=this.buildScrollDetails(t,s,a.cache),S=await this.tryFindElement({logger:e,cmd:t,description:n,tracer:o,scrollDetails:y});if(S)return S;if(!m)throw new Error(`ActionFailureError: Could not find element "${n}" after scrolling to the end`);e.debug({attempt:g,cumulativePixelDelta:s},"Element not found, scrolling further"),m=await this.scrollByPage({logger:e,direction:t.direction,containerBounds:l,scrollStepPercent:i,diffThresholdPercent:c,rawCoordinates:u}),s+=t.direction==="down"?d:-d;}let f=this.buildScrollDetails(t,s,a.cache),h=await this.tryFindElement({logger:e,cmd:t,description:n,tracer:o,scrollDetails:f});if(h)return h;throw new Error(`ActionFailureError: Could not find element "${n}" after ${p} scroll attempts`)}buildScrollDetails(e,t,n){return e.scrollableElement.type==="CUSTOM"?{pixelDelta:t,scrollableElement:{type:"CUSTOM",target:e.scrollableElement.target,cache:n},direction:e.direction}:e.scrollableElement.type==="CUSTOM_COORDINATES"?{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}:{pixelDelta:t,scrollableElement:e.scrollableElement,direction:e.direction}}async scrollByPage({logger:e,direction:t,containerBounds:n,scrollStepPercent:o,diffThresholdPercent:i,rawCoordinates:a}){return re().startAsyncSpan("EMULATOR_INTERACTION",async l=>(l.attributes.containerBounds=n,l.attributes.direction=t,(await this.executeScrollGesture({logger:e,span:l,direction:t,containerBounds:n,scrollStepPercent:o,diffThresholdPercent:i,rawCoordinates:a})).canScrollMore),{name:`Scroll ${t} by one page`})}async scrollByPixelDelta({logger:e,pixelDelta:t,scrollableElement:n,containerCache:o,direction:i,scrollStepPercent:a,useVisualDiff:s=!1}){if(t===0)return 0;let l=re(),c,u=Tm,d,m,p;if(n.type==="CUSTOM_COORDINATES")d=n.startX,m=n.startY,p=n.deltaPixels;else {c=await this.resolveContainer({logger:e,scrollableElement:n,containerCache:o});let g=c.bounds;u=c.diffThresholdPercent;let y=Fs({containerBounds:g,containerInsetRatio:ul})*a,S=this.calculateSwipeCoordinates({containerBounds:g,direction:i,desiredDelta:y});d=S.startX,m=S.startY,p=S.actualDelta;}let f=Math.ceil(Math.abs(t)/p),h=this.invertDirection(i);return e.debug({pixelDelta:t,swipeDirection:h,scrollableElementType:n.type,startX:d,startY:m,maxScrollPerStep:p,numScrolls:f},"scrollByPixelDelta calculated parameters"),l.startAsyncSpan("EMULATOR_INTERACTION",async g=>{g.attributes.pixelDelta=t,g.attributes.numScrolls=f,g.attributes.maxScrollPerStep=p,g.attributes.startX=d,g.attributes.startY=m;let y=0;for(let S=0;S<f;S++){this.throwIfAborted();let b=Math.abs(t)-y,C=Math.min(p,b);if(s){let A=await this.executeScrollGesture({logger:e,span:g,direction:i,containerBounds:c?.bounds,scrollStepPercent:a,diffThresholdPercent:u,rawCoordinates:{type:"CUSTOM_COORDINATES",startX:d,startY:m,deltaPixels:C}});if(A.didScroll&&(y+=C),!A.canScrollMore)break}else await this.performRawSwipe({logger:e,span:g,startX:d,startY:m,deltaPixels:C,direction:h}),y+=C;}return g.attributes.appliedPixels=y,y},{name:`Scroll ${i} by ${Math.abs(t)}px`})}async getCorrectiveScrollForTarget({logger:e,resolvedTarget:t}){let n=t.bounds,o=await this.stateManager.getViewportBounds(e),i=Math.max(1,o.bottom-o.top),a=o.top+i*NI,s=o.bottom-i*NI,l=Pb({viewportTop:o.top,viewportBottom:o.bottom,elementHeight:n.y2-n.y1,targetTopRatio:NI}),c=n.y1>=o.top&&n.y2<=o.bottom,u=n.y1<a||n.y2>s,d=await this.isResolvedTargetVisible({logger:e,resolvedTarget:t}),m=l-n.y1;if(!(c&&d!==!1&&!u)){if(m>0)return {direction:"up",pixelDelta:m};if(m<0)return {direction:"down",pixelDelta:Math.abs(m)}}}async isResolvedTargetVisible({logger:e,resolvedTarget:t}){if(t.type==="WEBVIEW")return null;let n=t.cache.xPath;if(!n)return gY(t.cache.elementOnlySerializedXml);let o=await this.getTargetVisibilityFromDriver({logger:e,xPath:n});return o!==null?o:gY(t.cache.elementOnlySerializedXml)}async getTargetVisibilityFromDriver({logger:e,xPath:t}){try{return await this.driver.executeInNativeContext(e,async n=>{let i=(await n.findElement("xpath",t))?.[ea];if(!i)return null;let a=await n.getElementAttribute(i,"visible");return a?a!=="false":null},{operationName:"getScrollToTargetVisibility"})}catch{return null}}async executeScrollGesture({logger:e,span:t,direction:n,containerBounds:o,scrollStepPercent:i,diffThresholdPercent:a=Tm,rawCoordinates:s}){let l=await this.stateManager.getRawScreenshotBase64({logger:e}),c,u,d;if(s)c=s.startX,u=s.startY,d=s.deltaPixels;else {if(!o)throw new Error("Expected container bounds for scroll gesture");let g=Fs({containerBounds:o,containerInsetRatio:ul})*i,y=this.calculateSwipeCoordinates({containerBounds:o,direction:n,desiredDelta:g});c=y.startX,u=y.startY,d=y.actualDelta;}await this.performRawSwipe({logger:e,span:t,startX:c,startY:u,deltaPixels:d,direction:this.invertDirection(n)});let m=await this.stateManager.getRawScreenshotBase64({logger:e}),p=Ds(l,m),f=p>a,h=p>a;return e.debug({diffPercent:p,didScroll:f,diffThresholdPercent:a,canScrollMore:h,direction:n,actualDelta:d,rawCoordinates:s},"Scroll gesture visual diff result"),{didScroll:f,canScrollMore:h}}};function hY(r){return !r||r.type!=="NATIVE"?r:Ib(r)}function _xe(r){if(r.type==="CUSTOM_COORDINATES")return r}function gY(r){if(!r)return null;let e=r.match(/\bvisible="(true|false)"/);return e?e[1]==="true":null}function Pxe(r){return "iterations"in r}function Ixe(r){let e={relativePosition:r.relativePosition},t=r.iterations??(r.doubleTap?2:void 0),n=r.tapDelayMs??r.doubleTapDelayMs;if(t!==void 0&&(!Number.isInteger(t)||t<1))throw new w("UserConfigurationError","iterations must be a positive integer");if(n!==void 0&&(!Number.isInteger(n)||n<0))throw new w("UserConfigurationError","tapDelayMs must be >= 0");if(t&&t>1&&r.longPress)throw new w("UserConfigurationError","Cannot specify both more than one tap iteration and long press at the same time");if(n!==void 0&&(!t||t<2))throw new w("UserConfigurationError","tapDelayMs requires iterations >= 2");if(r.longPress){if(n!==void 0)throw new w("UserConfigurationError","tapDelayMs cannot be used with longPress");return {...e,longPress:!0,longPressDurationMs:r.longPressDurationMs}}return t!==void 0?{...e,iterations:t,tapDelayMs:n}:e}var vm=class extends hr{async tapOnAbsoluteCoordinates(e,t){let n=t.x,o=t.y;if(e.info({x:n,y:o},"Tap at coordinates"),"longPress"in t&&t.longPress){let i=(t.longPressDurationMs??2e3)/1e3;await this.driver.executeInNativeContext(e,a=>a.executeScript("mobile: touchAndHold",[{x:n,y:o,duration:i}]),{operationName:"touchAndHold"});return}if(Pxe(t)){let i=t.tapDelayMs??100;for(let a=0;a<t.iterations;a++)await this.emulator.tap(n,o),a<t.iterations-1&&await te(i);return}await this.emulator.tap(n,o);}async tapOnTarget({logger:e,target:t,options:n}){return await re().startAsyncSpan("EMULATOR_INTERACTION",async i=>{i.attributes.options=n;let{x1:a,y1:s,x2:l,y2:c}=t.bounds,u=l-a,d=c-s,m=n?.relativePosition?.x??u/2,p=n?.relativePosition?.y??d/2;m=Math.max(0,Math.min(m,u)),p=Math.max(0,Math.min(p,d));let f=a+m,h=s+p;await this.tapOnAbsoluteCoordinates(e,{x:f,y:h,...n}),i.attributes.point={x:f,y:h};},{name:"Tap on target"})}async executeTap({logger:e,command:t}){let n=Ixe(t),o=re();if(t.target.type==="coordinates"){let s=await this.driver.executeInNativeContext(e,async u=>u.getWindowSize(),{operationName:"getTapWindowSize"}),l=t.target.xPercent*s.width,c=t.target.yPercent*s.height;return await o.startAsyncSpan("EMULATOR_INTERACTION",async()=>{await this.tapOnAbsoluteCoordinates(e,{...n,x:l,y:c});},{name:`Tap at coordinates ${l}, ${c}`}),{success:!0,message:`Tapped at ${l}, ${c}`}}let i=t.target.description,{thoughts:a}=await this.wrapTargetingAction({logger:e,tracer:o,command:t,action:s=>this.tapOnTarget({logger:e,target:s,options:n}),description:i});return {success:!0,message:a}}};var Mc=25,yY=150,Tv=class extends hr{async doType(e,t){let n=re();if(!t.target){if(t.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,t),{success:!0,message:"Successfully executed type action"}}if(t.target.type!=="description")throw new Error("UserConfigurationError: x/y targets are not supported for the Type step");let{thoughts:o}=await this.wrapTargetingAction({logger:e,tracer:n,command:t,action:async i=>{await this.doTypeHelper(e,t,i);},description:t.target.description});return {success:!0,message:o}}async doTypeHelper(e,t,n){let o=new vm(this.constructPerformerParams());t.clearContent?(await o.tapOnTarget({logger:e,target:n,options:{longPress:!0}}),await this.clearContent(e)):await o.tapOnTarget({logger:e,target:n,options:{}}),await this.sendKeys(e,t);}async sendKeys(e,t){let n=re(),o=t.keyPressDelayMs??Mc;o<=0&&(o=Mc),await n.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,l=>l.isKeyboardShown(),{operationName:"isKeyboardShown"}))return;await new Promise(l=>setTimeout(l,500));}a.attributes.timedOut=!0;}),await n.startAsyncSpan("EMULATOR_INTERACTION",async()=>{try{o!==Mc&&await this.driver.executeInNativeContext(e,async a=>a.updateSettings({maxTypingFrequency:1e3/o}),{operationName:"updateKeyInjectionDelay"});let i=[];for(let a=0;a<t.text.length;a+=yY)i.push(t.text.slice(a,a+yY));for(let a of i)await this.driver.executeInNativeContext(e,async s=>{await s.performActions(Nxe(a)),await s.releaseActions();},{operationName:"typeText",maxAttempts:1,attemptTimeoutMs:Nb(o,a)});}finally{o!==Mc&&await this.driver.executeInNativeContext(e,async i=>i.updateSettings({maxTypingFrequency:1e3/Mc}),{operationName:"resetKeyInjectionDelay"});}},{name:`Typing "${t.text}"${o?` with a ${o}ms delay`:""}`});}async clearContent(e){let t=re();try{await t.startAsyncSection("Clearing any content from the focused field",()=>this.clearContentHelper(e));}catch(n){e.warn({err:n},"Failed to find select all button, continuing...");}}async clearContentHelper(e){await this.driver.executeInNativeContext(e,async t=>{let n=t.$('-ios predicate string:label == "Select All"');await n.waitForExist({timeout:750}),await n.click();},{operationName:"selectAllText",maxAttempts:1}),await this.driver.executeInNativeContext(e,async t=>{await t.keys(["\uE003"]);},{operationName:"deleteSelectedText"});}};function Nxe(r){let e={type:"key",id:"pressKeys",actions:[]};for(let t of [...r])e.actions.push({type:"keyDown",value:t},{type:"keyUp",value:t});return [e]}async function SY({command:r,abortSignal:e}){return await te(r.timeoutSecs*1e3,e),{success:!0}}async function Lxe(r,e){try{await r.executeInNativeContext(e,t=>t.executeScript("mobile: pressButton",[{name:"home"}]),{operationName:"pressHomeButton"}),e.info("Navigated to home screen");}catch(t){e.warn({err:t},"Failed to press home button");}}var LI=["io.appium."],DI=["com.facebook.WebDriverAgentRunner.xctrunner"];async function Dxe(r,e){let t;try{t=await r.listApps();}catch(a){e.warn({err:a},"Failed to list installed apps");return}let n=t.filter(({bundleId:a})=>!DI.includes(a)&&!LI.some(s=>a.startsWith(s)));e.info({count:n.length},"Terminating all apps");let i=(await Promise.allSettled(n.map(async a=>{try{return await r.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 kxe(r,e){e.info("Resetting privacy settings for all apps");try{await r.resetSettings();}catch(t){e.warn({err:t},"Failed to reset privacy settings");}}async function bY(r){let{emulator:e,driver:t,logger:n}=r;await Lxe(t,n),await Dxe(e,n),await kxe(e,n);}var dl=class r extends hr{emulatorSettings;logger;splitInstalledApps(e){let t=[],n=[];for(let{bundleId:o}of e)if(!(DI.includes(o)||LI.some(i=>o.startsWith(i)))){if(o.startsWith("com.apple.")){n.push(o);continue}t.push(o);}return {installedApps:t,prunedApps:n}}constructor(e){super(e),this.logger=e.logger,this.emulatorSettings=e.emulatorSettings;}static async init({driver:e,logger:t,fixtures:n,orgId:o,options:i,abortController:a,emulator:s,generator:l,aiSettings:c}){let u={controller:a},d=i?.emulator??{},m=await dv.init({driver:e,orgId:o,emulator:s,options:d,aborter:u}),p=new r({generator:l,aiSettings:c,emulator:s,driver:e,stateManager:m,logger:t,fixtures:n,aborter:u,orgId:o,emulatorSettings:d});return await p.initializeSettings(),p}async executeCommand(e){let t=["type","a11yData","thoughts","cache","code"],n;try{n=await Ad({obj:e.command,context:this.fixtures.testContext,bannedKeys:t,orgId:this.orgId,logger:this.logger,signal:this.abortSignal,localTools:this.fixtures.localCodeEvalTools});}catch(o){throw this.throwIfAborted(),new Error(`ActionFailureError: Failed to substitute template strings in command: ${o.message}`,{cause:o})}try{return await this.executeCommandHelper(e)}catch(o){throw o.name!=="AbortError"&&this.logger.error({err:o},"Error thrown in action controller"),o}finally{Rd(e.command,n);}}async executeCommandHelper({command:e}){switch(e.type){case"TAP":return new vm(this.constructPerformerParams()).executeTap({logger:this.logger,command:e});case"SWIPE":return new Em(this.constructPerformerParams()).executeSwipe({logger:this.logger,command:e});case"DRAG_AND_DROP":return new pv(this.constructPerformerParams()).executeDragAndDrop({logger:this.logger,command:e});case"SCROLL_TO":return new Ev(this.constructPerformerParams()).executeScrollTo({logger:this.logger,command:e});case"TYPE":return new Tv(this.constructPerformerParams()).doType(this.logger,e);case"STATE":{let t=await this.stateManager.getDomState(this.logger),n=await this.stateManager.getContexts(this.logger);return {output:{xml:t.graph.xml,contexts:n},success:!0}}case"OPEN_APP":{let t=[];if(e.intentExtras)try{let n=JSON.parse(e.intentExtras);t=v__default.string().array().parse(n);}catch(n){throw new w("UserConfigurationError",`Invalid launch arguments: expected a JSON array of strings. ${n instanceof Error?n.message:`${n}`}`)}return await this.driver.executeInNativeContext(this.logger,n=>n.execute("mobile: launchApp",{bundleId:e.packageName,arguments:t}),{operationName:"launchApp"}),{success:!0}}case"KILL_APP":return new Sv(this.constructPerformerParams()).execute(this.logger);case"PRESS":{let t=new bm(this.constructPerformerParams());switch(e.key){case"HOME":await t.doPress(this.logger,{name:"home"});break;case"POWER":await this.driver.executeInNativeContext(this.logger,n=>n.isLocked(),{operationName:"isLocked"})?await this.driver.executeInNativeContext(this.logger,n=>n.unlock(),{operationName:"unlockDevice"}):await this.driver.executeInNativeContext(this.logger,n=>n.lock(),{operationName:"lockDevice"});break}return {success:!0}}case"PRESS_KEYBOARD":return uY({command:e,emulator:this.emulator});case"AI_CHECK":return W3({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 q3({command:e,logger:this.logger,generator:this.generator,aiSettings:this.aiSettings,getEmulatorDomState:()=>this.getEmulatorDomState(),getScreenshotBase64:()=>this.getScreenshotBase64(),abortSignal:this.abortSignal});case"JAVASCRIPT":return cY({command:e,orgId:this.orgId,logger:this.logger,fixtures:this.fixtures,abortSignal:this.abortSignal});case"WAIT":return SY({command:e,abortSignal:this.aborter.controller?.signal});case"REQUEST":return pY({command:e,logger:this.logger});case"ROTATE_ORIENTATION":return fY({command:e,emulator:this.emulator,driver:this.driver,logger:this.logger,getViewportBounds:()=>this.getViewportBounds()});case"ADD_FILE":{let t=await Rb(e.file);return await this.driver.executeInNativeContext(this.logger,n=>n.pushFile(e.storageLocation,t),{attemptTimeoutMs:12e4,operationName:"pushFile"}),{success:!0}}case"SCREEN_CHECK":return new bv(this.constructPerformerParams()).executeScreenCheck(this.logger,e);case"ELEMENT_CHECK":return new gv(this.constructPerformerParams()).executeElementCheck({logger:this.logger,command:e});case"APPIUM_EXECUTE":{let t=JSON.parse(e.jsonArgs??"{}"),n=await this.driver.executeInNativeContext(this.logger,async o=>o.execute(e.command,t),{attemptTimeoutMs:6e4,maxAttempts:1,operationName:"userAppiumExecuteOperation"});return this.logger.info({output:n},"Appium command executed successfully"),{success:!0,output:n,message:"Appium command executed successfully"}}default:{let t=e;throw new Error(`Unsupported mobile command type: ${t}`)}}}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:t}=this.emulatorSettings?.geolocation??Jc;await this.driver.executeInNativeContext(this.logger,async n=>{await n.setGeoLocation({latitude:e,longitude:t}),await n.updateSettings({pageSourceExcludedAttributes:"visible,accessible",maxTypingFrequency:1e3/Mc,reduceMotion:!0});},{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 bY({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 Cm({appFolderPath:r,source:e,overrideBaseDir:t}){let n=r?.trim();if(!n)return;if(e==="default")return n;let o=e==="override"&&t&&!xr__default.isAbsolute(n)?xr__default.resolve(t,n):xr__default.resolve(n);if(e==="override"&&(!Tr.existsSync(o)||!Tr.statSync(o).isDirectory()))throw new Error(`Local iOS app path "${o}" does not exist. Provide a valid directory path.`);return o}var Bxe=3;async function TY(r){let{results:e,fixtures:t,work:n}=r,{logger:o}=t,i=e[e.length-1],a=$xe(i,n);if(a)return o.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}`};o.info({failedResult:i},"Attempting failure recovery"),n.state.failureRecoveryAttempts=(n.state.failureRecoveryAttempts??0)+1;try{return await zxe(r)}catch(s){return o.warn({err:s},"Error during failure recovery attempt, continuing..."),null}}async function zxe(r){let{fixtures:e,results:t,failedStep:n,nextSteps:o,stepTracer:i,work:a}=r,{controller:s,logger:l}=e,c=i.parentTracer,{testMetadata:u}=r.inputs;if(!t.length)throw new Error("Attempted failure recovery with no failed results");let d=await s.getScreenshotPngString(),m=await s.getEmulatorDomState(),{results:p}=await KS(l,c,t,{numStepsWithScreenshots:5,addIndices:!0,includeBeforeScreenshots:!1,screenshotMediaType:"image/png"}),f=o.map(R=>Ni(R)),h=u.description.trim(),g=u?.settings?.ai?.failureRecoveryInstructions?.trim()||void 0,{scenario:y,thoughts:S,instructions:b}=await s.getMobileFailureRecoveryPlan({currentScreenshot:d,failedResults:p,currentScreenXml:m,nextStepsSerialized:f,testDescription:h,customInstructions:g});if(y!=="RECOVERABLE")return l.info({scenario:y,thoughts:S,instructions:b},"Failure recovery is not applicable"),{type:"NOT_ELIGIBLE",message:`Momentic's failure recovery agent determined that this failure is not eligible for recovery: ${S}`};if(!b)throw new Error("Momentic's failure recovery agent did not provide any instructions for recovery");let C={id:randomUUID(),type:"MOBILE_AI_ACTION_STEP",text:b},A,O=a.state.failureRecoveryDisabled;O||(a.state.failureRecoveryDisabled=!0),l.info("executing mobile step list");try{A=await r.executeMobileStepList({...r,fixtures:{...r.fixtures},listParams:{steps:[C,n],containerName:"AI-recovered step list",tracer:c}});}finally{O||(a.state.failureRecoveryDisabled=O);}let M=A.results[0];if(M&&M.type==="MOBILE_AI_ACTION_STEP")if(Pf({results:A.results,onPresetAction:R=>{R.aiSuggested=!0;},onModule:R=>{R.aiSuggested=!0;},onAiAction:R=>{R.aiSuggested=!0;}}),A.status==="SUCCESS"){let R=`The following steps were automatically executed by the failure recovery agent. Analysis: ${S}`;return M.message=R,Et.increment("test_event",1,["name:failure_recovery_success","platform:native",`orgId:${r.inputs.orgId}`]),l.info({thoughts:S},"Failure recovery succeeded"),{type:"ATTEMPTED",status:"SUCCESS",result:A,message:R}}else {Et.increment("test_event",1,["name:failure_recovery_failure","platform:native",`orgId:${r.inputs.orgId}`]);let R=`The following steps were unsuccessfully attempted by the failure recovery agent. Analysis: ${S}`;return M.message=R,M.status="FAILED",l.info({thoughts:S},"Failure recovery failed"),{type:"ATTEMPTED",status:"FAILED",result:A,message:R}}return null}function $xe(r,e){if(!r)return "There is no failed result";if(r.type!=="MOBILE_PRESET_STEP")return "The failed step is not a preset action";let t=r.message;return t?t.includes("AbortError:")?"The user aborted the test":_N.some(n=>t.includes(n))?"The failed step is an irrecoverable configuration error":(e.state.failureRecoveryAttempts??0)>Bxe?"Too many failure recovery attempts":"":"There is no error message available on the failed step"}async function vv({fixtures:r,step:e,inputs:t,stepTracer:n,work:o}){let i=Date.now(),{logger:a,controller:s}=r,l,c="",u,d=s.emulatorSettings?.disableXmlSnapshots??!0;if(!t.interactive){if(o.lastScreenshot&&Date.now()-o.lastScreenshot.capturedAtMs<500)l=o.lastScreenshot.screenshot,c=o.lastScreenshot.snapshotId;else {c=randomUUID();try{l=Buffer.from(await s.getScreenshotBase64(),"base64");}catch(h){a.warn({err:h},"Failed to take before screenshot");}}if(!d)if(o.lastScreenXml)u=o.lastScreenXml.screenXml;else try{u=await s.getEmulatorDomState();}catch(h){a.debug({err:h},"Failed to capture before XML snapshot");}}let m=$R(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:ne(h),startTime:i,endTime:Date.now()});}finally{if(!t.interactive){l&&(f.beforeSnapshot=c,n.attachBeforeScreenshot({snapshotId:c,screenshot:l}),!d&&u&&n.attachBeforeXmlSnapshot({snapshotId:c,xml:u}));let y=randomUUID();try{let S=await s.getScreenshotBase64();f.afterSnapshot=y;let b=Buffer.from(S,"base64");n.attachAfterScreenshot({snapshotId:y,screenshot:b}),o.lastScreenshot={capturedAtMs:Date.now(),snapshotId:y,screenshot:b};}catch(S){a.warn({err:S},"Failed to take after screenshot"),o.lastScreenshot=void 0;}if(!d)try{let S=await s.getEmulatorDomState();n.attachAfterXmlSnapshot({snapshotId:y,xml:S}),o.lastScreenXml={snapshotId:y,screenXml:S};}catch(S){a.debug({err:S},"Failed to capture after XML snapshot"),o.lastScreenXml=void 0;}}let h="cache"in e.command?e.command.cache??{}:{};f.status==="FAILED"&&y1({logger:a,step:e,originalAndroidCommandCache:m});let g=diff(p,h);g&&Object.keys(g).length>0&&a.info({diffs:nu(g)},"Updated cache");}return f}async function jxe(r,e,t){let{logger:n,controller:o}=r.fixtures,{stepTracer:i}=r.conditionalParams,a=e.assertion.command;try{let s=await vv({...r,step:e.assertion,stepTracer:i}),l=a.type;switch(l){case"AI_CHECK":case"SCREEN_CHECK":case"ELEMENT_CHECK":return s.status==="SUCCESS"?{type:"passed",conditionResult:s,steps:e.steps}:(n.info(s.message,`${a.type} mobile condition ${t} resolved to false`),{type:"failed",conditionResult:s});case"JAVASCRIPT":{if(s.status!=="SUCCESS")return {type:"execution_error",conditionResult:s};let c=!!s.data;return s.status=c?"SUCCESS":"FAILED",s.message=c?`JavaScript condition evaluated to true (${JSON.stringify(s.data)})`:`JavaScript condition evaluated to false (${JSON.stringify(s.data)})`,n.info({returnValue:s.data,conditionPassed:c},`JavaScript mobile condition ${t} evaluated`),c?{type:"passed",conditionResult:s,steps:e.steps}:{type:"failed",conditionResult:s}}default:return (u=>{throw new Error(`Unsupported mobile conditional command type: ${u}`)})(l)}}catch(s){n.error({err:s},`Mobile condition ${t} failed with error`);let l=s instanceof Error?s.message:"Unknown error during mobile condition evaluation";return {type:"execution_error",conditionResult:{...e.assertion,status:"FAILED",message:l,startTime:Date.now(),endTime:Date.now()}}}finally{o.throwIfAborted();}}function Gxe({step:r,fromStepId:e,conditionalChain:t,fromStepParentChain:n}){let o=n.slice(t.length+1);for(let i=0;i<r.blocks.length;i++){let a=r.blocks[i],{result:s}=vs(a.steps,e,o);if(s)return i}return -1}async function CY(r){let e=Date.now(),{logger:t}=r.fixtures,{fromStep:n}=r.inputs,{step:o,stepTracer:i,executeMobileStepList:a}=r.conditionalParams,s=i.getParentStepIdChain(),l=!!n&&Zz(s,n.parentStepIdChain),c=o.elseSteps,u=!0,d=[],m,p=!1;if(l&&n){let S=Gxe({step:o,fromStepId:n.fromStepId,conditionalChain:s,fromStepParentChain:n.parentStepIdChain});S>=0&&(c=o.blocks[S].steps,u=!1,p=!0,t.info(`Skipping mobile conditional assertion (execution starts from block ${S}), running ${c.length} steps`));}if(!p)for(let S=0;S<o.blocks.length;S++){t.info(`Evaluating mobile condition ${S} in conditional step`);let b=o.blocks[S],C=await jxe(r,b,S);if(d.push(C.conditionResult),m=C.conditionResult,C.type==="execution_error"){let A=C.conditionResult.status==="CANCELLED"?"CANCELLED":"FAILED",O={...o,assertionResult:C.conditionResult,steps:[],startTime:e,endTime:Date.now(),status:A,message:C.conditionResult.message};return xo({result:O,...Ro(d)}),O}if(C.type==="passed"){t.info(`Mobile condition ${S} resolved to true, executing ${C.steps.length} steps`),u=!1,c=C.steps;break}}if(!c){t.warn("No mobile conditions resolved to true and no else block was provided, skipping conditional step body");let S={...o,assertionResult:m,steps:[],status:"SUCCESS",startTime:e,endTime:Date.now(),data:d[d.length-1]?.data,message:d[d.length-1]?.message};return xo({result:S,...Ro(d)}),S}u&&t.info("No mobile conditions resolved to true, executing the else block steps"),t.info(`Executing ${c.length} steps in selected mobile conditional block`);let f=await i.startSubSteps(),{results:h,status:g}=await a({...r,listParams:{steps:c,containerName:"mobile conditional block",tracer:f}}),y={...o,assertionResult:m,steps:h,status:g,startTime:e,endTime:Date.now()};return xo({result:y,...Ro([...d,...h])}),y}async function wY(r){let e=Date.now(),t=r.fixtures.controller;try{return await Wxe(r)}catch(n){let o=t.isAborted();return {...r.moduleParams.step,steps:[],type:"MOBILE_MODULE_STEP",startTime:e,endTime:Date.now(),status:o?"CANCELLED":"FAILED",message:o?"Step cancelled.":ne(n)}}}async function Wxe({moduleParams:r,...e}){let t=Date.now(),{step:n,stepTracer:o,executeMobileStepList:i}=r,{controller:a,logger:s}=e.fixtures,l=await qxe({step:n,params:e});Object.keys(l).length>0&&(a.context.setInputs(l),s.info(Xl({json:{inputs:l,moduleId:n.moduleId},maxJsonStringSize:1e3}),"Set mobile module inputs"));let c={};Object.entries(l).forEach(([f,h])=>{c[f]=JSON.stringify(h);});let u={...n,type:"MOBILE_MODULE_STEP",inputs:c,startTime:t,steps:[],endTime:Date.now(),status:"SUCCESS"},d=await o.startSubSteps(),{status:m,results:p}=await i({...e,listParams:{steps:n.steps,containerName:`module ('${n.name}')`,tracer:d}});return u.steps=p,u.status=m,u.endTime=Date.now(),xo({result:u,...Ro(p)}),u}async function qxe({step:r,params:e}){let t={},{logger:n,controller:o}=e.fixtures;for(let i of r.parameters?.parameterNames??[]){let a=r.inputs?.[i]??r.parameters?.defaultParameters?.[i];if(!a){n.warn({k:i},"No value found for parameter in module");continue}t[i]=await Oo({orgId:e.inputs.orgId,code:a,fragment:!0,logger:n,context:o.context,localTools:o.localCodeEvalTools});}return t}var $a="finish",ml=v__default.object({message:v__default.string(),success:v__default.boolean()}),lg=3,cg=`You forgot to call ${$a}. Review the prior conversation and return only the JSON object that should have been passed as the ${$a} 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).`,ug=r=>{let e=tool({description:"Signal that the AI action has reached a terminal state (either success or failure).",inputSchema:ml,toModelOutput:t=>t,execute:async({message:t,success:n})=>{let{contextManager:o,logger:i}=r;return i.info({message:t,success:n},"AI action tool called (finish)"),o.finalState={message:t,status:n?"SUCCESS":"FAILED"},{type:"content",value:[{type:"text",text:"Done"}]}}});return {name:$a,tool:e}};var Cv=["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 Xxe(r){return r!==void 0&&Cv.includes(r)}function wv({input:r,logger:e,tempCaches:t}){let n=tg(r);if(!Xxe(n.stepType))throw new Error(`Unsupported AI Action V3 step type: ${n.stepType}. Supported types: ${Cv.join(", ")}`);let o=kT(n,"ANDROID");if(o.type!=="MOBILE_PRESET_STEP")throw new Error(`AI Action V3 only supports preset steps, got: ${o.type}`);if(n.cacheId&&Ci(o.command)){let i=t[n.cacheId];i?o.command.cache=i.cache:e.warn({cacheId:n.cacheId,commandType:o.command.type},"Temp mobile cache not found for AI action V3 step");}return o}function wm(r){let{id:e,cache:t,...n}=r;return JSON.stringify(n)}function pl(r){if(r.length===0)return "Generated cached steps: (none)";let e=r.map((t,n)=>` ${n}: ${wm(t.command)}`).join(`
|
|
5362
5362
|
`);return `Generated cached steps (${r.length}):
|
|
5363
5363
|
${e}`}var Av=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 t=[];for(let n of e){let o=this.subStepIndex++;this.callbacks.onAiActionEvent?.({type:"STEP_UPDATE",rootStep:this.rootStep,stepIndex:o,step:n,status:"running"});let i=await this.callbacks.executeStep(n,o);if(this.callbacks.onAiActionEvent?.({type:"STEP_UPDATE",rootStep:this.rootStep,stepIndex:o,step:n,status:i.status==="SUCCESS"?"success":"failed",message:i.message}),t.push(i),i.status!=="SUCCESS")break}return this.results.push(...t),t}spliceGeneratedSteps(e,t,...n){return this.generatedSteps.splice(e,t,...n)}saveTempCacheForCommand(e,t){if(!Ci(e)||!e.cache)return;let n=t??crypto.randomUUID();return this.tempCaches[n]={type:e.type,cache:cloneDeep(e.cache)},n}};var Qxe="get_emulator_screenshot",RY=r=>{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:v__default.object({includeEmulatorXml:v__default.boolean().optional()}),toModelOutput:t=>t,execute:async t=>{let{controller:n,logger:o}=r,i={includeEmulatorXml:t.includeEmulatorXml??!1};return o.info(i,"AI action V3 tool called (get_emulator_screenshot)"),Am({controller:n,...i})}});return {name:Qxe,tool:e}};async function Am(r){let{controller:e,includeEmulatorXml:t=!1}=r,n=await e.getScreenshotBase64(),o=await e.getViewportBounds(),i=o.right-o.left,a=o.bottom-o.top,s=[{type:"text",text:`<viewportSize width="${i}" height="${a}" />`}];if(t){let l=await e.getEmulatorDomState();s.push({type:"text",text:`<emulatorXml>
|
|
@@ -5688,7 +5688,7 @@ Choose the SCROLL_TO container based on which region will actually move:
|
|
|
5688
5688
|
- 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.
|
|
5689
5689
|
</rule>
|
|
5690
5690
|
</rules>
|
|
5691
|
-
`;function ZY(r){return xv(r,XY,JY(!1))}var Ha={initializeAIActionConfig:ZY,stepSchema:Xr,resultSchema:Nn};var HMe=5e3;async function e5({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:l,storageFactory:c,localToolsFactory:u,onRemoteEmulatorCreated:d,onRemoteEmulatorDeleted:m,billingReporterFactory:p,globalStateManager:f,getGitMetadata:h,region:g,localApkPath:y,localAvdId:S}){let b=r.id,C=await h(),A=r.handshake.query?.fileName,O=A?xr__default.basename(A,".test.yaml"):"",M=n.id;e=e.child({sessionId:b,testId:M,orgId:t,branch:C.gitBranchName});let R=await c(t),_=n.settings?.defaultEnv,k={};_&&(k=(await R.fetchEnvironment(_,e))?.variables??{});let B={...o.emulator,...n.settings?.emulator},J=f.getSession(b);if(J){if(e.info("Reconnecting to existing Android session"),J.local)return r.emit("session",J.metadata),J.softDeleted=!1,J.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let z=cs.optional().parse(g??B.region),L=z==="local",F,se,D;if(L){if(await f.clearSoftDeletedLocalSessions(e),f.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{avdId:uo,apkFilePath:hl,apkFilePathSource:zm}=_u({overrideAvdId:S,overrideApkFilePath:y,emulatorSettings:B,defaultApkFilePath:n.settings?.defaultApkFilePath,envVariables:k}),$m=Cd({apkFilePath:hl,source:zm});if(!uo)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 ${ts} key on the environment.`);D={avdId:uo,apkFilePath:$m};}else F=n.settings?.defaultChannel,se=n.settings?.defaultTag,D={region:z===Kn?void 0:z,apkToInstall:F?{channel:F,tag:se}:void 0,osVersion:B.remoteEmulatorSettings?.androidVersion??Tu};let j=Date.now(),Q=await i({socket:r,logger:e,creationOpts:D}),{driver:fe,cleanup:le,emulatorName:ae,adbPort:_e}=Q,je,Oe,I,me,Ce,ia;"limbarClient"in Q&&(je=Q.limbarClient,Oe=Q.limbarToken,I=Q.limbarUrl,me=Q.limbarRegion,Ce=Q.limbarOsVersion,ia=Q.playwrightDevice);let An=xr__default.join(tmpdir(),`logcat-logs-${t}-${M}-${b}.txt`);L||await d?.({emulatorName:ae,platform:"ANDROID"}),e.info({adbPort:_e,apkChannel:F,apkTag:se,duration:Date.now()-j,emulatorName:ae},"Android emulator session initiated"),e=e.child({emulator:ae});let qa=!1,aa=!1,Ka,be,Nc,Bm=async()=>{if(qa)return;qa=!0,aa=!0,clearInterval(Nc),Nc=void 0;let hl=[async()=>{await be?.cleanup();},async()=>{await Ka?.();},async()=>{await le(),L||await m?.({emulatorName:ae,platform:"ANDROID"});}].map(zm=>zm().catch($m=>{e.warn({err:$m},"Failed to clean up socket server resource");}));await q(Promise.allSettled(hl),{milliseconds:HMe,fallback:()=>{}});};f.registerPendingSession(b,{platform:"ANDROID",cleanup:Bm,emulatorName:ae,local:L});let lC=async()=>{Ka=await fe.executeInNativeContext(e,d9=>kb({driver:d9,onLogs:ce=>{r.emit("logcatLogs",ce);},logFilePath:An}),{operationName:"startLogcatListener"});let uo=await a(t,e),hl=await s(t,e),zm=await l(t,e),$m=u?await u(t):void 0,c9=new Di({logger:e,reporter:await p(t),runType:"mobile-test-run",runId:b,testMetadata:{id:n.id,name:O},isInteractive:!0}),NO=new Eo({variablesFromEnvironment:k,envName:_,testName:O});if(be=await ll.init({driver:fe,generator:uo,logger:e,limbarClient:je,playwrightDevice:ia,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...B,browserSettings:o.browser}},fixtures:{storage:R,browserEnricher:zm,browserGenerator:hl,localCodeEvalTools:$m,testContext:NO},orgId:t,adbPort:_e,abortController:new AbortController}),!be)throw new Error("Failed to initialize Android controller");let LO=be;if(aa||!r.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");let u9=await LO.getViewportBounds();if(aa||!r.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");Nc=jMe({socket:r,testContext:NO});let cC={sessionId:b,testId:M,orgId:t,emulatorName:ae,testName:O,limbarUrl:I,limbarToken:Oe,limbarRegion:me,limbarOsVersion:Ce,viewportBounds:u9,envName:_};return f.registerSession(b,{platform:"ANDROID",controller:LO,cleanup:Bm,emulatorName:ae,local:L,metadata:cC,logFilePath:An,helpers:Va,usageTracker:c9}),r.emit("session",cC),cC};try{return await lC()}catch(uo){throw await f.removeSession(b,e),uo}}function jMe({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t});},3e3)}async function t5({socket:r,logger:e,globalStateManager:t,authorization:n}){let o=r.id,i=t.getSession(o);i&&i.platform==="ANDROID"&&n&&i.logFilePath&&GMe({testId:i.metadata.testId,sessionId:o,logFilePath:i.logFilePath,authorization:n,logger:e}),await t.removeSession(o,e);}async function GMe({testId:r,sessionId:e,logFilePath:t,authorization:n,logger:o}){try{let i;try{i=await Mv.stat(t);}catch{o.debug({logFilePath:t},"No logcat file found to upload");return}if(i.size===0){o.debug({logFilePath:t},"Logcat file is empty, skipping upload"),await Mv.unlink(t);return}let a=new Er(n),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:r,sessionId:e}),l=await Mv.readFile(t),c=await fetch(s,{headers:{"Content-Length":l.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:l});if(c.status!==200)throw new Error(`Failed to upload logcat: ${c.status} ${await c.text()}`);o.info({testId:r,sessionId:e,objectUrl:$S(s)},"Logcat file uploaded successfully");}catch(i){o.warn({err:i,testId:r,sessionId:e},"Failed to upload logcat file");}finally{try{await Mv.unlink(t);}catch(i){o.warn({err:i,logFilePath:t},"Failed to delete temp logcat file");}}}var WMe=({socket:r,globalStateManager:e})=>async()=>{let t=e.getSession(r.id);if(!t)throw new Error("No active Mobile session found");t.controller.abort();},r5={event:"cancel",createHandler:WMe};var qMe=({logger:r,globalStateManager:e,socket:t})=>async(n,o)=>{let i=e.getSession(t.id);if(!i){o({err:"No active Mobile session found"});return}let a=i.controller;a.resetAbortController();let s=Date.now();try{let l=await a.getEmulatorDomState();r.info({durationMs:Date.now()-s},"Fetched screen XML"),o({screenXml:l});}catch(l){r.error({err:l},"Error fetching screen XML from the session controller"),o({err:l.message});}},n5={event:"fetchScreenXml",createHandler:qMe};var jI=class{parentTracer;socket;step;orgId;interactionTracer;platform;constructor({step:e,socket:t,parentTracer:n,orgId:o,platform:i}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o,this.platform=i,this.interactionTracer=new No,tn.initializeRootTracerContext(this.interactionTracer);}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:t,step:n}=e;if(!Ly(n))return;let o=Ny(n);Et.distribution("test_mobile_step_duration",t,[`type:${o}`,`platform:${this.platform.toLowerCase()}`,"executor:editor",`orgId:${this.orgId}`]);}async finish(e){this.interactionTracer.finish();let t=this.interactionTracer.getRootSpan(),n={result:e.result,parentStepIdChain:e.parentStepIdChain,trace:zw.parse(t)};switch(n.result.status){case"SUCCESS":this.socket.emit("success",n);break;case"FAILED":this.socket.emit("failure",n);break;case"CANCELLED":this.socket.emit("cancelled",n);break}return {trace:t}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new xm({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId,platform:this.platform})}},xm=class{parentTracer;parentStep;socket;orgId;platform;constructor({parentStep:e,socket:t,parentTracer:n,orgId:o,platform:i}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o,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 jI({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId,platform:this.platform})}async getScreenshot(e){}},_v=class{constructor(e,t,n){this.socket=e;this.orgId=t;this.platform=n;}appendLogs(){}setActiveVideo(){}async finish(){this.socket.emit("finished");}async startBeforeStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startMainStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startAfterStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}};var KMe=({metadata:r,logger:e,globalStateManager:t,socket:n,cacheStorageFactory:o,getGitMetadata:i})=>async(a,s)=>{let l=t.getSession(n.id);if(!l)throw new Error("No active Mobile session found");let c=await i(),u=e.child({testId:a.testMetadata.id,branch:c.gitBranchName}),d=await o(r.orgId,c);l.controller.resetAbortController();let m=l.usageTracker,p;try{p=await XMe({session:l,params:a,metadata:r,testLogger:u,cacheStorage:d,usageTracker:m,socket:n});}finally{await m.flush(u);}let f={results:l.helpers.resultSchema.array().parse(p.results),status:p.status};s?.(f);};async function XMe({session:r,...e}){switch(r.platform){case"ANDROID":return o5({session:r,...e});case"IOS":return o5({session:r,...e});default:return (n=>{throw new Error(`Unsupported platform: ${n}`)})(r)}}async function o5({session:r,params:e,metadata:t,testLogger:n,cacheStorage:o,usageTracker:i,socket:a}){let s=new _v(a,t.orgId,r.platform);try{return await Rm({platform:r.platform,work:{fastForwardingToStep:!!e.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:r.controller,logger:n,cacheStorage:o,usageTracker:i},containerName:"entire test",inputs:{steps:r.helpers.stepSchema.array().parse(e.steps),beforeSteps:e.beforeSteps?r.helpers.stepSchema.array().parse(e.beforeSteps):void 0,afterSteps:e.afterSteps?r.helpers.stepSchema.array().parse(e.afterSteps):void 0,fromStep:e.fromStep,toStep:e.toStep,orgId:t.orgId,testName:t.testName,testMetadata:e.testMetadata,interactive:!0},envName:t.envName,tracer:s,callbacks:{step:{onAiActionEvent:l=>{a.emit("aiActionEvent",l);}}},helpers:r.helpers})}finally{await s.finish();}}var i5={event:"execute",createHandler:KMe};var JMe=({socket:r,globalStateManager:e,keepSessionAlive:t})=>{let n=debounce(t,3e4,{maxWait:6e4});return async()=>{let o=e.getSession(r.id);if(!o)throw new Error("No active Mobile session found");o.emulatorName&&(o.local||n(o.platform,o.emulatorName));}},a5={event:"keepalive",createHandler:JMe};var ZMe=({socket:r,globalStateManager:e,logger:t})=>async(n,o)=>{let i=e.getSession(r.id);if(!i){let s="No active session found";t.error(s),o?.({success:!1,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),t.info({platform:i.platform},"Resetting emulator state");try{await a.softReset(),t.info({platform:i.platform},"Emulator reset completed"),o?.({success:!0,message:"Emulator reset successfully"});}catch(s){let l=ne(s);t.error({err:s,platform:i.platform},"Failed to reset emulator"),o?.({success:!1,err:`Failed to reset emulator: ${l}`});}},s5={event:"reset",createHandler:ZMe};var l5=[i5,r5,s5,a5,n5];var e_e=5e3;async function c5({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,localIosDeviceType:i,iosDriverFactory:a,mobileGeneratorFactory:s,browserGeneratorFactory:l,browserEnricherFactory:c,billingReporterFactory:u,storageFactory:d,localToolsFactory:m,onRemoteEmulatorCreated:p,onRemoteEmulatorDeleted:f,globalStateManager:h,getGitMetadata:g,region:y,localAppPath:S}){let b=r.id,C=await g(),A=r.handshake.query?.fileName,O=A?xr__default.basename(A,".test.yaml"):"",M=n.id,R=n.settings?.defaultChannel,_=n.settings?.defaultTag;e=e.child({sessionId:b,testId:M,orgId:t,branch:C.gitBranchName});let k=await d(t),B=n.settings?.defaultEnv,J={};B&&(J=(await k.fetchEnvironment(B,e))?.variables??{});let z={...o.emulator,...n.settings?.emulator},L=h.getSession(b);if(L){if(e.info("Reconnecting to existing iOS session"),L.local)return r.emit("session",L.metadata),L.softDeleted=!1,L.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let F=cs.optional().parse(y??z.region),se=F==="local",D;if(se){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{deviceType:An,appFilePath:qa,appFilePathSource:aa}=Pu({overrideDeviceType:i,overrideAppFilePath:S,emulatorSettings:z,defaultAppFilePath:n.settings?.defaultAppFilePath,envVariables:J});if(!An)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 ${rs} key on the environment.`);let Ka=Cm({appFolderPath:qa,source:aa});D={type:"local",deviceType:An,appFilePath:Ka};}else D={type:"remote",region:F===Kn?void 0:F,appToInstall:R?{channel:R,tag:_}:void 0,osVersion:vu};let j=Date.now(),{driver:Q,cleanup:fe,emulator:le,limbarParams:ae}=await a({socket:r,logger:e,creationOpts:D});e=e.child({emulator:le.name}),e.info({duration:Date.now()-j},"iOS emulator session initiated"),se||await p?.({emulatorName:le.name,platform:"IOS"});let _e=!1,je=!1,Oe,I,me,Ce=async()=>{if(_e)return;_e=!0,je=!0,me&&(clearInterval(me),me=void 0);let qa=[async()=>{await I?.cleanup();},async()=>{Oe?.();},async()=>{await fe(),se||await f?.({emulatorName:le.name,platform:"IOS"});}].map(aa=>aa().catch(Ka=>{e.warn({err:Ka},"Failed to clean up socket server resource");}));await q(Promise.allSettled(qa),{milliseconds:e_e,fallback:()=>{}});};h.registerPendingSession(b,{platform:"IOS",cleanup:Ce,emulatorName:le.name,local:se});let ia=async()=>{Oe=await sv({emulator:le,onLogs:hl=>{r.emit("syslogLogs",hl);}});let An=await s(t,e),qa=await l(t,e),aa=await c(t,e),Ka=m?await m(t):void 0,be=new Di({logger:e,reporter:await u(t),runType:"mobile-test-run",runId:b,testMetadata:{id:n.id,name:O},isInteractive:!0}),Nc=new Eo({variablesFromEnvironment:J,envName:B,testName:O});if(I=await dl.init({driver:Q,generator:An,logger:e,emulator:le,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...z,browserSettings:o.browser}},fixtures:{storage:k,browserEnricher:aa,browserGenerator:qa,localCodeEvalTools:Ka,testContext:Nc},orgId:t,abortController:new AbortController}),!I)throw new Error("Failed to initialize iOS controller");let Bm=I;if(je||!r.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");let lC=await Bm.getViewportBounds();if(je||!r.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");me=t_e({socket:r,testContext:Nc});let uo={sessionId:b,testId:M,orgId:t,emulatorName:le.name,testName:O,limbarUrl:ae?.webRtcUrl,limbarToken:ae?.token,limbarRegion:ae?.region,limbarOsVersion:ae?.osVersion,viewportBounds:lC,envName:B};return h.registerSession(b,{platform:"IOS",controller:Bm,cleanup:Ce,emulatorName:le.name,local:se,metadata:uo,helpers:Ha,usageTracker:be}),r.emit("session",uo),uo};try{return await ia()}catch(An){throw await h.removeSession(b,e),An}}function t_e({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t});},3e3)}var Pv=class{sessions=new Map;pendingSessions=new Map;registerPendingSession(e,t){this.pendingSessions.set(e,t);}registerSession(e,t){this.pendingSessions.delete(e),this.sessions.set(e,t);}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let t of this.sessions.values())t.softDeleted===!0&&t.local===!0&&await this.removeSession(t.metadata.sessionId,e);}hasActiveLocalSession(){for(let e of [...this.sessions.values(),...this.pendingSessions.values()])if(e.local===!0)return !0;return !1}async removeSession(e,t){let n=this.sessions.get(e)??this.pendingSessions.get(e);if(!n)return;let o=t.child({sessionId:e,emulatorName:n.emulatorName,platform:n.platform});try{await this.sessions.get(e)?.usageTracker.flush(o);}catch(i){o.error({err:i},"Error flushing usage tracker before cleanup");}try{await n.cleanup?.(),o.info("Emulator cleaned up by removeSession");}catch(i){o.error({err:i},"Error during emulator cleanup");}finally{this.sessions.delete(e),this.pendingSessions.delete(e);}}async removeAllSessions(e){let t=Array.from(new Set([...this.sessions.keys(),...this.pendingSessions.keys()]));await Promise.all(t.map(n=>this.removeSession(n,e)));}};function u5(r){let{logger:e,baseServer:t,globalStateManager:n,settingsFactory:o,getOrgId:i}=r,a=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:!0}}),s=async()=>{await n.removeAllSessions(e);};a.on("connection",async c=>{let u=c.id,d=e.child({sessionId:u});d.info({event:"connection",transport:c.conn.transport.name},"Mobile websocket connection initiated"),c.on("disconnect",async f=>{if(e.info({reason:f},"Disconnect received"),f.includes("namespace disconnect")){await t5({socket:c,globalStateManager:n,logger:d,authorization:r.authorization});return}let h=n.getSession(u);h&&(h.softDeleted=!0);});let m,p;try{let f=c.handshake.query?.testMetadata,h=Ru.parse(JSON.parse(f??"")),g=h.id,y=await i({testId:g});switch(p=await o(y,e),h.platform){case"ANDROID":m=await e5({...r,orgId:y,socket:c,globalStateManager:n,logger:d,globalOrgSettings:p,testMetadata:h});break;case"IOS":m=await c5({...r,orgId:y,socket:c,globalStateManager:n,logger:d,globalOrgSettings:p,testMetadata:h});break;default:throw new Error("Unsupported platform")}}catch(f){d.error({err:f},"Failed to setup mobile connection"),c.emit("error",{message:f instanceof Error?f.message:JSON.stringify(f)}),c.disconnect(!0);return}l5.forEach(f=>l(f,{...r,socket:c,metadata:m,globalOrgSettings:p,logger:d}));});let l=(c,u)=>{let d=c.createHandler(u),m=(...p)=>{c.event!=="keepalive"&&u.logger.debug({event:c.event},`Websocket event (${c.event})`);let f=h=>{u.logger.error({event:c.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(c.event,m);};return {server:a,dispose:s}}async function s_e(r,e){switch(r){case"ANDROID":return {uploadPath:e,cleanup:async()=>{}};case"IOS":{let t=await Tr.promises.mkdtemp(xr__default.join(Ta.tmpdir(),"momentic-mobile-asset-")),n=xr__default.join(t,"app.zip");return await l_e(e,n),{uploadPath:n,cleanup:()=>Tr.promises.rm(t,{recursive:!0,force:!0})}}}}function l_e(r,e){return new Promise((t,n)=>{let o=n_e("zip",{zlib:{level:9}}),i=Tr.createWriteStream(e);i.on("close",()=>t()),i.on("error",n),o.on("error",n),o.on("warning",a=>{a.code!=="ENOENT"&&n(a);}),o.pipe(i),o.directory(r,!1,a=>xr__default.basename(a.name)===".DS_Store"?!1:(a.mode=a.stats?.isDirectory()?493:420,a)),o.finalize().catch(n);})}async function c_e(r){let e=o_e.createHash("md5");await new Promise((n,o)=>{Tr.createReadStream(r).on("data",i=>e.update(i)).on("end",()=>n()).on("error",o);});let t=e.digest();return {md5Base64:t.toString("base64"),md5Hex:t.toString("hex")}}async function Iv({tag:r,channel:e,filePath:t,apiClient:n,consoleLogger:o,logger:i,platform:a}){i.info({channel:e,tag:r,platform:a,filePath:t},"starting asset upload");let s=Date.now(),{uploadPath:l,cleanup:c}=await s_e(a,t);try{let{md5Base64:u,md5Hex:d}=await c_e(l),{size:m}=await Tr.promises.stat(l),p=await n.generateAssetUploadUrl({channel:e,tag:r??"latest",md5:u,platform:a});if(p.md5&&(p.md5===u||p.md5===d)){o.info({channel:e,tag:r,md5:u,md5Hex:d},`Asset ${t} already exists on emulator platform`),i.info({channel:e,tag:r,platform:a,filePath:t,size:m,durationMs:Date.now()-s,skipped:!0},"skipped asset upload (md5 match)");return}if(!p.uploadUrl)throw new w("InternalPlatformError",`No upload URL was given for asset ${t}`);o.info({channel:e,tag:r,md5:u,uploadUrl:p.uploadUrl},`Uploading asset ${t} to emulator platform...`);try{let f=await fetch$1(p.uploadUrl,{headers:{"Content-Length":m.toString(),"Content-Type":"application/octet-stream"},method:"PUT",body:Tr.createReadStream(l),duplex:"half"});if(f.status!==200)throw new w("InternalPlatformError",`Got error response from emulator platform: ${f.status} ${await f.text()}`);o.info({channel:e,tag:r,md5:u},`Asset ${t} was uploaded successfully!`),i.info({channel:e,tag:r,platform:a,filePath:t,size:m,durationMs:Date.now()-s},"finished asset upload");}catch(f){try{await n.deleteAsset(e,r??"latest",a);}catch(h){o.warn({err:h,tag:r,channel:e},"Failed to cleanup asset for failed upload. Please contact Momentic support.");}throw o.error({err:f},"Failed to upload asset"),f}}finally{await c();}}async function Ov({channel:r,tag:e,platform:t,apiClient:n,logger:o}){let i=e??"latest";o.info({channel:r,tag:i,platform:t},`Deleting asset ${r}:${i} (${t})...`),await n.deleteAsset(r,i,t),o.info({channel:r,tag:i,platform:t},`Asset ${r}:${i} (${t}) deleted successfully!`);}var u_e=z.object({emulatorName:z.string(),platform:z.nativeEnum(ze)});z.object({runId:z.string(),emulators:z.array(u_e)});var d5;async function Nv(r){await d5?.registerEmulator(r);}async function Lv(r){await d5?.unregisterEmulator(r);}var Dv=new Pv;var WI="0.88.1",ut=Fu({app:"mobile-desktop-server",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:WI});(async()=>{try{let r=await Lf(ut);r.gitBranchName&&ut.addBinding("branch",r.gitBranchName);}catch{}})();var kv=Router();kv.get("/",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({message:"API client not initialized"});return}let n=await t.getMobileAssets();e.status(200).json(n);}));kv.post("/upload-url",Ue(async(r,e)=>{let t;try{t=$0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}let n=Bt();if(!n){e.status(500).json({error:"API client not initialized"});return}let o=xr__default.resolve(t.filePath);if(!existsSync(o)){e.status(400).json({error:`File not found: ${o}`});return}let i=/\.apk$/i.test(o),a=o.endsWith(".app")&&statSync(o).isDirectory();if(!i&&!a){e.status(400).json({error:"Unsupported file type. Only .apk files and .app directories are supported."});return}await Iv({tag:t.tag,channel:t.channel,filePath:o,apiClient:n,consoleLogger:ut,logger:ut,platform:i?"ANDROID":"IOS"}),e.sendStatus(204);}));kv.delete("/:channel/:tag/:platform",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let{channel:n,tag:o,platform:i}=r.params;if(!n||!o||!i){e.status(400).json({error:"Missing channel, tag, or platform."});return}let a=Jg.safeParse(i.toUpperCase());if(!a.success){e.status(400).json({error:`Invalid platform "${i}". Expected "android" or "ios".`});return}let s=a.data;await Ov({channel:n,tag:o,platform:s,apiClient:t,logger:ut}),e.sendStatus(204);}));var m5=kv;var Pm=Router();async function Fv(r){return (await j1(r,ut)).map(n=>{let o=r.mobileModules[n.moduleId];if(!o){N.warn(`Found a dangling mobile module with ID ${n.moduleId} that could not be found on disk.`);return}return {...o,content:n}}).filter(n=>n!==void 0)}Pm.get("/",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n);e.status(200).json(o);}));Pm.get("/tests-join",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n),i={};for(let s of o)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(n.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await br(s.fullFilePath,ut,n)})));for(let{id:s,name:l,relativePath:c,test:u}of a){let d=new Set;Ts({steps:u.steps,onPreset:()=>!1,onModule:m=>(d.add(m.moduleId),!1)});for(let m of d){let p=i[m];p&&p.tests.push({id:s,name:l,relativePath:c});}}e.status(200).json(i);}));Pm.get("/:moduleId",Ue(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await It(ot()),n=t.mobileModules[r.params.moduleId];if(!n){e.status(404).json({error:"Mobile module not found."});return}try{let o=await Ql(n,t,N);e.json(o);}catch(o){e.status(400).json({err:o});}}));Pm.patch("/:moduleId/metadata",Ue(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=H0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=ot(),o=await It(n);H1({moduleId:r.params.moduleId,patch:t,momenticFiles:o,logger:N,project:n}),e.status(201).json({message:"ok"});}));Pm.post("/",Ue(async(r,e)=>{let t;try{t=G0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{yo(t.name);}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=ot(),i=(await It(n)).mobileModules;if(Object.values(i).find(s=>s.name===t.name)){e.status(400).json({error:`A mobile module with the name "${t.name}" already exists. Please choose a different name.`});return}let a=xr__default.join(n.rootDir,t.folderPath??"");if(!Tr.existsSync(a)||!Tr.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}switch(t.platform){case"ANDROID":{let s=await kf({...t,folder:a,project:n});e.status(201).json(s);return}case"IOS":{let s=await kf({...t,folder:a,project:n});e.status(201).json(s);return}}}));var f5=Pm;var h5=Router();h5.get("/",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n),i=new Set;n?.mobileTests&&Object.values(n.mobileTests).forEach(c=>{c.labels?.forEach(u=>i.add(u));});let a=Array.from(i).sort(),s=Object.values(n.mobileTests),l={labels:a,modules:o,tests:s};e.status(200).json(l);}));var g5=h5;var Uv=Router();Uv.get("/",Ue((r,e)=>{let t=QS(ot(),ut);e.status(200).json(t);}));Uv.get("/names",Ue((r,e)=>{let n=ot().config.environments?.map(o=>o.name)??[];e.status(200).json(n);}));Uv.post("/",Ue((r,e)=>{let t;try{t=V0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{yo(t.name);}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let n=ot();if(n.config.environments?.find(s=>s.name===t.name)){e.status(400).json({error:`An environment with the name "${t.name}" already exists. Please choose a different name.`});return}let i={...n.config,environments:[...n.config.environments??[],{name:t.name}]};n.config=i,dd(i,n.configFilePath);let a=Yl(t.name,n,ut);e.status(201).json(a);}));var y5=Uv;var S5=Router();S5.get("/",Ue((r,e)=>{let t={userId:Ac(),orgId:Hr(),email:b3(),pylonEmailHash:E3(),cliVersion:WI};e.status(200).json(t);}));var b5=S5;var E5=Router();E5.get("/",Ue(async(r,e)=>{let t=r.query.sessionId;if(!t){e.status(400).json({packages:[]});return}let n=Dv.getSession(t);if(!n?.controller){e.status(200).json({packages:[]});return}try{let o=n.controller,{installedApps:i}=await o.getInstalledApps();e.status(200).json({packages:i});}catch(o){ut.error({err:o},"Error fetching installed packages from the session controller"),e.status(200).json({packages:[]});}}));var T5=E5;var v5=Router();v5.get("/",Ue(async(r,e)=>{let t=await ag(ut);e.status(200).json(t);}));var C5=v5;var Bv=Router(),w5=async({platform:r,steps:e,cacheStorage:t,stepId:n,parentStepIdChain:o,testId:i,environment:a})=>{let{result:s,parentChain:l}=vs(e,n,o);if(!s)return;let c=l.filter(u=>u.type==="RESOLVED_MOBILE_MODULE").map(u=>u.id);return await t.getCacheKeyForStep({platform:r,logger:ut,testId:i,environment:a,parentStepIdChain:c,step:s})};Bv.patch("/",Ue(async(r,e)=>{let t=ot(),n=Hr(),o=Bt(),i=t.config?.advanced?.isolateCachesByEnvironment;if(!o){e.status(500).json({error:"API client not initialized"});return}let a;try{a=K0.parse(r.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await Lr(ut,o,t),l=to({logger:ut,orgId:n,client:o,gitMetadata:s,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:i}),c=await w5({cacheStorage:l,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!c){e.status(400).json({error:"Cache-supporting step not found"});return}await o.updateMobileStepCaches({platform:a.platform,body:{entries:[{key:c,organizationId:n,value:a.value,testId:a.testId,environment:i?a.environment:void 0}]},headers:Gp(s)}),e.status(204).send();}));Bv.delete("/entry",Ue(async(r,e)=>{let t=ot(),n=Hr(),o=Bt(),i=t.config?.advanced?.isolateCachesByEnvironment;if(!o){e.status(500).json({error:"API client not initialized"});return}let a;try{a=Y0.parse(r.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await Lr(ut,o,t),l=to({logger:ut,orgId:n,client:o,gitMetadata:s,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:i}),c=await w5({cacheStorage:l,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!c){e.status(400).json({error:"Cache-supporting step not found"});return}await o.deleteMobileStepCacheEntry({platform:a.platform,body:{testId:a.testId,key:c,environment:i?a.environment:void 0},headers:Gp(s)}),e.status(204).send();}));Bv.post("/traces",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=J0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getMobileStepCacheMemoryTraces(n.platform,n);e.status(200).json(o);}));var A5=Bv;R5("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");R5("https://us.i.posthog.com","POSTHOG_WRITE_HOST is not set");var{captureEvent:Ho,setAnalyticsIdentity:zv,shutdownAnalytics:$v}=Uy({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://us.i.posthog.com",platform:"local_mobile_app",identity:"stashed",flushImmediately:!0});var _c=Router();_c.patch("/:testPath",Ue(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=B0.parse(r.body);}catch(l){e.status(400).json({error:`Invalid request body: ${l}`});return}if(n.steps===void 0&&n.beforeSteps===void 0&&n.afterSteps===void 0&&n.settings===void 0&&n.labels===void 0){e.status(400).json({error:"At least one of steps, beforeSteps, afterSteps, settings, or labels is required"});return}let o=ot(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,a=await It(o);await fd({platform:n.platform,filePath:i,steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps,settings:n.settings,labels:n.labels,folder:o.rootDir,project:o,momenticFiles:a,schemaVersion:_n});let s={message:"ok"};e.status(200).json(s);}));_c.post("/",Ue((r,e)=>{let t;try{t=F0.parse(r.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}let{name:n,description:o,settings:i,pathSegments:a,platform:s}=t;if(!n||typeof n!="string"){e.status(400).json({error:"Missing or invalid 'name' in body"});return}try{yo(n);}catch(h){e.status(400).json({error:h.message});return}let l=ot(),c=xr__default.join(l.rootDir,...a??[]),{fullPath:u,testId:d}=ob({name:n,description:o,settings:i,folder:c,platform:s});Ho({type:"test_editor:test_create",test_platform:Zo(s)});let m=xr__default.basename(u),p=xr__default.relative(l.rootDir,u),f={id:d,fileName:m,fullPath:u,relativeFilePath:p};e.status(201).json(f);}));_c.get("/:fileName",Ue(async(r,e)=>{let t=Bt(),n=Hr(),o=r.params.fileName;if(!o){e.status(400).json({error:"Missing fileName in path"});return}if(!t){e.status(500).json({error:"API client not initialized"});return}let i=o.endsWith(".test.yaml")?o:`${o}.test.yaml`,a=xr__default.basename(i).replace(".test.yaml",""),s=ot(),l=await It(s),[c,u]=await Promise.all([br(i,ut,l),Lr(ut,t,s,{includeHostingUsername:!1})]);await to({logger:ut,orgId:n,client:t,gitMetadata:u,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:s.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:ut,platform:c.platform,testId:c.id,environment:c.settings?.defaultEnv,stepLists:{steps:c.steps,...c.beforeSteps&&{beforeSteps:c.beforeSteps},...c.afterSteps&&{afterSteps:c.afterSteps}}});let m={...c,name:a};e.status(200).json(m);}));_c.patch("/:testPath/metadata",Ue(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=z0.parse(r.body);}catch(l){e.status(400).json({error:`Invalid request body: ${l}`});return}let o=ot(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,s={message:"ok",newRelativeTestPath:G1(i,n,o).newRelativeTestPath};e.status(200).json(s);}));_c.delete("/:testPath",Ue((r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n=ot(),o=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,i=xr__default.join(n.rootDir,o);if(!Tr.existsSync(i)){e.status(404).json({error:"Test not found."});return}Tr.unlinkSync(i),e.status(200).json({message:"ok"});}));_c.post("/:testPath/duplicate",Ue(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let n;try{n=W0.parse(r.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}try{yo(n.name);}catch(h){e.status(400).json({error:h.message});return}let o=ot(),i=xr__default.join(o.rootDir,t);if(!Tr.existsSync(i)){e.status(404).json({error:"Test not found."});return}let a=await It(o),s;try{s=await br(i,ut,a);}catch(h){e.status(400).json({error:h.message});return}let l=v4$1(),{stepsToSave:c}=await Dn({platform:s.platform,stepLists:{steps:s.steps,beforeSteps:s.beforeSteps,afterSteps:s.afterSteps},createNewCacheIds:!0}),u=Kl({fileType:et.MOBILE_TEST,id:l,schemaVersion:_n,description:s.description,platform:s.platform,settings:s.settings,labels:s.labels,...c});c0.parse(u);let d=xr__default.dirname(i),m=xr__default.join(d,`${n.name}.test.yaml`);if(Tr.existsSync(m)){e.status(409).send("A test with this name already exists");return}let p=YR.stringify(u);Tr.writeFileSync(m,p,"utf-8");let f={relativeFilePath:xr__default.relative(o.rootDir,m)};e.status(201).json(f);}));var x5=_c;var M5=Router();M5.get("/",Ue((r,e)=>{let t=ot(),n={ai:t.config.ai,displayRoot:t.config.displayRoot};e.status(200).json(n);}));var _5=M5;var P5=Router();P5.post("/traces",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=Z0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getWebStepCacheMemoryTraces(n);e.status(200).json(o);}));var I5=P5;var Im=class extends yd{constructor(t,n){super(t,n);this.client=t;this.orgId=n;}async fetchEnvironment(t,n){let o=ot();return Yl(t,o,N)}};var I_e=promisify$1(execFile$1);async function O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:o}){let{logger:i,sessionId:a}=r,s=T3(),l=Hr(),c=og(),u=new Er({apiKey:s,baseUrl:c,logger:i}),d=new Im(u,l),m=o??n.settings?.defaultEnv,p={};m&&(p=(await d.fetchEnvironment(m,i))?.variables??{});let f={...e.config.emulator,...n.settings?.emulator},h=new Vi({baseUrl:c,apiKey:s,logger:i,mode:"interactive"}),g=new _a(e.config.ai?.agentConfig,{baseUrl:c,apiKey:s,logger:i,mode:"interactive"}),y=new Ns({baseUrl:c,apiKey:s,logger:i,mode:"interactive"},g),S=new Ls({httpClient:u,fakerSeed:e.config.advanced?.fakerConstantSeed?Iu:void 0}),b=new Eo({variablesFromEnvironment:p,envName:m,testName:t.name}),C=new Di({logger:i,reporter:new Os(u),runType:"mobile-test-run",runId:a,testMetadata:t,isInteractive:!0});return {logger:i,sessionId:a,orgId:l,apiClient:u,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:{storage:d,browserEnricher:y,browserGenerator:g,localCodeEvalTools:S,testContext:b},aiSettings:{useMemory:!0,...e.config.ai,...n.settings?.ai},usageTracker:C}}async function N5({provider:r,platform:e,emulatorName:t,cleanupDriver:n}){let o=r==="remote";return o&&await Nv({emulatorName:t,platform:e}),async()=>{await n(),o&&await Lv({emulatorName:t,platform:e});}}async function L5({managedState:r,project:e,testEntity:t,resolvedTest:n,provider:o,envName:i,localAvdId:a,localApkPath:s}){let{logger:l,sessionId:c,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:g,aiSettings:y,usageTracker:S}=await O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:i}),b=n.settings?.defaultChannel,C=n.settings?.defaultTag,A=await O_e({provider:o,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:n,localAvdId:a,localApkPath:s,variablesFromEnvironment:p}),O=o==="local"?"local":"region"in A?A.region:void 0,M=await vd({apiClient:d,logger:l,creationOpts:o==="remote"?{...A,apkToInstall:b?{channel:b,tag:C}:void 0}:A,orgId:u,sessionId:c,callbacks:{onStatusUpdate:k=>{l.info({status:k},"Android session status update");}}}),R=await N5({provider:o,emulatorName:M.emulatorName,platform:"ANDROID",cleanupDriver:async()=>{await M.cleanup();}}),_;try{let k="limbarClient"in M?{limbarClient:M.limbarClient,limbarToken:M.limbarToken,limbarUrl:M.limbarUrl,limbarRegion:M.limbarRegion,playwrightDevice:M.playwrightDevice}:void 0;_=await ll.init({driver:M.driver,generator:h,logger:l,limbarClient:k?.limbarClient,playwrightDevice:k?.playwrightDevice,aiSettings:y,options:{emulator:{...f,region:O,browserSettings:e.config.browser}},fixtures:g,orgId:u,adbPort:M.adbPort,abortController:new AbortController});let B=await _.getViewportBounds(),J=_;return {...r,platform:"ANDROID",provider:o,controller:J,cleanup:[async()=>{await Promise.allSettled([J.cleanup(),R()]);}],testName:t.name,relativeTestPath:t.relativePath,testFileAbsolutePath:xr__default.join(e.rootDir,t.relativePath),envName:m,orgId:u,emulatorName:M.emulatorName,viewportBounds:B,adbPort:M.adbPort,tempCaches:{},limbarUrl:k?.limbarUrl,limbarToken:k?.limbarToken,limbarRegion:k?.limbarRegion,usageTracker:S}}catch(k){let B=_?[_.cleanup(),R()]:[R()];throw await Promise.allSettled(B),k}}async function D5({managedState:r,project:e,testEntity:t,resolvedTest:n,provider:o,envName:i,localDeviceId:a,localAppPath:s}){let{logger:l,sessionId:c,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:g,aiSettings:y,usageTracker:S}=await O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:i}),b=n.settings?.defaultChannel,C=n.settings?.defaultTag,A=N_e({provider:o,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:n,appChannel:b,appTag:C,localDeviceId:a,localAppPath:s,variablesFromEnvironment:p}),O=o==="local"?"local":A.type==="remote"?A.region:void 0,M=await pm({apiClient:d,logger:l,creationOpts:A,orgId:u,sessionId:c,callbacks:{onStatusUpdate:k=>{l.info({status:k},"iOS session status update");}}}),R=await N5({provider:o,emulatorName:M.emulator.name,platform:"IOS",cleanupDriver:async()=>{await M.cleanup();}}),_;try{_=await dl.init({driver:M.driver,generator:h,logger:l,emulator:M.emulator,aiSettings:y,options:{emulator:{...f,region:O,browserSettings:e.config.browser}},fixtures:g,orgId:u,abortController:new AbortController});let k=await _.getViewportBounds(),B=_;return {...r,platform:"IOS",provider:o,controller:B,cleanup:[async()=>{await Promise.allSettled([B.cleanup(),R()]);}],testName:t.name,relativeTestPath:t.relativePath,testFileAbsolutePath:xr__default.join(e.rootDir,t.relativePath),envName:m,orgId:u,emulatorName:M.emulator.name,viewportBounds:k,tempCaches:{},limbarUrl:M.limbarParams?.webRtcUrl,limbarToken:M.limbarParams?.token,limbarRegion:M.limbarParams?.region,usageTracker:S}}catch(k){let B=_?[_.cleanup(),R()]:[R()];throw await Promise.allSettled(B),k}}async function O_e({provider:r,projectRoot:e,emulatorSettings:t,resolvedTest:n,localAvdId:o,localApkPath:i,variablesFromEnvironment:a}){if(r==="remote")return {region:t?.region==="local"?void 0:t?.region,osVersion:t?.remoteEmulatorSettings?.androidVersion??Tu};let s=await KI(),{avdId:l,apkFilePath:c,apkFilePathSource:u}=_u({overrideAvdId:o,overrideApkFilePath:i,emulatorSettings:t,defaultApkFilePath:n.settings?.defaultApkFilePath,envVariables:a});if(!l){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 ${ts} on the environment, or pass localDeviceId directly.${d}${m}`)}if(s.availableAvdIds.length>0&&!s.availableAvdIds.includes(l))throw new Error(`AVD '${l}' is not available on this machine. Available AVDs: ${s.availableAvdIds.join(", ")}.`);return {avdId:l,apkFilePath:Cd({apkFilePath:c,source:u,overrideBaseDir:e})}}function N_e({provider:r,projectRoot:e,emulatorSettings:t,resolvedTest:n,appChannel:o,appTag:i,localDeviceId:a,localAppPath:s,variablesFromEnvironment:l}){if(r==="remote")return {type:"remote",region:t?.region==="local"?void 0:t?.region,appToInstall:o?{channel:o,tag:i}:void 0,osVersion:vu};let{deviceType:c,appFilePath:u,appFilePathSource:d}=Pu({overrideDeviceType:a,overrideAppFilePath:s,emulatorSettings:t,defaultAppFilePath:n.settings?.defaultAppFilePath,envVariables:l});if(!c)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 ${rs} key on the environment.`);return {type:"local",deviceType:c,appFilePath:Cm({appFolderPath:u,source:d,overrideBaseDir:e})}}async function KI(){try{let{stdout:r}=await I_e(L_e(),["-list-avds"],{encoding:"utf8",timeout:5e3});return {availableAvdIds:r.split(/\r?\n/).map(t=>t.trim()).filter(Boolean)}}catch(r){return {availableAvdIds:[],avdDiscoveryError:ne(r)}}}function L_e(){let r=process.platform==="win32"?"emulator.exe":"emulator";return process.env.ANDROID_HOME?xr__default.join(process.env.ANDROID_HOME,"emulator",r):r}var k5=5,XI=class extends LT{isStartingSession=!1;constructor(){super({sessionTypeLabel:"mobile MCP session"});}async kill(e,t){try{let n;for(let i of e.cleanup)try{await i();}catch(a){n??=a;}if(n)throw n;await e.usageTracker.flush(e.logger);let o=RX(e);return await GX({apiClient:Bt(),logger:e.logger,orgId:e.orgId,testId:e.testId,sessionId:e.sessionId,reason:t,report:o}),e.logger.info({sessionId:e.sessionId,reason:t,emulatorName:e.emulatorName},"MCP session cleaned up"),{killed:!0,sessionId:e.sessionId,reason:t,report:o}}catch(n){return e.logger.error({err:n,sessionId:e.sessionId,reason:t},"Failed to clean up mobile MCP session"),{killed:!1,sessionId:e.sessionId,reason:t}}}touchSession(e){let t=super.touchSession(e);return t?.provider==="remote"&&Bt()?.extendEmulatorTtl(t.platform,t.emulatorName).catch(()=>{}),t}async createSession({logger:e,testId:t,idleTimeoutMs:n,provider:o,envName:i,localDeviceId:a,localAppPath:s,project:l}){let c=this.listSessionIds();if(this.isStartingSession||c.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:c},null,2));this.isStartingSession=!0;let u;try{let{entity:d,momenticFiles:m}=await Pa(l,{id:t},"mobileTests"),p=await br(d.fullFilePath,e,m),g=(p.settings?.emulator?.region??l.config.emulator?.region)==="local"?"local":"remote",y=o??g,S,{platform:b}=p,C=e.child({testId:p.id});switch(b){case"ANDROID":u=this.buildManagedSessionState({logger:C,idleTimeoutMs:n,testId:d.id}),S=await L5({managedState:u,project:l,testEntity:d,resolvedTest:p,provider:y,envName:i,localAvdId:a,localApkPath:s});break;case"IOS":u=this.buildManagedSessionState({logger:C,idleTimeoutMs:n,testId:d.id}),S=await D5({managedState:u,project:l,testEntity:d,resolvedTest:p,provider:y,envName:i,localDeviceId:a,localAppPath:s});break;default:return Ir(b)}return C.info({sessionId:S.sessionId,testId:p.id},"Started MCP session for test"),S}catch(d){throw u&&clearTimeout(u.timeoutHandle),d}finally{this.isStartingSession=!1;}}},lo=new XI,Pc=({response:r,sessionId:e,toolName:t})=>{let n=lo.touchSession(e);if(n)return r.addCleanupCallback(()=>{jX({session:n,toolCallId:r.toolCallId});}),HX({session:n,toolCallId:r.toolCallId,toolName:t}),n;r.addError(JSON.stringify({message:`No active session found for id '${e}'.`,availableSessionIds:lo.listSessionIds()},null,2));};var k_e=4e4,F_e=1e4,JI,U5=({staticDir:r})=>{JI=r;},Vv=class r{url;server;constructor({url:e,server:t}){this.url=e,this.server=t;}static async init({logger:e,testId:t,testName:n,sessionId:o,platform:i,limbarUrl:a,limbarToken:s,limbarRegion:l,tabLabel:c}){let u=await $_e({logger:e,assets:U_e()}),d=new URL(`http://localhost:${u.port}/`);return d.searchParams.set("testId",t),n&&d.searchParams.set("testName",n),d.searchParams.set("sessionId",o),d.searchParams.set("platform",i),d.searchParams.set("url",a),d.searchParams.set("token",s),l&&d.searchParams.set("region",l),c&&d.searchParams.set("tabLabel",c),new r({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 U_e(){if(!JI)throw new Error("Remote control viewer static directory is not configured. Pass remoteControlStaticDir when starting the mobile MCP server.");let r=xr__default.resolve(JI),e=xr__default.join(r,"index.html");if(!Tr.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:r,indexHtmlBuffer:Tr.readFileSync(e)}}function YI({response:r,statusCode:e,body:t,allow:n}){let o={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"};n&&(o.Allow=n),r.writeHead(e,o),r.end(t);}function F5({request:r,response:e,buffer:t,contentType:n}){if(e.writeHead(200,{"Content-Type":n,"Cache-Control":"no-store"}),r.method==="HEAD"){e.end();return}e.end(t);}function B_e({staticDir:r,pathname:e}){let t;try{t=decodeURIComponent(e);}catch{return}let n=t==="/"?"index.html":t.replace(/^\/+/,""),o=xr__default.resolve(r,n),i=xr__default.relative(r,o);if(!(i.startsWith("..")||xr__default.isAbsolute(i)))return o}function z_e({request:r,response:e,assets:t}){if(r.method!=="GET"&&r.method!=="HEAD"){YI({response:e,statusCode:405,body:"Method Not Allowed",allow:"GET, HEAD"});return}let n=new URL(r.url??"/","http://localhost").pathname;if(n==="/"||n==="/index.html"){F5({request:r,response:e,buffer:t.indexHtmlBuffer,contentType:"text/html; charset=utf-8"});return}let o=B_e({staticDir:t.staticDir,pathname:n});if(!o){YI({response:e,statusCode:403,body:"Forbidden"});return}if(!Tr.existsSync(o)||!Tr.statSync(o).isFile()){YI({response:e,statusCode:404,body:"Not Found"});return}let i=xr__default.extname(o).toLowerCase(),a=Ll[i]??"application/octet-stream";F5({request:r,response:e,buffer:Tr.readFileSync(o),contentType:a});}async function $_e({logger:r,assets:e}){let t=createServer((i,a)=>z_e({request:i,response:a,assets:e})),n=Math.floor(Math.random()*F_e)+k_e,o=await Es(n,"mobile-mcp-remote-control-viewer");return await new Promise((i,a)=>{let s=l=>{a(l);};t.once("error",s),t.listen(o,()=>{t.off("error",s),i();});}),r.info({port:o,staticDir:e.staticDir},"Started mobile MCP remote control viewer server"),{port:o,server:t}}function ZI({logger:r,applicationName:e,cliVersion:t,serverId:n=randomUUID()}){let o={serverId:n,applicationName:e,cliVersion:t},i=Hr(),a=r.child({orgId:i,userId:Ac(),...o});return {info:o,mcpLogger:a,orgId:i}}function QI({sessionIdleTimeoutMinutes:r}){return (r&&r>=1?r:k5)*60*1e3}async function Hv({project:r,apiKey:e,serverUrl:t,alwaysSaveCache:n,noCache:o,remoteControlStaticDir:i}){U5({staticDir:i}),um(t),QT({alwaysSaveCache:n,noCache:o}),await mm(e),zv({userId:Ac(),orgId:Hr()}),ev(r,a=>ki({configFilePath:a}));}function jv({project:r,logger:e,apiKey:t,serverUrl:n,supportsFileOutput:o,headfulDefault:i,sessionIdleTimeoutMinutes:a,applicationName:s,cliVersion:l,serverId:c}){let{info:u,mcpLogger:d,orgId:m}=ZI({logger:e,applicationName:s,cliVersion:l,serverId:c}),p=new Vi({baseUrl:n,apiKey:t,logger:d,mode:"interactive"});return {context:{project:r,orgId:m,logger:d,generator:p,serverId:u.serverId,saveChangesToDisk:!0,sessionIdleTimeoutMs:QI({sessionIdleTimeoutMinutes:a}),supportsFileOutput:o,headfulDefault:i},info:u}}async function G_e({moduleId:r,name:e,description:t,enabled:n,parameters:o,steps:i,project:a}){let s=await It(a),{stepsToSave:{steps:l}}=await Dn({platform:"ANDROID",stepLists:{steps:i}});pd({content:{platform:"ANDROID",moduleId:r,name:e,description:t,enabled:n,parameters:o,steps:l},schemaVersion:_n,momenticFiles:s,project:a});}function W_e({module:r,inputs:e}){return {...r,id:randomUUID(),type:"RESOLVED_MOBILE_MODULE",inputs:e}}async function B5({project:r,logger:e,testPath:t,saveChangesToDisk:n,params:o}){yo(o.name);let i=await It(r),a;if(o.startIndex!==void 0&&t!==void 0){let m=xr__default.isAbsolute(t)?t:xr__default.join(r.rootDir,t),p=await br(m,e,i);if(p.platform!=="ANDROID")throw new Error("Error: Mobile module creation from tests only supports Android.");a=p.steps;}let{stepsToExtract:s,startIndex:l,endIndex:c}=KX({moduleName:o.name,existingModuleNames:Object.values(i.mobileModules).map(m=>m.name),parameterNames:o.parameters?.parameterNames,defaultParameters:o.parameters?.defaultParameters,parameterEnums:o.parameters?.parameterEnums,moduleInputs:o.moduleInputs,testPath:t,startIndex:o.startIndex,endIndex:o.endIndex,availableSteps:a,containsNestedModuleStep:E1}),u=xr__default.join(r.rootDir,o.folderPath??"");o.folderPath&&Tr.mkdirSync(u,{recursive:!0});let d=await kf({name:o.name,platform:"ANDROID",description:o.description??"",enabled:o.enabled??!0,steps:s,folder:u,project:r});if(o.parameters!==void 0&&(await G_e({moduleId:d.moduleId,name:o.name,description:o.description??"",enabled:o.enabled??!0,parameters:o.parameters,steps:s,project:r}),d={...d,name:o.name,description:o.description??"",parameters:o.parameters}),n&&o.startIndex!==void 0&&t!==void 0){let m=await It(r),p=xr__default.isAbsolute(t)?t:xr__default.join(r.rootDir,t),f=await br(p,e,m);if(f.platform!=="ANDROID")throw new Error("Mobile module was created successfully, but the source test was not Android when reloaded.");let h=W_e({module:d,inputs:o.moduleInputs}),g=[...f.steps];g.splice(l,c-l,h),await fd({platform:"ANDROID",filePath:t,steps:g,folder:r.rootDir,project:r,momenticFiles:m,schemaVersion:_n});}return {module:d}}var z5=En({schema:{name:FN,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:zN})},handle:async(r,e,t)=>{let{project:n,logger:o}=r;try{let i=await Pa(n,e.selector,"mobileModules"),a=await Ql(i.entity,i.momenticFiles,o);t.addPartFromText(JSON.stringify({module:a},null,2));}catch(i){t.addError(ne(i));}}}),$5=En({schema:{name:kN,description:"Create a mobile module. If startIndex is provided, testPath is required and the specified Android test range is extracted into the module, then replaced with a module invocation in that test.",inputSchema:Kw},handle:async(r,e,t)=>{try{let n=Kw.parse(e),{testPath:o,...i}=n,a=mW({projectRoot:r.project.rootDir,filePath:o,pathLabel:"testPath"}),s=await B5({project:r.project,logger:r.logger,testPath:a,saveChangesToDisk:r.saveChangesToDisk,params:i});t.addPartFromText(JSON.stringify(s.module,null,2));}catch(n){t.addError(ne(n));}}});var K_e=`## Note
|
|
5691
|
+
`;function ZY(r){return xv(r,XY,JY(!1))}var Ha={initializeAIActionConfig:ZY,stepSchema:Xr,resultSchema:Nn};var HMe=5e3;async function e5({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,androidDriverFactory:i,mobileGeneratorFactory:a,browserGeneratorFactory:s,browserEnricherFactory:l,storageFactory:c,localToolsFactory:u,onRemoteEmulatorCreated:d,onRemoteEmulatorDeleted:m,billingReporterFactory:p,globalStateManager:f,getGitMetadata:h,region:g,localApkPath:y,localAvdId:S}){let b=r.id,C=await h(),A=r.handshake.query?.fileName,O=A?xr__default.basename(A,".test.yaml"):"",M=n.id;e=e.child({sessionId:b,testId:M,orgId:t,branch:C.gitBranchName});let R=await c(t),_=n.settings?.defaultEnv,k={};_&&(k=(await R.fetchEnvironment(_,e))?.variables??{});let B={...o.emulator,...n.settings?.emulator},J=f.getSession(b);if(J){if(e.info("Reconnecting to existing Android session"),J.local)return r.emit("session",J.metadata),J.softDeleted=!1,J.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let z=cs.optional().parse(g??B.region),L=z==="local",F,se,D;if(L){if(await f.clearSoftDeletedLocalSessions(e),f.hasActiveLocalSession())throw new Error("Another local emulator session is already active. Please close the existing session before creating a new one.");let{avdId:uo,apkFilePath:hl,apkFilePathSource:zm}=_u({overrideAvdId:S,overrideApkFilePath:y,emulatorSettings:B,defaultApkFilePath:n.settings?.defaultApkFilePath,envVariables:k}),$m=Cd({apkFilePath:hl,source:zm});if(!uo)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 ${ts} key on the environment.`);D={avdId:uo,apkFilePath:$m};}else F=n.settings?.defaultChannel,se=n.settings?.defaultTag,D={region:z===Kn?void 0:z,apkToInstall:F?{channel:F,tag:se}:void 0,osVersion:B.remoteEmulatorSettings?.androidVersion??Tu};let j=Date.now(),Q=await i({socket:r,logger:e,creationOpts:D}),{driver:fe,cleanup:le,emulatorName:ae,adbPort:_e}=Q,je,Oe,I,me,Ce,ia;"limbarClient"in Q&&(je=Q.limbarClient,Oe=Q.limbarToken,I=Q.limbarUrl,me=Q.limbarRegion,Ce=Q.limbarOsVersion,ia=Q.playwrightDevice);let An=xr__default.join(tmpdir(),`logcat-logs-${t}-${M}-${b}.txt`);L||await d?.({emulatorName:ae,platform:"ANDROID"}),e.info({adbPort:_e,apkChannel:F,apkTag:se,duration:Date.now()-j,emulatorName:ae},"Android emulator session initiated"),e=e.child({emulator:ae});let qa=!1,aa=!1,Ka,be,Nc,Bm=async()=>{if(qa)return;qa=!0,aa=!0,clearInterval(Nc),Nc=void 0;let hl=[async()=>{await be?.cleanup();},async()=>{await Ka?.();},async()=>{await le(),L||await m?.({emulatorName:ae,platform:"ANDROID"});}].map(zm=>zm().catch($m=>{e.warn({err:$m},"Failed to clean up socket server resource");}));await q(Promise.allSettled(hl),{milliseconds:HMe,fallback:()=>{}});};f.registerPendingSession(b,{platform:"ANDROID",cleanup:Bm,emulatorName:ae,local:L});let lC=async()=>{Ka=await fe.executeInNativeContext(e,d9=>kb({driver:d9,onLogs:ce=>{r.emit("logcatLogs",ce);},logFilePath:An}),{operationName:"startLogcatListener"});let uo=await a(t,e),hl=await s(t,e),zm=await l(t,e),$m=u?await u(t):void 0,c9=new Di({logger:e,reporter:await p(t),runType:"mobile-test-run",runId:b,testMetadata:{id:n.id,name:O},isInteractive:!0}),NO=new Eo({variablesFromEnvironment:k,envName:_,testName:O});if(be=await ll.init({driver:fe,generator:uo,logger:e,limbarClient:je,playwrightDevice:ia,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...B,browserSettings:o.browser}},fixtures:{storage:R,browserEnricher:zm,browserGenerator:hl,localCodeEvalTools:$m,testContext:NO},orgId:t,adbPort:_e,abortController:new AbortController}),!be)throw new Error("Failed to initialize Android controller");let LO=be;if(aa||!r.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");let u9=await LO.getViewportBounds();if(aa||!r.connected)throw new Error("Socket not connected anymore, not proceeding with Android session setup");Nc=jMe({socket:r,testContext:NO});let cC={sessionId:b,testId:M,orgId:t,emulatorName:ae,testName:O,limbarUrl:I,limbarToken:Oe,limbarRegion:me,limbarOsVersion:Ce,viewportBounds:u9,envName:_};return f.registerSession(b,{platform:"ANDROID",controller:LO,cleanup:Bm,emulatorName:ae,local:L,metadata:cC,logFilePath:An,helpers:Va,usageTracker:c9}),r.emit("session",cC),cC};try{return await lC()}catch(uo){throw await f.removeSession(b,e),uo}}function jMe({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t});},3e3)}async function t5({socket:r,logger:e,globalStateManager:t,authorization:n}){let o=r.id,i=t.getSession(o);i&&i.platform==="ANDROID"&&n&&i.logFilePath&&GMe({testId:i.metadata.testId,sessionId:o,logFilePath:i.logFilePath,authorization:n,logger:e}),await t.removeSession(o,e);}async function GMe({testId:r,sessionId:e,logFilePath:t,authorization:n,logger:o}){try{let i;try{i=await Mv.stat(t);}catch{o.debug({logFilePath:t},"No logcat file found to upload");return}if(i.size===0){o.debug({logFilePath:t},"Logcat file is empty, skipping upload"),await Mv.unlink(t);return}let a=new Er(n),{uploadUrl:s}=await a.generateMobileLogcatUploadUrl({testId:r,sessionId:e}),l=await Mv.readFile(t),c=await fetch(s,{headers:{"Content-Length":l.length.toString(),"Content-Type":"text/plain"},method:"PUT",body:l});if(c.status!==200)throw new Error(`Failed to upload logcat: ${c.status} ${await c.text()}`);o.info({testId:r,sessionId:e,objectUrl:$S(s)},"Logcat file uploaded successfully");}catch(i){o.warn({err:i,testId:r,sessionId:e},"Failed to upload logcat file");}finally{try{await Mv.unlink(t);}catch(i){o.warn({err:i,logFilePath:t},"Failed to delete temp logcat file");}}}var WMe=({socket:r,globalStateManager:e})=>async()=>{let t=e.getSession(r.id);if(!t)throw new Error("No active Mobile session found");t.controller.abort();},r5={event:"cancel",createHandler:WMe};var qMe=({logger:r,globalStateManager:e,socket:t})=>async(n,o)=>{let i=e.getSession(t.id);if(!i){o({err:"No active Mobile session found"});return}let a=i.controller;a.resetAbortController();let s=Date.now();try{let l=await a.getEmulatorDomState();r.info({durationMs:Date.now()-s},"Fetched screen XML"),o({screenXml:l});}catch(l){r.error({err:l},"Error fetching screen XML from the session controller"),o({err:l.message});}},n5={event:"fetchScreenXml",createHandler:qMe};var jI=class{parentTracer;socket;step;orgId;interactionTracer;platform;constructor({step:e,socket:t,parentTracer:n,orgId:o,platform:i}){this.socket=t,this.parentTracer=n,this.step=e,this.orgId=o,this.platform=i,this.interactionTracer=new No,tn.initializeRootTracerContext(this.interactionTracer);}attachBeforeScreenshot(){}attachAfterScreenshot(){}attachBeforeXmlSnapshot(){}attachAfterXmlSnapshot(){}recordStepDuration(e){let{durationMs:t,step:n}=e;if(!Ly(n))return;let o=Ny(n);Et.distribution("test_mobile_step_duration",t,[`type:${o}`,`platform:${this.platform.toLowerCase()}`,"executor:editor",`orgId:${this.orgId}`]);}async finish(e){this.interactionTracer.finish();let t=this.interactionTracer.getRootSpan(),n={result:e.result,parentStepIdChain:e.parentStepIdChain,trace:zw.parse(t)};switch(n.result.status){case"SUCCESS":this.socket.emit("success",n);break;case"FAILED":this.socket.emit("failure",n);break;case"CANCELLED":this.socket.emit("cancelled",n);break}return {trace:t}}getParentStepIdChain(){return this.parentTracer?this.parentTracer?.getParentStepIdChain()??[]:[]}async startSubSteps(){return new xm({parentStep:this.step,socket:this.socket,parentTracer:this,orgId:this.orgId,platform:this.platform})}},xm=class{parentTracer;parentStep;socket;orgId;platform;constructor({parentStep:e,socket:t,parentTracer:n,orgId:o,platform:i}){this.parentTracer=n,this.parentStep=e,this.socket=t,this.orgId=o,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 jI({step:e.step,parentTracer:this,socket:this.socket,orgId:this.orgId,platform:this.platform})}async getScreenshot(e){}},_v=class{constructor(e,t,n){this.socket=e;this.orgId=t;this.platform=n;}appendLogs(){}setActiveVideo(){}async finish(){this.socket.emit("finished");}async startBeforeStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startMainStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}async startAfterStepList(){return new xm({parentStep:null,parentTracer:null,socket:this.socket,orgId:this.orgId,platform:this.platform})}};var KMe=({metadata:r,logger:e,globalStateManager:t,socket:n,cacheStorageFactory:o,getGitMetadata:i})=>async(a,s)=>{let l=t.getSession(n.id);if(!l)throw new Error("No active Mobile session found");let c=await i(),u=e.child({testId:a.testMetadata.id,branch:c.gitBranchName}),d=await o(r.orgId,c);l.controller.resetAbortController();let m=l.usageTracker,p;try{p=await XMe({session:l,params:a,metadata:r,testLogger:u,cacheStorage:d,usageTracker:m,socket:n});}finally{await m.flush(u);}let f={results:l.helpers.resultSchema.array().parse(p.results),status:p.status};s?.(f);};async function XMe({session:r,...e}){switch(r.platform){case"ANDROID":return o5({session:r,...e});case"IOS":return o5({session:r,...e});default:return (n=>{throw new Error(`Unsupported platform: ${n}`)})(r)}}async function o5({session:r,params:e,metadata:t,testLogger:n,cacheStorage:o,usageTracker:i,socket:a}){let s=new _v(a,t.orgId,r.platform);try{return await Rm({platform:r.platform,work:{fastForwardingToStep:!!e.fromStep,state:{failureRecoveryDisabled:!0,failureRecoveryAttempts:0}},fixtures:{controller:r.controller,logger:n,cacheStorage:o,usageTracker:i},containerName:"entire test",inputs:{steps:r.helpers.stepSchema.array().parse(e.steps),beforeSteps:e.beforeSteps?r.helpers.stepSchema.array().parse(e.beforeSteps):void 0,afterSteps:e.afterSteps?r.helpers.stepSchema.array().parse(e.afterSteps):void 0,fromStep:e.fromStep,toStep:e.toStep,orgId:t.orgId,testName:t.testName,testMetadata:e.testMetadata,interactive:!0},envName:t.envName,tracer:s,callbacks:{step:{onAiActionEvent:l=>{a.emit("aiActionEvent",l);}}},helpers:r.helpers})}finally{await s.finish();}}var i5={event:"execute",createHandler:KMe};var JMe=({socket:r,globalStateManager:e,keepSessionAlive:t})=>{let n=debounce(t,3e4,{maxWait:6e4});return async()=>{let o=e.getSession(r.id);if(!o)throw new Error("No active Mobile session found");o.emulatorName&&(o.local||n(o.platform,o.emulatorName));}},a5={event:"keepalive",createHandler:JMe};var ZMe=({socket:r,globalStateManager:e,logger:t})=>async(n,o)=>{let i=e.getSession(r.id);if(!i){let s="No active session found";t.error(s),o?.({success:!1,err:s});return}let a=i.controller;a.abort(),a.resetAbortController(),t.info({platform:i.platform},"Resetting emulator state");try{await a.softReset(),t.info({platform:i.platform},"Emulator reset completed"),o?.({success:!0,message:"Emulator reset successfully"});}catch(s){let l=ne(s);t.error({err:s,platform:i.platform},"Failed to reset emulator"),o?.({success:!1,err:`Failed to reset emulator: ${l}`});}},s5={event:"reset",createHandler:ZMe};var l5=[i5,r5,s5,a5,n5];var e_e=5e3;async function c5({socket:r,logger:e,orgId:t,testMetadata:n,globalOrgSettings:o,localIosDeviceType:i,iosDriverFactory:a,mobileGeneratorFactory:s,browserGeneratorFactory:l,browserEnricherFactory:c,billingReporterFactory:u,storageFactory:d,localToolsFactory:m,onRemoteEmulatorCreated:p,onRemoteEmulatorDeleted:f,globalStateManager:h,getGitMetadata:g,region:y,localAppPath:S}){let b=r.id,C=await g(),A=r.handshake.query?.fileName,O=A?xr__default.basename(A,".test.yaml"):"",M=n.id,R=n.settings?.defaultChannel,_=n.settings?.defaultTag;e=e.child({sessionId:b,testId:M,orgId:t,branch:C.gitBranchName});let k=await d(t),B=n.settings?.defaultEnv,J={};B&&(J=(await k.fetchEnvironment(B,e))?.variables??{});let z={...o.emulator,...n.settings?.emulator},L=h.getSession(b);if(L){if(e.info("Reconnecting to existing iOS session"),L.local)return r.emit("session",L.metadata),L.softDeleted=!1,L.metadata;throw new Error("Restoring existing remote emulator sessions is not supported. Please reconnect to a new emulator.")}let F=cs.optional().parse(y??z.region),se=F==="local",D;if(se){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{deviceType:An,appFilePath:qa,appFilePathSource:aa}=Pu({overrideDeviceType:i,overrideAppFilePath:S,emulatorSettings:z,defaultAppFilePath:n.settings?.defaultAppFilePath,envVariables:J});if(!An)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 ${rs} key on the environment.`);let Ka=Cm({appFolderPath:qa,source:aa});D={type:"local",deviceType:An,appFilePath:Ka};}else D={type:"remote",region:F===Kn?void 0:F,appToInstall:R?{channel:R,tag:_}:void 0,osVersion:vu};let j=Date.now(),{driver:Q,cleanup:fe,emulator:le,limbarParams:ae}=await a({socket:r,logger:e,creationOpts:D});e=e.child({emulator:le.name}),e.info({duration:Date.now()-j},"iOS emulator session initiated"),se||await p?.({emulatorName:le.name,platform:"IOS"});let _e=!1,je=!1,Oe,I,me,Ce=async()=>{if(_e)return;_e=!0,je=!0,me&&(clearInterval(me),me=void 0);let qa=[async()=>{await I?.cleanup();},async()=>{Oe?.();},async()=>{await fe(),se||await f?.({emulatorName:le.name,platform:"IOS"});}].map(aa=>aa().catch(Ka=>{e.warn({err:Ka},"Failed to clean up socket server resource");}));await q(Promise.allSettled(qa),{milliseconds:e_e,fallback:()=>{}});};h.registerPendingSession(b,{platform:"IOS",cleanup:Ce,emulatorName:le.name,local:se});let ia=async()=>{Oe=await sv({emulator:le,onLogs:hl=>{r.emit("syslogLogs",hl);}});let An=await s(t,e),qa=await l(t,e),aa=await c(t,e),Ka=m?await m(t):void 0,be=new Di({logger:e,reporter:await u(t),runType:"mobile-test-run",runId:b,testMetadata:{id:n.id,name:O},isInteractive:!0}),Nc=new Eo({variablesFromEnvironment:J,envName:B,testName:O});if(I=await dl.init({driver:Q,generator:An,logger:e,emulator:le,aiSettings:{...o.ai,useMemory:o.ai?.useMemory!==!1,...n.settings?.ai},options:{emulator:{...z,browserSettings:o.browser}},fixtures:{storage:k,browserEnricher:aa,browserGenerator:qa,localCodeEvalTools:Ka,testContext:Nc},orgId:t,abortController:new AbortController}),!I)throw new Error("Failed to initialize iOS controller");let Bm=I;if(je||!r.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");let lC=await Bm.getViewportBounds();if(je||!r.connected)throw new Error("Socket not connected anymore, not proceeding with iOS session setup");me=t_e({socket:r,testContext:Nc});let uo={sessionId:b,testId:M,orgId:t,emulatorName:le.name,testName:O,limbarUrl:ae?.webRtcUrl,limbarToken:ae?.token,limbarRegion:ae?.region,limbarOsVersion:ae?.osVersion,viewportBounds:lC,envName:B};return h.registerSession(b,{platform:"IOS",controller:Bm,cleanup:Ce,emulatorName:le.name,local:se,metadata:uo,helpers:Ha,usageTracker:be}),r.emit("session",uo),uo};try{return await ia()}catch(An){throw await h.removeSession(b,e),An}}function t_e({socket:r,testContext:e}){return setInterval(()=>{let t=e.toEditorDisplayCopy();r.emit("emulatorState",{context:t});},3e3)}var Pv=class{sessions=new Map;pendingSessions=new Map;registerPendingSession(e,t){this.pendingSessions.set(e,t);}registerSession(e,t){this.pendingSessions.delete(e),this.sessions.set(e,t);}getSession(e){return this.sessions.get(e)}async clearSoftDeletedLocalSessions(e){for(let t of this.sessions.values())t.softDeleted===!0&&t.local===!0&&await this.removeSession(t.metadata.sessionId,e);}hasActiveLocalSession(){for(let e of [...this.sessions.values(),...this.pendingSessions.values()])if(e.local===!0)return !0;return !1}async removeSession(e,t){let n=this.sessions.get(e)??this.pendingSessions.get(e);if(!n)return;let o=t.child({sessionId:e,emulatorName:n.emulatorName,platform:n.platform});try{await this.sessions.get(e)?.usageTracker.flush(o);}catch(i){o.error({err:i},"Error flushing usage tracker before cleanup");}try{await n.cleanup?.(),o.info("Emulator cleaned up by removeSession");}catch(i){o.error({err:i},"Error during emulator cleanup");}finally{this.sessions.delete(e),this.pendingSessions.delete(e);}}async removeAllSessions(e){let t=Array.from(new Set([...this.sessions.keys(),...this.pendingSessions.keys()]));await Promise.all(t.map(n=>this.removeSession(n,e)));}};function u5(r){let{logger:e,baseServer:t,globalStateManager:n,settingsFactory:o,getOrgId:i}=r,a=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},pingTimeout:15*60*1e3,pingInterval:15*60*1e3,maxHttpBufferSize:1e7,perMessageDeflate:!0,connectionStateRecovery:{maxDisconnectionDuration:60*60*1e3,skipMiddlewares:!0}}),s=async()=>{await n.removeAllSessions(e);};a.on("connection",async c=>{let u=c.id,d=e.child({sessionId:u});d.info({event:"connection",transport:c.conn.transport.name},"Mobile websocket connection initiated"),c.on("disconnect",async f=>{if(e.info({reason:f},"Disconnect received"),f.includes("namespace disconnect")){await t5({socket:c,globalStateManager:n,logger:d,authorization:r.authorization});return}let h=n.getSession(u);h&&(h.softDeleted=!0);});let m,p;try{let f=c.handshake.query?.testMetadata,h=Ru.parse(JSON.parse(f??"")),g=h.id,y=await i({testId:g});switch(p=await o(y,e),h.platform){case"ANDROID":m=await e5({...r,orgId:y,socket:c,globalStateManager:n,logger:d,globalOrgSettings:p,testMetadata:h});break;case"IOS":m=await c5({...r,orgId:y,socket:c,globalStateManager:n,logger:d,globalOrgSettings:p,testMetadata:h});break;default:throw new Error("Unsupported platform")}}catch(f){d.error({err:f},"Failed to setup mobile connection"),c.emit("error",{message:f instanceof Error?f.message:JSON.stringify(f)}),c.disconnect(!0);return}l5.forEach(f=>l(f,{...r,socket:c,metadata:m,globalOrgSettings:p,logger:d}));});let l=(c,u)=>{let d=c.createHandler(u),m=(...p)=>{c.event!=="keepalive"&&u.logger.debug({event:c.event},`Websocket event (${c.event})`);let f=h=>{u.logger.error({event:c.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(c.event,m);};return {server:a,dispose:s}}async function s_e(r,e){switch(r){case"ANDROID":return {uploadPath:e,cleanup:async()=>{}};case"IOS":{let t=await Tr.promises.mkdtemp(xr__default.join(Ta.tmpdir(),"momentic-mobile-asset-")),n=xr__default.join(t,"app.zip");return await l_e(e,n),{uploadPath:n,cleanup:()=>Tr.promises.rm(t,{recursive:!0,force:!0})}}}}function l_e(r,e){return new Promise((t,n)=>{let o=n_e("zip",{zlib:{level:9}}),i=Tr.createWriteStream(e);i.on("close",()=>t()),i.on("error",n),o.on("error",n),o.on("warning",a=>{a.code!=="ENOENT"&&n(a);}),o.pipe(i),o.directory(r,!1,a=>xr__default.basename(a.name)===".DS_Store"?!1:(a.mode=a.stats?.isDirectory()?493:420,a)),o.finalize().catch(n);})}async function c_e(r){let e=o_e.createHash("md5");await new Promise((n,o)=>{Tr.createReadStream(r).on("data",i=>e.update(i)).on("end",()=>n()).on("error",o);});let t=e.digest();return {md5Base64:t.toString("base64"),md5Hex:t.toString("hex")}}async function Iv({tag:r,channel:e,filePath:t,apiClient:n,consoleLogger:o,logger:i,platform:a}){i.info({channel:e,tag:r,platform:a,filePath:t},"starting asset upload");let s=Date.now(),{uploadPath:l,cleanup:c}=await s_e(a,t);try{let{md5Base64:u,md5Hex:d}=await c_e(l),{size:m}=await Tr.promises.stat(l),p=await n.generateAssetUploadUrl({channel:e,tag:r??"latest",md5:u,platform:a});if(p.md5&&(p.md5===u||p.md5===d)){o.info({channel:e,tag:r,md5:u,md5Hex:d},`Asset ${t} already exists on emulator platform`),i.info({channel:e,tag:r,platform:a,filePath:t,size:m,durationMs:Date.now()-s,skipped:!0},"skipped asset upload (md5 match)");return}if(!p.uploadUrl)throw new w("InternalPlatformError",`No upload URL was given for asset ${t}`);o.info({channel:e,tag:r,md5:u,uploadUrl:p.uploadUrl},`Uploading asset ${t} to emulator platform...`);try{let f=await fetch$1(p.uploadUrl,{headers:{"Content-Length":m.toString(),"Content-Type":"application/octet-stream"},method:"PUT",body:Tr.createReadStream(l),duplex:"half"});if(f.status!==200)throw new w("InternalPlatformError",`Got error response from emulator platform: ${f.status} ${await f.text()}`);o.info({channel:e,tag:r,md5:u},`Asset ${t} was uploaded successfully!`),i.info({channel:e,tag:r,platform:a,filePath:t,size:m,durationMs:Date.now()-s},"finished asset upload");}catch(f){try{await n.deleteAsset(e,r??"latest",a);}catch(h){o.warn({err:h,tag:r,channel:e},"Failed to cleanup asset for failed upload. Please contact Momentic support.");}throw o.error({err:f},"Failed to upload asset"),f}}finally{await c();}}async function Ov({channel:r,tag:e,platform:t,apiClient:n,logger:o}){let i=e??"latest";o.info({channel:r,tag:i,platform:t},`Deleting asset ${r}:${i} (${t})...`),await n.deleteAsset(r,i,t),o.info({channel:r,tag:i,platform:t},`Asset ${r}:${i} (${t}) deleted successfully!`);}var u_e=z.object({emulatorName:z.string(),platform:z.nativeEnum(ze)});z.object({runId:z.string(),emulators:z.array(u_e)});var d5;async function Nv(r){await d5?.registerEmulator(r);}async function Lv(r){await d5?.unregisterEmulator(r);}var Dv=new Pv;var WI="0.88.2",ut=Fu({app:"mobile-desktop-server",hostname:hostname(),disableConsoleLogs:!0}).child({cliVersion:WI});(async()=>{try{let r=await Lf(ut);r.gitBranchName&&ut.addBinding("branch",r.gitBranchName);}catch{}})();var kv=Router();kv.get("/",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({message:"API client not initialized"});return}let n=await t.getMobileAssets();e.status(200).json(n);}));kv.post("/upload-url",Ue(async(r,e)=>{let t;try{t=$0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}let n=Bt();if(!n){e.status(500).json({error:"API client not initialized"});return}let o=xr__default.resolve(t.filePath);if(!existsSync(o)){e.status(400).json({error:`File not found: ${o}`});return}let i=/\.apk$/i.test(o),a=o.endsWith(".app")&&statSync(o).isDirectory();if(!i&&!a){e.status(400).json({error:"Unsupported file type. Only .apk files and .app directories are supported."});return}await Iv({tag:t.tag,channel:t.channel,filePath:o,apiClient:n,consoleLogger:ut,logger:ut,platform:i?"ANDROID":"IOS"}),e.sendStatus(204);}));kv.delete("/:channel/:tag/:platform",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let{channel:n,tag:o,platform:i}=r.params;if(!n||!o||!i){e.status(400).json({error:"Missing channel, tag, or platform."});return}let a=Jg.safeParse(i.toUpperCase());if(!a.success){e.status(400).json({error:`Invalid platform "${i}". Expected "android" or "ios".`});return}let s=a.data;await Ov({channel:n,tag:o,platform:s,apiClient:t,logger:ut}),e.sendStatus(204);}));var m5=kv;var Pm=Router();async function Fv(r){return (await j1(r,ut)).map(n=>{let o=r.mobileModules[n.moduleId];if(!o){N.warn(`Found a dangling mobile module with ID ${n.moduleId} that could not be found on disk.`);return}return {...o,content:n}}).filter(n=>n!==void 0)}Pm.get("/",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n);e.status(200).json(o);}));Pm.get("/tests-join",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n),i={};for(let s of o)i[s.id]={...s,tests:[]};let a=await Promise.all(Object.values(n.mobileTests).map(async s=>({id:s.id,name:s.name,relativePath:s.relativePath,test:await br(s.fullFilePath,ut,n)})));for(let{id:s,name:l,relativePath:c,test:u}of a){let d=new Set;Ts({steps:u.steps,onPreset:()=>!1,onModule:m=>(d.add(m.moduleId),!1)});for(let m of d){let p=i[m];p&&p.tests.push({id:s,name:l,relativePath:c});}}e.status(200).json(i);}));Pm.get("/:moduleId",Ue(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t=await It(ot()),n=t.mobileModules[r.params.moduleId];if(!n){e.status(404).json({error:"Mobile module not found."});return}try{let o=await Ql(n,t,N);e.json(o);}catch(o){e.status(400).json({err:o});}}));Pm.patch("/:moduleId/metadata",Ue(async(r,e)=>{if(!r.params.moduleId){e.status(400).json({error:"Missing moduleId in url path."});return}let t;try{t=H0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let n=ot(),o=await It(n);H1({moduleId:r.params.moduleId,patch:t,momenticFiles:o,logger:N,project:n}),e.status(201).json({message:"ok"});}));Pm.post("/",Ue(async(r,e)=>{let t;try{t=G0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{yo(t.name);}catch(s){e.status(400).json({error:`Invalid module name: ${s}`});return}let n=ot(),i=(await It(n)).mobileModules;if(Object.values(i).find(s=>s.name===t.name)){e.status(400).json({error:`A mobile module with the name "${t.name}" already exists. Please choose a different name.`});return}let a=xr__default.join(n.rootDir,t.folderPath??"");if(!Tr.existsSync(a)||!Tr.statSync(a).isDirectory()){e.status(400).json({error:`The folder configured for mobile module creation does not exist: ${a}`});return}switch(t.platform){case"ANDROID":{let s=await kf({...t,folder:a,project:n});e.status(201).json(s);return}case"IOS":{let s=await kf({...t,folder:a,project:n});e.status(201).json(s);return}}}));var f5=Pm;var h5=Router();h5.get("/",Ue(async(r,e)=>{let t=ot(),n=await It(t),o=await Fv(n),i=new Set;n?.mobileTests&&Object.values(n.mobileTests).forEach(c=>{c.labels?.forEach(u=>i.add(u));});let a=Array.from(i).sort(),s=Object.values(n.mobileTests),l={labels:a,modules:o,tests:s};e.status(200).json(l);}));var g5=h5;var Uv=Router();Uv.get("/",Ue((r,e)=>{let t=QS(ot(),ut);e.status(200).json(t);}));Uv.get("/names",Ue((r,e)=>{let n=ot().config.environments?.map(o=>o.name)??[];e.status(200).json(n);}));Uv.post("/",Ue((r,e)=>{let t;try{t=V0.parse(r.body);}catch(s){e.status(400).json({error:`Invalid request body: ${s}`});return}try{yo(t.name);}catch(s){e.status(400).json({error:`Invalid environment name: ${s}`});return}let n=ot();if(n.config.environments?.find(s=>s.name===t.name)){e.status(400).json({error:`An environment with the name "${t.name}" already exists. Please choose a different name.`});return}let i={...n.config,environments:[...n.config.environments??[],{name:t.name}]};n.config=i,dd(i,n.configFilePath);let a=Yl(t.name,n,ut);e.status(201).json(a);}));var y5=Uv;var S5=Router();S5.get("/",Ue((r,e)=>{let t={userId:Ac(),orgId:Hr(),email:b3(),pylonEmailHash:E3(),cliVersion:WI};e.status(200).json(t);}));var b5=S5;var E5=Router();E5.get("/",Ue(async(r,e)=>{let t=r.query.sessionId;if(!t){e.status(400).json({packages:[]});return}let n=Dv.getSession(t);if(!n?.controller){e.status(200).json({packages:[]});return}try{let o=n.controller,{installedApps:i}=await o.getInstalledApps();e.status(200).json({packages:i});}catch(o){ut.error({err:o},"Error fetching installed packages from the session controller"),e.status(200).json({packages:[]});}}));var T5=E5;var v5=Router();v5.get("/",Ue(async(r,e)=>{let t=await ag(ut);e.status(200).json(t);}));var C5=v5;var Bv=Router(),w5=async({platform:r,steps:e,cacheStorage:t,stepId:n,parentStepIdChain:o,testId:i,environment:a})=>{let{result:s,parentChain:l}=vs(e,n,o);if(!s)return;let c=l.filter(u=>u.type==="RESOLVED_MOBILE_MODULE").map(u=>u.id);return await t.getCacheKeyForStep({platform:r,logger:ut,testId:i,environment:a,parentStepIdChain:c,step:s})};Bv.patch("/",Ue(async(r,e)=>{let t=ot(),n=Hr(),o=Bt(),i=t.config?.advanced?.isolateCachesByEnvironment;if(!o){e.status(500).json({error:"API client not initialized"});return}let a;try{a=K0.parse(r.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await Lr(ut,o,t),l=to({logger:ut,orgId:n,client:o,gitMetadata:s,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:i}),c=await w5({cacheStorage:l,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!c){e.status(400).json({error:"Cache-supporting step not found"});return}await o.updateMobileStepCaches({platform:a.platform,body:{entries:[{key:c,organizationId:n,value:a.value,testId:a.testId,environment:i?a.environment:void 0}]},headers:Gp(s)}),e.status(204).send();}));Bv.delete("/entry",Ue(async(r,e)=>{let t=ot(),n=Hr(),o=Bt(),i=t.config?.advanced?.isolateCachesByEnvironment;if(!o){e.status(500).json({error:"API client not initialized"});return}let a;try{a=Y0.parse(r.body);}catch(u){e.status(400).json({error:`Invalid request body: ${u}`});return}let s=await Lr(ut,o,t),l=to({logger:ut,orgId:n,client:o,gitMetadata:s,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:i}),c=await w5({cacheStorage:l,platform:a.platform,steps:a.steps,stepId:a.stepId,parentStepIdChain:a.parentStepIdChain,testId:a.testId,environment:i?a.environment:void 0});if(!c){e.status(400).json({error:"Cache-supporting step not found"});return}await o.deleteMobileStepCacheEntry({platform:a.platform,body:{testId:a.testId,key:c,environment:i?a.environment:void 0},headers:Gp(s)}),e.status(204).send();}));Bv.post("/traces",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=J0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getMobileStepCacheMemoryTraces(n.platform,n);e.status(200).json(o);}));var A5=Bv;R5("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");R5("https://us.i.posthog.com","POSTHOG_WRITE_HOST is not set");var{captureEvent:Ho,setAnalyticsIdentity:zv,shutdownAnalytics:$v}=Uy({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://us.i.posthog.com",platform:"local_mobile_app",identity:"stashed",flushImmediately:!0});var _c=Router();_c.patch("/:testPath",Ue(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=B0.parse(r.body);}catch(l){e.status(400).json({error:`Invalid request body: ${l}`});return}if(n.steps===void 0&&n.beforeSteps===void 0&&n.afterSteps===void 0&&n.settings===void 0&&n.labels===void 0){e.status(400).json({error:"At least one of steps, beforeSteps, afterSteps, settings, or labels is required"});return}let o=ot(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,a=await It(o);await fd({platform:n.platform,filePath:i,steps:n.steps,beforeSteps:n.beforeSteps,afterSteps:n.afterSteps,settings:n.settings,labels:n.labels,folder:o.rootDir,project:o,momenticFiles:a,schemaVersion:_n});let s={message:"ok"};e.status(200).json(s);}));_c.post("/",Ue((r,e)=>{let t;try{t=F0.parse(r.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}let{name:n,description:o,settings:i,pathSegments:a,platform:s}=t;if(!n||typeof n!="string"){e.status(400).json({error:"Missing or invalid 'name' in body"});return}try{yo(n);}catch(h){e.status(400).json({error:h.message});return}let l=ot(),c=xr__default.join(l.rootDir,...a??[]),{fullPath:u,testId:d}=ob({name:n,description:o,settings:i,folder:c,platform:s});Ho({type:"test_editor:test_create",test_platform:Zo(s)});let m=xr__default.basename(u),p=xr__default.relative(l.rootDir,u),f={id:d,fileName:m,fullPath:u,relativeFilePath:p};e.status(201).json(f);}));_c.get("/:fileName",Ue(async(r,e)=>{let t=Bt(),n=Hr(),o=r.params.fileName;if(!o){e.status(400).json({error:"Missing fileName in path"});return}if(!t){e.status(500).json({error:"API client not initialized"});return}let i=o.endsWith(".test.yaml")?o:`${o}.test.yaml`,a=xr__default.basename(i).replace(".test.yaml",""),s=ot(),l=await It(s),[c,u]=await Promise.all([br(i,ut,l),Lr(ut,t,s,{includeHostingUsername:!1})]);await to({logger:ut,orgId:n,client:t,gitMetadata:u,regenerateCache:!1,noCache:!1,alwaysSaveCache:!1,isolateCachesByEnvironment:s.config?.advanced?.isolateCachesByEnvironment}).resolveEntries({logger:ut,platform:c.platform,testId:c.id,environment:c.settings?.defaultEnv,stepLists:{steps:c.steps,...c.beforeSteps&&{beforeSteps:c.beforeSteps},...c.afterSteps&&{afterSteps:c.afterSteps}}});let m={...c,name:a};e.status(200).json(m);}));_c.patch("/:testPath/metadata",Ue(async(r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n;try{n=z0.parse(r.body);}catch(l){e.status(400).json({error:`Invalid request body: ${l}`});return}let o=ot(),i=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,s={message:"ok",newRelativeTestPath:G1(i,n,o).newRelativeTestPath};e.status(200).json(s);}));_c.delete("/:testPath",Ue((r,e)=>{let t=r.params.testPath;if(!t){e.status(400).json({error:"Missing testPath in path"});return}let n=ot(),o=t.endsWith(".test.yaml")?t:`${t}.test.yaml`,i=xr__default.join(n.rootDir,o);if(!Tr.existsSync(i)){e.status(404).json({error:"Test not found."});return}Tr.unlinkSync(i),e.status(200).json({message:"ok"});}));_c.post("/:testPath/duplicate",Ue(async(r,e)=>{let{testPath:t}=r.params;if(!t){e.status(400).json({error:"Missing testPath in url path."});return}let n;try{n=W0.parse(r.body);}catch(h){e.status(400).json({error:`Invalid request body: ${h}`});return}try{yo(n.name);}catch(h){e.status(400).json({error:h.message});return}let o=ot(),i=xr__default.join(o.rootDir,t);if(!Tr.existsSync(i)){e.status(404).json({error:"Test not found."});return}let a=await It(o),s;try{s=await br(i,ut,a);}catch(h){e.status(400).json({error:h.message});return}let l=v4$1(),{stepsToSave:c}=await Dn({platform:s.platform,stepLists:{steps:s.steps,beforeSteps:s.beforeSteps,afterSteps:s.afterSteps},createNewCacheIds:!0}),u=Kl({fileType:et.MOBILE_TEST,id:l,schemaVersion:_n,description:s.description,platform:s.platform,settings:s.settings,labels:s.labels,...c});c0.parse(u);let d=xr__default.dirname(i),m=xr__default.join(d,`${n.name}.test.yaml`);if(Tr.existsSync(m)){e.status(409).send("A test with this name already exists");return}let p=YR.stringify(u);Tr.writeFileSync(m,p,"utf-8");let f={relativeFilePath:xr__default.relative(o.rootDir,m)};e.status(201).json(f);}));var x5=_c;var M5=Router();M5.get("/",Ue((r,e)=>{let t=ot(),n={ai:t.config.ai,displayRoot:t.config.displayRoot};e.status(200).json(n);}));var _5=M5;var P5=Router();P5.post("/traces",Ue(async(r,e)=>{let t=Bt();if(!t){e.status(500).json({error:"API client not initialized"});return}let n;try{n=Z0.parse(r.body);}catch(i){e.status(400).json({error:`Invalid request body: ${i}`});return}let o=await t.getWebStepCacheMemoryTraces(n);e.status(200).json(o);}));var I5=P5;var Im=class extends yd{constructor(t,n){super(t,n);this.client=t;this.orgId=n;}async fetchEnvironment(t,n){let o=ot();return Yl(t,o,N)}};var I_e=promisify$1(execFile$1);async function O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:o}){let{logger:i,sessionId:a}=r,s=T3(),l=Hr(),c=og(),u=new Er({apiKey:s,baseUrl:c,logger:i}),d=new Im(u,l),m=o??n.settings?.defaultEnv,p={};m&&(p=(await d.fetchEnvironment(m,i))?.variables??{});let f={...e.config.emulator,...n.settings?.emulator},h=new Vi({baseUrl:c,apiKey:s,logger:i,mode:"interactive"}),g=new _a(e.config.ai?.agentConfig,{baseUrl:c,apiKey:s,logger:i,mode:"interactive"}),y=new Ns({baseUrl:c,apiKey:s,logger:i,mode:"interactive"},g),S=new Ls({httpClient:u,fakerSeed:e.config.advanced?.fakerConstantSeed?Iu:void 0}),b=new Eo({variablesFromEnvironment:p,envName:m,testName:t.name}),C=new Di({logger:i,reporter:new Os(u),runType:"mobile-test-run",runId:a,testMetadata:t,isInteractive:!0});return {logger:i,sessionId:a,orgId:l,apiClient:u,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:{storage:d,browserEnricher:y,browserGenerator:g,localCodeEvalTools:S,testContext:b},aiSettings:{useMemory:!0,...e.config.ai,...n.settings?.ai},usageTracker:C}}async function N5({provider:r,platform:e,emulatorName:t,cleanupDriver:n}){let o=r==="remote";return o&&await Nv({emulatorName:t,platform:e}),async()=>{await n(),o&&await Lv({emulatorName:t,platform:e});}}async function L5({managedState:r,project:e,testEntity:t,resolvedTest:n,provider:o,envName:i,localAvdId:a,localApkPath:s}){let{logger:l,sessionId:c,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:g,aiSettings:y,usageTracker:S}=await O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:i}),b=n.settings?.defaultChannel,C=n.settings?.defaultTag,A=await O_e({provider:o,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:n,localAvdId:a,localApkPath:s,variablesFromEnvironment:p}),O=o==="local"?"local":"region"in A?A.region:void 0,M=await vd({apiClient:d,logger:l,creationOpts:o==="remote"?{...A,apkToInstall:b?{channel:b,tag:C}:void 0}:A,orgId:u,sessionId:c,callbacks:{onStatusUpdate:k=>{l.info({status:k},"Android session status update");}}}),R=await N5({provider:o,emulatorName:M.emulatorName,platform:"ANDROID",cleanupDriver:async()=>{await M.cleanup();}}),_;try{let k="limbarClient"in M?{limbarClient:M.limbarClient,limbarToken:M.limbarToken,limbarUrl:M.limbarUrl,limbarRegion:M.limbarRegion,playwrightDevice:M.playwrightDevice}:void 0;_=await ll.init({driver:M.driver,generator:h,logger:l,limbarClient:k?.limbarClient,playwrightDevice:k?.playwrightDevice,aiSettings:y,options:{emulator:{...f,region:O,browserSettings:e.config.browser}},fixtures:g,orgId:u,adbPort:M.adbPort,abortController:new AbortController});let B=await _.getViewportBounds(),J=_;return {...r,platform:"ANDROID",provider:o,controller:J,cleanup:[async()=>{await Promise.allSettled([J.cleanup(),R()]);}],testName:t.name,relativeTestPath:t.relativePath,testFileAbsolutePath:xr__default.join(e.rootDir,t.relativePath),envName:m,orgId:u,emulatorName:M.emulatorName,viewportBounds:B,adbPort:M.adbPort,tempCaches:{},limbarUrl:k?.limbarUrl,limbarToken:k?.limbarToken,limbarRegion:k?.limbarRegion,usageTracker:S}}catch(k){let B=_?[_.cleanup(),R()]:[R()];throw await Promise.allSettled(B),k}}async function D5({managedState:r,project:e,testEntity:t,resolvedTest:n,provider:o,envName:i,localDeviceId:a,localAppPath:s}){let{logger:l,sessionId:c,orgId:u,apiClient:d,resolvedEnvName:m,variablesFromEnvironment:p,emulatorSettings:f,mobileGenerator:h,fixtures:g,aiSettings:y,usageTracker:S}=await O5({managedState:r,project:e,testEntity:t,resolvedTest:n,envName:i}),b=n.settings?.defaultChannel,C=n.settings?.defaultTag,A=N_e({provider:o,projectRoot:e.rootDir,emulatorSettings:f,resolvedTest:n,appChannel:b,appTag:C,localDeviceId:a,localAppPath:s,variablesFromEnvironment:p}),O=o==="local"?"local":A.type==="remote"?A.region:void 0,M=await pm({apiClient:d,logger:l,creationOpts:A,orgId:u,sessionId:c,callbacks:{onStatusUpdate:k=>{l.info({status:k},"iOS session status update");}}}),R=await N5({provider:o,emulatorName:M.emulator.name,platform:"IOS",cleanupDriver:async()=>{await M.cleanup();}}),_;try{_=await dl.init({driver:M.driver,generator:h,logger:l,emulator:M.emulator,aiSettings:y,options:{emulator:{...f,region:O,browserSettings:e.config.browser}},fixtures:g,orgId:u,abortController:new AbortController});let k=await _.getViewportBounds(),B=_;return {...r,platform:"IOS",provider:o,controller:B,cleanup:[async()=>{await Promise.allSettled([B.cleanup(),R()]);}],testName:t.name,relativeTestPath:t.relativePath,testFileAbsolutePath:xr__default.join(e.rootDir,t.relativePath),envName:m,orgId:u,emulatorName:M.emulator.name,viewportBounds:k,tempCaches:{},limbarUrl:M.limbarParams?.webRtcUrl,limbarToken:M.limbarParams?.token,limbarRegion:M.limbarParams?.region,usageTracker:S}}catch(k){let B=_?[_.cleanup(),R()]:[R()];throw await Promise.allSettled(B),k}}async function O_e({provider:r,projectRoot:e,emulatorSettings:t,resolvedTest:n,localAvdId:o,localApkPath:i,variablesFromEnvironment:a}){if(r==="remote")return {region:t?.region==="local"?void 0:t?.region,osVersion:t?.remoteEmulatorSettings?.androidVersion??Tu};let s=await KI(),{avdId:l,apkFilePath:c,apkFilePathSource:u}=_u({overrideAvdId:o,overrideApkFilePath:i,emulatorSettings:t,defaultApkFilePath:n.settings?.defaultApkFilePath,envVariables:a});if(!l){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 ${ts} on the environment, or pass localDeviceId directly.${d}${m}`)}if(s.availableAvdIds.length>0&&!s.availableAvdIds.includes(l))throw new Error(`AVD '${l}' is not available on this machine. Available AVDs: ${s.availableAvdIds.join(", ")}.`);return {avdId:l,apkFilePath:Cd({apkFilePath:c,source:u,overrideBaseDir:e})}}function N_e({provider:r,projectRoot:e,emulatorSettings:t,resolvedTest:n,appChannel:o,appTag:i,localDeviceId:a,localAppPath:s,variablesFromEnvironment:l}){if(r==="remote")return {type:"remote",region:t?.region==="local"?void 0:t?.region,appToInstall:o?{channel:o,tag:i}:void 0,osVersion:vu};let{deviceType:c,appFilePath:u,appFilePathSource:d}=Pu({overrideDeviceType:a,overrideAppFilePath:s,emulatorSettings:t,defaultAppFilePath:n.settings?.defaultAppFilePath,envVariables:l});if(!c)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 ${rs} key on the environment.`);return {type:"local",deviceType:c,appFilePath:Cm({appFolderPath:u,source:d,overrideBaseDir:e})}}async function KI(){try{let{stdout:r}=await I_e(L_e(),["-list-avds"],{encoding:"utf8",timeout:5e3});return {availableAvdIds:r.split(/\r?\n/).map(t=>t.trim()).filter(Boolean)}}catch(r){return {availableAvdIds:[],avdDiscoveryError:ne(r)}}}function L_e(){let r=process.platform==="win32"?"emulator.exe":"emulator";return process.env.ANDROID_HOME?xr__default.join(process.env.ANDROID_HOME,"emulator",r):r}var k5=5,XI=class extends LT{isStartingSession=!1;constructor(){super({sessionTypeLabel:"mobile MCP session"});}async kill(e,t){try{let n;for(let i of e.cleanup)try{await i();}catch(a){n??=a;}if(n)throw n;await e.usageTracker.flush(e.logger);let o=RX(e);return await GX({apiClient:Bt(),logger:e.logger,orgId:e.orgId,testId:e.testId,sessionId:e.sessionId,reason:t,report:o}),e.logger.info({sessionId:e.sessionId,reason:t,emulatorName:e.emulatorName},"MCP session cleaned up"),{killed:!0,sessionId:e.sessionId,reason:t,report:o}}catch(n){return e.logger.error({err:n,sessionId:e.sessionId,reason:t},"Failed to clean up mobile MCP session"),{killed:!1,sessionId:e.sessionId,reason:t}}}touchSession(e){let t=super.touchSession(e);return t?.provider==="remote"&&Bt()?.extendEmulatorTtl(t.platform,t.emulatorName).catch(()=>{}),t}async createSession({logger:e,testId:t,idleTimeoutMs:n,provider:o,envName:i,localDeviceId:a,localAppPath:s,project:l}){let c=this.listSessionIds();if(this.isStartingSession||c.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:c},null,2));this.isStartingSession=!0;let u;try{let{entity:d,momenticFiles:m}=await Pa(l,{id:t},"mobileTests"),p=await br(d.fullFilePath,e,m),g=(p.settings?.emulator?.region??l.config.emulator?.region)==="local"?"local":"remote",y=o??g,S,{platform:b}=p,C=e.child({testId:p.id});switch(b){case"ANDROID":u=this.buildManagedSessionState({logger:C,idleTimeoutMs:n,testId:d.id}),S=await L5({managedState:u,project:l,testEntity:d,resolvedTest:p,provider:y,envName:i,localAvdId:a,localApkPath:s});break;case"IOS":u=this.buildManagedSessionState({logger:C,idleTimeoutMs:n,testId:d.id}),S=await D5({managedState:u,project:l,testEntity:d,resolvedTest:p,provider:y,envName:i,localDeviceId:a,localAppPath:s});break;default:return Ir(b)}return C.info({sessionId:S.sessionId,testId:p.id},"Started MCP session for test"),S}catch(d){throw u&&clearTimeout(u.timeoutHandle),d}finally{this.isStartingSession=!1;}}},lo=new XI,Pc=({response:r,sessionId:e,toolName:t})=>{let n=lo.touchSession(e);if(n)return r.addCleanupCallback(()=>{jX({session:n,toolCallId:r.toolCallId});}),HX({session:n,toolCallId:r.toolCallId,toolName:t}),n;r.addError(JSON.stringify({message:`No active session found for id '${e}'.`,availableSessionIds:lo.listSessionIds()},null,2));};var k_e=4e4,F_e=1e4,JI,U5=({staticDir:r})=>{JI=r;},Vv=class r{url;server;constructor({url:e,server:t}){this.url=e,this.server=t;}static async init({logger:e,testId:t,testName:n,sessionId:o,platform:i,limbarUrl:a,limbarToken:s,limbarRegion:l,tabLabel:c}){let u=await $_e({logger:e,assets:U_e()}),d=new URL(`http://localhost:${u.port}/`);return d.searchParams.set("testId",t),n&&d.searchParams.set("testName",n),d.searchParams.set("sessionId",o),d.searchParams.set("platform",i),d.searchParams.set("url",a),d.searchParams.set("token",s),l&&d.searchParams.set("region",l),c&&d.searchParams.set("tabLabel",c),new r({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 U_e(){if(!JI)throw new Error("Remote control viewer static directory is not configured. Pass remoteControlStaticDir when starting the mobile MCP server.");let r=xr__default.resolve(JI),e=xr__default.join(r,"index.html");if(!Tr.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:r,indexHtmlBuffer:Tr.readFileSync(e)}}function YI({response:r,statusCode:e,body:t,allow:n}){let o={"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"};n&&(o.Allow=n),r.writeHead(e,o),r.end(t);}function F5({request:r,response:e,buffer:t,contentType:n}){if(e.writeHead(200,{"Content-Type":n,"Cache-Control":"no-store"}),r.method==="HEAD"){e.end();return}e.end(t);}function B_e({staticDir:r,pathname:e}){let t;try{t=decodeURIComponent(e);}catch{return}let n=t==="/"?"index.html":t.replace(/^\/+/,""),o=xr__default.resolve(r,n),i=xr__default.relative(r,o);if(!(i.startsWith("..")||xr__default.isAbsolute(i)))return o}function z_e({request:r,response:e,assets:t}){if(r.method!=="GET"&&r.method!=="HEAD"){YI({response:e,statusCode:405,body:"Method Not Allowed",allow:"GET, HEAD"});return}let n=new URL(r.url??"/","http://localhost").pathname;if(n==="/"||n==="/index.html"){F5({request:r,response:e,buffer:t.indexHtmlBuffer,contentType:"text/html; charset=utf-8"});return}let o=B_e({staticDir:t.staticDir,pathname:n});if(!o){YI({response:e,statusCode:403,body:"Forbidden"});return}if(!Tr.existsSync(o)||!Tr.statSync(o).isFile()){YI({response:e,statusCode:404,body:"Not Found"});return}let i=xr__default.extname(o).toLowerCase(),a=Ll[i]??"application/octet-stream";F5({request:r,response:e,buffer:Tr.readFileSync(o),contentType:a});}async function $_e({logger:r,assets:e}){let t=createServer((i,a)=>z_e({request:i,response:a,assets:e})),n=Math.floor(Math.random()*F_e)+k_e,o=await Es(n,"mobile-mcp-remote-control-viewer");return await new Promise((i,a)=>{let s=l=>{a(l);};t.once("error",s),t.listen(o,()=>{t.off("error",s),i();});}),r.info({port:o,staticDir:e.staticDir},"Started mobile MCP remote control viewer server"),{port:o,server:t}}function ZI({logger:r,applicationName:e,cliVersion:t,serverId:n=randomUUID()}){let o={serverId:n,applicationName:e,cliVersion:t},i=Hr(),a=r.child({orgId:i,userId:Ac(),...o});return {info:o,mcpLogger:a,orgId:i}}function QI({sessionIdleTimeoutMinutes:r}){return (r&&r>=1?r:k5)*60*1e3}async function Hv({project:r,apiKey:e,serverUrl:t,alwaysSaveCache:n,noCache:o,remoteControlStaticDir:i}){U5({staticDir:i}),um(t),QT({alwaysSaveCache:n,noCache:o}),await mm(e),zv({userId:Ac(),orgId:Hr()}),ev(r,a=>ki({configFilePath:a}));}function jv({project:r,logger:e,apiKey:t,serverUrl:n,supportsFileOutput:o,headfulDefault:i,sessionIdleTimeoutMinutes:a,applicationName:s,cliVersion:l,serverId:c}){let{info:u,mcpLogger:d,orgId:m}=ZI({logger:e,applicationName:s,cliVersion:l,serverId:c}),p=new Vi({baseUrl:n,apiKey:t,logger:d,mode:"interactive"});return {context:{project:r,orgId:m,logger:d,generator:p,serverId:u.serverId,saveChangesToDisk:!0,sessionIdleTimeoutMs:QI({sessionIdleTimeoutMinutes:a}),supportsFileOutput:o,headfulDefault:i},info:u}}async function G_e({moduleId:r,name:e,description:t,enabled:n,parameters:o,steps:i,project:a}){let s=await It(a),{stepsToSave:{steps:l}}=await Dn({platform:"ANDROID",stepLists:{steps:i}});pd({content:{platform:"ANDROID",moduleId:r,name:e,description:t,enabled:n,parameters:o,steps:l},schemaVersion:_n,momenticFiles:s,project:a});}function W_e({module:r,inputs:e}){return {...r,id:randomUUID(),type:"RESOLVED_MOBILE_MODULE",inputs:e}}async function B5({project:r,logger:e,testPath:t,saveChangesToDisk:n,params:o}){yo(o.name);let i=await It(r),a;if(o.startIndex!==void 0&&t!==void 0){let m=xr__default.isAbsolute(t)?t:xr__default.join(r.rootDir,t),p=await br(m,e,i);if(p.platform!=="ANDROID")throw new Error("Error: Mobile module creation from tests only supports Android.");a=p.steps;}let{stepsToExtract:s,startIndex:l,endIndex:c}=KX({moduleName:o.name,existingModuleNames:Object.values(i.mobileModules).map(m=>m.name),parameterNames:o.parameters?.parameterNames,defaultParameters:o.parameters?.defaultParameters,parameterEnums:o.parameters?.parameterEnums,moduleInputs:o.moduleInputs,testPath:t,startIndex:o.startIndex,endIndex:o.endIndex,availableSteps:a,containsNestedModuleStep:E1}),u=xr__default.join(r.rootDir,o.folderPath??"");o.folderPath&&Tr.mkdirSync(u,{recursive:!0});let d=await kf({name:o.name,platform:"ANDROID",description:o.description??"",enabled:o.enabled??!0,steps:s,folder:u,project:r});if(o.parameters!==void 0&&(await G_e({moduleId:d.moduleId,name:o.name,description:o.description??"",enabled:o.enabled??!0,parameters:o.parameters,steps:s,project:r}),d={...d,name:o.name,description:o.description??"",parameters:o.parameters}),n&&o.startIndex!==void 0&&t!==void 0){let m=await It(r),p=xr__default.isAbsolute(t)?t:xr__default.join(r.rootDir,t),f=await br(p,e,m);if(f.platform!=="ANDROID")throw new Error("Mobile module was created successfully, but the source test was not Android when reloaded.");let h=W_e({module:d,inputs:o.moduleInputs}),g=[...f.steps];g.splice(l,c-l,h),await fd({platform:"ANDROID",filePath:t,steps:g,folder:r.rootDir,project:r,momenticFiles:m,schemaVersion:_n});}return {module:d}}var z5=En({schema:{name:FN,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:zN})},handle:async(r,e,t)=>{let{project:n,logger:o}=r;try{let i=await Pa(n,e.selector,"mobileModules"),a=await Ql(i.entity,i.momenticFiles,o);t.addPartFromText(JSON.stringify({module:a},null,2));}catch(i){t.addError(ne(i));}}}),$5=En({schema:{name:kN,description:"Create a mobile module. If startIndex is provided, testPath is required and the specified Android test range is extracted into the module, then replaced with a module invocation in that test.",inputSchema:Kw},handle:async(r,e,t)=>{try{let n=Kw.parse(e),{testPath:o,...i}=n,a=mW({projectRoot:r.project.rootDir,filePath:o,pathLabel:"testPath"}),s=await B5({project:r.project,logger:r.logger,testPath:a,saveChangesToDisk:r.saveChangesToDisk,params:i});t.addPartFromText(JSON.stringify(s.module,null,2));}catch(n){t.addError(ne(n));}}});var K_e=`## Note
|
|
5692
5692
|
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 Ic({controller:r,supportsFileOutput:e,rootDir:t}){let n;try{n=await r.getScreenshotBase64();}catch{try{n=await r.getScreenshotBase64();}catch(i){return yt({text:"MCP emulator screenshot capture failed. Error on retry: "+ne(i),section:"Screenshot"})}}if(e){Na(t);let o=La({rootDir:t,entity:"screenshot",ext:"png"});return await writeFile(o,Buffer.from(n,"base64")),[...wM({base64Data:n,mediaType:"image/png",section:"Screenshot"}),...yt({text:qi({filePath:o,title:"Screenshot"}),section:"Screenshot Path"})]}return wM({base64Data:n,mediaType:"image/png",section:"Screenshot"})}async function X_e({controller:r,emulatorName:e,supportsFileOutput:t,returnSnapshot:n=!0,rootDir:o}){let i=await r.getViewportBounds(),a=i.right-i.left,s=i.bottom-i.top,l=[`- Emulator Name: ${e}`,`- Viewport Size: ${a}x${s}`,`- Viewport Bounds: left=${i.left}, top=${i.top}, right=${i.right}, bottom=${i.bottom}`];if(n)try{let u=await r.getEmulatorDomState();l.push("- Emulator Snapshot:","```xml",u,"```");}catch(u){l.push("MCP emulator XML state capture failed. Error: "+ne(u));}let c=l.join(`
|
|
5693
5693
|
`);if(t){Na(o);let u=La({rootDir:o,entity:"emulator-state",ext:"txt"});return await writeFile(u,c,"utf8"),yt({text:qi({filePath:u,title:"Emulator state"}),section:"Emulator State"})}return yt({text:c,section:"Emulator State"})}function V5(r,e){return [`## ${r}`,`Count: ${e.length}`,e.length>0?e.map(t=>`- ${t}`).join(`
|
|
5694
5694
|
`):"- None"].join(`
|
|
@@ -5704,7 +5704,7 @@ The "Installed apps" list may still include default or system packages; it is a
|
|
|
5704
5704
|
`);}R5("phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI","POSTHOG_WEB_WRITE_KEY is not set");R5("https://us.i.posthog.com","POSTHOG_WRITE_HOST is not set");var{captureEvent:Eg,setAnalyticsIdentity:TJ,shutdownAnalytics:vJ}=Uy({writeKey:"phc_WRWd8LYIv6rolgDsyCdrPpxtZhsu6qXAkEwPicl44bI",host:"https://us.i.posthog.com",platform:"mobile_cli",identity:"stashed",flushImmediately:!0});async function aO({tests:r,momenticFiles:e,project:t,yes:n,include:o,exclude:i,labels:a,logger:s,quarantinedTestsMetadata:l}){let c=new Set;if(r&&r.length>0){let d=r.some(p=>Tr.existsSync(p)),m=cwd();d?(m!==t.rootDir&&s.warn(`The current working directory ('${m}') is different from the project root directory ('${t.rootDir}'). All test path arguments will be resolved relative to the current working directory and only those tests matched by the project inclusion configuration will be ran. To avoid confusion, Momentic strongly recommends running the CLI from the project root directory or using substring filters rather than file paths.`),s.info(`Reading tests from the following local file paths:
|
|
5705
5705
|
- ${r.join(`
|
|
5706
5706
|
- `)}
|
|
5707
|
-
`),r.forEach(p=>{if(!Tr.existsSync(p))throw new Error(`Path '${p}' does not exist.`);let f,h;try{f=Tr.statSync(p),h=f.isDirectory();}catch(y){s.warn({err:y},`Skipping path ${p} because it cannot be read`);return}let g=xr__default.resolve(p);Object.values(e.mobileTests).filter(y=>h?y.fullFilePath.startsWith(g):y.fullFilePath===g).forEach(y=>{c.add(y.fullFilePath);});})):(s.info("The arguments provided don't appear to be valid paths. Treating them as substrings instead... "),Object.values(e.mobileTests).forEach(p=>{r.some(f=>p.relativePath.includes(f))&&c.add(p.fullFilePath);}));}else {!n&&!await rd("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let d=Object.values(e.mobileTests);s.info(`Reading all ${d.length} mobile tests in the project from local disk.`),d.forEach(m=>{c.add(m.fullFilePath);});}for(let d of Array.from(c)){let m=xr__default.relative(t.rootDir,d);o&&!o.some(p=>new RegExp(p).test(m))&&c.delete(d),i&&i.some(p=>new RegExp(p).test(m))&&c.delete(d);}return (await Promise.all(Array.from(c).map(async d=>{try{let m=xr__default.relative(t.rootDir,d),p=await br(d,s,e),f=xr__default.basename(d,".test.yaml");if(p.disabled)return null;if(a&&a.length>0){let g=p.labels||[];if(!a.some(S=>g.includes(S)))return null}let h={id:p.id,name:f,description:p.description,schemaVersion:p.schemaVersion,settings:p.settings,fullFilePath:d,relativeFilePath:m,quarantined:!!l[p.id],quarantinedMetadata:l[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 (y=>{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)}var CJ=58890;function Oc(r){let e=parseInt(r,10);if(isNaN(e))throw new InvalidArgumentError("Not a number.");return e}function SPe(r){if(r.toUpperCase()==="AUTO")return "AUTO";let e=Number(r);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 wJ=new Option("--port <port>",`Port to run the local app on. Defaults to ${CJ}.`).env("PORT").default(CJ).argParser(Oc),na=new Option("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").default(ZV()).argParser(r=>{if(!r)throw new InvalidArgumentError("API key is required. Run `npx @momentic/wizard@latest login` or set MOMENTIC_API_KEY.");return r}).makeOptionMandatory(),Lm=new Option("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),Xv=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."),oa=new Option("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default(QV()??"https://api.momentic.ai").argParser(r=>{try{return z.string().url().parse(r),r}catch{throw new InvalidArgumentError("Not a valid URL.")}}),sO=new Option("-y, --yes","Skip all confirmation prompts.").env("CI"),lO=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."),Yv=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"),Jv=new Option("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:!1}),cO=new Option("--tag <tag>","Tag identifier for the asset."),uO=new Option("--channel <channel>","Channel name for the asset."),Zv=new Option("--channel <channel>","Channel name for the asset.").makeOptionMandatory(),dO=new Option("--tag <tag>","Tag identifier for the asset.").makeOptionMandatory(),mO=new Option("--platform <platform>","Mobile platform for the asset."),AJ=new Option("--platform <platform>","Mobile platform for the asset.").makeOptionMandatory(),RJ=new Option("--tag-filter <tagFilter>","Case-insensitive substring filter applied to tags when listing a channel."),xJ=new Option("--json","Emit machine-readable JSON output instead of a human-readable table.");function Qv(r){if(!r)return "ANDROID";switch(r.toLowerCase()){case"android":return "ANDROID";case"ios":return "IOS";default:throw new InvalidArgumentError('Invalid platform. Valid options are "android" and "ios".')}}var MJ=new Option("--env <env>","Environment to run all tests in (overrides test-level configuration)."),_J=new Option("--android-home <androidHome>","Path to the Android SDK root. Sets ANDROID_HOME for this command."),PJ=new Option("--java-home <javaHome>","Path to the Java home directory. Sets JAVA_HOME for this command."),pO=new Option("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(Ol).join(", ")}, ${Kn}, ${Object.values(wi).join(", ")}.`),fO=new Option("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),hO=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."),gO=new Option("--local-ios-device-type <localIosDeviceType>","Force tests to use a specific local iOS device type instead of remote emulators."),yO=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."),IJ=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(SPe),OJ=new Option("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>{let e=Oc(r);if(e<1)throw new InvalidArgumentError("Shard index must be greater than 0.");return e}),NJ=new Option("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(Oc),SO=new Option("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),bO=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."),EO=new Option("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),LJ=new Option("--upload-results","Upload test results to the Momentic dashboard.").default(!1),bPe=["true","false","on-fail"],DJ=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(bPe),TO=new Option("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),kJ=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:!1,onlyQuarantined:!1}),FJ=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(Oc),UJ=new Option("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(iy)),BJ=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"),zJ=new Option("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard."),$J=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(Oc),VJ=new Option("--headful [headful]","Launch mobile MCP remote control browsers headfully by default.").argParser($w),HJ=new Option("--supports-file-output [supportsFileOutput]","Allow MCP tool responses to include file output references.").argParser($w),jJ=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.");var Dm="screen-recording.mp4";var GJ={...Va,prepareRunParams:async({runTracer:r,metadata:{orgId:e},fixtures:{logger:t,apiClient:n,mobileGenerator:o,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:g},settings:{emulatorSettings:y,aiSettings:S},options:{logLevel:b,localAvdId:C,localApkPath:A,region:O},registerCleanup:M})=>{let R=!1,_=[],k=async()=>{R=!0;for(let j of _.toReversed())try{await j();}catch(Q){F.warn({err:Q},"Failed to run cleanup function");}await s.flush(t);};M?.(async()=>k());let B=cs.optional().parse(O??y.region),J=B==="local",z;if(J){let{avdId:j,apkFilePath:Q,apkFilePathSource:fe}=_u({overrideAvdId:C,overrideApkFilePath:A,emulatorSettings:y,defaultApkFilePath:f.settings?.defaultApkFilePath,envVariables:g}),le=Cd({apkFilePath:Q,source:fe});if(!j)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 ${ts} key on the environment.`);z={avdId:j,apkFilePath:le};}else z={region:B===Kn?void 0:B,apkToInstall:d?{channel:d,tag:m}:void 0,osVersion:y.remoteEmulatorSettings?.androidVersion??Tu};let L=randomUUID(),F=t.child({runAttemptId:L}),se=await vd({apiClient:n,logger:t,driverLogLevel:b,creationOpts:z,callbacks:{onStatusUpdate:j=>{t.debug({status:j},"Emulator status update");},onHeartbeatFailure:()=>{let j="Appium heartbeat connection lost \u2014 possible ADB tunnel/emulator failure";R||N.warn(j);},onHeartbeatRestored:()=>{let j="Appium heartbeat connection restored";N.info(j);},onLimbarConnectionStateChange:j=>{j==="disconnected"?R||N.warn("Emulator websocket connection lost. Emulator may be unavailable."):(j==="reconnecting"||j==="connecting")&&N.info("Emulator websocket is reconnecting...");}},orgId:e,sessionId:L});_.push(()=>se.cleanup());let D="limbarRegion"in se?se.limbarRegion:void 0;try{let j=await r.startAttempt({emulatorName:se.emulatorName,runAttemptId:L,assetDetails:{avdId:Nl in z?z.avdId:void 0,tag:"apkToInstall"in z?z.apkToInstall?.tag:void 0,channel:"apkToInstall"in z?z.apkToInstall?.channel:void 0,region:D??B??Kn}});F=F.child(j.loggerBindings||{});let Q=await se.driver.executeInNativeContext(F,async je=>kb({driver:je,onLogs:Oe=>{j.appendLogs(Oe);}}),{operationName:"startLogcatListener"});_.push(()=>Q());let fe=new Eo({variablesFromEnvironment:g,envName:h,testName:f.name}),le="limbarClient"in se?se.limbarClient:void 0,ae="playwrightDevice"in se?se.playwrightDevice:void 0,_e=await ll.init({driver:se.driver,generator:o,logger:F,limbarClient:le,playwrightDevice:ae,orgId:e,adbPort:se.adbPort,options:{emulator:{...y,browserSettings:p.config.browser}},aiSettings:S,fixtures:{storage:i,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u,testContext:fe}});if(_.push(()=>_e.cleanup()),j.videoOutputPath&&le)try{await le.startRecording({quality:RecordingQuality.Q5}),j.setActiveVideo(Dm,new Date),F.info("Started Android video recording"),_.push(async()=>{if(!j.videoOutputPath)return;let je=xr__default.join(j.videoOutputPath,Dm);await le.stopRecording({localPath:je}),F.info({videoPath:je},"Saved Android video recording");});}catch(je){F.warn({err:je},"Failed to start Android video recording");}return {platform:"ANDROID",envName:h,tracer:j,fixtures:{controller:_e,logger:F,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:S.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f},callbacks:{},cleanup:k}}catch(j){throw await k(),j}}};var WJ={...Ha,prepareRunParams:async({runTracer:r,metadata:{orgId:e},fixtures:{logger:t,apiClient:n,mobileGenerator:o,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:g},settings:{emulatorSettings:y,aiSettings:S},options:{logLevel:b,region:C,localIosDeviceType:A,localAppPath:O},registerCleanup:M})=>{let R=!1,_=[],k=async()=>{R=!0;for(let j of _.toReversed())try{await j();}catch(Q){F.warn({err:Q},"Failed to run cleanup function");}await s.flush(t);};M?.(async()=>k());let B=cs.optional().parse(C??y.region),J;if(B==="local"){let{deviceType:j,appFilePath:Q,appFilePathSource:fe}=Pu({overrideDeviceType:A,overrideAppFilePath:O,emulatorSettings:y,defaultAppFilePath:f.settings?.defaultAppFilePath,envVariables:g});if(!j)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 ${rs} key on the environment.`);let le=Cm({appFolderPath:Q,source:fe});J={type:"local",deviceType:j,appFilePath:le};}else J={type:"remote",region:B===Kn?void 0:B,appToInstall:d?{channel:d,tag:m}:void 0,osVersion:vu};let L=randomUUID(),F=t.child({runAttemptId:L}),se=await pm({apiClient:n,logger:t,driverLogLevel:b,creationOpts:J,callbacks:{onStatusUpdate:j=>{t.debug({status:j},"Emulator status update");},onHeartbeatFailure:()=>{R||N.warn("Appium heartbeat connection lost \u2014 possible emulator failure");},onHeartbeatRestored:()=>{N.info("Appium heartbeat connection restored");},onLimbarConnectionStateChange:j=>{j==="disconnected"?R||N.warn("Emulator websocket connection lost. Emulator may be unavailable."):(j==="reconnecting"||j==="connecting")&&N.info("Emulator websocket is reconnecting...");}},orgId:e,sessionId:L});_.push(()=>se.cleanup());let D=se.limbarParams?.region;try{let j=await r.startAttempt({emulatorName:se.emulator.name,runAttemptId:L,assetDetails:{region:D??B??Kn,tag:"appToInstall"in J?J.appToInstall?.tag:void 0,channel:"appToInstall"in J?J.appToInstall?.channel:void 0}});F=F.child(j.loggerBindings||{});let Q=await sv({emulator:se.emulator,onLogs:_e=>{j.appendLogs(_e);}});Q&&_.push(async()=>Q());let fe=new Eo({variablesFromEnvironment:g,envName:h,testName:f.name}),le=await dl.init({driver:se.driver,generator:o,logger:F,emulator:se.emulator,orgId:e,options:{emulator:{...y,browserSettings:p.config.browser}},aiSettings:S,fixtures:{storage:i,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u,testContext:fe}});_.push(()=>le?.cleanup());let ae=se.emulator;if(j.videoOutputPath&&ae.startScreenRecording&&ae.stopScreenRecording)try{await ae.startScreenRecording(),j.setActiveVideo(Dm,new Date),F.info("Started iOS video recording"),_.push(async()=>{if(!j.videoOutputPath||!ae.stopScreenRecording)return;let _e=xr__default.join(j.videoOutputPath,Dm);await ae.stopScreenRecording(_e),F.info({videoPath:_e},"Saved iOS video recording");});}catch(_e){F.warn({err:_e},"Failed to start iOS video recording");}return {platform:"IOS",envName:h,tracer:j,fixtures:{controller:le,logger:F,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:S.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f},callbacks:{},cleanup:k}}catch(j){throw await k(),j}}};var jo="0.88.1";var CO=class{constructor(e,t,n,o,i,a,s){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.diskStorage=i;this.parentTracer=a;this.orgId=s;this.interactionTracer=new No(void 0,l=>this.storeTraceAsset(l)),tn.initializeRootTracerContext(this.interactionTracer);}children=[];finished=!1;interactionTracer;getParentStepIdChain(){return []}recordStepDuration(e){let{durationMs:t,step:n}=e;if(!Ly(n))return;let o=Ny(n);Et.distribution("test_mobile_step_duration",t,[`type:${o}`,`platform:${this.platform.toLowerCase()}`,"executor:cli",`orgId:${this.orgId}`]);}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.png`,contents:n});}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.png`,contents:n});}storeTraceAsset(e){let{snapshotId:t,data:n,extension:o}=e;this.diskStorage.storeFile({name:`${To}/${t}.${o??"png"}`,contents:n});}attachBeforeXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.xml`,contents:n});}attachAfterXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.xml`,contents:n});}async finishInternal(e){this.finished||(this.finished=!0,this.interactionTracer.finish(),await Promise.all(this.children.map(t=>t.finish({status:pp(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 km(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}},km=class{constructor(e,t,n,o,i,a){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.diskStorage=i;this.orgId=a;}children=[];finished=!1;async getScreenshot(e){return this.diskStorage.readFile(`${To}/${e}.png`)??this.diskStorage.readFile(`${To}/${e}.jpeg`)}getParentStepIdChain(){return []}async startStep(e){this.keepalive();let t=new CO(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this,this.orgId);return this.children.push(t),t}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:PL(e.status),finishedAt:e.finishedAt}))));}},wO=class{constructor(e,t,n,o,i,a,s,l,c,u,d){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.runAttemptId=i;this.metadata=a;this.diskStorage=s;this.orgId=l;this.resultSchema=c;this.recordVideo=u;this.assetDetails=d;this.diskStorage.mkdir("assets");let m=o==="IOS"?"assets/logs.syslog":"assets/logs.logcat";this.logStream=this.diskStorage.createFileStream(m),this.resourceUsageStream=this.diskStorage.createFileStream(`${To}/resource-usage.ndjson`),this.resourceUsageSampler=wF({keepSamples:!1,onSample:p=>{this.resourceUsageStream.write(`${JSON.stringify(p)}
|
|
5707
|
+
`),r.forEach(p=>{if(!Tr.existsSync(p))throw new Error(`Path '${p}' does not exist.`);let f,h;try{f=Tr.statSync(p),h=f.isDirectory();}catch(y){s.warn({err:y},`Skipping path ${p} because it cannot be read`);return}let g=xr__default.resolve(p);Object.values(e.mobileTests).filter(y=>h?y.fullFilePath.startsWith(g):y.fullFilePath===g).forEach(y=>{c.add(y.fullFilePath);});})):(s.info("The arguments provided don't appear to be valid paths. Treating them as substrings instead... "),Object.values(e.mobileTests).forEach(p=>{r.some(f=>p.relativePath.includes(f))&&c.add(p.fullFilePath);}));}else {!n&&!await rd("No test paths or substrings were provided. Do you want to run all tests?")&&(s.error("Cancelled by user."),process.exit(1));let d=Object.values(e.mobileTests);s.info(`Reading all ${d.length} mobile tests in the project from local disk.`),d.forEach(m=>{c.add(m.fullFilePath);});}for(let d of Array.from(c)){let m=xr__default.relative(t.rootDir,d);o&&!o.some(p=>new RegExp(p).test(m))&&c.delete(d),i&&i.some(p=>new RegExp(p).test(m))&&c.delete(d);}return (await Promise.all(Array.from(c).map(async d=>{try{let m=xr__default.relative(t.rootDir,d),p=await br(d,s,e),f=xr__default.basename(d,".test.yaml");if(p.disabled)return null;if(a&&a.length>0){let g=p.labels||[];if(!a.some(S=>g.includes(S)))return null}let h={id:p.id,name:f,description:p.description,schemaVersion:p.schemaVersion,settings:p.settings,fullFilePath:d,relativeFilePath:m,quarantined:!!l[p.id],quarantinedMetadata:l[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 (y=>{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)}var CJ=58890;function Oc(r){let e=parseInt(r,10);if(isNaN(e))throw new InvalidArgumentError("Not a number.");return e}function SPe(r){if(r.toUpperCase()==="AUTO")return "AUTO";let e=Number(r);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 wJ=new Option("--port <port>",`Port to run the local app on. Defaults to ${CJ}.`).env("PORT").default(CJ).argParser(Oc),na=new Option("--api-key <key>","Momentic API key").env("MOMENTIC_API_KEY").default(ZV()).argParser(r=>{if(!r)throw new InvalidArgumentError("API key is required. Run `npx @momentic/wizard@latest login` or set MOMENTIC_API_KEY.");return r}).makeOptionMandatory(),Lm=new Option("-c, --config <configPath>","Absolute or relative path to a Momentic configuration file."),Xv=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."),oa=new Option("--server <server>","Momentic server to use.").env("MOMENTIC_SERVER").default(QV()??"https://api.momentic.ai").argParser(r=>{try{return z.string().url().parse(r),r}catch{throw new InvalidArgumentError("Not a valid URL.")}}),sO=new Option("-y, --yes","Skip all confirmation prompts.").env("CI"),lO=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."),Yv=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"),Jv=new Option("--disable-cache","Disable using step caches completely. Using this option may lead to non-deterministic behavior and significantly longer runtimes.").implies({saveCache:!1}),cO=new Option("--tag <tag>","Tag identifier for the asset."),uO=new Option("--channel <channel>","Channel name for the asset."),Zv=new Option("--channel <channel>","Channel name for the asset.").makeOptionMandatory(),dO=new Option("--tag <tag>","Tag identifier for the asset.").makeOptionMandatory(),mO=new Option("--platform <platform>","Mobile platform for the asset."),AJ=new Option("--platform <platform>","Mobile platform for the asset.").makeOptionMandatory(),RJ=new Option("--tag-filter <tagFilter>","Case-insensitive substring filter applied to tags when listing a channel."),xJ=new Option("--json","Emit machine-readable JSON output instead of a human-readable table.");function Qv(r){if(!r)return "ANDROID";switch(r.toLowerCase()){case"android":return "ANDROID";case"ios":return "IOS";default:throw new InvalidArgumentError('Invalid platform. Valid options are "android" and "ios".')}}var MJ=new Option("--env <env>","Environment to run all tests in (overrides test-level configuration)."),_J=new Option("--android-home <androidHome>","Path to the Android SDK root. Sets ANDROID_HOME for this command."),PJ=new Option("--java-home <javaHome>","Path to the Java home directory. Sets JAVA_HOME for this command."),pO=new Option("--region <region>",`Region to run all tests in (overrides all other configuration). Valid values: ${Object.values(Ol).join(", ")}, ${Kn}, ${Object.values(wi).join(", ")}.`),fO=new Option("--local-avd-id <localAvdId>","Force tests to use a specific local Android Virtual Device (AVD) instead of remote emulators."),hO=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."),gO=new Option("--local-ios-device-type <localIosDeviceType>","Force tests to use a specific local iOS device type instead of remote emulators."),yO=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."),IJ=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(SPe),OJ=new Option("--shard-index <shardIndex>","The index of the shard to run tests for. Defaults to 1.").default(1).argParser(r=>{let e=Oc(r);if(e<1)throw new InvalidArgumentError("Shard index must be greater than 0.");return e}),NJ=new Option("--shard-count <shardCount>","The number of shards that tests are being run on. Defaults to 1.").default(1).argParser(Oc),SO=new Option("--output-dir <outputDir>","Output directory to store run artifacts such as screenshots, results, and logs."),bO=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."),EO=new Option("--exclude <excludePatterns...>","The inverted version of --include: a test that matches any of the provided exclusion patterns will be excluded from running."),LJ=new Option("--upload-results","Upload test results to the Momentic dashboard.").default(!1),bPe=["true","false","on-fail"],DJ=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(bPe),TO=new Option("--log-level <logLevel>","Log level for Momentic and dependent services.").choices(["error","warn","info","debug"]),kJ=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:!1,onlyQuarantined:!1}),FJ=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(Oc),UJ=new Option("--reporter <reporter>","Output report files in a standardized format to a local directory.").choices(Object.values(iy)),BJ=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"),zJ=new Option("--name <name>","A name to associate with this run for easier identification in the Momentic dashboard."),$J=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(Oc),VJ=new Option("--headful [headful]","Launch mobile MCP remote control browsers headfully by default.").argParser($w),HJ=new Option("--supports-file-output [supportsFileOutput]","Allow MCP tool responses to include file output references.").argParser($w),jJ=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.");var Dm="screen-recording.mp4";var GJ={...Va,prepareRunParams:async({runTracer:r,metadata:{orgId:e},fixtures:{logger:t,apiClient:n,mobileGenerator:o,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:g},settings:{emulatorSettings:y,aiSettings:S},options:{logLevel:b,localAvdId:C,localApkPath:A,region:O},registerCleanup:M})=>{let R=!1,_=[],k=async()=>{R=!0;for(let j of _.toReversed())try{await j();}catch(Q){F.warn({err:Q},"Failed to run cleanup function");}await s.flush(t);};M?.(async()=>k());let B=cs.optional().parse(O??y.region),J=B==="local",z;if(J){let{avdId:j,apkFilePath:Q,apkFilePathSource:fe}=_u({overrideAvdId:C,overrideApkFilePath:A,emulatorSettings:y,defaultApkFilePath:f.settings?.defaultApkFilePath,envVariables:g}),le=Cd({apkFilePath:Q,source:fe});if(!j)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 ${ts} key on the environment.`);z={avdId:j,apkFilePath:le};}else z={region:B===Kn?void 0:B,apkToInstall:d?{channel:d,tag:m}:void 0,osVersion:y.remoteEmulatorSettings?.androidVersion??Tu};let L=randomUUID(),F=t.child({runAttemptId:L}),se=await vd({apiClient:n,logger:t,driverLogLevel:b,creationOpts:z,callbacks:{onStatusUpdate:j=>{t.debug({status:j},"Emulator status update");},onHeartbeatFailure:()=>{let j="Appium heartbeat connection lost \u2014 possible ADB tunnel/emulator failure";R||N.warn(j);},onHeartbeatRestored:()=>{let j="Appium heartbeat connection restored";N.info(j);},onLimbarConnectionStateChange:j=>{j==="disconnected"?R||N.warn("Emulator websocket connection lost. Emulator may be unavailable."):(j==="reconnecting"||j==="connecting")&&N.info("Emulator websocket is reconnecting...");}},orgId:e,sessionId:L});_.push(()=>se.cleanup());let D="limbarRegion"in se?se.limbarRegion:void 0;try{let j=await r.startAttempt({emulatorName:se.emulatorName,runAttemptId:L,assetDetails:{avdId:Nl in z?z.avdId:void 0,tag:"apkToInstall"in z?z.apkToInstall?.tag:void 0,channel:"apkToInstall"in z?z.apkToInstall?.channel:void 0,region:D??B??Kn}});F=F.child(j.loggerBindings||{});let Q=await se.driver.executeInNativeContext(F,async je=>kb({driver:je,onLogs:Oe=>{j.appendLogs(Oe);}}),{operationName:"startLogcatListener"});_.push(()=>Q());let fe=new Eo({variablesFromEnvironment:g,envName:h,testName:f.name}),le="limbarClient"in se?se.limbarClient:void 0,ae="playwrightDevice"in se?se.playwrightDevice:void 0,_e=await ll.init({driver:se.driver,generator:o,logger:F,limbarClient:le,playwrightDevice:ae,orgId:e,adbPort:se.adbPort,options:{emulator:{...y,browserSettings:p.config.browser}},aiSettings:S,fixtures:{storage:i,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u,testContext:fe}});if(_.push(()=>_e.cleanup()),j.videoOutputPath&&le)try{await le.startRecording({quality:RecordingQuality.Q5}),j.setActiveVideo(Dm,new Date),F.info("Started Android video recording"),_.push(async()=>{if(!j.videoOutputPath)return;let je=xr__default.join(j.videoOutputPath,Dm);await le.stopRecording({localPath:je}),F.info({videoPath:je},"Saved Android video recording");});}catch(je){F.warn({err:je},"Failed to start Android video recording");}return {platform:"ANDROID",envName:h,tracer:j,fixtures:{controller:_e,logger:F,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:S.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f},callbacks:{},cleanup:k}}catch(j){throw await k(),j}}};var WJ={...Ha,prepareRunParams:async({runTracer:r,metadata:{orgId:e},fixtures:{logger:t,apiClient:n,mobileGenerator:o,storage:i,cacheStorage:a,usageTracker:s,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u},inputs:{channel:d,tag:m,project:p,testDefinition:f},env:{envName:h,envVariables:g},settings:{emulatorSettings:y,aiSettings:S},options:{logLevel:b,region:C,localIosDeviceType:A,localAppPath:O},registerCleanup:M})=>{let R=!1,_=[],k=async()=>{R=!0;for(let j of _.toReversed())try{await j();}catch(Q){F.warn({err:Q},"Failed to run cleanup function");}await s.flush(t);};M?.(async()=>k());let B=cs.optional().parse(C??y.region),J;if(B==="local"){let{deviceType:j,appFilePath:Q,appFilePathSource:fe}=Pu({overrideDeviceType:A,overrideAppFilePath:O,emulatorSettings:y,defaultAppFilePath:f.settings?.defaultAppFilePath,envVariables:g});if(!j)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 ${rs} key on the environment.`);let le=Cm({appFolderPath:Q,source:fe});J={type:"local",deviceType:j,appFilePath:le};}else J={type:"remote",region:B===Kn?void 0:B,appToInstall:d?{channel:d,tag:m}:void 0,osVersion:vu};let L=randomUUID(),F=t.child({runAttemptId:L}),se=await pm({apiClient:n,logger:t,driverLogLevel:b,creationOpts:J,callbacks:{onStatusUpdate:j=>{t.debug({status:j},"Emulator status update");},onHeartbeatFailure:()=>{R||N.warn("Appium heartbeat connection lost \u2014 possible emulator failure");},onHeartbeatRestored:()=>{N.info("Appium heartbeat connection restored");},onLimbarConnectionStateChange:j=>{j==="disconnected"?R||N.warn("Emulator websocket connection lost. Emulator may be unavailable."):(j==="reconnecting"||j==="connecting")&&N.info("Emulator websocket is reconnecting...");}},orgId:e,sessionId:L});_.push(()=>se.cleanup());let D=se.limbarParams?.region;try{let j=await r.startAttempt({emulatorName:se.emulator.name,runAttemptId:L,assetDetails:{region:D??B??Kn,tag:"appToInstall"in J?J.appToInstall?.tag:void 0,channel:"appToInstall"in J?J.appToInstall?.channel:void 0}});F=F.child(j.loggerBindings||{});let Q=await sv({emulator:se.emulator,onLogs:_e=>{j.appendLogs(_e);}});Q&&_.push(async()=>Q());let fe=new Eo({variablesFromEnvironment:g,envName:h,testName:f.name}),le=await dl.init({driver:se.driver,generator:o,logger:F,emulator:se.emulator,orgId:e,options:{emulator:{...y,browserSettings:p.config.browser}},aiSettings:S,fixtures:{storage:i,browserEnricher:l,browserGenerator:c,localCodeEvalTools:u,testContext:fe}});_.push(()=>le?.cleanup());let ae=se.emulator;if(j.videoOutputPath&&ae.startScreenRecording&&ae.stopScreenRecording)try{await ae.startScreenRecording(),j.setActiveVideo(Dm,new Date),F.info("Started iOS video recording"),_.push(async()=>{if(!j.videoOutputPath||!ae.stopScreenRecording)return;let _e=xr__default.join(j.videoOutputPath,Dm);await ae.stopScreenRecording(_e),F.info({videoPath:_e},"Saved iOS video recording");});}catch(_e){F.warn({err:_e},"Failed to start iOS video recording");}return {platform:"IOS",envName:h,tracer:j,fixtures:{controller:le,logger:F,cacheStorage:a,usageTracker:s},work:{state:{failureRecoveryDisabled:S.failureRecovery===!1,failureRecoveryAttempts:0}},inputs:{testName:f.name,steps:f.steps,beforeSteps:f.beforeSteps,afterSteps:f.afterSteps,orgId:e,testMetadata:f},callbacks:{},cleanup:k}}catch(j){throw await k(),j}}};var jo="0.88.2";var CO=class{constructor(e,t,n,o,i,a,s){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.diskStorage=i;this.parentTracer=a;this.orgId=s;this.interactionTracer=new No(void 0,l=>this.storeTraceAsset(l)),tn.initializeRootTracerContext(this.interactionTracer);}children=[];finished=!1;interactionTracer;getParentStepIdChain(){return []}recordStepDuration(e){let{durationMs:t,step:n}=e;if(!Ly(n))return;let o=Ny(n);Et.distribution("test_mobile_step_duration",t,[`type:${o}`,`platform:${this.platform.toLowerCase()}`,"executor:cli",`orgId:${this.orgId}`]);}attachBeforeScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.png`,contents:n});}attachAfterScreenshot(e){let{snapshotId:t,screenshot:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.png`,contents:n});}storeTraceAsset(e){let{snapshotId:t,data:n,extension:o}=e;this.diskStorage.storeFile({name:`${To}/${t}.${o??"png"}`,contents:n});}attachBeforeXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.xml`,contents:n});}attachAfterXmlSnapshot(e){let{snapshotId:t,xml:n}=e;this.diskStorage.storeFile({name:`${To}/${t}.xml`,contents:n});}async finishInternal(e){this.finished||(this.finished=!0,this.interactionTracer.finish(),await Promise.all(this.children.map(t=>t.finish({status:pp(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 km(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}},km=class{constructor(e,t,n,o,i,a){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.diskStorage=i;this.orgId=a;}children=[];finished=!1;async getScreenshot(e){return this.diskStorage.readFile(`${To}/${e}.png`)??this.diskStorage.readFile(`${To}/${e}.jpeg`)}getParentStepIdChain(){return []}async startStep(e){this.keepalive();let t=new CO(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this,this.orgId);return this.children.push(t),t}async finish(e){this.finished||(this.finished=!0,await Promise.all(this.children.map(t=>t.finishInternal({status:PL(e.status),finishedAt:e.finishedAt}))));}},wO=class{constructor(e,t,n,o,i,a,s,l,c,u,d){this.keepalive=e;this.testId=t;this.testName=n;this.platform=o;this.runAttemptId=i;this.metadata=a;this.diskStorage=s;this.orgId=l;this.resultSchema=c;this.recordVideo=u;this.assetDetails=d;this.diskStorage.mkdir("assets");let m=o==="IOS"?"assets/logs.syslog":"assets/logs.logcat";this.logStream=this.diskStorage.createFileStream(m),this.resourceUsageStream=this.diskStorage.createFileStream(`${To}/resource-usage.ndjson`),this.resourceUsageSampler=wF({keepSamples:!1,onSample:p=>{this.resourceUsageStream.write(`${JSON.stringify(p)}
|
|
5708
5708
|
`);}});}finished=!1;children=[];logStream;resourceUsageStream;resourceUsageSampler;get loggerBindings(){return {runAttemptId:this.runAttemptId}}get videoOutputPath(){if(this.recordVideo)return xr.resolve(this.diskStorage.cwd(),To)}appendLogs(e){let t=e.join(`
|
|
5709
5709
|
`);this.logStream.write(t+`
|
|
5710
5710
|
`);}setActiveVideo(e,t){this.recordVideo&&(this.metadata.activeVideos=this.metadata.activeVideos||[],this.metadata.activeVideos.push({videoName:e,timestamp:t}));}async finish(e){if(this.finished)return;this.finished=!0;let{logger:t,status:n,results:o,beforeResults:i,afterResults:a}=e,s={...this.metadata,status:n,assetDetails:this.assetDetails,finishedAt:new Date,results:xb(o,this.resultSchema,t),beforeResults:i?xb(i,this.resultSchema,t):void 0,afterResults:a?xb(a,this.resultSchema,t):void 0};await Promise.all(this.children.map(l=>l.finish({status:s.status,finishedAt:s.finishedAt})));try{this.logStream.end();}catch{}try{this.resourceUsageSampler.stop(),this.resourceUsageStream.end();}catch{}this.recordVideo==="on-fail"&&n==="PASSED"&&(qz(t,this.videoOutputPath),s.activeVideos=void 0),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(s,null,2)});}async startBeforeStepList(){let e=new km(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async startMainStepList(){let e=new km(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async startAfterStepList(){let e=new km(this.keepalive,this.testId,this.testName,this.platform,this.diskStorage,this.orgId);return this.children.push(e),e}async getScreenshot(e,t){return this.diskStorage.readFile(`${To}/${t}.png`)??this.diskStorage.readFile(`${To}/${t}.jpeg`)}},AO=class{constructor(e,t,n,o,i,a,s,l,c,u){this.client=e;this.testId=t;this.testName=n;this.platform=o;this.runId=i;this.metadata=a;this.diskStorage=s;this.orgId=l;this.resultSchema=c;this.recordVideo=u;}children=[];finished=!1;get loggerBindings(){return {runId:this.runId}}async finish(e){if(this.finished)return;this.finished=!0;let t={...this.metadata,finishedAt:e.finishedAt||new Date,status:e.status,failureDetails:e.failureDetails,failureReason:e.failureReason,flake:e.isFlake||!1,failureRecoveryDetails:e.failureRecoveryDetails};await Promise.all(this.children.map(n=>n.finish({logger:e.logger,status:t.status,results:[],beforeResults:[],afterResults:[]}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(t,null,2)}),this.diskStorage.close();}async startAttempt(e){let{runAttemptId:t}=e;this.metadata.attempts=this.metadata.attempts+1,this.metadata.status="RUNNING",this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(this.metadata,null,2)});let n=this.diskStorage.cd(`attempts/${this.metadata.attempts}`),o={id:t,schemaVersion:Wc,runAttemptSchemaVersion:Yk,startedAt:new Date,status:"RUNNING"};n.storeFile({name:"metadata.json",contents:JSON.stringify(o,null,2)});let i=debounce(async()=>{await this.client.extendEmulatorTtl(this.platform,e.emulatorName);},3e4,{maxWait:6e4}),a=new wO(()=>void i(),this.testId,this.testName,this.platform,t,o,n,this.orgId,this.resultSchema,this.recordVideo,e.assetDetails);return this.children.push(a),a}},eC=class r{constructor(e,t,n,o,i,a){this.orgId=e;this.runGroupId=t;this.metadata=n;this.client=o;this.diskStorage=i;this.recordVideo=a;}children=[];finished=!1;get loggerBindings(){return {orgId:this.orgId,runGroupId:this.runGroupId,branch:this.metadata.gitBranchName}}static async start({orgId:e,runGroupId:t,outputDir:n,client:o,gitMetadata:i,labels:a,suiteName:s,recordVideo:l}){let c={...i,suiteName:s&&Ko(s),id:t,trigger:So.CLI,startedAt:new Date,status:"RUNNING",cliVersion:jo,labels:a??[]},u=new $f(n);return u.storeFile({name:"metadata.json",contents:JSON.stringify(c,null,2)}),new r(e,t,c,o,u,l??!1)}async finish(e){if(this.finished)return;this.finished=!0;let{status:t}=e,n={...this.metadata,status:t,updatedAt:new Date,finishedAt:new Date};await Promise.all(this.children.map(o=>o.finish({logger:e.logger,status:n.status,finishedAt:n.finishedAt}))),this.diskStorage.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});}async startRun(e){let t=this.diskStorage.createRunArchive(e.runId),n={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?Ko(e.testName):e.testName,testDescription:e.testDescription,directory:e.directory,labels:e.testLabels,trigger:"CLI",status:"RUNNING",environmentName:e.environmentName,cliVersion:jo,schemaVersion:e.schemaVersion,startedAt:new Date,attempts:0,quarantined:e.quarantined,quarantinedReason:e.quarantinedReason,executionType:e.platform,aiSettings:e.aiSettings};t.storeFile({name:"metadata.json",contents:JSON.stringify(n,null,2)});let o=new AO(this.client,e.testId,e.testName,e.platform,e.runId,n,t,this.orgId,e.resultSchema,this.recordVideo);return this.children.push(o),o}};function KJ(r){return {platform:r.platform,originalSteps:{steps:cloneDeep(r.steps),beforeSteps:r.beforeSteps?cloneDeep(r.beforeSteps):void 0,afterSteps:r.afterSteps?cloneDeep(r.afterSteps):void 0}}}async function RO(r){let{inputs:e,fixtures:t,metadata:n,helpers:o}=r,{tracer:i,logger:a}=t,{runId:s}=n,{platform:l,testDefinition:c,project:u}=e,d=new Date,m=await i.startRun({...KJ(c),logger:a,testId:c.id,testName:c.name,directory:dirname(c.relativeFilePath),runId:s,testDescription:c.description,testLabels:c.labels,schemaVersion:c.schemaVersion,quarantined:c.quarantined,quarantinedReason:c.quarantinedMetadata?.quarantinedReason,aiSettings:u.config.ai,resultSchema:o.resultSchema}),p=a.child(m.loggerBindings||{}),f=1+(c.settings?.retries??u.config.retries??1);for(let h=0;h<f;h++){let g=new Date,y=await MPe({...r,runTracer:m,fixtures:{...t,logger:p},constants:{attemptNumber:h+1,totalAttempts:f}}),S=new Date;if(y.status!=="FAILED")return await m.finish({logger:p,status:y.status,failureRecoveryDetails:y.failureRecoveryDetails,finishedAt:S}),{...y,testMetadata:c,platformType:l,steps:c.steps,startedAt:d,lastAttemptStartedAt:g,finishedAt:S,runId:s,attempts:h+1,filePath:c.relativeFilePath,quarantined:c.quarantined,quarantinedMetadata:c.quarantinedMetadata,status:y.status};if(h!==f-1){p.warn("Retrying failed mobile run");continue}p.error("Mobile test failed after all exhausting attempts");let b={failureReason:y.error?.reason,failureDetails:y.error?{errorMessage:y.error.message,errorStack:y.error.stack}:void 0};return await m.finish({logger:p,status:y.status,...b,finishedAt:S}),{...y,testMetadata:c,platformType:l,steps:c.steps,startedAt:d,lastAttemptStartedAt:g,finishedAt:S,runId:s,...b,attempts:h+1,filePath:c.relativeFilePath,quarantined:c.quarantined,quarantinedMetadata:c.quarantinedMetadata,status:y.status}}throw new Error("This code should not be reachable")}async function MPe(r){let{metadata:e,constants:t,fixtures:n,inputs:o,options:i}=r,{attemptNumber:a,totalAttempts:s}=t,{orgId:l,gitMetadata:c}=e,{apiClient:u,logger:d,usageTracker:m}=n,{testDefinition:p,logUpdate:f,project:h,envOverride:g}=o,{regenerateCache:y,alwaysSaveCache:S,noCache:b}=i;a!==1&&f("RETRY",`attempt ${a}/${s}`);let C={...o.project.config.emulator,...p.settings?.emulator},A={...h.config.ai,useMemory:h.config.ai?.useMemory!==!1,...p.settings?.ai},O=g||p.settings?.defaultEnv,R=(O?Yl(O,h,d):void 0)?.variables??{},_=to({logger:d,orgId:l,client:u,gitMetadata:c,regenerateCache:y,alwaysSaveCache:S,noCache:b,isolateCachesByEnvironment:h.config?.advanced?.isolateCachesByEnvironment}),k=new yd(u,l),B={type:"API_KEY",baseUrl:u.baseUrl,apiKey:u.apiKey,logger:d,mode:"runner"},J=new Vi(B),z=new _a(A.agentConfig,B),L=new Ns(B,z),F=new Ls({httpClient:u,fakerSeed:h.config.advanced?.fakerConstantSeed?Iu:void 0});return await _Pe({...r,fixtures:{...r.fixtures,mobileGenerator:J,storage:k,cacheStorage:_,browserEnricher:L,browserGenerator:z,localCodeEvalTools:F},env:{envName:O,envVariables:R},settings:{aiSettings:A,emulatorSettings:C}})}async function _Pe(r){let{inputs:{testDefinition:e},env:{envName:t},helpers:n}=r,o;try{o=await n.prepareRunParams(r);}catch(s){return {status:"FAILED",results:[],error:new w("UserConfigurationError",`Fatal error creating mobile driver: ${s.message}`)}}let i;try{i=await Rm({...o,containerName:`mobile test ${e.name}`,envName:t,helpers:n});}finally{await o.cleanup();}await o.tracer.finish({logger:o.fixtures.logger,results:i.results,beforeResults:i.beforeResults,afterResults:i.afterResults,status:i.status});let a;if(i.status==="FAILED"&&i.terminalResult){let s=i.terminalResult.message;s?a=w.fromMessage(s):a=new w("UnknownError",s||"Unknown failure");}return {...i,error:a}}function tC(r){if(r.status!=="FAILED")return "none";switch(r.failureReason){case"SetupFailureError":return "setup";case"TeardownFailureError":return "teardown";default:return "main"}}function IPe(r){switch(r){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 Ir(r)}}function ZJ(r){let e=xr__default.relative(".",r);return e===""?r:e}function XJ(r,e){return Math.max(0,(r.getTime()-e.getTime())/1e3)}function OPe(r,e,t){let n=XJ(e,r),o=XJ(t,r);return {start_at:n,end_at:o,duration:Math.max(0,o-n)}}function QJ(r){let e=r.reduce((t,[n,o])=>(!o||Object.keys(t).length>=10||(t[n]=o),t),{});return Object.keys(e).length>0?e:void 0}function NPe(r){if(r.status!=="FAILED"||!r.failureReason)return;let e=rp({failureReason:r.failureReason,classification:r.failureDetails?.classification,manualClassification:r.failureDetails?.manualClassification,errorMessage:r.failureDetails?.errorMessage});if(!(e.title==null||e.description==null))return `${e.title}: ${e.description}`}function LPe(r){if(r.status!=="FAILED")return;let e=[r.failureDetails?.classification?.summary,r.failureDetails?.classification?.rootCause,r.failureDetails?.errorMessage].filter(n=>!!n),t=r.failureDetails?.errorStack?.split(`
|
|
@@ -5715,4 +5715,4 @@ ${I.stack}`;N.error(me),je.error({err:I},`Encountered unexpected fatal error whe
|
|
|
5715
5715
|
`),N.info("This wizard will help you bootstrap a new Momentic project."),Tr.existsSync(As)&&(N.error(`A ${As} file already exists in this directory. Please rename or remove it to initialize a new project.`),process.exit(1));let e=r.name??await Oz("Choose an identifier for your project, such as a service, product, or team name (default: 'app'):","app"),t=await GV({cwd:process.cwd(),projectName:e});N.success(`Initialized Momentic project file at ${t.configPath}`),await Mr(),process.exit(0);});co.command("upgrade").description("Upgrade your configuration to the latest recommended settings").addOption(Lm).addOption(Xv).action(async r=>{let e=await ki({configFilePath:r.config,nameFilter:r.filter});N.info("Updating momentic-mobile version in package.json..."),await a9(),N.info("Updating project configuration..."),s9(e),N.success("Your project configuration was successfully updated to the latest recommended settings."),N.info("You can optionally run tests with the `--regenerate-cache` flag to entirely rebuild caches with the newer configuration. Warning: using this option will cause all steps to run without any cached data, resulting in significantly longer execution times."),await Mr(),process.exit(0);});co.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: ${OS.join(", ")}.`).action(async(r,e)=>{!e.all&&r.length===0&&(N.error("No browsers specified"),process.exit(1)),await NS({rawBrowsers:r,force:e.force,all:e.all}),await Mr(),process.exit(0);});co.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(WV).makeOptionMandatory()).action(async r=>{N.warn("`momentic-mobile install-skills` is deprecated. Run `npx skills@latest add momentic-ai/skills` instead.");let e=r.editor,t=fileURLToPath(import.meta.url),n=xr__default.dirname(t),o=xr__default.resolve(n,"..","skills");qV({editor:e,skillsDir:o}),await Mr(),process.exit(0);});async function dIe(){try{await co.parseAsync(process.argv),await Mr();}catch(r){mr.error({err:r},"Uncaught error in CLI"),N.error(r),await Mr(),process.exit(1);}}dIe();
|
|
5716
5716
|
//# sourceMappingURL=out.js.map
|
|
5717
5717
|
//# sourceMappingURL=cli.js.map
|
|
5718
|
-
//# debugId=
|
|
5718
|
+
//# debugId=c91712a2-0f42-5d8f-974c-7398d5eaaeab
|