momentic 0.0.21 → 0.0.23
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 +20 -20
- package/dist/index.js +16 -16
- package/package.json +4 -2
- package/static/assets/index-DIeAPgo_.css +1 -0
- package/static/assets/index-WgifKSm3.js +245 -0
- package/static/index.html +2 -2
- package/static/assets/index-PO_8pQjA.css +0 -1
- package/static/assets/index-tokXt2uE.js +0 -245
package/dist/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import It from"dedent";import*as a from"zod";import*as D from"zod";var ae=D.object({id:D.number().int(),role:D.string().optional(),name:D.string().optional(),numChildren:D.number().optional(),content:D.string().optional(),pathFromRoot:D.string().optional(),serializedForm:D.string().optional()});function le(r){return r.name||r.role||r.content||r.serializedForm}var F=(u=>(u.AI_ASSERTION="AI_ASSERTION",u.CLICK="CLICK",u.SELECT_OPTION="SELECT_OPTION",u.REQUEST="REQUEST",u.TYPE="TYPE",u.PRESS="PRESS",u.NAVIGATE="NAVIGATE",u.SCROLL_UP="SCROLL_UP",u.SCROLL_DOWN="SCROLL_DOWN",u.GO_BACK="GO_BACK",u.GO_FORWARD="GO_FORWARD",u.WAIT="WAIT",u.REFRESH="REFRESH",u.TAB="TAB",u.COOKIE="COOKIE",u.LOCAL_STORAGE="LOCAL_STORAGE",u.HOVER="HOVER",u.CAPTCHA="CAPTCHA",u.SUCCESS="SUCCESS",u))(F||{}),X=a.object({elementDescriptor:a.string(),a11yData:ae.optional()}),R=a.object({thoughts:a.string().optional()}),Lt=R.merge(a.object({type:a.literal("NAVIGATE"),url:a.string()})).describe("NAVIGATE <URL> - Go to the specified URL. Only navigate to URLs relevant to the user goal."),Nt=R.merge(a.object({target:X.optional(),type:a.literal("SCROLL_UP"),useVision:a.boolean().default(!1),deltaY:a.number().optional()})).describe("SCROLL_UP [id] - Scroll up while hovering over the element with the specified id. If no id is provided, scroll the entire page."),Ot=R.merge(a.object({target:X.optional(),type:a.literal("SCROLL_DOWN"),useVision:a.boolean().default(!1),deltaY:a.number().optional()})).describe("SCROLL_DOWN [id] - Scroll down while hovering over the element with the specified id. If no id is provided, scroll the entire page."),Dt=R.merge(a.object({type:a.literal("WAIT"),delay:a.number()})),Mt=R.merge(a.object({type:a.literal("REFRESH")})),zt=R.merge(a.object({type:a.literal("GO_BACK")})),Pt=R.merge(a.object({type:a.literal("GO_FORWARD")})),_t=R.merge(a.object({type:a.literal("CAPTCHA"),useVision:a.boolean().default(!1)})),kt=R.merge(a.object({type:a.literal("CLICK"),target:X,doubleClick:a.boolean().default(!1),rightClick:a.boolean().default(!1),useVision:a.boolean().default(!1),force:a.boolean().optional()})).describe(It`CLICK <id> - click on the element that has the specified id.
|
|
2
2
|
You are NOT allowed to click on disabled, hidden or StaticText elements.
|
|
3
3
|
Only click on elements on the Current Page.
|
|
4
4
|
Only click on elements with the following tag names: button, input, link, image, generic.
|
|
5
5
|
`.replaceAll(`
|
|
6
|
-
`," ")),_t=T.merge(a.object({type:a.literal("HOVER"),target:Y,useVision:a.boolean().default(!1)})),kt=T.merge(a.object({type:a.literal("SELECT_OPTION"),target:Y,option:a.string()})).describe('SELECT_OPTION <id> "<option>" - select an option from a combobox, listbox, or menu element on the page. Provide the id of the parent combobox, listbox, or menu element in <id>. Do NOT provide the id of the option: instead, provide the name of the option in <option> enclosed by single quotes.'),Fe=T.merge(a.object({type:a.literal("AI_ASSERTION"),assertion:a.string(),useVision:a.boolean().default(!1),disableCache:a.boolean().default(!1),cancelOnFailure:a.boolean().default(!1)})),Ut=a.object({clearContent:a.boolean().default(!0),pressKeysSequentially:a.boolean().default(!1)}),Ft=T.merge(a.object({type:a.literal("TYPE"),target:Y,value:a.string(),pressEnter:a.boolean().default(!1),useVision:a.boolean().default(!1),force:a.boolean().optional()})).merge(Ut).describe('TYPE <id> "<text>" - type the specified text into the input with the specified id. The text should be specified by the user - do not use text from the EXAMPLES or generate text yourself. Make sure to include quotes around the text.'),Ht=T.merge(a.object({type:a.literal("PRESS"),value:a.string()})).describe('PRESS <key> - press the specified key, such as "ArrowLeft", "Enter", or "a". You must specify at least one key.'),Bt=T.merge(a.object({type:a.literal("TAB"),url:a.string()})),Gt=T.merge(a.object({type:a.literal("COOKIE"),value:a.string()})),$t=T.merge(a.object({type:a.literal("LOCAL_STORAGE"),key:a.string(),value:a.string()})),jt=T.merge(a.object({type:a.literal("REQUEST"),url:a.string(),method:a.union([a.literal("GET"),a.literal("POST"),a.literal("PUT"),a.literal("DELETE"),a.literal("PATCH")]),headers:a.record(a.string(),a.string()).optional(),params:a.record(a.string(),a.string()).optional(),body:a.string().optional(),timeout:a.number().optional().describe("Max seconds to wait for the request to complete")})),Wt=T.merge(a.object({type:a.literal("SUCCESS"),condition:Fe.optional()})).describe("SUCCESS - the user goal has been successfully achieved"),J=a.discriminatedUnion("type",[Pt,Ft,Ht,kt,xt,Lt,It,Wt]),Vt=a.discriminatedUnion("type",[Dt,Mt,Ot,Fe,Nt,Bt,Gt,$t,_t,jt,zt]),He=a.discriminatedUnion("type",[...J.options,...Vt.options]),Kt=T.merge(a.object({type:a.literal("FAILURE")})).describe("FAILURE - there are no commands to suggest that could make progress that have not already been tried before"),we=a.discriminatedUnion("type",[...J.options,Kt]);import*as A from"zod";var _=(o=>(o.AI_ACTION="AI_ACTION",o.PRESET_ACTION="PRESET_ACTION",o.MODULE="MODULE",o))(_||{}),Q=A.object({type:A.literal("AI_ACTION"),text:A.string(),commands:A.array(J).optional()}),Z=A.object({type:A.literal("PRESET_ACTION"),command:He}),Se=A.object({type:A.literal("MODULE"),moduleId:A.string().uuid()}),ee=A.union([Q,Z]),te=A.object({type:A.literal("RESOLVED_MODULE"),moduleId:A.string().uuid(),name:A.string(),steps:ee.array()}),ce=A.union([Q,Z,Se]),oe=A.union([Q,Z,te]);import{distance as Uo}from"fastest-levenshtein";import{homedir as Fo}from"os";import{join as Ho}from"path";import{chromium as Bo,devices as Tt}from"playwright";import{addExtra as Go}from"playwright-extra";import $o from"puppeteer-extra-plugin-recaptcha";import jo from"puppeteer-extra-plugin-stealth";import{z as re}from"zod";var Be=re.object({thoughts:re.string(),result:re.boolean(),relevantElements:re.array(re.number()).optional()});import ur from"string-argv";import{z as G}from"zod";var de=(s=>(s.AI_PROVIDER="AIProviderError",s.AI_TIMEOUT="AITimeoutError",s.JOB_TIMEOUT="JobTimeoutError",s.ACTION_FAILURE="ActionFailureError",s.ASSERTION_FAILURE="AssertionFailureError",s.WEB_AGENT_PLATFORM="InternalWebAgentError",s.UNKNOWN_PLATFORM="InternalPlatformError",s))(de||{});var ie=class extends Error{constructor(e,t={}){super(e,t),this.name="BrowserExecutionError"}};var me=class extends Error{constructor(e={}){super("Got empty a11y tree",e),this.name="EmptyA11yTreeError"}};var x=class extends Error{reason;constructor(e,t,o={}){let r=!1;for(let n of Object.values(de))if(t.startsWith(n)){r=!0,e=n;break}r?super(t,o):super(`${e}: ${t}`,o),this.name="TestFailureError",this.stack=this.stack?.slice(this.name.length+2),this.reason=e}toString(){return this.message}toJSON(){return{message:this.message}}};var yr=G.object({command:G.string(),thoughts:G.string()}),br=G.string().pipe(G.coerce.number());var Ge=G.object({phrase:G.string()});var Cr=new Set(Object.values(H));var qt={AI_ACTION:"AI action",MODULE:"Module",AI_ASSERTION:"AI check",CLICK:"Click",HOVER:"Hover",SELECT_OPTION:"Select",TYPE:"Type",PRESS:"Press",NAVIGATE:"Navigate",SCROLL_UP:"Scroll up",SCROLL_DOWN:"Scroll down",CAPTCHA:"Captcha",GO_BACK:"Go back",GO_FORWARD:"Go forward",WAIT:"Wait",REFRESH:"Refresh",TAB:"Switch tab",COOKIE:"Set cookie",LOCAL_STORAGE:"Set local storage",REQUEST:"Request",SUCCESS:"Done"},vr={AI_ACTION:"Ask AI to plan and execute something on the page.",MODULE:"A list of steps that can be reused in multiple tests.",AI_ASSERTION:"Ask AI whether something is true on the page.",CLICK:"Click on an element on the page based on a description.",HOVER:"Hover over an element on the page based on a description.",SELECT_OPTION:"Select an option from a dropdown based on a description.",TYPE:"Type the specified text into an element.",PRESS:"Press the specified keys using the keyboard. (e.g. Ctrl+A)",NAVIGATE:"Navigate to the specified URL.",SCROLL_UP:"Scroll up one page.",SCROLL_DOWN:"Scroll down one page.",GO_BACK:"Go back in browser history.",GO_FORWARD:"Go forward in browser history.",WAIT:"Wait for the specified number of seconds.",REFRESH:"Refresh the page. This will not clear cookies or session data.",TAB:"Switch to different tab in the browser.",COOKIE:"Set a cookie that will persist throughout the browser session",LOCAL_STORAGE:"Set a local storage value that will persist throughout the browser session",CAPTCHA:"Solve captchas on the page. This may take 10-60 seconds.",REQUEST:"Make an API request to a URL.",SUCCESS:"Indicate the entire AI action has succeeded, optionally based on a condition."};import*as u from"zod";var $e=(n=>(n.SUCCESS="SUCCESS",n.FAILED="FAILED",n.RUNNING="RUNNING",n.IDLE="IDLE",n.CANCELLED="CANCELLED",n))($e||{}),je=(o=>(o.SUCCESS="SUCCESS",o.FAILED="FAILED",o.CANCELLED="CANCELLED",o))(je||{}),Xt=u.object({beforeUrl:u.string(),beforeScreenshot:u.string().or(u.any()),afterUrl:u.string().optional(),afterScreenshot:u.string().or(u.any()).optional(),startedAt:u.coerce.date(),finishedAt:u.coerce.date(),viewport:u.object({height:u.number(),width:u.number()}),status:u.nativeEnum(je),message:u.string().optional(),elementInteracted:u.string().optional()}),pe=u.object({startedAt:u.coerce.date(),finishedAt:u.coerce.date(),status:u.nativeEnum($e),message:u.string().optional(),data:u.record(u.string(),u.unknown()).optional(),userAgent:u.string().optional()}),Ee=Z.merge(pe).merge(u.object({results:Xt.array()})),We=Q.merge(pe).merge(u.object({results:Ee.array()})),Yt=Se.merge(pe).merge(u.object({results:u.union([We,Ee]).array()})),ue=u.discriminatedUnion("type",[We,Ee,Yt]),Rr=pe.pick({startedAt:!0,finishedAt:!0,status:!0,message:!0,data:!0});function Jt(i,e){return i.length<e?i:i.slice(0,e-3)+"[...]"}function Ce(i){switch(i.type){case"SUCCESS":return i.condition?.assertion?`Check success condition: ${i.condition.assertion}`:"All commands completed";case"NAVIGATE":return`Go to URL: ${Jt(i.url,30)}`;case"CAPTCHA":return"Solve captchas on the page";case"GO_BACK":return"Go back to the previous page";case"GO_FORWARD":return"Go forward to the next page";case"SCROLL_DOWN":return`Scroll down one page${i.target?` in the container of: ${i.target.elementDescriptor}`:""}`;case"SCROLL_UP":return`Scroll up one page${i.target?` in the container of: ${i.target.elementDescriptor}`:""}`;case"WAIT":return`Wait for ${i.delay} seconds`;case"REFRESH":return"Refresh the page";case"CLICK":return`Click on '${i.target.elementDescriptor}'`;case"TYPE":{let t="";return i.target.a11yData?.serializedForm?t=`in element: ${i.target.a11yData.serializedForm}`:i.target.elementDescriptor.length>0&&(t=`in element: ${i.target.elementDescriptor}`),`Type '${i.value}' ${t}`}case"HOVER":{let t="";return i.target.a11yData?.serializedForm?t=` over element: ${i.target.a11yData.serializedForm}`:i.target.elementDescriptor.length>0&&(t=` over element: ${i.target.elementDescriptor}`),`Hover${t}`}case"PRESS":return`Press '${i.value}'`;case"SELECT_OPTION":return`Select option '${i.option}' in '${i.target.elementDescriptor}'`;case"TAB":return`Switch to tab: ${i.url}`;case"REQUEST":return`Send ${i.method} request to ${i.url}`;case"COOKIE":return`Set cookie: ${i.value}`;case"LOCAL_STORAGE":return`Set local storage: ${i.key}: ${i.value}`;case"AI_ASSERTION":return`${i.useVision?"Visual assertion":"Assertion"}: '${i.assertion}'`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(i)}}import*as M from"zod";import*as $ from"zod";var Ve=$.object({type:$.nativeEnum(_),generatedStep:J.optional(),serializedCommand:$.string().optional(),elementInteracted:$.string().optional()});var B=M.object({goal:M.string(),url:M.string(),browserState:M.string(),history:M.string(),numPrevious:M.number(),lastCommand:Ve.or(M.null())});import{parseString as Qt}from"set-cookie-parser";function Ke(i){let e=Qt(i);if(!e.name)throw new Error("Name missing from cookie");if(!e.value)throw new Error("Value missing from cookie");let t;if(e.sameSite){let r=e.sameSite.trim().toLowerCase();if(r==="strict")t="Strict";else if(r==="lax")t="Lax";else if(r==="none")t="None";else throw new Error(`Invalid sameSite setting in cookie: ${r}`)}return!e.path&&e.domain&&(e.path="/"),{...e,expires:e.expires?e.expires.getTime()/1e3:void 0,sameSite:t}}import{z as O}from"zod";var eo="1.0.0",qe=O.object({run:O.string().describe("Run a single command in the shell. The working directory will be set to where the CLI was invoked from."),waitForCompletion:O.boolean().optional().describe("Defaults to true")}),Hr=O.object({type:O.literal("momentic/fixture"),schemaVersion:O.string(),name:O.string(),description:O.string().optional(),setup:O.object({steps:qe.array(),timeout:O.number().optional().describe("Timeout for all steps in seconds")}).optional(),teardown:O.object({steps:qe.array(),timeout:O.number().optional().describe("Timeout for all steps in seconds")}).optional()}),Br={type:"momentic/fixture",schemaVersion:eo,name:"example",description:"An example fixture",setup:{steps:[{run:"./scripts/seed_db.sh",waitForCompletion:!0},{run:"npm run start",waitForCompletion:!1}],timeout:30},teardown:{steps:[{run:"./scripts/shutdown_db.sh"}]}};import{z as to}from"zod";var jr=to.string().array();import{z as E}from"zod";import{z as I}from"zod";import{z as he}from"zod";var Xe=he.object({name:he.string(),fixtures:he.array(he.string().describe("Name of the fixture (must be available locally in the fixtures directory).")).optional()});import{isValidCron as oo}from"cron-validator";import{z}from"zod";var Ye=z.object({availableAsModule:z.boolean().default(!1),disableAICaching:z.boolean().default(!1)}),Je=z.object({cron:z.string().refine(i=>oo(i),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:z.boolean().default(!1),timeZone:z.string().default("America/Los_Angeles"),jobKey:z.string().optional()}),Qe=z.object({onSuccess:z.boolean().default(!1),onFailure:z.boolean().default(!0)});var ro=I.string().min(1).max(255).superRefine((i,e)=>{try{lo(i)}catch(t){return e.addIssue({code:I.ZodIssueCode.custom,message:t.message,fatal:!0}),I.NEVER}}),j=I.object({id:I.string(),name:ro,baseUrl:I.string(),schemaVersion:I.string(),advanced:Ye,retries:I.number(),envSettings:Xe.array().optional(),localOnly:I.boolean().optional()}),ti=j.pick({name:!0,baseUrl:!0,retries:!0,advanced:!0}),io=I.object({createdAt:I.coerce.date(),updatedAt:I.coerce.date(),schedule:Je,notification:Qe,createdBy:I.string(),organizationId:I.string()}),no=j.merge(io).merge(I.object({steps:I.array(oe)})),Ze=j.merge(I.object({steps:I.array(oe)})),oi=j.merge(I.object({steps:ce.array()}));var so=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/,ao=["modules","fixtures"];function lo(i){if(i=i.toLowerCase().trim(),i.length===0||i.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"\/\\|?*\x00]/.test(i))throw new Error("Name can only contain alphanumeric characters, dashes, and underscores.");if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(i))throw new Error(`"${i}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(i)||/^\s|\s$/.test(i))throw new Error("Name cannot start or end with a space or dot.");if(i.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(ao.includes(i))throw new Error("'modules' is a reserved folder name in Momentic. Please choose a different name.");if(i.match(so))throw new Error("Name cannot be a UUID. Please choose a different name.")}var co="momentic-frame",ai=`${co}-0`,li=E.array(E.object({id:E.string(),name:E.string(),fullFilePath:E.string(),testPath:E.string().describe("path relative to the root test directory, i.e. my-folder/my-test.yaml"),fileName:E.string(),lastModified:E.coerce.date(),createdAt:E.coerce.date()}));var ci=E.object({steps:oe.array()}),di=E.object({name:E.string(),baseUrl:E.string().url()}),mi=Ze.merge(E.object({testPath:E.string()})),pi=E.object({name:E.string(),steps:ee.array()});var ui=E.array(te),hi=E.array(E.object({name:E.string(),moduleId:E.string().uuid(),numSteps:E.number()}));import*as k from"zod";var et=k.object({thoughts:k.string(),id:k.number().int(),options:k.array(k.string()).optional()});var mo={0:"DEBUG",1:"INFO",2:"WARN",3:"ERROR"},po={0:"\x1B[90m",1:"\x1B[32m",2:"\x1B[33m",3:"\x1B[31m"},ve=class i{minLogLevel;logBindings;constructor(e,t){this.minLogLevel=e,this.logBindings=t}log(e,...t){let o=mo[e],r;Array.isArray(t[0])?(r=t[0],t=t.slice(1)):typeof t[0]=="object"&&!(t[0]instanceof Error)&&(r={...t[0],...this.logBindings},t=t.slice(1));let n=po[e],l=[`${n}[${new Date().toTimeString().slice(0,8)}][${o}]`];if(e!==0&&l.push("\x1B[39m"),l.push(...t),console.log(...l),r&&!Array.isArray(r))for(let[s,c]of Object.entries(r)){let m=c;c instanceof Error?m=c.message:typeof c=="object"&&(m=JSON.stringify(c,void 0,2),m=m.split(`
|
|
7
|
-
`).map((
|
|
8
|
-
`)),console.log(e===0?`${
|
|
9
|
-
`).map((m,
|
|
10
|
-
`)),console.log(e===0?`${n} `:" ",c)}e===0&&process.stdout.write("\x1B[39m")}setMinLevel(e){this.minLogLevel=e}info(...e){1<this.minLogLevel||this.log(1,...e)}debug(...e){0<this.minLogLevel||this.log(0,...e)}warn(...e){2<this.minLogLevel||this.log(2,...e)}error(...e){3<this.minLogLevel||this.log(3,...e)}child(e){return new i(this.minLogLevel,{...this.logBindings,...e})}flush(){}bindings(){return this.logBindings}},yi=new ve(1,{});import{z as U}from"zod";var uo=U.object({id:U.string(),createdAt:U.coerce.date(),createdBy:U.string(),organizationId:U.string(),name:U.string(),schemaVersion:U.string(),numSteps:U.number()}),Ei=U.object({steps:ee.array()}).merge(uo.omit({numSteps:!0}));import*as d from"zod";import{z as y}from"zod";var Ae={WEBHOOK:"WEBHOOK",CRON:"CRON",MANUAL:"MANUAL",CLI:"CLI"},Te={PENDING:"PENDING",RUNNING:"RUNNING",PASSED:"PASSED",FAILED:"FAILED",CANCELLED:"CANCELLED"},ho={PASSED:"PASSED",FAILED:"FAILED"},ge=y.string().pipe(y.coerce.date()).or(y.date()),go=y.object({id:y.string(),createdAt:ge,createdBy:y.string(),organizationId:y.string(),scheduledAt:ge.or(y.null()),startedAt:ge.or(y.null()),finishedAt:ge.or(y.null()),testId:y.string().or(y.null()),status:y.nativeEnum(Te),expectedStatus:y.nativeEnum(ho).or(y.null()),runKey:y.string(),trigger:y.nativeEnum(Ae),attempts:y.number(),test:y.object({name:y.string(),id:y.string()}).or(y.null())}),fo=go.merge(y.object({results:ue.array(),test:y.object({name:y.string(),id:y.string(),baseUrl:y.string()}).or(y.null())}));var W=d.object({disableCache:d.boolean()}),zi=d.object({error:d.boolean(),reason:d.string(),message:d.string()}),Pi=B.merge(W),tt=we,_i=d.discriminatedUnion("vision",[B.merge(W).merge(d.object({vision:d.literal(!1)})),B.pick({goal:!0,url:!0}).merge(W).merge(d.object({screenshot:d.string(),vision:d.literal(!0)}))]),Re=Be,ki=B.pick({browserState:!0,goal:!0}).merge(W),Ui=B.pick({goal:!0}).merge(W).merge(d.object({screenshot:d.string().describe("base64 encoded image"),hintActivatedScreenshot:d.string().describe("base64 encoded image")})),xe=et,Fi=B.pick({goal:!0,url:!0}).merge(W),ot=d.string().array(),Hi=B.pick({goal:!0,browserState:!0}).merge(W),rt=Ge,Bi=d.object({testPaths:d.string().array().describe("can be either hyphenated, lowercase test names or UUIDs"),all:d.boolean().optional()}),Gi=d.object({message:d.string(),queuedTests:d.object({name:d.string(),id:d.string()}).array()});var $i=d.string().array(),ji=d.union([d.object({paths:d.string().array().describe("run specific test paths (e.g. todo-test)")}),d.object({path:d.string().describe("deprecated; present for backcompat")}),d.object({all:d.boolean().describe("run all tests")})]),Wi=d.object({tests:d.record(d.string().describe("Test name"),d.string().describe("Test YAML")),modules:d.record(d.string().describe("Module name"),d.string().describe("Module YAML"))}),yo=d.object({test:d.string().describe("test YAML"),modules:d.record(d.string().describe("moduleId"),d.string().describe("module YAML"))}),Vi=yo.array();var Ki=d.object({testPath:d.string(),testId:d.string()}).partial().merge(d.object({trigger:d.nativeEnum(Ae)}));var qi=d.object({startedAt:d.coerce.date(),finishedAt:d.coerce.date(),results:ue.array(),status:d.nativeEnum(Te)}).partial(),Xi=d.object({screenshot:d.string()}),Yi=d.object({key:d.string()}),Ji=d.object({orgId:d.string()});import{stringify as sn}from"yaml";import{z as C}from"zod";var un=C.object({test:C.string().describe("YAML for the test, including metadata and steps"),modules:C.record(C.string(),C.string()).describe("Map of module name to YAML for the module")}),hn=j.merge(C.object({steps:ce.array(),fileType:C.literal("momentic/test")})),gn=te.omit({type:!0}).merge(C.object({schemaVersion:C.string(),fileType:C.literal("momentic/module")})),fn=j.merge(C.object({steps:C.array(C.record(C.string(),C.unknown()))})),yn=C.object({moduleId:C.string().uuid(),name:C.string(),schemaVersion:C.string(),steps:C.array(C.record(C.string(),C.unknown()))});var Ie={js:'var K=Object.defineProperty;var P=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var H=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,D=(t,e)=>{for(var n in e||(e={}))z.call(e,n)&&H(t,n,e[n]);if(P)for(var n of P(e))B.call(e,n)&&H(t,n,e[n]);return t};var g=(t,e,n)=>(H(t,typeof e!="symbol"?e+"":e,n),n);var _=(t,e,n)=>new Promise((o,r)=>{var i=s=>{try{d(n.next(s))}catch(l){r(l)}},a=s=>{try{d(n.throw(s))}catch(l){r(l)}},d=s=>s.done?o(s.value):Promise.resolve(s.value).then(i,a);d((n=n.apply(t,e)).next())});var E=t=>function(e){return e&&e.isTrusted?t.apply(this,arguments):!0};globalThis.forTrusted==null&&(globalThis.forTrusted=E);var k={create(t,e,n,o){return{bottom:o,top:e,left:t,right:n,width:n-t,height:o-e}},copy(t){return{bottom:t.bottom,top:t.top,left:t.left,right:t.right,width:t.width,height:t.height}},translate(t,e,n){return e==null&&(e=0),n==null&&(n=0),{bottom:t.bottom+n,top:t.top+n,left:t.left+e,right:t.right+e,width:t.width,height:t.height}},subtract(t,e){return e=this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom)),e.width<0||e.height<0?[k.copy(t)]:[this.create(t.left,t.top,e.left,e.top),this.create(e.left,t.top,e.right,e.top),this.create(e.right,t.top,t.right,e.top),this.create(t.left,e.top,e.left,e.bottom),this.create(e.right,e.top,t.right,e.bottom),this.create(t.left,e.bottom,e.left,t.bottom),this.create(e.left,e.bottom,e.right,t.bottom),this.create(e.right,e.bottom,t.right,t.bottom)].filter(o=>o.height>0&&o.width>0)},intersects(t,e){return t.right>e.left&&t.left<e.right&&t.bottom>e.top&&t.top<e.bottom},intersectsStrict(t,e){return t.right>=e.left&&t.left<=e.right&&t.bottom>=e.top&&t.top<=e.bottom},equals(t,e){for(let n of["top","bottom","left","right","width","height"])if(t[n]!==e[n])return!1;return!0},intersect(t,e){return this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom))}};var N={_browserInfoLoaded:!0,_firefoxVersion:null,_isFirefox:!1,isFirefox(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._isFirefox},firefoxVersion(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._firefoxVersion},isString(t){return typeof t=="string"||t instanceof String}};var f={isReady(){return document.readyState!=="loading"},documentReady:function(){let t=document.readyState!=="loading",e=[];if(!t){let n;globalThis.addEventListener("DOMContentLoaded",n=E(function(){globalThis.removeEventListener("DOMContentLoaded",n,!0),t=!0;for(let o of e)o();e=null}),!0)}return function(n){if(t)return n();e.push(n)}}(),documentComplete:function(){let t=document.readyState==="complete",e=[];if(!t){let n;globalThis.addEventListener("load",n=E(function(o){if(o.target===document){globalThis.removeEventListener("load",n,!0),t=!0;for(let r of e)r();e=null}}),!0)}return function(n){t?n():e.push(n)}}(),createElement(t){let e=document.createElement(t);return e instanceof HTMLElement?(this.createElement=n=>document.createElement(n),e):(this.createElement=n=>document.createElementNS("http://www.w3.org/1999/xhtml",n),this.createElement(t))},addElementsToPage(t,e){let n=this.createElement("div");e.id!=null&&(n.id=e.id),e.className!=null&&(n.className=e.className);for(let o of t)n.appendChild(o);return document.body.appendChild(n),n},removeElement(t){return t.parentNode.removeChild(t)},isTopFrame(){return globalThis.top===globalThis.self},makeXPath(t){let e=[];for(let n of t)e.push(".//"+n,".//xhtml:"+n);return e.join(" | ")},evaluateXPath(t,e){let n=document.webkitIsFullScreen?document.webkitFullscreenElement:document.documentElement,o=function(r){return r==="xhtml"?"http://www.w3.org/1999/xhtml":null};return document.evaluate(t,n,o,e,null)},getVisibleClientRect(t,e){let n;e==null&&(e=!1);let o=(()=>{let i=[];for(n of t.getClientRects())i.push(k.copy(n));return i})(),r=function(){let i=window.getComputedStyle(t,null),a=i.getPropertyValue("display").indexOf("inline")===0&&i.getPropertyValue("font-size")==="0px";return r=()=>a,a};for(n of o){let i;if((n.width===0||n.height===0)&&e)for(let a of Array.from(t.children)){i=window.getComputedStyle(a,null);let d=i.getPropertyValue("position");if(i.getPropertyValue("float")==="none"&&!["absolute","fixed"].includes(d)&&!(n.height===0&&r()&&i.getPropertyValue("display").indexOf("inline")===0))continue;let s=this.getVisibleClientRect(a,!0);if(!(s===null||s.width<3||s.height<3))return s}else{if(n=this.cropRectToVisible(n),n===null||n.width<3||n.height<3||(i=window.getComputedStyle(t,null),i.getPropertyValue("visibility")!=="visible"))continue;return n}}return null},cropRectToVisible(t){let e=k.create(Math.max(t.left,0),Math.max(t.top,0),t.right,t.bottom);return e.top>=window.innerHeight-4||e.left>=window.innerWidth-4?null:e},getClientRectsForAreas(t,e){let n=[];for(let o of e){let r,i,a,d,s=o.coords.split(",").map(p=>parseInt(p,10)),l=o.shape.toLowerCase();if(["rect","rectangle"].includes(l))s.length==4&&([r,a,i,d]=s);else if(["circle","circ"].includes(l)){if(s.length==3){let[p,w,v]=s,u=v/Math.sqrt(2);r=p-u,i=p+u,a=w-u,d=w+u}}else l==="default"?s.length==2&&([r,a,i,d]=[0,0,t.width,t.height]):s.length>=4&&([r,a,i,d]=s);let c=k.translate(k.create(r,a,i,d),t.left,t.top);c=this.cropRectToVisible(c),c&&!isNaN(c.top)&&!isNaN(c.left)&&!isNaN(c.width)&&!isNaN(c.height)&&n.push({element:o,rect:c})}return n},isSelectable(t){if(!(t instanceof Element))return!1;let e=["button","checkbox","color","file","hidden","image","radio","reset","submit"];return t.nodeName.toLowerCase()==="input"&&e.indexOf(t.type)===-1||t.nodeName.toLowerCase()==="textarea"||t.isContentEditable},isEditable(t){return this.isSelectable(t)||(t.nodeName!=null?t.nodeName.toLowerCase():void 0)==="select"},isEmbed(t){let e=t.nodeName!=null?t.nodeName.toLowerCase():null;return["embed","object"].includes(e)},isFocusable(t){return t&&(this.isEditable(t)||this.isEmbed(t))},isDOMDescendant(t,e){let n=e;for(;n!==null;){if(n===t)return!0;n=n.parentNode}return!1},isSelected(t){let e=document.getSelection();if(t.isContentEditable){let n=e.anchorNode;return n&&this.isDOMDescendant(t,n)}else if(f.getSelectionType(e)==="Range"&&e.isCollapsed){let n=e.anchorNode.childNodes[e.anchorOffset];return t===n}else return!1},simulateSelect(t){if(t===document.activeElement&&f.isEditable(document.activeElement))return handlerStack.bubbleEvent("click",{target:t});if(t.focus(),t.tagName.toLowerCase()!=="textarea"||t.value.indexOf(`\n`)<0)try{if(t.selectionStart===0&&t.selectionEnd===0)return t.setSelectionRange(t.value.length,t.value.length)}catch(e){}},simulateClick(t,e){e==null&&(e={});let n=["mouseover","mousedown","mouseup","click"],o=[];for(let r of n){let i=this.simulateMouseEvent(r,t,e);o.push(i)}return o},simulateMouseEvent(t,e,n){if(n==null&&(n={}),t==="mouseout"){if(e==null&&(e=this.lastHoveredElement),this.lastHoveredElement=void 0,e==null)return}else t==="mouseover"&&(this.simulateMouseEvent("mouseout",void 0,n),this.lastHoveredElement=e);let o=new MouseEvent(t,{bubbles:!0,cancelable:!0,composed:!0,view:window,detail:1,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey});return e.dispatchEvent(o)},simulateClickDefaultAction(t,e){let n;if(e==null&&(e={}),(t.tagName!=null?t.tagName.toLowerCase():void 0)!=="a"||!t.href)return;let{ctrlKey:o,shiftKey:r,metaKey:i,altKey:a}=e;KeyboardUtils.platform==="Mac"?n=i===!0&&o===!1:n=i===!1&&o===!0,n?chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:r===!0}):r===!0&&i===!1&&o===!1&&a===!1?chrome.runtime.sendMessage({handler:"openUrlInNewWindow",url:t.href}):t.target==="_blank"&&chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:!0})},simulateHover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseover",t,e)},simulateUnhover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseout",t,e)},addFlashRect(t){let e=this.createElement("div");return e.classList.add("vimiumReset"),e.classList.add("vimiumFlash"),e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",document.documentElement.appendChild(e),e},getViewportTopLeft(){let t=document.documentElement,e=getComputedStyle(t),n=t.getBoundingClientRect();if(e.position==="static"&&!/content|paint|strict/.test(e.contain||"")){let o=parseInt(e.marginTop),r=parseInt(e.marginLeft);return{top:-n.top+o,left:-n.left+r}}else{let o,r;return N.isFirefox()?(r=parseInt(e.borderTopWidth),o=parseInt(e.borderLeftWidth)):{clientTop:r,clientLeft:o}=t,{top:-n.top-r,left:-n.left-o}}},suppressPropagation(t){t.stopImmediatePropagation()},suppressEvent(t){t.preventDefault(),this.suppressPropagation(t)},consumeKeyup:function(){let t=null;return function(e,n=null,o){if(!e.repeat){t!=null&&handlerStack.remove(t);let{code:r}=e;t=handlerStack.push({_name:"dom_utils/consumeKeyup",keyup(i){return i.code!==r||(this.remove(),o?f.suppressPropagation(i):f.suppressEvent(i)),handlerStack.continueBubbling},blur(i){return i.target===window&&this.remove(),handlerStack.continueBubbling}})}return typeof n=="function"&&n(),o?(f.suppressPropagation(e),handlerStack.suppressPropagation):(f.suppressEvent(e),handlerStack.suppressEvent)}}(),getSelectionType(t){return t==null&&(t=document.getSelection()),t.type?t.type:t.rangeCount===0?"None":t.isCollapsed?"Caret":"Range"},getElementWithFocus(t,e){let n,o=n=t.getRangeAt(0);f.getSelectionType(t)==="Range"&&(o=n.cloneRange(),o.collapse(e)),n=o.startContainer,n.nodeType===1&&(n=n.childNodes[o.startOffset]);let r=n;for(;r&&r.nodeType!==1;)r=r.previousSibling;return n=r||(n!=null?n.parentNode:void 0),n},getSelectionFocusElement(){let t=window.getSelection(),e=t.focusNode;return e==null?null:(e===t.anchorNode&&t.focusOffset===t.anchorOffset&&(e=e.childNodes[t.focusOffset]||e),e.nodeType!==Node.ELEMENT_NODE?e.parentElement:e)},getContainingElement(t){return(typeof t.getDestinationInsertionPoints=="function"?t.getDestinationInsertionPoints()[0]:void 0)||t.parentElement},windowIsTooSmall(){return window.innerWidth<3||window.innerHeight<3},injectUserCss(){let t=document.createElement("style");t.type="text/css",t.textContent=Settings.get("userDefinedLinkHintCss"),document.head.appendChild(t)}};var O={MAX_CONTENT_LENGTH:1e3,MAX_ATTRIBUTE_LENGTH:500,MAX_NUM_DATA_ATTRIBUTES:10,commonAttributes:["id","className","title","aria-label","aria-labelledby"],attributeNamesMapping:new Map([["a",["href","title","rel","target"]],["label",["for"]],["input",["type","name","placeholder","checked","maximumLength"]],["textarea",["placeholder","maximumLength"]],["button",["type"]],["select",["name","multiple"]],["div",["role"]],["iframe",["src"]],["img",["src","alt"]]]),describe(t){var r,i;let e={};this.addAttributes(t,this.commonAttributes,e);let n=((i=(r=t.tagName).toLowerCase)==null?void 0:i.call(r))||"";this.attributeNamesMapping.has(n)&&this.addAttributes(t,this.attributeNamesMapping.get(n),e),this.addDataAttrs(t,e);let o=this.getContent(t);return this.additionalHandling(t,D({tag:n,attributes:e},o&&{content:o}))},getContent(t){var n,o;let e=((o=(n=t.tagName).toLowerCase)==null?void 0:o.call(n))||"";return["input","textarea"].includes(e)?t.value:["div","iframe","img","body"].includes(e)?null:(["a","button","select","label"].includes(e),t.innerText)},additionalHandling(t,e){var o,r;if((((r=(o=t.tagName).toLowerCase)==null?void 0:r.call(o))||"")=="label"&&t.hasAttribute("for")){let i=t.getAttribute("for"),a=document.getElementById(i);a&&(e.target=this.describe(a))}return e},addAttributes(t,e,n){n||(n={});for(let o of e)t.hasAttribute(o)&&(n[o]=t.getAttribute(o).substring(0,this.MAX_ATTRIBUTE_LENGTH));return n},addDataAttrs(t,e){let n=0;for(let o in t.dataset)if(e[`data-${o}`]=t.dataset[o].substring(0,this.MAX_ATTRIBUTE_LENGTH),n++,n>this.MAX_NUM_DATA_ATTRIBUTES)return e;return e}};var x=null,C=()=>G()||document.scrollingElement||document.body,W=function(t){return t?t<0?-1:1:0},U={x:{axisName:"scrollLeft",max:"scrollWidth",viewSize:"clientWidth"},y:{axisName:"scrollTop",max:"scrollHeight",viewSize:"clientHeight"}},X=function(t,e,n){if(N.isString(n)){let o=n;return o==="viewSize"&&t===C()?e==="x"?window.innerWidth:window.innerHeight:t[U[e][o]]}else return n},V=function(t,e,n){let o=U[e].axisName,r=t[o];if(t.scrollBy){let i={behavior:"instant"};i[e==="x"?"left":"top"]=n,t.scrollBy(i)}else t[o]+=n;return t[o]!==r},q=function(t,e){let n=window.getComputedStyle(t);return!(n.getPropertyValue(`overflow-${e}`)==="hidden"||["hidden","collapse"].includes(n.getPropertyValue("visibility"))||n.getPropertyValue("display")==="none")},T=function(t,e,n,o){let r=o*X(t,e,n)||-1;return r=W(r),V(t,e,r)&&V(t,e,-r)},$=function(t,e,n,o){return e==null&&(e="y"),n==null&&(n=1),o==null&&(o=1),T(t,e,n,o)&&q(t,e)},j=function(t=null){let e;if(!t){let n=C();if(T(n,"y",1,1)||T(n,"y",-1,1))return n;t=document.body||C()}if(T(t,"y",1,1)||T(t,"y",-1,1))return t;{let n=Array.from(t.children).map(o=>({element:o,rect:f.getVisibleClientRect(o)})).filter(o=>o.rect);n.map(o=>o.area=o.rect.width*o.rect.height);for(e of n.sort((o,r)=>r.area-o.area)){let o=j(e.element);if(o)return o}return null}},L={init(){x=null},isScrollableElement(t){return x||(x=C()&&j()||C()),t!==x&&$(t)}},G=function(){let t=J[window.location.host];if(t)return document.querySelector(t)},J={"twitter.com":"div.permalink-container div.permalink[role=main]","reddit.com":"#overlayScrollContainer","new.reddit.com":"#overlayScrollContainer","www.reddit.com":"#overlayScrollContainer","web.telegram.org":".MessageList"};window.Scroller=L;var A=function(){let t=null;return f.documentReady(()=>t=document.hasFocus()),globalThis.addEventListener("focus",E(function(e){return e.target===window&&(t=!0),!0}),!0),globalThis.addEventListener("blur",E(function(e){return e.target===window&&(t=!1),!0}),!0),()=>t}();Object.assign(globalThis,{windowIsFocused:A});var R=class{constructor(e){g(this,"element");g(this,"image");g(this,"rect");g(this,"linkText");g(this,"showLinkText");g(this,"reason");g(this,"secondClassCitizen");g(this,"possibleFalsePositive");Object.seal(this),e&&Object.assign(this,e)}},M={getLocalHintsForElement(t){var p,w,v;let e=((w=(p=t.tagName).toLowerCase)==null?void 0:w.call(p))||"",n=!1,o=!1,r=!1,i=[],a=[],d=null;if(e==="img"){let u=t.getAttribute("usemap");if(u){let h=t.getClientRects();u=u.replace(/^#/,"").replace(\'"\',\'\\\\"\');let m=document.querySelector(`map[name="${u}"]`);if(m&&h.length>0){n=!0;let y=m.getElementsByTagName("area"),S=f.getClientRectsForAreas(h[0],y);S=S.map(F=>Object.assign(F,{image:t})),a.push(...S)}}}let s=t.getAttribute("aria-disabled");if(s&&["","true"].includes(s.toLowerCase()))return[];if(this.checkForAngularJs||(this.checkForAngularJs=function(){if(document.getElementsByClassName("ng-scope").length===0)return()=>!1;{let h=[];for(let m of["","data-","x-"])for(let y of["-",":","_"])h.push(`${m}ng${y}click`);return function(m){for(let y of h)if(m.hasAttribute(y))return!0;return!1}}}()),n||(n=this.checkForAngularJs(t)),t.hasAttribute("onclick"))n=!0;else{let u=t.getAttribute("role"),h=["button","tab","link","checkbox","menuitem","menuitemcheckbox","menuitemradio","radio"];if(u!=null&&h.includes(u.toLowerCase()))n=!0;else{let m=t.getAttribute("contentEditable");m!=null&&["","contenteditable","true","plaintext-only"].includes(m.toLowerCase())&&(n=!0)}}if(!n&&t.hasAttribute("jsaction")){let u=t.getAttribute("jsaction").split(";");for(let h of u){let m=h.trim().split(":");if(m.length>=1&&m.length<=2){let[y,S,F]=m.length===1?["click",...m[0].trim().split("."),"_"]:[m[0],...m[1].trim().split("."),"_"];n||(n=y==="click"&&S!=="none"&&F!=="_")}}}switch(e){case"a":n=!0;break;case"textarea":n||(n=!t.disabled&&!t.readOnly);break;case"input":n||(n=!(((v=t.getAttribute("type"))==null?void 0:v.toLowerCase())=="hidden"||t.disabled||t.readOnly&&f.isSelectable(t)));break;case"button":case"select":n||(n=!t.disabled);break;case"object":case"embed":n=!0;break;case"label":n||(n=t.control!=null&&!t.control.disabled&&this.getLocalHintsForElement(t.control).length===0);break;case"body":n||(n=t===document.body&&!A()&&window.innerWidth>3&&window.innerHeight>3&&(document.body!=null?document.body.tagName.toLowerCase():void 0)!=="frameset"?d="Frame.":void 0),n||(n=t===document.body&&A()&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"img":n||(n=["zoom-in","zoom-out"].includes(t.style.cursor));break;case"div":case"ol":case"ul":n||(n=t.clientHeight<t.scrollHeight&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"details":n=!0,d="Open.";break}let l=t.getAttribute("class");!n&&(l!=null&&l.toLowerCase().includes("button"))&&(n=!0,r=!0);let c=t.getAttribute("tabindex"),b=c?parseInt(c):-1;if(!n&&!(b<0)&&!isNaN(b)&&(n=!0,o=!0),n)if(a.length>0){let u=a.map(h=>new R({element:h.element,image:t,rect:h.rect,secondClassCitizen:o,possibleFalsePositive:r,reason:d}));i.push(...u)}else{let u=f.getVisibleClientRect(t,!0);if(u!==null){let h=new R({element:t,rect:u,secondClassCitizen:o,possibleFalsePositive:r,reason:d});i.push(h)}}return i},getElementFromPoint(t,e,n,o){n==null&&(n=document),o==null&&(o=[]);let r=n.elementsFromPoint?n.elementsFromPoint(t,e)[0]:n.elementFromPoint(t,e);return o.includes(r)?r:(o.push(r),r&&r.shadowRoot?M.getElementFromPoint(t,e,r.shadowRoot,o):r)},getLocalHints(t){if(!document.body)return[];let e=(s,l)=>{l==null&&(l=[]);for(let c of Array.from(s.querySelectorAll("*")))l.push(c),c.shadowRoot&&e(c.shadowRoot,l);return l},n=e(document.body),o=[];for(let s of Array.from(n))if(!t||s.href){let l=this.getLocalHintsForElement(s);o.push(...l)}o=o.reverse();let r=[1,2,3];o=o.filter((s,l)=>{if(!s.possibleFalsePositive)return!0;let b=Math.max(0,l-6);for(;b<l;){let p=o[b].element;for(let w of r)if(p=p==null?void 0:p.parentElement,p===s.element)return!1;b+=1}return!0});let i=o.filter(s=>{if(s.secondClassCitizen)return!1;let l=s.rect,c=M.getElementFromPoint(l.left+l.width*.5,l.top+l.height*.5);if(c&&(s.element.contains(c)||c.contains(s.element))||s.element.localName=="area"&&c==s.image)return!0;let p=[l.top+.1,l.bottom-.1],w=[l.left+.1,l.right-.1];for(let v of p)for(let u of w){let h=M.getElementFromPoint(u,v);if(h&&(s.element.contains(h)||h.contains(s.element)))return!0}});i.reverse();let{top:a,left:d}=f.getViewportTopLeft();for(let s of i)s.rect.top+=a,s.rect.left+=d;return i}};var I=class{constructor(){this.hints=null;this.hintMarkers=null;this.markersDiv=null;this.enrichedMarkers=null}reset(){this.removeMarkers(),this.hints=null,this.hintMarkers=null,this.markersDiv=null}capture(){return _(this,null,function*(){this.reset(),this.createMarkers(),this.displayMarkers()})}createMarkers(){this.hints=M.getLocalHints(),this.hintMarkers=new Map,this.hints.forEach((e,n)=>{var i,a;let o=f.createElement("div"),r=(a=(i=e.element.attributes["data-momentic-id"])==null?void 0:i.value)!=null?a:void 0;if(!r){console.warn(`[Momentic] No data-momentic-id found for interactive element ${e.element.outerHTML}`);return}o.style.left=e.rect.left+"px",o.style.top=e.rect.top+"px",o.style.zIndex=214e7+n,o.className="vimiumReset internalVimiumHintMarker vimiumHintMarker",Z(o,r),this.hintMarkers.set(r,{hint:e,marker:o})})}enrichMarkers(){if(this.hintMarkers){this.enrichedMarkers=[];for(let[e,n]of this.hintMarkers)this.enrichedMarkers.push(Object.assign(O.describe(n.hint.element),{hintString:e}))}}displayMarkers(){this.hintMarkers&&(this.markersDiv||(this.markersDiv=f.addElementsToPage(Array.from(this.hintMarkers.values()).map(e=>e.marker),{id:"vimiumHintMarkerContainer",className:"vimiumReset"})))}removeMarkers(){this.markersDiv&&(f.removeElement(this.markersDiv),this.markersDiv=null)}toggleMarkers(){this.markersDiv?this.removeMarkers():this.displayMarkers()}},Z=(t,e)=>{for(let n of e){let o=document.createElement("span");o.className="vimiumReset",o.textContent=n,t.appendChild(o)}};window.HintManager=I;\n',css:'.vimiumReset,a.vimiumReset,a:hover.vimiumReset,a:link.vimiumReset,a:visited.vimiumReset,div.vimiumReset,span.vimiumReset,table.vimiumReset,td.vimiumReset,tr.vimiumReset{background:none;border:none;bottom:auto;box-shadow:none;color:#000;cursor:auto;display:inline;float:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:inherit;font-style:normal;font-variant:normal;font-weight:400;height:auto;left:auto;letter-spacing:0;line-height:100%;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;padding:0;position:static;right:auto;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;vertical-align:baseline;white-space:normal;width:auto;z-index:2140000000}tbody.vimiumReset,thead.vimiumReset{display:table-header-group}tbody.vimiumReset{display:table-row-group}div.internalVimiumHintMarker{background:linear-gradient(180deg,#fff785 0,#ffc542);border:1px solid #c38a22;border-radius:3px;box-shadow:0 3px 7px 0 rgba(0,0,0,.3);display:block;font-size:11px;left:-1px;overflow:hidden;padding:1px 3px 0;position:absolute;top:-1px;white-space:nowrap}div.internalVimiumHintMarker span{color:#302505;font-family:Helvetica,Arial,sans-serif;font-size:11px;font-weight:700;text-shadow:0 1px 0 hsla(0,0%,100%,.6)}div.internalVimiumHintMarker>.matchingCharacter{color:#d4ac3a}div>.vimiumActiveHintMarker span{color:#a07555!important}div.internalVimiumInputHint{background-color:rgba(255,247,133,.3);border:1px solid #c38a22;display:block;pointer-events:none;position:absolute}div.internalVimiumSelectedInputHint{background-color:hsla(0,100%,70%,.3);border:1px solid #933!important}div.internalVimiumSelectedInputHint span{color:#fff!important}div.vimiumHighlightedFrame{border:5px solid #ff0;box-sizing:border-box;margin:0;pointer-events:none}div.vimiumHighlightedFrame,iframe.vimiumHelpDialogFrame{height:100%;left:0;padding:0;position:fixed;top:0;width:100%}iframe.vimiumHelpDialogFrame{background-color:hsla(0,0%,4%,.6);border:none;display:block;z-index:2139999997}div#vimiumHelpDialogContainer{background-color:#fff;border:2px solid #b3b3b3;border-radius:6px;margin:50px auto;max-height:calc(100% - 100px);max-width:calc(100% - 100px);opacity:1;overflow-x:auto;overflow-y:auto;width:840px}div#vimiumHelpDialog{min-width:600px;padding:8px 12px}span#vimiumTitle,span#vimiumTitle *,span#vimiumTitle span{font-size:20px}#vimiumTitle{display:block;line-height:130%;white-space:nowrap}td.vimiumHelpDialogTopButtons{text-align:right;width:100%}#helpDialogOptionsPage,#helpDialogWikiPage{font-size:14px;padding-left:5px;padding-right:5px}div.vimiumColumn{float:left;font-size:11px;line-height:130%;width:50%}div.vimiumColumn tr{display:table-row}div.vimiumColumn td{display:table-cell;font-size:11px;line-height:130%}div.vimiumColumn table,div.vimiumColumn td,div.vimiumColumn tr{margin:0;padding:0}div.vimiumColumn table{table-layout:auto;width:100%}div.vimiumColumn td{padding:1px;vertical-align:top}div#vimiumHelpDialog div.vimiumColumn tr>td:first-of-type{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;text-align:right;white-space:nowrap}span.vimiumHelpDialogKey{background-color:#f3f3f3;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#212121;font-family:monospace;font-size:11px;margin-left:2px;padding:1px 4px}div#vimiumHelpDialog div.vimiumColumn tr>td:nth-of-type(3){width:100%}div#vimiumHelpDialog div.vimiumDivider{background-color:#9a9a9a;display:block;height:1px;margin:10px auto;width:100%}div#vimiumHelpDialog td.vimiumHelpSectionTitle{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:16px;font-weight:700;padding-top:3px}div#vimiumHelpDialog td.vimiumHelpDescription{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px}div#vimiumHelpDialog span.vimiumCopyCommandNameName{cursor:pointer;font-size:12px;font-style:italic}div#vimiumHelpDialog tr.advanced{display:none}div#vimiumHelpDialog.showAdvanced tr.advanced{display:table-row}div#vimiumHelpDialog div.advanced td:nth-of-type(3){color:#555}div#vimiumHelpDialog a.closeButton{color:#555;cursor:pointer;font-family:courier new;font-size:24px;font-weight:700;padding-left:5px;position:relative;text-decoration:none;top:3px}div#vimiumHelpDialog a{text-decoration:underline}div#vimiumHelpDialog a.closeButton:hover{color:#000;-webkit-user-select:none}div#vimiumHelpDialogFooter{display:block;margin-bottom:37px;position:relative}table.helpDialogBottom{width:100%}td.helpDialogBottomRight{float:right;text-align:right;width:100%}td.helpDialogBottomLeft,td.helpDialogBottomRight{padding:0}div#vimiumHelpDialogFooter *{font-size:10px}a#toggleAdvancedCommands,span#help-dialog-tip{font-size:10px;position:relative;top:19px;white-space:nowrap}a#toggleAdvancedCommands,a:active.vimiumHelDialogLink,a:hover.vimiumHelDialogLink,a:link.vimiumHelDialogLink,a:visited.vimiumHelDialogLink{color:#2f508e;cursor:pointer;text-decoration:underline}div.vimiumHUD{background:#f1f1f1;border:1px solid #aaa;border-radius:4px;bottom:8px;box-shadow:0 2px 10px rgba(0,0,0,.8);display:block;left:8px;position:fixed;text-align:left;width:calc(100% - 20px);z-index:2139999999}iframe.vimiumHUDFrame{background-color:transparent;border:none;bottom:-14px;display:block;height:58px;margin:0 0 0 -40%;min-width:300px;opacity:0;overflow:hidden;padding:0;position:fixed;right:20px;width:20%;z-index:2139999998}div.vimiumHUD .vimiumHUDSearchArea{background-color:#f1f1f1;border-radius:4px 4px 0 0;display:block;padding:3px}div.vimiumHUD .vimiumHUDSearchAreaInner{border-radius:3px;box-sizing:border-box;color:#777;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;height:30px;line-height:20px;margin-bottom:0;outline:none;padding:2px 4px;width:100%}div.vimiumHUD .hud-find{background:#fff;border:1px solid #ccc}div.vimiumHUD span#hud-find-input,div.vimiumHUD span#hud-match-count{color:#000;display:inline;outline:none;overflow-y:hidden;white-space:nowrap}div.vimiumHUD span#hud-find-input:before{content:"/"}div.vimiumHUD span#hud-match-count{color:#aaa;font-size:12px}div.vimiumHUD span#hud-find-input br{display:none}div.vimiumHUD span#hud-find-input *{display:inline;white-space:nowrap}body.vimiumFindMode ::selection{background:#ff9632}iframe.vomnibarFrame{background-color:transparent;border:none;display:block;font-family:sans-serif;height:calc(100% - 70px);left:50%;margin:0 0 0 -40%;min-width:400px;overflow:hidden;padding:0;position:fixed;top:70px;width:calc(80% + 20px);z-index:2139999998}div.vimiumFlash{background-color:transparent;box-shadow:0 0 4px 2px #4183c4;padding:1px;position:absolute;z-index:2140000000}iframe.vimiumUIComponentHidden{display:none}iframe.vimiumUIComponentVisible{color-scheme:light dark;display:block}iframe.vimiumUIComponentReactivated{border:5px solid #ff0}iframe.vimiumNonClickable{pointer-events:none}@media (prefers-color-scheme:dark){iframe.reverseDarkReaderFilter{-webkit-filter:invert(100%) hue-rotate(180deg)!important;filter:invert(100%) hue-rotate(180deg)!important}body.vimiumBody{background-color:#292a2d;color:#fff}body.vimiumBody a,body.vimiumBody a:visited{color:#8ab4f8}body.vimiumBody input,body.vimiumBody textarea{background-color:#1d1d1f;border-color:#1d1d1f;color:#e8eaed}body.vimiumBody div.example{color:#9aa0a6}body.vimiumBody div#footer,body.vimiumBody div#state,div#vimiumHelpDialogContainer{background-color:#202124;border-color:hsla(0,0%,100%,.1)}div#vimiumHelpDialog{background-color:#292a2d;color:#fff}div#vimiumHelpDialog td.vimiumHelpDescription{color:#c9cccf}div#vimiumHelpDialog td.vimiumHelpSectionTitle,span#vimiumTitle{color:#fff}#vimiumTitle>span:first-child{color:#8ab4f8!important}div#vimiumHelpDialog a{color:#8ab4f8}div#vimiumHelpDialog div.vimiumDivider{background-color:hsla(0,0%,100%,.1)}span.vimiumHelpDialogKey{background-color:#1d1d1f;border:1px solid #000;box-shadow:none;color:#fff}}'};var V=(i,e)=>{let{hostname:t,pathname:o}=new URL(i),{hostname:r,pathname:n}=new URL(e);return t!==r||o!==n},Le=i=>{try{return new URL(i),!0}catch{return!1}},Ne=(i,e)=>{try{return new URL(i,e),!0}catch{return!1}};import{distance as lt}from"fastest-levenshtein";var it=new Set(["about:blank","chrome-error://chromewebdata/"]),nt=2;var wo=["focusable","keyshortcuts","controls"],So=["textbox","checkbox","combobox","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch"],Eo=["notRendered","notVisible","ariaHiddenElement","ariaHiddenSubtree"],Co=80,vo={paragraph:"p",searchbox:"input"},dt=["paragraph","StaticText"],ct={indentLevel:0,noID:!1,noChildren:!1,noProperties:!1,maxLevel:void 0,neighbors:void 0},Oe=class{id;role;name;content;properties;dataMomenticId;pathFromRoot;parent;children;backendNodeID;constructor(e){this.id=e.id,this.role=e.role,this.name=e.name,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeID=e.backendNodeID,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeID})}isInteresting(){return So.includes(this.role)||this.children.some(e=>e.role==="StaticText")?!0:!!this.name.trim()||!!this.content}serialize(e=ct){let{indentLevel:t,noChildren:o,noProperties:r,noID:n}=Object.assign({},ct,e),l=" ".repeat(t),s=vo[this.role]||this.role,c=this.name,m={...this.properties};s==="heading"&&(m.level&&(s=`h${m.level}`,delete m.level),c==="heading"&&(c=""));let h=!dt.includes(this.role);if(this.role==="StaticText")return`${l}${c}
|
|
11
|
-
`;let p=`${l}<${
|
|
12
|
-
`;else{let
|
|
13
|
-
`)?p+=`>${
|
|
6
|
+
`," ")),Ut=R.merge(a.object({type:a.literal("HOVER"),target:X,useVision:a.boolean().default(!1)})),Ft=R.merge(a.object({type:a.literal("SELECT_OPTION"),target:X,option:a.string()})).describe('SELECT_OPTION <id> "<option>" - select an option from a combobox, listbox, or menu element on the page. Provide the id of the parent combobox, listbox, or menu element in <id>. Do NOT provide the id of the option: instead, provide the name of the option in <option> enclosed by single quotes.'),He=R.merge(a.object({type:a.literal("AI_ASSERTION"),assertion:a.string(),useVision:a.boolean().default(!1),disableCache:a.boolean().default(!1),cancelOnFailure:a.boolean().default(!1)})),Ht=a.object({clearContent:a.boolean().default(!0),pressKeysSequentially:a.boolean().default(!1)}),Bt=R.merge(a.object({type:a.literal("TYPE"),target:X,value:a.string(),pressEnter:a.boolean().default(!1),useVision:a.boolean().default(!1),force:a.boolean().optional()})).merge(Ht).describe('TYPE <id> "<text>" - type the specified text into the input with the specified id. The text should be specified by the user - do not use text from the EXAMPLES or generate text yourself. Make sure to include quotes around the text.'),Gt=R.merge(a.object({type:a.literal("PRESS"),value:a.string()})).describe('PRESS <key> - press the specified key, such as "ArrowLeft", "Enter", or "a". You must specify at least one key.'),$t=R.merge(a.object({type:a.literal("TAB"),url:a.string()})),jt=R.merge(a.object({type:a.literal("COOKIE"),value:a.string()})),Vt=R.merge(a.object({type:a.literal("LOCAL_STORAGE"),key:a.string(),value:a.string()})),Wt=R.merge(a.object({type:a.literal("REQUEST"),url:a.string(),method:a.union([a.literal("GET"),a.literal("POST"),a.literal("PUT"),a.literal("DELETE"),a.literal("PATCH")]),headers:a.record(a.string(),a.string()).optional(),params:a.record(a.string(),a.string()).optional(),body:a.string().optional(),timeout:a.number().optional().describe("Max seconds to wait for the request to complete")})),Kt=R.merge(a.object({type:a.literal("SUCCESS"),condition:He.optional()})).describe("SUCCESS - the user goal has been successfully achieved"),Y=a.discriminatedUnion("type",[kt,Bt,Gt,Ft,Lt,Ot,Nt,Kt]),qt=a.discriminatedUnion("type",[zt,Pt,Mt,He,Dt,$t,jt,Vt,Ut,Wt,_t]),Be=a.discriminatedUnion("type",[...Y.options,...qt.options]),Xt=R.merge(a.object({type:a.literal("FAILURE")})).describe("FAILURE - there are no commands to suggest that could make progress that have not already been tried before"),Se=a.discriminatedUnion("type",[...Y.options,Xt]);import*as T from"zod";var P=(o=>(o.AI_ACTION="AI_ACTION",o.PRESET_ACTION="PRESET_ACTION",o.MODULE="MODULE",o))(P||{}),J=T.object({type:T.literal("AI_ACTION"),text:T.string(),commands:T.array(Y).optional()}),Q=T.object({type:T.literal("PRESET_ACTION"),command:Be}),Ce=T.object({type:T.literal("MODULE"),moduleId:T.string().uuid()}),Z=T.union([J,Q]),ee=T.object({type:T.literal("RESOLVED_MODULE"),moduleId:T.string().uuid(),name:T.string(),steps:Z.array()}),ce=T.union([J,Q,Ce]),te=T.union([J,Q,ee]);import{distance as Ho}from"fastest-levenshtein";import{homedir as Bo}from"os";import{join as Go}from"path";import{chromium as $o,devices as Rt}from"playwright";import{addExtra as jo}from"playwright-extra";import Vo from"puppeteer-extra-plugin-recaptcha";import Wo from"puppeteer-extra-plugin-stealth";import{z as oe}from"zod";var Ge=oe.object({thoughts:oe.string(),result:oe.boolean(),relevantElements:oe.array(oe.number()).optional()});import gr from"string-argv";import{z as G}from"zod";var de=(n=>(n.AI_PROVIDER="AIProviderError",n.AI_TIMEOUT="AITimeoutError",n.JOB_TIMEOUT="JobTimeoutError",n.ACTION_FAILURE="ActionFailureError",n.ASSERTION_FAILURE="AssertionFailureError",n.WEB_AGENT_PLATFORM="InternalWebAgentError",n.UNKNOWN_PLATFORM="InternalPlatformError",n))(de||{});var re=class extends Error{constructor(e,t={}){super(e,t),this.name="BrowserExecutionError"}};var me=class extends Error{constructor(e={}){super("Got empty a11y tree",e),this.name="EmptyA11yTreeError"}};var x=class extends Error{reason;constructor(e,t,o={}){let i=!1;for(let s of Object.values(de))if(t.startsWith(s)){i=!0,e=s;break}i?super(t,o):super(`${e}: ${t}`,o),this.name="TestFailureError",this.stack=this.stack?.slice(this.name.length+2),this.reason=e}toString(){return this.message}toJSON(){return{message:this.message}}};var wr=G.object({command:G.string(),thoughts:G.string()}),Sr=G.string().pipe(G.coerce.number());var $e=G.object({phrase:G.string()});var Ar=new Set(Object.values(F));var Yt={AI_ACTION:"AI action",MODULE:"Module",AI_ASSERTION:"AI check",CLICK:"Click",HOVER:"Hover",SELECT_OPTION:"Select",TYPE:"Type",PRESS:"Press",NAVIGATE:"Navigate",SCROLL_UP:"Scroll up",SCROLL_DOWN:"Scroll down",CAPTCHA:"Captcha",GO_BACK:"Go back",GO_FORWARD:"Go forward",WAIT:"Wait",REFRESH:"Refresh",TAB:"Switch tab",COOKIE:"Set cookie",LOCAL_STORAGE:"Set local storage",REQUEST:"Request",SUCCESS:"Done"},Tr={AI_ACTION:"Ask AI to plan and execute something on the page.",MODULE:"A list of steps that can be reused in multiple tests.",AI_ASSERTION:"Ask AI whether something is true on the page.",CLICK:"Click on an element on the page based on a description.",HOVER:"Hover over an element on the page based on a description.",SELECT_OPTION:"Select an option from a dropdown based on a description.",TYPE:"Type the specified text into an element.",PRESS:"Press the specified keys using the keyboard. (e.g. Ctrl+A)",NAVIGATE:"Navigate to the specified URL.",SCROLL_UP:"Scroll up one page.",SCROLL_DOWN:"Scroll down one page.",GO_BACK:"Go back in browser history.",GO_FORWARD:"Go forward in browser history.",WAIT:"Wait for the specified number of seconds.",REFRESH:"Refresh the page. This will not clear cookies or session data.",TAB:"Switch to different tab in the browser.",COOKIE:"Set a cookie that will persist throughout the browser session",LOCAL_STORAGE:"Set a local storage value that will persist throughout the browser session",CAPTCHA:"Solve captchas on the page. This may take 10-60 seconds.",REQUEST:"Make an API request to a URL.",SUCCESS:"Indicate the entire AI action has succeeded, optionally based on a condition."};import*as h from"zod";var je=(s=>(s.SUCCESS="SUCCESS",s.FAILED="FAILED",s.RUNNING="RUNNING",s.IDLE="IDLE",s.CANCELLED="CANCELLED",s))(je||{}),Ve=(o=>(o.SUCCESS="SUCCESS",o.FAILED="FAILED",o.CANCELLED="CANCELLED",o))(Ve||{}),Jt=h.object({beforeUrl:h.string(),beforeScreenshot:h.string().or(h.any()).optional(),afterUrl:h.string().optional(),afterScreenshot:h.string().or(h.any()).optional(),startedAt:h.coerce.date(),finishedAt:h.coerce.date(),viewport:h.object({height:h.number(),width:h.number()}),status:h.nativeEnum(Ve),message:h.string().optional(),elementInteracted:h.string().optional()}),pe=h.object({startedAt:h.coerce.date(),finishedAt:h.coerce.date(),status:h.nativeEnum(je),message:h.string().optional(),data:h.record(h.string(),h.unknown()).optional(),userAgent:h.string().optional()}),Ee=Q.merge(pe).merge(h.object({results:Jt.array()})),We=J.merge(pe).merge(h.object({results:Ee.array()})),Qt=Ce.merge(pe).merge(h.object({results:h.union([We,Ee]).array()})),ue=h.discriminatedUnion("type",[We,Ee,Qt]),Ir=pe.pick({startedAt:!0,finishedAt:!0,status:!0,message:!0,data:!0});function Zt(r,e){return r.length<e?r:r.slice(0,e-3)+"[...]"}function ve(r){switch(r.type){case"SUCCESS":return r.condition?.assertion?`Check success condition: ${r.condition.assertion}`:"All commands completed";case"NAVIGATE":return`Go to URL: ${Zt(r.url,30)}`;case"CAPTCHA":return"Solve captchas on the page";case"GO_BACK":return"Go back to the previous page";case"GO_FORWARD":return"Go forward to the next page";case"SCROLL_DOWN":return`Scroll down one page${r.target?` in the container of: ${r.target.elementDescriptor}`:""}`;case"SCROLL_UP":return`Scroll up one page${r.target?` in the container of: ${r.target.elementDescriptor}`:""}`;case"WAIT":return`Wait for ${r.delay} seconds`;case"REFRESH":return"Refresh the page";case"CLICK":return`Click on '${r.target.elementDescriptor}'`;case"TYPE":{let t="";return r.target.a11yData?.serializedForm?t=`in element: ${r.target.a11yData.serializedForm}`:r.target.elementDescriptor.length>0&&(t=`in element: ${r.target.elementDescriptor}`),`Type '${r.value}' ${t}`}case"HOVER":{let t="";return r.target.a11yData?.serializedForm?t=` over element: ${r.target.a11yData.serializedForm}`:r.target.elementDescriptor.length>0&&(t=` over element: ${r.target.elementDescriptor}`),`Hover${t}`}case"PRESS":return`Press '${r.value}'`;case"SELECT_OPTION":return`Select option '${r.option}' in '${r.target.elementDescriptor}'`;case"TAB":return`Switch to tab: ${r.url}`;case"REQUEST":return`Send ${r.method} request to ${r.url}`;case"COOKIE":return`Set cookie: ${r.value}`;case"LOCAL_STORAGE":return`Set local storage: ${r.key}: ${r.value}`;case"AI_ASSERTION":return`${r.useVision?"Visual assertion":"Assertion"}: '${r.assertion}'`;default:return(t=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(r)}}import*as M from"zod";import*as $ from"zod";var Ke=$.object({type:$.nativeEnum(P),generatedStep:Y.optional(),serializedCommand:$.string().optional(),elementInteracted:$.string().optional()});var H=M.object({goal:M.string(),url:M.string(),browserState:M.string(),history:M.string(),numPrevious:M.number(),lastCommand:Ke.or(M.null())});import{parseString as eo}from"set-cookie-parser";function qe(r){let e=eo(r);if(!e.name)throw new Error("Name missing from cookie");if(!e.value)throw new Error("Value missing from cookie");let t;if(e.sameSite){let i=e.sameSite.trim().toLowerCase();if(i==="strict")t="Strict";else if(i==="lax")t="Lax";else if(i==="none")t="None";else throw new Error(`Invalid sameSite setting in cookie: ${i}`)}return!e.path&&e.domain&&(e.path="/"),{...e,expires:e.expires?e.expires.getTime()/1e3:void 0,sameSite:t}}import{z as O}from"zod";var oo="1.0.0",Xe=O.object({run:O.string().describe("Run a single command in the shell. The working directory will be set to where the CLI was invoked from."),waitForCompletion:O.boolean().optional().describe("Defaults to true")}),Gr=O.object({type:O.literal("momentic/fixture"),schemaVersion:O.string(),name:O.string(),description:O.string().optional(),setup:O.object({steps:Xe.array(),timeout:O.number().optional().describe("Timeout for all steps in seconds")}).optional(),teardown:O.object({steps:Xe.array(),timeout:O.number().optional().describe("Timeout for all steps in seconds")}).optional()}),$r={type:"momentic/fixture",schemaVersion:oo,name:"example",description:"An example fixture",setup:{steps:[{run:"./scripts/seed_db.sh",waitForCompletion:!0},{run:"npm run start",waitForCompletion:!1}],timeout:30},teardown:{steps:[{run:"./scripts/shutdown_db.sh"}]}};import{z as ro}from"zod";var Wr=ro.string().array();import{z as E}from"zod";import{z as I}from"zod";import{z as he}from"zod";var Ye=he.object({name:he.string(),fixtures:he.array(he.string().describe("Name of the fixture (must be available locally in the fixtures directory).")).optional()});import{isValidCron as io}from"cron-validator";import{z}from"zod";var Je=z.object({availableAsModule:z.boolean().default(!1),disableAICaching:z.boolean().default(!1)}),Qe=z.object({cron:z.string().refine(r=>io(r),{message:"Invalid cron expression."}).default("0 0 */1 * *"),enabled:z.boolean().default(!1),timeZone:z.string().default("America/Los_Angeles"),jobKey:z.string().optional()}),Ze=z.object({onSuccess:z.boolean().default(!1),onFailure:z.boolean().default(!0)});var no=I.string().min(1).max(255).superRefine((r,e)=>{try{mo(r)}catch(t){return e.addIssue({code:I.ZodIssueCode.custom,message:t.message,fatal:!0}),I.NEVER}}),j=I.object({id:I.string(),name:no,baseUrl:I.string(),schemaVersion:I.string(),advanced:Je,retries:I.number(),envSettings:Ye.array().optional(),localOnly:I.boolean().optional()}),ri=j.pick({name:!0,baseUrl:!0,retries:!0,advanced:!0}),so=I.object({createdAt:I.coerce.date(),updatedAt:I.coerce.date(),schedule:Qe,notification:Ze,createdBy:I.string(),organizationId:I.string()}),ao=j.merge(so).merge(I.object({steps:I.array(te)})),et=j.merge(I.object({steps:I.array(te)})),ii=j.merge(I.object({steps:ce.array()}));var lo=/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/,co=["modules","fixtures"];function mo(r){if(r=r.toLowerCase().trim(),r.length===0||r.length>255)throw new Error("Name must be between 1 and 255 characters long");if(/[<>:"\/\\|?*\x00]/.test(r))throw new Error("Name can only contain alphanumeric characters, dashes, and underscores.");if(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i.test(r))throw new Error(`"${r}" is a reserved name on Windows and cannot be used as a filename.`);if(/^\.+$/.test(r)||/^\s|\s$/.test(r))throw new Error("Name cannot start or end with a space or dot.");if(r.endsWith(".yaml"))throw new Error('Name cannot end with ".yaml".');if(co.includes(r))throw new Error("'modules' is a reserved folder name in Momentic. Please choose a different name.");if(r.match(lo))throw new Error("Name cannot be a UUID. Please choose a different name.")}var po="momentic-frame",ci=`${po}-0`,di=E.array(E.object({id:E.string(),name:E.string(),fullFilePath:E.string(),testPath:E.string().describe("path relative to the root test directory, i.e. my-folder/my-test.yaml"),fileName:E.string(),lastModified:E.coerce.date(),createdAt:E.coerce.date()}));var mi=E.object({steps:te.array()}),pi=E.object({name:E.string(),baseUrl:E.string().url()}),ui=et.merge(E.object({testPath:E.string()})),hi=E.object({name:E.string(),steps:Z.array()});var gi=E.array(ee),fi=E.array(E.object({name:E.string(),moduleId:E.string().uuid(),numSteps:E.number()}));import*as _ from"zod";var tt=_.object({thoughts:_.string(),id:_.number().int(),options:_.array(_.string()).optional()});var uo={0:"DEBUG",1:"INFO",2:"WARN",3:"ERROR"},ho={0:"\x1B[90m",1:"\x1B[32m",2:"\x1B[33m",3:"\x1B[31m"},Ae=class r{minLogLevel;logBindings;constructor(e,t){this.minLogLevel=e,this.logBindings=t}log(e,...t){let o=uo[e],i;Array.isArray(t[0])?(i=t[0],t=t.slice(1)):typeof t[0]=="object"&&!(t[0]instanceof Error)&&(i={...t[0],...this.logBindings},t=t.slice(1));let s=ho[e],l=[`${s}[${new Date().toTimeString().slice(0,8)}][${o}]`];if(e!==0&&l.push("\x1B[39m"),l.push(...t),console.log(...l),i&&!Array.isArray(i))for(let[n,c]of Object.entries(i)){let m=c;c instanceof Error?m=c.message:typeof c=="object"&&(m=JSON.stringify(c,void 0,2),m=m.split(`
|
|
7
|
+
`).map((g,p)=>p>0?` ${g}`:g).join(`
|
|
8
|
+
`)),console.log(e===0?`${s} ${n}:`:` ${n}:`,m)}else if(i)for(let n of i){let c=n;typeof n=="object"&&(c=JSON.stringify(n,void 0,2),c=c.split(`
|
|
9
|
+
`).map((m,g)=>g>0?` ${m}`:m).join(`
|
|
10
|
+
`)),console.log(e===0?`${s} `:" ",c)}e===0&&process.stdout.write("\x1B[39m")}setMinLevel(e){this.minLogLevel=e}info(...e){1<this.minLogLevel||this.log(1,...e)}debug(...e){0<this.minLogLevel||this.log(0,...e)}warn(...e){2<this.minLogLevel||this.log(2,...e)}error(...e){3<this.minLogLevel||this.log(3,...e)}child(e){return new r(this.minLogLevel,{...this.logBindings,...e})}flush(){}bindings(){return this.logBindings}},wi=new Ae(1,{});import{z as k}from"zod";var go=k.object({id:k.string(),createdAt:k.coerce.date(),createdBy:k.string(),organizationId:k.string(),name:k.string(),schemaVersion:k.string(),numSteps:k.number()}),vi=k.object({steps:Z.array()}).merge(go.omit({numSteps:!0}));import*as d from"zod";import{z as b}from"zod";var Te={WEBHOOK:"WEBHOOK",CRON:"CRON",MANUAL:"MANUAL",CLI:"CLI"},Re={PENDING:"PENDING",RUNNING:"RUNNING",PASSED:"PASSED",FAILED:"FAILED",CANCELLED:"CANCELLED"},fo={PASSED:"PASSED",FAILED:"FAILED"},ge=b.string().pipe(b.coerce.date()).or(b.date()),yo=b.object({id:b.string(),createdAt:ge,createdBy:b.string(),organizationId:b.string(),scheduledAt:ge.or(b.null()),startedAt:ge.or(b.null()),finishedAt:ge.or(b.null()),testId:b.string().or(b.null()),status:b.nativeEnum(Re),expectedStatus:b.nativeEnum(fo).or(b.null()),runKey:b.string(),trigger:b.nativeEnum(Te),attempts:b.number(),test:b.object({name:b.string(),id:b.string()}).or(b.null())}),bo=yo.merge(b.object({results:ue.array(),test:b.object({name:b.string(),id:b.string(),baseUrl:b.string()}).or(b.null())}));var V=d.object({disableCache:d.boolean()}),_i=d.object({error:d.boolean(),reason:d.string(),message:d.string()}),ki=H.merge(V),ot=Se,Ui=d.discriminatedUnion("vision",[H.merge(V).merge(d.object({vision:d.literal(!1)})),H.pick({goal:!0,url:!0}).merge(V).merge(d.object({screenshot:d.string(),vision:d.literal(!0)}))]),xe=Ge,Fi=H.pick({browserState:!0,goal:!0}).merge(V),Hi=H.pick({goal:!0}).merge(V).merge(d.object({screenshot:d.string().describe("base64 encoded image"),hintActivatedScreenshot:d.string().describe("base64 encoded image")})),Ie=tt,Bi=H.pick({goal:!0,url:!0}).merge(V),rt=d.string().array(),Gi=H.pick({goal:!0,browserState:!0}).merge(V),it=$e,$i=d.object({testPaths:d.string().array().describe("can be either hyphenated, lowercase test names or UUIDs"),all:d.boolean().optional()}),ji=d.object({message:d.string(),queuedTests:d.object({name:d.string(),id:d.string()}).array()});var Vi=d.string().array(),Wi=d.union([d.object({paths:d.string().array().describe("run specific test paths (e.g. todo-test)")}),d.object({path:d.string().describe("deprecated; present for backcompat")}),d.object({all:d.boolean().describe("run all tests")})]),Ki=d.object({tests:d.record(d.string().describe("Test name"),d.string().describe("Test YAML")),modules:d.record(d.string().describe("Module name"),d.string().describe("Module YAML"))}),wo=d.object({test:d.string().describe("test YAML"),modules:d.record(d.string().describe("moduleId"),d.string().describe("module YAML"))}),qi=wo.array();var Xi=d.object({testPath:d.string(),testId:d.string()}).partial().merge(d.object({trigger:d.nativeEnum(Te)}));var Yi=d.object({startedAt:d.coerce.date(),finishedAt:d.coerce.date(),results:ue.array(),status:d.nativeEnum(Re)}).partial(),Ji=d.object({screenshot:d.string()}),Qi=d.object({key:d.string()}),Zi=d.object({orgId:d.string()});import{stringify as ln}from"yaml";import{z as v}from"zod";var gn=v.object({test:v.string().describe("YAML for the test, including metadata and steps"),modules:v.record(v.string(),v.string()).describe("Map of module name to YAML for the module")}),fn=j.merge(v.object({steps:ce.array(),fileType:v.literal("momentic/test")})),yn=ee.omit({type:!0}).merge(v.object({schemaVersion:v.string(),fileType:v.literal("momentic/module")})),bn=j.merge(v.object({steps:v.array(v.record(v.string(),v.unknown()))})),wn=v.object({moduleId:v.string().uuid(),name:v.string(),schemaVersion:v.string(),steps:v.array(v.record(v.string(),v.unknown()))});var Le={js:'var K=Object.defineProperty;var P=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var H=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,D=(t,e)=>{for(var n in e||(e={}))z.call(e,n)&&H(t,n,e[n]);if(P)for(var n of P(e))B.call(e,n)&&H(t,n,e[n]);return t};var g=(t,e,n)=>(H(t,typeof e!="symbol"?e+"":e,n),n);var _=(t,e,n)=>new Promise((o,r)=>{var i=s=>{try{d(n.next(s))}catch(l){r(l)}},a=s=>{try{d(n.throw(s))}catch(l){r(l)}},d=s=>s.done?o(s.value):Promise.resolve(s.value).then(i,a);d((n=n.apply(t,e)).next())});var E=t=>function(e){return e&&e.isTrusted?t.apply(this,arguments):!0};globalThis.forTrusted==null&&(globalThis.forTrusted=E);var k={create(t,e,n,o){return{bottom:o,top:e,left:t,right:n,width:n-t,height:o-e}},copy(t){return{bottom:t.bottom,top:t.top,left:t.left,right:t.right,width:t.width,height:t.height}},translate(t,e,n){return e==null&&(e=0),n==null&&(n=0),{bottom:t.bottom+n,top:t.top+n,left:t.left+e,right:t.right+e,width:t.width,height:t.height}},subtract(t,e){return e=this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom)),e.width<0||e.height<0?[k.copy(t)]:[this.create(t.left,t.top,e.left,e.top),this.create(e.left,t.top,e.right,e.top),this.create(e.right,t.top,t.right,e.top),this.create(t.left,e.top,e.left,e.bottom),this.create(e.right,e.top,t.right,e.bottom),this.create(t.left,e.bottom,e.left,t.bottom),this.create(e.left,e.bottom,e.right,t.bottom),this.create(e.right,e.bottom,t.right,t.bottom)].filter(o=>o.height>0&&o.width>0)},intersects(t,e){return t.right>e.left&&t.left<e.right&&t.bottom>e.top&&t.top<e.bottom},intersectsStrict(t,e){return t.right>=e.left&&t.left<=e.right&&t.bottom>=e.top&&t.top<=e.bottom},equals(t,e){for(let n of["top","bottom","left","right","width","height"])if(t[n]!==e[n])return!1;return!0},intersect(t,e){return this.create(Math.max(t.left,e.left),Math.max(t.top,e.top),Math.min(t.right,e.right),Math.min(t.bottom,e.bottom))}};var N={_browserInfoLoaded:!0,_firefoxVersion:null,_isFirefox:!1,isFirefox(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._isFirefox},firefoxVersion(){if(!this._browserInfoLoaded)throw Error("browserInfo has not yet loaded.");return this._firefoxVersion},isString(t){return typeof t=="string"||t instanceof String}};var f={isReady(){return document.readyState!=="loading"},documentReady:function(){let t=document.readyState!=="loading",e=[];if(!t){let n;globalThis.addEventListener("DOMContentLoaded",n=E(function(){globalThis.removeEventListener("DOMContentLoaded",n,!0),t=!0;for(let o of e)o();e=null}),!0)}return function(n){if(t)return n();e.push(n)}}(),documentComplete:function(){let t=document.readyState==="complete",e=[];if(!t){let n;globalThis.addEventListener("load",n=E(function(o){if(o.target===document){globalThis.removeEventListener("load",n,!0),t=!0;for(let r of e)r();e=null}}),!0)}return function(n){t?n():e.push(n)}}(),createElement(t){let e=document.createElement(t);return e instanceof HTMLElement?(this.createElement=n=>document.createElement(n),e):(this.createElement=n=>document.createElementNS("http://www.w3.org/1999/xhtml",n),this.createElement(t))},addElementsToPage(t,e){let n=this.createElement("div");e.id!=null&&(n.id=e.id),e.className!=null&&(n.className=e.className);for(let o of t)n.appendChild(o);return document.body.appendChild(n),n},removeElement(t){return t.parentNode.removeChild(t)},isTopFrame(){return globalThis.top===globalThis.self},makeXPath(t){let e=[];for(let n of t)e.push(".//"+n,".//xhtml:"+n);return e.join(" | ")},evaluateXPath(t,e){let n=document.webkitIsFullScreen?document.webkitFullscreenElement:document.documentElement,o=function(r){return r==="xhtml"?"http://www.w3.org/1999/xhtml":null};return document.evaluate(t,n,o,e,null)},getVisibleClientRect(t,e){let n;e==null&&(e=!1);let o=(()=>{let i=[];for(n of t.getClientRects())i.push(k.copy(n));return i})(),r=function(){let i=window.getComputedStyle(t,null),a=i.getPropertyValue("display").indexOf("inline")===0&&i.getPropertyValue("font-size")==="0px";return r=()=>a,a};for(n of o){let i;if((n.width===0||n.height===0)&&e)for(let a of Array.from(t.children)){i=window.getComputedStyle(a,null);let d=i.getPropertyValue("position");if(i.getPropertyValue("float")==="none"&&!["absolute","fixed"].includes(d)&&!(n.height===0&&r()&&i.getPropertyValue("display").indexOf("inline")===0))continue;let s=this.getVisibleClientRect(a,!0);if(!(s===null||s.width<3||s.height<3))return s}else{if(n=this.cropRectToVisible(n),n===null||n.width<3||n.height<3||(i=window.getComputedStyle(t,null),i.getPropertyValue("visibility")!=="visible"))continue;return n}}return null},cropRectToVisible(t){let e=k.create(Math.max(t.left,0),Math.max(t.top,0),t.right,t.bottom);return e.top>=window.innerHeight-4||e.left>=window.innerWidth-4?null:e},getClientRectsForAreas(t,e){let n=[];for(let o of e){let r,i,a,d,s=o.coords.split(",").map(p=>parseInt(p,10)),l=o.shape.toLowerCase();if(["rect","rectangle"].includes(l))s.length==4&&([r,a,i,d]=s);else if(["circle","circ"].includes(l)){if(s.length==3){let[p,w,v]=s,u=v/Math.sqrt(2);r=p-u,i=p+u,a=w-u,d=w+u}}else l==="default"?s.length==2&&([r,a,i,d]=[0,0,t.width,t.height]):s.length>=4&&([r,a,i,d]=s);let c=k.translate(k.create(r,a,i,d),t.left,t.top);c=this.cropRectToVisible(c),c&&!isNaN(c.top)&&!isNaN(c.left)&&!isNaN(c.width)&&!isNaN(c.height)&&n.push({element:o,rect:c})}return n},isSelectable(t){if(!(t instanceof Element))return!1;let e=["button","checkbox","color","file","hidden","image","radio","reset","submit"];return t.nodeName.toLowerCase()==="input"&&e.indexOf(t.type)===-1||t.nodeName.toLowerCase()==="textarea"||t.isContentEditable},isEditable(t){return this.isSelectable(t)||(t.nodeName!=null?t.nodeName.toLowerCase():void 0)==="select"},isEmbed(t){let e=t.nodeName!=null?t.nodeName.toLowerCase():null;return["embed","object"].includes(e)},isFocusable(t){return t&&(this.isEditable(t)||this.isEmbed(t))},isDOMDescendant(t,e){let n=e;for(;n!==null;){if(n===t)return!0;n=n.parentNode}return!1},isSelected(t){let e=document.getSelection();if(t.isContentEditable){let n=e.anchorNode;return n&&this.isDOMDescendant(t,n)}else if(f.getSelectionType(e)==="Range"&&e.isCollapsed){let n=e.anchorNode.childNodes[e.anchorOffset];return t===n}else return!1},simulateSelect(t){if(t===document.activeElement&&f.isEditable(document.activeElement))return handlerStack.bubbleEvent("click",{target:t});if(t.focus(),t.tagName.toLowerCase()!=="textarea"||t.value.indexOf(`\n`)<0)try{if(t.selectionStart===0&&t.selectionEnd===0)return t.setSelectionRange(t.value.length,t.value.length)}catch(e){}},simulateClick(t,e){e==null&&(e={});let n=["mouseover","mousedown","mouseup","click"],o=[];for(let r of n){let i=this.simulateMouseEvent(r,t,e);o.push(i)}return o},simulateMouseEvent(t,e,n){if(n==null&&(n={}),t==="mouseout"){if(e==null&&(e=this.lastHoveredElement),this.lastHoveredElement=void 0,e==null)return}else t==="mouseover"&&(this.simulateMouseEvent("mouseout",void 0,n),this.lastHoveredElement=e);let o=new MouseEvent(t,{bubbles:!0,cancelable:!0,composed:!0,view:window,detail:1,ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey});return e.dispatchEvent(o)},simulateClickDefaultAction(t,e){let n;if(e==null&&(e={}),(t.tagName!=null?t.tagName.toLowerCase():void 0)!=="a"||!t.href)return;let{ctrlKey:o,shiftKey:r,metaKey:i,altKey:a}=e;KeyboardUtils.platform==="Mac"?n=i===!0&&o===!1:n=i===!1&&o===!0,n?chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:r===!0}):r===!0&&i===!1&&o===!1&&a===!1?chrome.runtime.sendMessage({handler:"openUrlInNewWindow",url:t.href}):t.target==="_blank"&&chrome.runtime.sendMessage({handler:"openUrlInNewTab",url:t.href,active:!0})},simulateHover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseover",t,e)},simulateUnhover(t,e){return e==null&&(e={}),this.simulateMouseEvent("mouseout",t,e)},addFlashRect(t){let e=this.createElement("div");return e.classList.add("vimiumReset"),e.classList.add("vimiumFlash"),e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",document.documentElement.appendChild(e),e},getViewportTopLeft(){let t=document.documentElement,e=getComputedStyle(t),n=t.getBoundingClientRect();if(e.position==="static"&&!/content|paint|strict/.test(e.contain||"")){let o=parseInt(e.marginTop),r=parseInt(e.marginLeft);return{top:-n.top+o,left:-n.left+r}}else{let o,r;return N.isFirefox()?(r=parseInt(e.borderTopWidth),o=parseInt(e.borderLeftWidth)):{clientTop:r,clientLeft:o}=t,{top:-n.top-r,left:-n.left-o}}},suppressPropagation(t){t.stopImmediatePropagation()},suppressEvent(t){t.preventDefault(),this.suppressPropagation(t)},consumeKeyup:function(){let t=null;return function(e,n=null,o){if(!e.repeat){t!=null&&handlerStack.remove(t);let{code:r}=e;t=handlerStack.push({_name:"dom_utils/consumeKeyup",keyup(i){return i.code!==r||(this.remove(),o?f.suppressPropagation(i):f.suppressEvent(i)),handlerStack.continueBubbling},blur(i){return i.target===window&&this.remove(),handlerStack.continueBubbling}})}return typeof n=="function"&&n(),o?(f.suppressPropagation(e),handlerStack.suppressPropagation):(f.suppressEvent(e),handlerStack.suppressEvent)}}(),getSelectionType(t){return t==null&&(t=document.getSelection()),t.type?t.type:t.rangeCount===0?"None":t.isCollapsed?"Caret":"Range"},getElementWithFocus(t,e){let n,o=n=t.getRangeAt(0);f.getSelectionType(t)==="Range"&&(o=n.cloneRange(),o.collapse(e)),n=o.startContainer,n.nodeType===1&&(n=n.childNodes[o.startOffset]);let r=n;for(;r&&r.nodeType!==1;)r=r.previousSibling;return n=r||(n!=null?n.parentNode:void 0),n},getSelectionFocusElement(){let t=window.getSelection(),e=t.focusNode;return e==null?null:(e===t.anchorNode&&t.focusOffset===t.anchorOffset&&(e=e.childNodes[t.focusOffset]||e),e.nodeType!==Node.ELEMENT_NODE?e.parentElement:e)},getContainingElement(t){return(typeof t.getDestinationInsertionPoints=="function"?t.getDestinationInsertionPoints()[0]:void 0)||t.parentElement},windowIsTooSmall(){return window.innerWidth<3||window.innerHeight<3},injectUserCss(){let t=document.createElement("style");t.type="text/css",t.textContent=Settings.get("userDefinedLinkHintCss"),document.head.appendChild(t)}};var O={MAX_CONTENT_LENGTH:1e3,MAX_ATTRIBUTE_LENGTH:500,MAX_NUM_DATA_ATTRIBUTES:10,commonAttributes:["id","className","title","aria-label","aria-labelledby"],attributeNamesMapping:new Map([["a",["href","title","rel","target"]],["label",["for"]],["input",["type","name","placeholder","checked","maximumLength"]],["textarea",["placeholder","maximumLength"]],["button",["type"]],["select",["name","multiple"]],["div",["role"]],["iframe",["src"]],["img",["src","alt"]]]),describe(t){var r,i;let e={};this.addAttributes(t,this.commonAttributes,e);let n=((i=(r=t.tagName).toLowerCase)==null?void 0:i.call(r))||"";this.attributeNamesMapping.has(n)&&this.addAttributes(t,this.attributeNamesMapping.get(n),e),this.addDataAttrs(t,e);let o=this.getContent(t);return this.additionalHandling(t,D({tag:n,attributes:e},o&&{content:o}))},getContent(t){var n,o;let e=((o=(n=t.tagName).toLowerCase)==null?void 0:o.call(n))||"";return["input","textarea"].includes(e)?t.value:["div","iframe","img","body"].includes(e)?null:(["a","button","select","label"].includes(e),t.innerText)},additionalHandling(t,e){var o,r;if((((r=(o=t.tagName).toLowerCase)==null?void 0:r.call(o))||"")=="label"&&t.hasAttribute("for")){let i=t.getAttribute("for"),a=document.getElementById(i);a&&(e.target=this.describe(a))}return e},addAttributes(t,e,n){n||(n={});for(let o of e)t.hasAttribute(o)&&(n[o]=t.getAttribute(o).substring(0,this.MAX_ATTRIBUTE_LENGTH));return n},addDataAttrs(t,e){let n=0;for(let o in t.dataset)if(e[`data-${o}`]=t.dataset[o].substring(0,this.MAX_ATTRIBUTE_LENGTH),n++,n>this.MAX_NUM_DATA_ATTRIBUTES)return e;return e}};var x=null,C=()=>G()||document.scrollingElement||document.body,W=function(t){return t?t<0?-1:1:0},U={x:{axisName:"scrollLeft",max:"scrollWidth",viewSize:"clientWidth"},y:{axisName:"scrollTop",max:"scrollHeight",viewSize:"clientHeight"}},X=function(t,e,n){if(N.isString(n)){let o=n;return o==="viewSize"&&t===C()?e==="x"?window.innerWidth:window.innerHeight:t[U[e][o]]}else return n},V=function(t,e,n){let o=U[e].axisName,r=t[o];if(t.scrollBy){let i={behavior:"instant"};i[e==="x"?"left":"top"]=n,t.scrollBy(i)}else t[o]+=n;return t[o]!==r},q=function(t,e){let n=window.getComputedStyle(t);return!(n.getPropertyValue(`overflow-${e}`)==="hidden"||["hidden","collapse"].includes(n.getPropertyValue("visibility"))||n.getPropertyValue("display")==="none")},T=function(t,e,n,o){let r=o*X(t,e,n)||-1;return r=W(r),V(t,e,r)&&V(t,e,-r)},$=function(t,e,n,o){return e==null&&(e="y"),n==null&&(n=1),o==null&&(o=1),T(t,e,n,o)&&q(t,e)},j=function(t=null){let e;if(!t){let n=C();if(T(n,"y",1,1)||T(n,"y",-1,1))return n;t=document.body||C()}if(T(t,"y",1,1)||T(t,"y",-1,1))return t;{let n=Array.from(t.children).map(o=>({element:o,rect:f.getVisibleClientRect(o)})).filter(o=>o.rect);n.map(o=>o.area=o.rect.width*o.rect.height);for(e of n.sort((o,r)=>r.area-o.area)){let o=j(e.element);if(o)return o}return null}},L={init(){x=null},isScrollableElement(t){return x||(x=C()&&j()||C()),t!==x&&$(t)}},G=function(){let t=J[window.location.host];if(t)return document.querySelector(t)},J={"twitter.com":"div.permalink-container div.permalink[role=main]","reddit.com":"#overlayScrollContainer","new.reddit.com":"#overlayScrollContainer","www.reddit.com":"#overlayScrollContainer","web.telegram.org":".MessageList"};window.Scroller=L;var A=function(){let t=null;return f.documentReady(()=>t=document.hasFocus()),globalThis.addEventListener("focus",E(function(e){return e.target===window&&(t=!0),!0}),!0),globalThis.addEventListener("blur",E(function(e){return e.target===window&&(t=!1),!0}),!0),()=>t}();Object.assign(globalThis,{windowIsFocused:A});var R=class{constructor(e){g(this,"element");g(this,"image");g(this,"rect");g(this,"linkText");g(this,"showLinkText");g(this,"reason");g(this,"secondClassCitizen");g(this,"possibleFalsePositive");Object.seal(this),e&&Object.assign(this,e)}},M={getLocalHintsForElement(t){var p,w,v;let e=((w=(p=t.tagName).toLowerCase)==null?void 0:w.call(p))||"",n=!1,o=!1,r=!1,i=[],a=[],d=null;if(e==="img"){let u=t.getAttribute("usemap");if(u){let h=t.getClientRects();u=u.replace(/^#/,"").replace(\'"\',\'\\\\"\');let m=document.querySelector(`map[name="${u}"]`);if(m&&h.length>0){n=!0;let y=m.getElementsByTagName("area"),S=f.getClientRectsForAreas(h[0],y);S=S.map(F=>Object.assign(F,{image:t})),a.push(...S)}}}let s=t.getAttribute("aria-disabled");if(s&&["","true"].includes(s.toLowerCase()))return[];if(this.checkForAngularJs||(this.checkForAngularJs=function(){if(document.getElementsByClassName("ng-scope").length===0)return()=>!1;{let h=[];for(let m of["","data-","x-"])for(let y of["-",":","_"])h.push(`${m}ng${y}click`);return function(m){for(let y of h)if(m.hasAttribute(y))return!0;return!1}}}()),n||(n=this.checkForAngularJs(t)),t.hasAttribute("onclick"))n=!0;else{let u=t.getAttribute("role"),h=["button","tab","link","checkbox","menuitem","menuitemcheckbox","menuitemradio","radio"];if(u!=null&&h.includes(u.toLowerCase()))n=!0;else{let m=t.getAttribute("contentEditable");m!=null&&["","contenteditable","true","plaintext-only"].includes(m.toLowerCase())&&(n=!0)}}if(!n&&t.hasAttribute("jsaction")){let u=t.getAttribute("jsaction").split(";");for(let h of u){let m=h.trim().split(":");if(m.length>=1&&m.length<=2){let[y,S,F]=m.length===1?["click",...m[0].trim().split("."),"_"]:[m[0],...m[1].trim().split("."),"_"];n||(n=y==="click"&&S!=="none"&&F!=="_")}}}switch(e){case"a":n=!0;break;case"textarea":n||(n=!t.disabled&&!t.readOnly);break;case"input":n||(n=!(((v=t.getAttribute("type"))==null?void 0:v.toLowerCase())=="hidden"||t.disabled||t.readOnly&&f.isSelectable(t)));break;case"button":case"select":n||(n=!t.disabled);break;case"object":case"embed":n=!0;break;case"label":n||(n=t.control!=null&&!t.control.disabled&&this.getLocalHintsForElement(t.control).length===0);break;case"body":n||(n=t===document.body&&!A()&&window.innerWidth>3&&window.innerHeight>3&&(document.body!=null?document.body.tagName.toLowerCase():void 0)!=="frameset"?d="Frame.":void 0),n||(n=t===document.body&&A()&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"img":n||(n=["zoom-in","zoom-out"].includes(t.style.cursor));break;case"div":case"ol":case"ul":n||(n=t.clientHeight<t.scrollHeight&&L.isScrollableElement(t)?d="Scroll.":void 0);break;case"details":n=!0,d="Open.";break}let l=t.getAttribute("class");!n&&(l!=null&&l.toLowerCase().includes("button"))&&(n=!0,r=!0);let c=t.getAttribute("tabindex"),b=c?parseInt(c):-1;if(!n&&!(b<0)&&!isNaN(b)&&(n=!0,o=!0),n)if(a.length>0){let u=a.map(h=>new R({element:h.element,image:t,rect:h.rect,secondClassCitizen:o,possibleFalsePositive:r,reason:d}));i.push(...u)}else{let u=f.getVisibleClientRect(t,!0);if(u!==null){let h=new R({element:t,rect:u,secondClassCitizen:o,possibleFalsePositive:r,reason:d});i.push(h)}}return i},getElementFromPoint(t,e,n,o){n==null&&(n=document),o==null&&(o=[]);let r=n.elementsFromPoint?n.elementsFromPoint(t,e)[0]:n.elementFromPoint(t,e);return o.includes(r)?r:(o.push(r),r&&r.shadowRoot?M.getElementFromPoint(t,e,r.shadowRoot,o):r)},getLocalHints(t){if(!document.body)return[];let e=(s,l)=>{l==null&&(l=[]);for(let c of Array.from(s.querySelectorAll("*")))l.push(c),c.shadowRoot&&e(c.shadowRoot,l);return l},n=e(document.body),o=[];for(let s of Array.from(n))if(!t||s.href){let l=this.getLocalHintsForElement(s);o.push(...l)}o=o.reverse();let r=[1,2,3];o=o.filter((s,l)=>{if(!s.possibleFalsePositive)return!0;let b=Math.max(0,l-6);for(;b<l;){let p=o[b].element;for(let w of r)if(p=p==null?void 0:p.parentElement,p===s.element)return!1;b+=1}return!0});let i=o.filter(s=>{if(s.secondClassCitizen)return!1;let l=s.rect,c=M.getElementFromPoint(l.left+l.width*.5,l.top+l.height*.5);if(c&&(s.element.contains(c)||c.contains(s.element))||s.element.localName=="area"&&c==s.image)return!0;let p=[l.top+.1,l.bottom-.1],w=[l.left+.1,l.right-.1];for(let v of p)for(let u of w){let h=M.getElementFromPoint(u,v);if(h&&(s.element.contains(h)||h.contains(s.element)))return!0}});i.reverse();let{top:a,left:d}=f.getViewportTopLeft();for(let s of i)s.rect.top+=a,s.rect.left+=d;return i}};var I=class{constructor(){this.hints=null;this.hintMarkers=null;this.markersDiv=null;this.enrichedMarkers=null}reset(){this.removeMarkers(),this.hints=null,this.hintMarkers=null,this.markersDiv=null}capture(){return _(this,null,function*(){this.reset(),this.createMarkers(),this.displayMarkers()})}createMarkers(){this.hints=M.getLocalHints(),this.hintMarkers=new Map,this.hints.forEach((e,n)=>{var i,a;let o=f.createElement("div"),r=(a=(i=e.element.attributes["data-momentic-id"])==null?void 0:i.value)!=null?a:void 0;if(!r){console.warn(`[Momentic] No data-momentic-id found for interactive element ${e.element.outerHTML}`);return}o.style.left=e.rect.left+"px",o.style.top=e.rect.top+"px",o.style.zIndex=214e7+n,o.className="vimiumReset internalVimiumHintMarker vimiumHintMarker",Z(o,r),this.hintMarkers.set(r,{hint:e,marker:o})})}enrichMarkers(){if(this.hintMarkers){this.enrichedMarkers=[];for(let[e,n]of this.hintMarkers)this.enrichedMarkers.push(Object.assign(O.describe(n.hint.element),{hintString:e}))}}displayMarkers(){this.hintMarkers&&(this.markersDiv||(this.markersDiv=f.addElementsToPage(Array.from(this.hintMarkers.values()).map(e=>e.marker),{id:"vimiumHintMarkerContainer",className:"vimiumReset"})))}removeMarkers(){this.markersDiv&&(f.removeElement(this.markersDiv),this.markersDiv=null)}toggleMarkers(){this.markersDiv?this.removeMarkers():this.displayMarkers()}},Z=(t,e)=>{for(let n of e){let o=document.createElement("span");o.className="vimiumReset",o.textContent=n,t.appendChild(o)}};window.HintManager=I;\n',css:'.vimiumReset,a.vimiumReset,a:hover.vimiumReset,a:link.vimiumReset,a:visited.vimiumReset,div.vimiumReset,span.vimiumReset,table.vimiumReset,td.vimiumReset,tr.vimiumReset{background:none;border:none;bottom:auto;box-shadow:none;color:#000;cursor:auto;display:inline;float:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:inherit;font-style:normal;font-variant:normal;font-weight:400;height:auto;left:auto;letter-spacing:0;line-height:100%;margin:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;padding:0;position:static;right:auto;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;top:auto;vertical-align:baseline;white-space:normal;width:auto;z-index:2140000000}tbody.vimiumReset,thead.vimiumReset{display:table-header-group}tbody.vimiumReset{display:table-row-group}div.internalVimiumHintMarker{background:linear-gradient(180deg,#fff785 0,#ffc542);border:1px solid #c38a22;border-radius:3px;box-shadow:0 3px 7px 0 rgba(0,0,0,.3);display:block;font-size:11px;left:-1px;overflow:hidden;padding:1px 3px 0;position:absolute;top:-1px;white-space:nowrap}div.internalVimiumHintMarker span{color:#302505;font-family:Helvetica,Arial,sans-serif;font-size:11px;font-weight:700;text-shadow:0 1px 0 hsla(0,0%,100%,.6)}div.internalVimiumHintMarker>.matchingCharacter{color:#d4ac3a}div>.vimiumActiveHintMarker span{color:#a07555!important}div.internalVimiumInputHint{background-color:rgba(255,247,133,.3);border:1px solid #c38a22;display:block;pointer-events:none;position:absolute}div.internalVimiumSelectedInputHint{background-color:hsla(0,100%,70%,.3);border:1px solid #933!important}div.internalVimiumSelectedInputHint span{color:#fff!important}div.vimiumHighlightedFrame{border:5px solid #ff0;box-sizing:border-box;margin:0;pointer-events:none}div.vimiumHighlightedFrame,iframe.vimiumHelpDialogFrame{height:100%;left:0;padding:0;position:fixed;top:0;width:100%}iframe.vimiumHelpDialogFrame{background-color:hsla(0,0%,4%,.6);border:none;display:block;z-index:2139999997}div#vimiumHelpDialogContainer{background-color:#fff;border:2px solid #b3b3b3;border-radius:6px;margin:50px auto;max-height:calc(100% - 100px);max-width:calc(100% - 100px);opacity:1;overflow-x:auto;overflow-y:auto;width:840px}div#vimiumHelpDialog{min-width:600px;padding:8px 12px}span#vimiumTitle,span#vimiumTitle *,span#vimiumTitle span{font-size:20px}#vimiumTitle{display:block;line-height:130%;white-space:nowrap}td.vimiumHelpDialogTopButtons{text-align:right;width:100%}#helpDialogOptionsPage,#helpDialogWikiPage{font-size:14px;padding-left:5px;padding-right:5px}div.vimiumColumn{float:left;font-size:11px;line-height:130%;width:50%}div.vimiumColumn tr{display:table-row}div.vimiumColumn td{display:table-cell;font-size:11px;line-height:130%}div.vimiumColumn table,div.vimiumColumn td,div.vimiumColumn tr{margin:0;padding:0}div.vimiumColumn table{table-layout:auto;width:100%}div.vimiumColumn td{padding:1px;vertical-align:top}div#vimiumHelpDialog div.vimiumColumn tr>td:first-of-type{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;text-align:right;white-space:nowrap}span.vimiumHelpDialogKey{background-color:#f3f3f3;border:1px solid;border-color:#ccc #ccc #bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb;color:#212121;font-family:monospace;font-size:11px;margin-left:2px;padding:1px 4px}div#vimiumHelpDialog div.vimiumColumn tr>td:nth-of-type(3){width:100%}div#vimiumHelpDialog div.vimiumDivider{background-color:#9a9a9a;display:block;height:1px;margin:10px auto;width:100%}div#vimiumHelpDialog td.vimiumHelpSectionTitle{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:16px;font-weight:700;padding-top:3px}div#vimiumHelpDialog td.vimiumHelpDescription{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px}div#vimiumHelpDialog span.vimiumCopyCommandNameName{cursor:pointer;font-size:12px;font-style:italic}div#vimiumHelpDialog tr.advanced{display:none}div#vimiumHelpDialog.showAdvanced tr.advanced{display:table-row}div#vimiumHelpDialog div.advanced td:nth-of-type(3){color:#555}div#vimiumHelpDialog a.closeButton{color:#555;cursor:pointer;font-family:courier new;font-size:24px;font-weight:700;padding-left:5px;position:relative;text-decoration:none;top:3px}div#vimiumHelpDialog a{text-decoration:underline}div#vimiumHelpDialog a.closeButton:hover{color:#000;-webkit-user-select:none}div#vimiumHelpDialogFooter{display:block;margin-bottom:37px;position:relative}table.helpDialogBottom{width:100%}td.helpDialogBottomRight{float:right;text-align:right;width:100%}td.helpDialogBottomLeft,td.helpDialogBottomRight{padding:0}div#vimiumHelpDialogFooter *{font-size:10px}a#toggleAdvancedCommands,span#help-dialog-tip{font-size:10px;position:relative;top:19px;white-space:nowrap}a#toggleAdvancedCommands,a:active.vimiumHelDialogLink,a:hover.vimiumHelDialogLink,a:link.vimiumHelDialogLink,a:visited.vimiumHelDialogLink{color:#2f508e;cursor:pointer;text-decoration:underline}div.vimiumHUD{background:#f1f1f1;border:1px solid #aaa;border-radius:4px;bottom:8px;box-shadow:0 2px 10px rgba(0,0,0,.8);display:block;left:8px;position:fixed;text-align:left;width:calc(100% - 20px);z-index:2139999999}iframe.vimiumHUDFrame{background-color:transparent;border:none;bottom:-14px;display:block;height:58px;margin:0 0 0 -40%;min-width:300px;opacity:0;overflow:hidden;padding:0;position:fixed;right:20px;width:20%;z-index:2139999998}div.vimiumHUD .vimiumHUDSearchArea{background-color:#f1f1f1;border-radius:4px 4px 0 0;display:block;padding:3px}div.vimiumHUD .vimiumHUDSearchAreaInner{border-radius:3px;box-sizing:border-box;color:#777;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;height:30px;line-height:20px;margin-bottom:0;outline:none;padding:2px 4px;width:100%}div.vimiumHUD .hud-find{background:#fff;border:1px solid #ccc}div.vimiumHUD span#hud-find-input,div.vimiumHUD span#hud-match-count{color:#000;display:inline;outline:none;overflow-y:hidden;white-space:nowrap}div.vimiumHUD span#hud-find-input:before{content:"/"}div.vimiumHUD span#hud-match-count{color:#aaa;font-size:12px}div.vimiumHUD span#hud-find-input br{display:none}div.vimiumHUD span#hud-find-input *{display:inline;white-space:nowrap}body.vimiumFindMode ::selection{background:#ff9632}iframe.vomnibarFrame{background-color:transparent;border:none;display:block;font-family:sans-serif;height:calc(100% - 70px);left:50%;margin:0 0 0 -40%;min-width:400px;overflow:hidden;padding:0;position:fixed;top:70px;width:calc(80% + 20px);z-index:2139999998}div.vimiumFlash{background-color:transparent;box-shadow:0 0 4px 2px #4183c4;padding:1px;position:absolute;z-index:2140000000}iframe.vimiumUIComponentHidden{display:none}iframe.vimiumUIComponentVisible{color-scheme:light dark;display:block}iframe.vimiumUIComponentReactivated{border:5px solid #ff0}iframe.vimiumNonClickable{pointer-events:none}@media (prefers-color-scheme:dark){iframe.reverseDarkReaderFilter{-webkit-filter:invert(100%) hue-rotate(180deg)!important;filter:invert(100%) hue-rotate(180deg)!important}body.vimiumBody{background-color:#292a2d;color:#fff}body.vimiumBody a,body.vimiumBody a:visited{color:#8ab4f8}body.vimiumBody input,body.vimiumBody textarea{background-color:#1d1d1f;border-color:#1d1d1f;color:#e8eaed}body.vimiumBody div.example{color:#9aa0a6}body.vimiumBody div#footer,body.vimiumBody div#state,div#vimiumHelpDialogContainer{background-color:#202124;border-color:hsla(0,0%,100%,.1)}div#vimiumHelpDialog{background-color:#292a2d;color:#fff}div#vimiumHelpDialog td.vimiumHelpDescription{color:#c9cccf}div#vimiumHelpDialog td.vimiumHelpSectionTitle,span#vimiumTitle{color:#fff}#vimiumTitle>span:first-child{color:#8ab4f8!important}div#vimiumHelpDialog a{color:#8ab4f8}div#vimiumHelpDialog div.vimiumDivider{background-color:hsla(0,0%,100%,.1)}span.vimiumHelpDialogKey{background-color:#1d1d1f;border:1px solid #000;box-shadow:none;color:#fff}}'};var W=(r,e)=>{let{hostname:t,pathname:o}=new URL(r),{hostname:i,pathname:s}=new URL(e);return t!==i||o!==s},Ne=r=>{try{return new URL(r),!0}catch{return!1}},Oe=(r,e)=>{try{return new URL(r,e),!0}catch{return!1}};import{distance as ct}from"fastest-levenshtein";var nt=new Set(["about:blank","chrome-error://chromewebdata/"]),st=2;var Co=["focusable","keyshortcuts","controls"],Eo=["textbox","checkbox","combobox","button","link","list","listitem","tablist","tabpanel","tab","searchbox","menu","menubar","form","dialog","alertdialog","banner","navigation","main","menuitem","menuitemcheckbox","menuitemradio","option","radio","progressbar","switch"],vo=["notRendered","notVisible","ariaHiddenElement","ariaHiddenSubtree"],Ao=80,To={paragraph:"p",searchbox:"input"},mt=["paragraph","StaticText"],dt={indentLevel:0,noID:!1,noChildren:!1,noProperties:!1,maxLevel:void 0,neighbors:void 0},De=class{id;role;name;content;properties;dataMomenticId;pathFromRoot;parent;children;backendNodeID;constructor(e){this.id=e.id,this.role=e.role,this.name=e.name,this.content=e.content,this.properties={},this.pathFromRoot=e.pathFromRoot,this.children=e.children,this.backendNodeID=e.backendNodeID,e.properties&&e.properties.forEach(t=>{t.name==="keyshortcuts"?this.dataMomenticId=parseInt(t.value.value):this.properties[t.name]=t.value.value})}getLogForm(){return JSON.stringify({id:this.id,name:this.name??"",role:this.role??"",backendNodeId:this.backendNodeID})}isInteresting(){return Eo.includes(this.role)||this.children.some(e=>e.role==="StaticText")?!0:!!this.name.trim()||!!this.content}serialize(e=dt){let{indentLevel:t,noChildren:o,noProperties:i,noID:s}=Object.assign({},dt,e),l=" ".repeat(t),n=To[this.role]||this.role,c=this.name,m={...this.properties};n==="heading"&&(m.level&&(n=`h${m.level}`,delete m.level),c==="heading"&&(c=""));let g=!mt.includes(this.role);if(this.role==="StaticText")return`${l}${c}
|
|
11
|
+
`;let p=`${l}<${n}`;!s&&g&&(p+=` id="${this.id}"`),c&&(p+=` name="${c}"`),this.content&&(p+=` content="${this.content}"`),Object.keys(this.properties).length>0&&!i&&Object.entries(this.properties).forEach(([y,w])=>{Co.includes(y)||(typeof w=="string"?p+=` ${y}="${w}"`:typeof w=="boolean"?w?p+=` ${y}`:p+=` ${y}={false}`:typeof w<"u"&&(p+=` ${y}={${JSON.stringify(w)}}`))});let L=e.maxLevel!==void 0&&t/2>=e.maxLevel;if(this.children.length===0||o||L)p+=` />
|
|
12
|
+
`;else{let y="";for(let A of this.children)y+=A.serialize({...e,indentLevel:t+2});let w=y.trim();w.length<=Ao&&!w.includes(`
|
|
13
|
+
`)?p+=`>${w}</${n}>
|
|
14
14
|
`:p+=`>
|
|
15
|
-
${
|
|
16
|
-
`}if(e.neighbors!==void 0&&e.neighbors>0&&this.parent){let
|
|
15
|
+
${y}${l}</${n}>
|
|
16
|
+
`}if(e.neighbors!==void 0&&e.neighbors>0&&this.parent){let y=this.parent.children.findIndex(C=>C.id===this.id),w=y>0?this.parent.children[y-1]?.serialize({...e,neighbors:0}):"",A=y<this.parent.children.length-1?this.parent.children[y+1]?.serialize({...e,neighbors:0}):"";return`${w||""}
|
|
17
17
|
${p}
|
|
18
|
-
${N||""}`}return p}},De=class{constructor(e,t,o){this.root=e;this.a11yIdNodeMap=t;this.dataMomenticIdMap=o}serialize(){return this.root?this.root.serialize():""}};function Ao(i){return i.name?.value?`"${i.name.value}"`:i.role?.value&&i.role.value!=="none"&&i.role.value!=="generic"?`"${i.role.value}"`:`"${i.nodeId}"`}function mt(i,e,t){if(!e&&i.parentId)throw new Error(`Got no parent for accessibility node ${i.nodeId}: ${JSON.stringify(i)}`);let o=new Oe({id:parseInt(i.nodeId),role:i.role?.value||"",name:i.name?.value||"",content:i.value?.value||"",properties:i.properties,children:[],pathFromRoot:(e?`${e.pathFromRoot} `:"")+Ao(i),backendNodeID:i.backendDOMNodeId});i.value?.value&&(o.content=`${i.value?.value}`);let r=i.childIds??[];for(let s of r){if(!s)continue;let c=t.get(parseInt(s));if(!c)continue;let m=mt(c,o,t);m.length&&(o.children=o.children.concat(m))}if(o.role==="StaticText"&&(o.children=[]),o.children.length===1&&o.children[0].role==="StaticText"){let s=o.name,c=o.children[0]?.name;(s===c||!c)&&(o.children=[])}let n=[];for(let s=o.children.length-1;s>=0;s--){let c=o.children[s];if(c.role!=="StaticText"){n.push(c);continue}if(s===0||o.children[s-1].role!=="StaticText"){n.push(c);continue}o.children[s-1].name+=` ${c.name}`}if(o.children=n.reverse(),o.role==="generic"&&o.children.length===1){let s=o.children[0];if(!dt.includes(s.role)&&o.name===s.name)return o.children}if(!o.isInteresting()&&i.parentId)return o.children;for(let s of o.children)s.parent=o;return[o]}function pt(i,e,t,o,r=1){i.id=r,r+=1,e.set(i.id,i),i.dataMomenticId?t.set(i.dataMomenticId,i):i.role!=="StaticText"&&i.role!=="RootWebArea"&&i.role!=="paragraph"&&o.debug({node:i.serialize({neighbors:1,maxLevel:1})},"Node has no data-momentic-id");for(let n of i.children)r=pt(n,e,t,o,r);return r}function ut(i,e){if(!i.root)throw new Error("a11y tree has null root");i.allNodes=i.allNodes.filter(l=>l.ignored?!l.ignoredReasons?.find(c=>Eo.includes(c.name)):!0);let t=new Map;for(let l of i.allNodes)t.set(parseInt(l.nodeId),l);let o=mt(i.root,null,t);if(o.length>1)throw new Error(`Something went horribly wrong processing the a11y tree, we got: ${JSON.stringify(o)}`);if(o.length===0)throw new me;let r=new Map,n=new Map;return pt(o[0],r,n,e),new De(o[0],r,n)}var ne=(i,e)=>{e.id=i.id,e.content=i.content,e.name=i.name,e.role=i.role,e.numChildren=i.children.length,e.serializedForm=i.serialize({noID:!0,maxLevel:1,neighbors:1})},Me=(i,e)=>{let t=1;i.role===e.role&&t++;let o=["name","content"];for(let r of o){if(!i[r]?.trim())continue;let n=lt(i[r],e[r])/Math.min(i[r].length,e[r].length);n===0?t+=2:n<=.1&&t++}if(e.numChildren!==void 0&&(i.children.length===e.numChildren&&e.numChildren>0?t++:(e.numChildren>0&&i.children.length===0||Math.abs(i.children.length-e.numChildren)>2)&&t--),e.serializedForm){let r=i.serialize({noID:!0,maxLevel:1,neighbors:1}),n=lt(r,e.serializedForm)/Math.min(r.length,e.serializedForm.length);n===0?t+=2:n<=.1&&t++}return t};var K={r:147,g:196,b:125,a:.55},ht={showInfo:!1,showRulers:!1,showStyles:!1,showAccessibilityInfo:!1,showExtensionLines:!1,contrastAlgorithm:"aa",contentColor:K,paddingColor:K,borderColor:K,marginColor:K,eventTargetColor:K,shapeColor:K,shapeMarginColor:K};var F=(i=1e3)=>new Promise(e=>setTimeout(()=>e(),i));function gt(){cursor=document.createElement("img"),cursor.setAttribute("src","data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMyIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHdpZHRoPSIzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwIDcpIj48cGF0aCBkPSJtNi4xNDggMTguNDczIDEuODYzLTEuMDAzIDEuNjE1LS44MzktMi41NjgtNC44MTZoNC4zMzJsLTExLjM3OS0xMS40MDh2MTYuMDE1bDMuMzE2LTMuMjIxeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im02LjQzMSAxNyAxLjc2NS0uOTQxLTIuNzc1LTUuMjAyaDMuNjA0bC04LjAyNS04LjA0M3YxMS4xODhsMi41My0yLjQ0MnoiIGZpbGw9IiMwMDAiLz48L2c+PC9zdmc+"),cursor.setAttribute("id","selenium_cursor"),cursor.setAttribute("style","position: absolute; z-index: 99999999999; pointer-events: none; left:0; top:0"),cursor.style.filter="invert(0%) sepia(6%) saturate(24%) hue-rotate(315deg) brightness(89%) contrast(110%)",document.body.appendChild(cursor),document.onmousemove=function(i){i=i||window.event,document.getElementById("selenium_cursor").style.left=i.pageX+"px",document.getElementById("selenium_cursor").style.top=i.pageY+"px"}}function ft(){window.globalHintManager||(window.globalHintManager=new window.HintManager),window.globalHintManager.capture()}function yt(){window.globalHintManager&&window.globalHintManager.reset()}function bt(){let i=document.body.getElementsByTagName("*"),e=1;for(let t=0;t<i.length;t++){let o=e.toString();for(;[6].some(n=>o.includes(n.toString()));)e++,o=e.toString();let r=i[t];r?.setAttribute("data-momentic-id",`${e}`),r?.setAttribute("aria-keyshortcuts",`${e}`),e++}}var To=new Set(["document","script","XMLHttpRequest","fetch","xhr"]),Ro=new Set(["script","document"]),xo=["intercom.io","googletagmanager.com","google-analytics.com","www.gstatic.com","gstatic.com","apis.google.com","sentry.io","newrelic.com","p.retool.com","m.stripe.com","m.stripe.network","js.stripe.com","assets.trybento.co","udon.trybento.co","cdn.lr-in-prod.com","r.lr-in-prod.com","content.product-usage.assembledhq.com","data.product-usage.assembledhq.com","static.zdassets.com","o.clarity.ms/collect"],Io=["api.stripe.com","supabase.co"];function ze(i){return`${i.resourceType()} ${i.method()} ${i.url()}`}function wt(i){return i=i.replace(/^www\./,""),i}function St(i){return Io.some(e=>i.includes(e))}function Et(i,e){if(!To.has(i.resourceType()))return!1;let t=new URL(e),o=new URL(i.url());return xo.some(r=>o.hostname.includes(r))?!1:Ro.has(i.resourceType())||i.method()!=="GET"?!0:wt(o.hostname).includes(wt(t.hostname))}var be=Go(Bo);be.use(jo());be.use($o({provider:{id:"2captcha",token:process.env.TWO_CAPTCHA_KEY},visualFeedback:!0}));var _e=class i{browser;context;page;a11yIdToNodeMap=new Map;dataMomenticIdToNodeMap=new Map;cdpClient;logger;localMode;activeFrame;baseURL;constructor({browser:e,context:t,page:o,baseUrl:r,cdpClient:n,logger:l,localMode:s}){this.browser=e,this.context=t,this.page=o,this.baseURL=r,this.cdpClient=n,this.logger=l,this.localMode=!!s}static USER_AGENT=Tt["Desktop Chrome"].userAgent;static VIEWPORT={width:1920,height:1080};static async init({baseUrl:e,logger:t,browserArgs:o,contextArgs:r,sendScreenshotsDuringLoad:n,onClose:l,localMode:s,localAppUrl:c,timeout:m=8e3}){let h={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,serviceWorkers:"block",...o??{}},p={viewport:i.VIEWPORT,deviceScaleFactor:process.platform==="darwin"?2:1,userAgent:Tt["Desktop Chrome"].userAgent,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",...r??{}},R=null,g,b;s?(g=await be.launchPersistentContext(Ho(Fo(),"momentic","chromium"),{...h,...p,ignoreDefaultArgs:["--enable-automation"],ignoreHTTPSErrors:!0,bypassCSP:!0,args:["--allow-insecure-localhost","--disable-web-security","--disable-site-isolation-for-policy","--disable-site-isolation-trials",`--unsafely-treat-insecure-origin-as-secure=${c}`],baseURL:e}),b=g.pages()[0],b.on("close",()=>{l?.()})):(R=await be.launch(h),g=await R.newContext({...p,baseURL:e}),b=await g.newPage());let N=await g.newCDPSession(b),v=new i({browser:R,context:g,page:b,baseUrl:e,cdpClient:N,logger:t,localMode:s}),P=!1;(async()=>{try{await v.navigate({url:e,wrapPossibleNavigation:!1,initialNavigation:!0})}catch(X){t.error({err:X},"Failed to initialize chrome browser")}finally{P=!0}})();let f=async()=>{if(n)try{n({viewport:await v.viewport(),buffer:await v.screenshot()})}catch(X){t.error({err:X},"Failed to take screenshot")}};f();let w=setInterval(()=>{f()},250),S=Date.now();for(;!P&&Date.now()-S<m;)await F(250);return clearInterval(w),P||t.warn("Timeout elapsed waiting for browser to initialize - are you sure this page is accessible?"),v}async getUserPageOrFrame(){if(this.localMode&&this.activeFrame){let e=this.page.frame(this.activeFrame);if(!e)throw new Error(`Failed to get non-existent frame: ${this.activeFrame}`);return e}return this.page}async initCDPSession(e=2){try{await this.cdpClient.send("Accessibility.enable"),await this.cdpClient.send("DOM.enable"),await this.cdpClient.send("Overlay.enable")}catch(t){if(e>0)return this.logger.error({err:t},"Failed to initialize CDP session, re-creating CDP client"),this.cdpClient=await this.context.newCDPSession(this.page),await F(250),this.initCDPSession(e-1)}}setLogger(e){this.logger=e}async registerLocalRequestInterceptors(e){await e.route("**/*",async t=>{let o;try{o=await t.fetch()}catch(n){this.closed||this.logger.warn({err:n},"Network request failed");return}let r=o.headers();delete r["content-security-policy"],delete r["x-frame-options"],delete r["x-xss-protection"],r["Access-Control-Allow-Origin"]="*",await t.fulfill({headers:r,response:o})})}ping(){if(this.closed)throw new Error("Page has been closed");if(this.browser&&!this.browser.isConnected())throw new Error("Browser is not connected")}setActiveFrame(e){this.activeFrame=e}async reset(e){this.a11yIdToNodeMap.clear(),this.dataMomenticIdToNodeMap.clear();let t=this.context.pages();this.page=t[0];for(let o=1;o<t.length;o++)await t[o].close();e.clearCookies&&await this.context.clearCookies(),!this.page.isClosed()&&(e.clearStorage&&await(await this.getUserPageOrFrame()).evaluate(()=>{localStorage.clear()}),await this.navigate({url:e.url??this.baseURL,wrapPossibleNavigation:!1,initialNavigation:!0}))}async pageSetup(){try{this.localMode||await this.page.evaluate(gt)}catch{}}async wait(e){await F(e)}async toggleHints(e){let t=await this.getUserPageOrFrame();e.state==="on"?(await t.addStyleTag({content:Ie.css}),await t.addScriptTag({content:Ie.js}),await t.evaluate(ft)):await t.evaluate(yt)}async showHints(){await this.toggleHints({state:"on"});let e=async()=>{try{await this.toggleHints({state:"off"})}catch(t){this.logger.debug({err:t},"Failed to remove vision hints")}};setTimeout(()=>{e()},3e3)}async cleanup(){await this.page.close(),await this.context.close(),this.browser&&await this.browser.close()}get closed(){return this.page.isClosed()||!!this.browser&&!this.browser.isConnected()}async html(){return(await this.getUserPageOrFrame()).content()}async url(){return(await this.getUserPageOrFrame()).url()}async screenshotWithHints(e=100,t="device",o="/tmp/screenshots/test.jpg"){let r=o?.split("."),n=r?.slice(0,-1).join("."),l=r?.slice(-1)[0],s=Buffer.from("");await this.showHints();let c=await this.screenshot(e,t,o?`${n}-after-hint.${l}`:void 0);return{before:s,after:c}}async screenshot(e=100,t="device",o){let r={fullPage:!1,quality:e,scale:t,type:"jpeg",caret:"initial",path:o};return!this.localMode||!this.activeFrame?this.page.screenshot(r):this.page.locator(`iframe[name="${this.activeFrame}"]`).screenshot(r)}async viewport(){if(this.localMode&&this.activeFrame){let t=await this.page.locator(`iframe[name="${this.activeFrame}"]`).boundingBox();if(!t)throw new Error(`Failed to get bounding box for frame: ${this.activeFrame}`);return t}let e=this.page.viewportSize();if(!e)throw new Error("failed to get viewport");return e}async navigate({url:e,wrapPossibleNavigation:t=!0,initialNavigation:o=!1}){this.logger.debug(`Navigating to ${e}`),o&&this.localMode&&await this.registerLocalRequestInterceptors(this.context);let r=Date.now(),n=async()=>{try{await(await this.getUserPageOrFrame()).goto(e,{waitUntil:"load",timeout:3e3}),this.logger.debug({url:e},`Got load event in ${Math.floor(Date.now()-r)}ms`)}catch{this.logger.warn({url:e},"Timeout elapsed waiting for page to fire load event, continuing anyways...")}finally{await this.initCDPSession()}};t?await this.wrapPossibleNavigation(n):await n();let l=await this.url();if(it.has(l)&&process.env.NODE_ENV==="production")throw new Error(`${e} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`);await this.pageSetup(),this.logger.info({url:e},"Navigation complete")}async type(e,t={}){let{clearContent:o=!0,pressKeysSequentially:r=!1}=t;o&&(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")),r?await this.page.keyboard.type(e):await this.page.keyboard.insertText(e)}async clickByA11yID(e,t={}){let o=this.a11yIdToNodeMap.get(e);if(!o)throw new Error(`Could not find DOM node during click: ${e}`);let r=await this.clickUsingCDP(o,t);return await this.highlightNode(r),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async selectOptionByA11yID(e,t){let o=this.a11yIdToNodeMap.get(e);if(!o)throw new Error(`Could not find DOM node while selecting option: ${e}`);if(!o.backendNodeID)throw new Error(`Select target missing backend node id: ${o.getLogForm()}`);return await(await this.getLocatorFromBackendID(o.backendNodeID)).selectOption(t,{timeout:8e3}),await this.highlightNode(o),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async scrollIntoView(e){let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find node in DOM with a11y id: ${t}`);if(!o.backendNodeID)throw new Error(`Focus target missing backend node id: ${o.getLogForm()}`);await(await this.getLocatorFromBackendID(o.backendNodeID)).scrollIntoViewIfNeeded({timeout:8e3})}async highlight(e){try{let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find DOM node during highlight: ${t}`);if(!o.backendNodeID)throw new Error(`Select target missing backend node id: ${o.getLogForm()}`);await this.highlightNode(o)}catch(t){this.logger.warn({err:t,target:e},"Failed to highlight target")}}async highlightNode(e){try{await this.cdpClient.send("Overlay.highlightNode",{highlightConfig:ht,backendNodeId:e.backendNodeID})}catch{this.logger.warn("Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests.")}let t=async()=>{try{await this.cdpClient.send("Overlay.hideHighlight",{backendNodeId:e.backendNodeID})}catch(o){this.logger.debug({err:o},"Failed to remove node highlight")}};setTimeout(()=>{t()},3e3)}async wrapPossibleNavigation(e,t=8e3,o=!0){let r=Date.now(),n=await this.url(),l=Date.now(),s=new Map,c=new Map,m=w=>{let S=ze(w.request());c.set(S,(c.get(S)??0)+1);let X=w.status();X>=500&&this.logger.warn({request:S,status:X},"Received 500 level response")},h=w=>{if(!Et(w,n))return;let S=ze(w);s.set(S,(s.get(S)??0)+1),l=Date.now()};this.page.on("response",m),this.page.on("request",h);let p=[];o&&(p=this.context.pages().map(w=>w.url()));let R=!1,g=e().catch(w=>(R=!0,w instanceof Error?w:new Error(`${w}`)));await F(250);let b=async w=>{let S=await w;if(S instanceof Error)throw S;return S},N=new Set,v=!1,L=await(async()=>{for(;!R&&!(!v&&Date.now()-r>t);){if(await F(250),v=!1,N=new Set,Date.now()-l<=1250)continue;let w=!1;for(let S of s.keys())s.get(S)!==c.get(S)&&(St(S)&&(v=!0),w=!0,N.add(S));if(!w)return this.logger.debug({url:await this.url(),requests:JSON.stringify(Array.from(s.entries()))},`Network idle in ${Math.floor(Date.now()-r)}ms`),!0}return!R&&N.size>0&&this.logger.warn({url:await this.url(),unfinishedRequests:JSON.stringify(Array.from(N.entries()))},"Timeout elapsed waiting for network idle, continuing anyways..."),!1})();if(this.page.off("response",m),this.page.off("request",h),!L)return b(g);let f=await this.url();if(!R&&V(f,n)){this.logger.debug({startUrl:n,newUrl:f},"Detected url change in wrapPossibleNavigation, waiting for load state");let w=Math.max(t-(Date.now()-r),0);if(w>0)try{await(await this.getUserPageOrFrame()).waitForLoadState("load",{timeout:w})}catch{this.logger.warn({url:await this.url()},"Timeout elapsed waiting for load state, continuing anyways...")}}if(o){let w=this.context.pages().map(S=>S.url());if(w.length>p.length)for(let S of w)S!==f&&await this.switchToPage(S)}return b(g)}async resolveCachedTargetToID(e){if(!le(e)){let s=this.a11yIdToNodeMap.get(e.id);if(!s)throw new Error(`Resolving target failed, fresh value did not exist in node map: ${e.id}`);return ne(s,e),e.id}let t=(await this.getA11yTree()).serialize();this.logger.debug({tree:t},"Refreshed a11y tree before resolving target");let o=this.a11yIdToNodeMap.get(e.id);if(o){let s=Me(o,e);if(s>=5)return this.logger.debug({target:e,proposedNode:o.getLogForm(),comparisonScore:s},"Resolved cached a11y target to node with exact same id"),ne(o,e),e.id}let r=1/0,n=1/0,l;for(let s of this.a11yIdToNodeMap.values()){let c=Me(s,e);if(c>=5)return this.logger.debug({newNode:s.getLogForm(),target:e,comparisonScore:c},"Resolved cached a11y target to new node with field comparison"),ne(s,e),s.id;if(!e.serializedForm)continue;let m=s.serialize({noID:!0,maxLevel:1,neighbors:1});if(Math.abs(m.length-e.serializedForm.length)>15)continue;let h=Uo(e.serializedForm,m),p=h/Math.min(e.serializedForm.length,m.length);h<r&&p<.2&&(r=h,n=p,l=s)}if(l&&r<15)return this.logger.debug({newNode:l.getLogForm(),target:e,distance:r,ratio:n},"Resolved cached a11y target to new node with pure levenshtein distance"),ne(l,e),l.id;throw new Error(`Could not find any relevant node given cached target: ${JSON.stringify(e)}`)}async click(e,t={}){let o=await this.resolveCachedTargetToID(e);return await this.wrapPossibleNavigation(()=>this.clickByA11yID(o,t))}async hover(e){let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find DOM node for hover: ${t}`);if(!o.backendNodeID)throw new Error(`Hover target missing backend node id: ${o.getLogForm()}`);return await(await this.getLocatorFromBackendID(o.backendNodeID)).hover({timeout:8e3}),await this.highlightNode(o),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async selectOption(e,t){let o=await this.resolveCachedTargetToID(e);return this.selectOptionByA11yID(o,t)}async press(e){await this.wrapPossibleNavigation(()=>this.page.keyboard.press(e))}async refresh(){if(this.localMode&&this.activeFrame){let t=(await this.getUserPageOrFrame()).url();await this.navigate({url:t,wrapPossibleNavigation:!0})}else await this.page.reload({timeout:3e3}),await this.pageSetup()}async getA11yTree(){await this.initCDPSession();let e=null,t=0,o=await this.url();for(;!e;)try{let r=await this.getRawA11yTree();if(!r.root||r.allNodes.length===0)throw new Error("No a11y tree found on page");e=ut(r,this.logger)}catch(r){if(this.logger.error({err:r,url:o},"Error fetching a11y tree"),t===0)await F(1e3),t++;else throw new Error(`Max retries exceeded fetching a11y tree: ${r}`)}return e.root||this.logger.warn("A11y tree was pruned entirely"),this.a11yIdToNodeMap=e.a11yIdNodeMap,this.dataMomenticIdToNodeMap=e.dataMomenticIdMap,e}getA11yIdFromDataMomenticId(e){return this.dataMomenticIdToNodeMap.get(e)?.id}async getRawA11yTree(){let e=await this.url(),t=Date.now(),o=()=>{t=Date.now()};this.cdpClient.addListener("Accessibility.nodesUpdated",o);let r=!1,n=()=>{this.logger.info({url:e},"Load event fired on page"),r=!0,t=Date.now()};this.cdpClient.addListener("Accessibility.loadComplete",n);let l=Date.now(),s=!0;for(;Date.now()-l<3e3;){if(await F(250),!r&&Date.now()-l<1e3){process.env.NODE_ENV!=="production"&&this.logger.debug({url:e},"A11y tree not loaded yet, waiting...");continue}if(Date.now()-t>=1250){s=!1;break}this.logger.debug({url:e},"A11y tree not stable yet, waiting...")}this.logger.debug({duration:Date.now()-l,eventReceived:r,timeoutTriggered:s},"A11y wait phase completed"),await(await this.getUserPageOrFrame()).evaluate(bt);let c;if(this.localMode&&this.activeFrame){let{result:{objectId:h}}=await this.cdpClient.send("Runtime.evaluate",{expression:`document.querySelector("#${this.activeFrame}")`}),p=await this.cdpClient.send("DOM.describeNode",{objectId:h});c=(await this.cdpClient.send("Accessibility.getRootAXNode",{frameId:p.node.frameId})).node.backendDOMNodeId}else{let{node:h}=await this.cdpClient.send("Accessibility.getRootAXNode");c=h.backendDOMNodeId}let{nodes:m}=await this.cdpClient.send("Accessibility.queryAXTree",{backendNodeId:c});return this.cdpClient.removeListener("Accessibility.loadComplete",n),this.cdpClient.removeListener("Accessibility.nodesUpdated",o),{root:m[0],allNodes:m}}async clickUsingVisualCoordinates(e){let t=await this.getElementLocation(e);if(!t)throw new Error(`Could not find element location with backend node id: ${e}`);this.logger.debug({location:t},"Executing mouse click"),await this.page.mouse.click(t.centerX,t.centerY)}async getIDAttributeUsingCDP(e){await this.cdpClient.send("DOM.getDocument",{depth:0});let t=await this.cdpClient.send("DOM.requestNode",{objectId:e}),r=(await this.cdpClient.send("DOM.getAttributes",{nodeId:t.nodeId})).attributes,n=r.findIndex(l=>l==="data-momentic-id");return n===-1?"":r[n+1]||""}async getLocatorFromBackendID(e){let t=await this.cdpClient.send("DOM.resolveNode",{backendNodeId:e});if(!t||!t.object.objectId)throw new Error(`Could not resolve backend node ${e}`);try{let o=await this.getIDAttributeUsingCDP(t.object.objectId);if(!o)throw new Error("Failed getting data-momentic-id attribute using CDP");return(await this.getUserPageOrFrame()).locator(`[data-momentic-id="${o}"]`)}catch(o){throw this.logger.error({err:o},"Failed to get ID attribute"),o}}async clickUsingCDP(e,t={}){let o=0,r=e;for(;o<nt;){if(!r||r.role==="RootWebArea")throw new Error(`Attempted to click node with no clickable surrounding elements: ${e.getLogForm()}`);if(r.role==="StaticText"){r=r.parent;continue}let n=r.backendNodeID;if(!n){this.logger.warn({node:r.getLogForm()},"Click candidate had no backend node ID"),r=r.parent;continue}try{let l=await this.getLocatorFromBackendID(n);return t.doubleClick?await l.dblclick({timeout:8e3}):await l.click({timeout:8e3,button:t.rightClick?"right":"left",force:t.force}),r.id!==e.id&&this.logger.info({oldNode:e.getLogForm(),newNode:r.getLogForm()},"Redirected click successfully to new element"),r}catch(l){this.logger.error({err:l,node:r.getLogForm()},"Failed click or click timed out"),o++,r=r.parent}}throw new Error(`Max click redirection attempts exhausted on original element: ${e.getLogForm()}`)}async getElementLocation(e){let t=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!0}),o=await this.page.evaluate(()=>window.devicePixelRatio);process.platform==="darwin"&&o===1&&(o=2);let r=t.documents[0],n=r.layout,l=r.nodes,s=l.nodeName||[],c=l.backendNodeId||[],m=n.nodeIndex,h=n.bounds,p=-1;for(let L=0;L<s.length;L++)if(c[L]===e){p=m.indexOf(L);break}if(p===-1)throw new Error(`Could not find any backend node with ID ${e}`);let[R=0,g=0,b=0,N=0]=h[p];R/=o,g/=o,b/=o,N/=o;let v=R+b/2,P=g+N/2;return{centerX:v,centerY:P}}async scrollUp(e){await this.page.mouse.wheel(0,-(e??i.VIEWPORT.height))}async scrollDown(e){await this.page.mouse.wheel(0,e??i.VIEWPORT.height)}async goForward(){await this.wrapPossibleNavigation(async()=>this.localMode&&this.activeFrame?(await this.getUserPageOrFrame()).evaluate(e=>{let t=e().contentWindow;t?t.history.forward():console.error("Failed to get content window for frame")},()=>document.querySelector(`iframe[name="${this.activeFrame}"]`)):this.page.goForward({timeout:8e3})),await this.pageSetup()}async goBack(){await this.wrapPossibleNavigation(async()=>this.localMode&&this.activeFrame?(await this.getUserPageOrFrame()).evaluate(e=>{let t=e().contentWindow;t?t.history.back():console.error("Failed to get content window for frame")},()=>document.querySelector(`iframe[name="${this.activeFrame}"]`)):this.page.goBack({timeout:8e3})),await this.pageSetup()}async switchToPage(e){let t=this.context.pages();for(let o=0;o<t.length;o++){let r=t[o];if(r.url().includes(e)){this.logger.info(`Switching to tab ${o} with url ${r.url()}`),this.page=r;try{await r.waitForLoadState("load",{timeout:3e3})}catch{this.logger.warn({url:await this.url()},"Timeout elapsed waiting for load state during tab switch, continuing anyways...")}await this.pageSetup(),await this.initCDPSession();return}}throw new Error(`Could not find page with url containing ${e}`)}async setCookie(e){let t=Ke(e);await this.context.addCookies([t])}async setLocalStorage(e,t){await(await this.getUserPageOrFrame()).evaluate(([r,n])=>{r&&localStorage.setItem(r,n||"")},[e,t])}async solveCaptcha(){await this.getA11yTree();let e;for(let s of this.a11yIdToNodeMap.values())if(s.role==="image"&&s.name.toLowerCase().includes("captcha")){if(!s.backendNodeID)continue;e=await this.getLocatorFromBackendID(s.backendNodeID);break}if(!e){let s=await(await this.getUserPageOrFrame()).solveRecaptchas();if(!s.captchas||!s.captchas.length)throw new Error("No captchas found on the page");return}let t=await e.screenshot({type:"jpeg",animations:"allow",quality:100}),o=await fetch("https://api.2captcha.com/createTask",{method:"POST",body:JSON.stringify({clientKey:process.env.TWO_CAPTCHA_KEY,task:{type:"ImageToTextTask",body:t.toString("base64"),case:!0},languagePool:"en"})});if(!o.ok){let s=`Captcha solver API returned error response: ${o.statusText}`;throw this.logger.error({text:await o.text()},s),new Error(s)}let{taskId:r}=await o.json(),n=Date.now(),l="";for(;Date.now()-n<6e4;){await F(2500);let s=await fetch("https://api.2captcha.com/getTaskResult",{method:"POST",body:JSON.stringify({clientKey:process.env.TWO_CAPTCHA_KEY,taskId:r})});if(!s.ok){let m=`Captcha solution API returned error response: ${s.statusText}`;throw this.logger.error({text:await s.text()},m),new Error(m)}let c=await s.json();if(c.errorId){let m=`Captcha solution API returned error ID ${c.errorId}`;throw this.logger.error(m),new Error(m)}if(c.status==="ready"){l=c.solution.text;break}}if(!l)throw new Error("Captcha solution timed out");return l}getActiveFrame(){return this.activeFrame}};var Wo={type:"a11y",version:"1.0.0",useHistory:"diff",useGoalSplitter:!0},Vo=Wo;import Ko from"dedent";import qo from"diff-lines";var Xo=1e4,ke=class{browser;pendingInstructions;generator;commandHistory;config;closed=!1;logger;constructor({browser:e,config:t,generator:o,logger:r}){this.browser=e,this.generator=o,this.config=t,this.logger=r,this.pendingInstructions=[],this.commandHistory=[]}get history(){return this.commandHistory.filter(e=>e.state==="DONE")}get lastExecutedCommand(){let e=this.history;return e.length===0?null:e[e.length-1]}setOpen(){this.closed=!1}isClosed(){return this.closed}setLogger(e){this.logger=e}resetHistory(){this.commandHistory=[],this.pendingInstructions=[]}async resetState(e){this.resetHistory(),this.closed=!0,await this.browser.reset(e)}async getBrowserState(){let t=await(await this.browser.getA11yTree()).serialize();return this.logger.debug({tree:t,activeFrame:this.browser.getActiveFrame()},"Got a11y tree"),t}getSerializedHistory(e,t){let o;return this.config.useHistory==="diff"?o=this.getDiffHistory(e,t):o=this.getListHistory(),o}async splitUserGoal(e,t,o){if(e==="AI_ACTION"&&t.match(/[,!;.]|(?:and)|(?:then)/)&&this.config.useGoalSplitter){let r=await this.generator.getGranularGoals({goal:t,url:await this.browser.url()},o);this.pendingInstructions=r.reverse()}else this.pendingInstructions=[t]}async promptToCommand(e,t,o){try{return await this.promptToCommandHelper(e,t,o)}catch(r){throw r instanceof x?r:new x("InternalWebAgentError",r instanceof Error?r.message:`${r}`,{cause:r})}}async promptToCommandHelper(e,t,o){if(this.pendingInstructions.length===0){if(!t.trim())throw new Error("Cannot generate commands for empty goal");await this.splitUserGoal(e,t,o)}let r=this.pendingInstructions[this.pendingInstructions.length-1];this.logger.info({goal:r},"Starting prompt translation");let n=Date.now(),l=await this.browser.url(),s=await this.getBrowserState();this.logger.info({duration:Date.now()-n,url:l},"Got browser state");let c=this.commandHistory.length;this.commandHistory.push({state:"PENDING",browserStateBeforeCommand:s,urlBeforeCommand:l,type:e});let m=this.getSerializedHistory(l,s),h={url:l,numPrevious:c,browserState:s,history:m,goal:r,lastCommand:this.lastExecutedCommand},p=await this.generator.getProposedCommand(h,o);if(this.logger.info({type:p.type,thoughts:p.thoughts},"Got proposed command"),p.type==="SUCCESS"){let R=this.pendingInstructions.pop();if(this.logger.info({finishedInstruction:R,remainingInstructions:this.pendingInstructions},"Removing pending instruction due to SUCCESS"),this.pendingInstructions.length!==0)return this.commandHistory=[],this.promptToCommand(e,"",o)}else p.type==="FAILURE"&&(this.logger.info({remainingInstructions:this.pendingInstructions},"Removing pending instructions due to FAILURE"),this.pendingInstructions=[]);return{context:h,command:p}}async locateElement(e,t,o){if(!e)throw new x("InternalWebAgentError","Cannot locate element with empty description");let r=await this.getBrowserState(),n;if(t){let{before:l,after:s}=await this.browser.screenshotWithHints();if(n=await this.generator.getElementLocationWithVision({goal:e,screenshot:l,hintActivatedScreenshot:s},o),n.id>0){let c=this.browser.getA11yIdFromDataMomenticId(n.id);if(!c)throw new x("InternalWebAgentError",`Unable to find corresponding DOM node for id ${n.id}`);n.id=c}}else n=await this.generator.getElementLocation({browserState:r,goal:e},o);if(n.id<0)throw new x("ActionFailureError",`Unable to locate element: ${n.thoughts?n.thoughts:"please ensure the element is visible and conforms to Accessibility guidelines"}`);return n}getDiffHistory(e,t){let o=this.history.filter(n=>n.type==="AI_ACTION");if(o.length===0)return"<NONE/>";let r=[`
|
|
19
|
-
You have already executed the following commands successfully (most recent listed first)`,"-".repeat(10)];return o.reverse().forEach((
|
|
20
|
-
`).forEach(c=>
|
|
21
|
-
`)}getListHistory(){return
|
|
18
|
+
${A||""}`}return p}},Me=class{constructor(e,t,o){this.root=e;this.a11yIdNodeMap=t;this.dataMomenticIdMap=o}serialize(){return this.root?this.root.serialize():""}};function Ro(r){return r.name?.value?`"${r.name.value}"`:r.role?.value&&r.role.value!=="none"&&r.role.value!=="generic"?`"${r.role.value}"`:`"${r.nodeId}"`}function pt(r,e,t){if(!e&&r.parentId)throw new Error(`Got no parent for accessibility node ${r.nodeId}: ${JSON.stringify(r)}`);let o=new De({id:parseInt(r.nodeId),role:r.role?.value||"",name:r.name?.value||"",content:r.value?.value||"",properties:r.properties,children:[],pathFromRoot:(e?`${e.pathFromRoot} `:"")+Ro(r),backendNodeID:r.backendDOMNodeId});r.value?.value&&(o.content=`${r.value?.value}`);let i=r.childIds??[];for(let n of i){if(!n)continue;let c=t.get(parseInt(n));if(!c)continue;let m=pt(c,o,t);m.length&&(o.children=o.children.concat(m))}if(o.role==="StaticText"&&(o.children=[]),o.children.length===1&&o.children[0].role==="StaticText"){let n=o.name,c=o.children[0]?.name;(n===c||!c)&&(o.children=[])}let s=[];for(let n=o.children.length-1;n>=0;n--){let c=o.children[n];if(c.role!=="StaticText"){s.push(c);continue}if(n===0||o.children[n-1].role!=="StaticText"){s.push(c);continue}o.children[n-1].name+=` ${c.name}`}if(o.children=s.reverse(),o.role==="generic"&&o.children.length===1){let n=o.children[0];if(!mt.includes(n.role)&&o.name===n.name)return o.children}if(!o.isInteresting()&&r.parentId)return o.children;for(let n of o.children)n.parent=o;return[o]}function ut(r,e,t,o,i=1){r.id=i,i+=1,e.set(r.id,r),r.dataMomenticId?t.set(r.dataMomenticId,r):r.role!=="StaticText"&&r.role!=="RootWebArea"&&r.role!=="paragraph"&&o.debug({node:r.serialize({neighbors:1,maxLevel:1})},"Node has no data-momentic-id");for(let s of r.children)i=ut(s,e,t,o,i);return i}function ht(r,e){if(!r.root)throw new Error("a11y tree has null root");r.allNodes=r.allNodes.filter(l=>l.ignored?!l.ignoredReasons?.find(c=>vo.includes(c.name)):!0);let t=new Map;for(let l of r.allNodes)t.set(parseInt(l.nodeId),l);let o=pt(r.root,null,t);if(o.length>1)throw new Error(`Something went horribly wrong processing the a11y tree, we got: ${JSON.stringify(o)}`);if(o.length===0)throw new me;let i=new Map,s=new Map;return ut(o[0],i,s,e),new Me(o[0],i,s)}var ie=(r,e)=>{e.id=r.id,e.content=r.content,e.name=r.name,e.role=r.role,e.numChildren=r.children.length,e.serializedForm=r.serialize({noID:!0,maxLevel:1,neighbors:1})},ze=(r,e)=>{let t=1;r.role===e.role&&t++;let o=["name","content"];for(let i of o){if(!r[i]?.trim())continue;let s=ct(r[i],e[i])/Math.min(r[i].length,e[i].length);s===0?t+=2:s<=.1&&t++}if(e.numChildren!==void 0&&(r.children.length===e.numChildren&&e.numChildren>0?t++:(e.numChildren>0&&r.children.length===0||Math.abs(r.children.length-e.numChildren)>2)&&t--),e.serializedForm){let i=r.serialize({noID:!0,maxLevel:1,neighbors:1}),s=ct(i,e.serializedForm)/Math.min(i.length,e.serializedForm.length);s===0?t+=2:s<=.1&&t++}return t};var K={r:147,g:196,b:125,a:.55},gt={showInfo:!1,showRulers:!1,showStyles:!1,showAccessibilityInfo:!1,showExtensionLines:!1,contrastAlgorithm:"aa",contentColor:K,paddingColor:K,borderColor:K,marginColor:K,eventTargetColor:K,shapeColor:K,shapeMarginColor:K};var U=(r=1e3)=>new Promise(e=>setTimeout(()=>e(),r));function ft(){cursor=document.createElement("img"),cursor.setAttribute("src","data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMyIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHdpZHRoPSIzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwIDcpIj48cGF0aCBkPSJtNi4xNDggMTguNDczIDEuODYzLTEuMDAzIDEuNjE1LS44MzktMi41NjgtNC44MTZoNC4zMzJsLTExLjM3OS0xMS40MDh2MTYuMDE1bDMuMzE2LTMuMjIxeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im02LjQzMSAxNyAxLjc2NS0uOTQxLTIuNzc1LTUuMjAyaDMuNjA0bC04LjAyNS04LjA0M3YxMS4xODhsMi41My0yLjQ0MnoiIGZpbGw9IiMwMDAiLz48L2c+PC9zdmc+"),cursor.setAttribute("id","selenium_cursor"),cursor.setAttribute("style","position: absolute; z-index: 99999999999; pointer-events: none; left:0; top:0"),cursor.style.filter="invert(0%) sepia(6%) saturate(24%) hue-rotate(315deg) brightness(89%) contrast(110%)",document.body.appendChild(cursor),document.onmousemove=function(r){r=r||window.event,document.getElementById("selenium_cursor").style.left=r.pageX+"px",document.getElementById("selenium_cursor").style.top=r.pageY+"px"}}function yt(){window.globalHintManager||(window.globalHintManager=new window.HintManager),window.globalHintManager.capture()}function bt(){window.globalHintManager&&window.globalHintManager.reset()}function wt(){let r=document.body.getElementsByTagName("*"),e=1;for(let t=0;t<r.length;t++){let o=e.toString();for(;[6].some(s=>o.includes(s.toString()));)e++,o=e.toString();let i=r[t];i?.setAttribute("data-momentic-id",`${e}`),i?.setAttribute("aria-keyshortcuts",`${e}`),e++}}var xo=new Set(["document","script","XMLHttpRequest","fetch","xhr"]),Io=new Set(["script","document"]),Lo=["intercom.io","googletagmanager.com","google-analytics.com","www.gstatic.com","gstatic.com","apis.google.com","sentry.io","newrelic.com","p.retool.com","m.stripe.com","m.stripe.network","js.stripe.com","assets.trybento.co","udon.trybento.co","cdn.lr-in-prod.com","r.lr-in-prod.com","content.product-usage.assembledhq.com","data.product-usage.assembledhq.com","static.zdassets.com","o.clarity.ms/collect"],No=["api.stripe.com","supabase.co"];function Pe(r){return`${r.resourceType()} ${r.method()} ${r.url()}`}function St(r){return r=r.replace(/^www\./,""),r}function Ct(r){return No.some(e=>r.includes(e))}function Et(r,e){if(!xo.has(r.resourceType()))return!1;let t=new URL(e),o=new URL(r.url());return Lo.some(i=>o.hostname.includes(i))?!1:Io.has(r.resourceType())||r.method()!=="GET"?!0:St(o.hostname).includes(St(t.hostname))}var be=jo($o);be.use(Wo());be.use(Vo({provider:{id:"2captcha",token:process.env.TWO_CAPTCHA_KEY},visualFeedback:!0}));var ke=class r{browser;context;page;a11yIdToNodeMap=new Map;dataMomenticIdToNodeMap=new Map;cdpClient;logger;localMode;activeFrame;baseURL;constructor({browser:e,context:t,page:o,baseUrl:i,cdpClient:s,logger:l,localMode:n}){this.browser=e,this.context=t,this.page=o,this.baseURL=i,this.cdpClient=s,this.logger=l,this.localMode=!!n}static USER_AGENT=Rt["Desktop Chrome"].userAgent;static VIEWPORT={width:1920,height:1080};static async init({baseUrl:e,logger:t,browserArgs:o,contextArgs:i,takeScreenshots:s,onScreenshot:l,onClose:n,localMode:c,localAppUrl:m,extensionPath:g,timeout:p=8e3}){let L={headless:!0,handleSIGTERM:!1,chromiumSandbox:!1,...o??{}},y={viewport:r.VIEWPORT,deviceScaleFactor:process.platform==="darwin"?2:1,userAgent:Rt["Desktop Chrome"].userAgent,geolocation:{latitude:37.7749,longitude:-122.4194},locale:"en-US",timezoneId:"America/Los_Angeles",...i??{}},w=null,A,C;c?(A=await be.launchPersistentContext(Go(Bo(),"momentic","chromium"),{...L,...y,ignoreDefaultArgs:["--enable-automation"],ignoreHTTPSErrors:!0,bypassCSP:!0,args:["--allow-insecure-localhost","--disable-web-security","--disable-site-isolation-for-policy","--disable-site-isolation-trials",`--unsafely-treat-insecure-origin-as-secure=${m}`,`--load-extension=${g}`],baseURL:e}),C=A.pages()[0],C.on("close",()=>{n?.()})):(w=await be.launch(L),A=await w.newContext({...y,baseURL:e}),C=await A.newPage());let B=await A.newCDPSession(C),N=new r({browser:w,context:A,page:C,baseUrl:e,cdpClient:B,logger:t,localMode:c}),u=!1;(async()=>{try{await N.navigate({url:e,wrapPossibleNavigation:!1,initialNavigation:!0})}catch(we){t.error({err:we},"Failed to initialize chrome browser")}finally{u=!0}})();let S=async()=>{if(s)try{l?.({viewport:await N.viewport(),buffer:await N.screenshot()})}catch(we){t.error({err:we},"Failed to take screenshot")}};S();let se=setInterval(()=>{S()},250),xt=Date.now();for(;!u&&Date.now()-xt<p;)await U(250);return clearInterval(se),u||t.warn("Timeout elapsed waiting for browser to initialize - are you sure this page is accessible?"),N}async getUserPageOrFrame(){if(this.localMode&&this.activeFrame){let e=this.page.frame(this.activeFrame);if(!e)throw new Error(`Failed to get non-existent frame: ${this.activeFrame}`);return e}return this.page}async initCDPSession(e=2){try{await this.cdpClient.send("Accessibility.enable"),await this.cdpClient.send("DOM.enable"),await this.cdpClient.send("Overlay.enable")}catch(t){if(e>0)return this.logger.error({err:t},"Failed to initialize CDP session, re-creating CDP client"),this.cdpClient=await this.context.newCDPSession(this.page),await U(250),this.initCDPSession(e-1)}}setLogger(e){this.logger=e}ping(){if(this.closed)throw new Error("Page has been closed");if(this.browser&&!this.browser.isConnected())throw new Error("Browser is not connected")}setActiveFrame(e){this.activeFrame=e}async reset(e){this.a11yIdToNodeMap.clear(),this.dataMomenticIdToNodeMap.clear();let t=this.context.pages();this.page=t[0];for(let o=1;o<t.length;o++)await t[o].close();e.clearCookies&&await this.context.clearCookies(),!this.page.isClosed()&&(e.clearStorage&&await(await this.getUserPageOrFrame()).evaluate(()=>{localStorage.clear()}),await this.navigate({url:e.url??this.baseURL,wrapPossibleNavigation:!1,initialNavigation:!0}))}async pageSetup(){try{this.localMode||await this.page.evaluate(ft)}catch{}}async wait(e){await U(e)}async toggleHints(e){let t=await this.getUserPageOrFrame();e.state==="on"?(await t.addStyleTag({content:Le.css}),await t.addScriptTag({content:Le.js}),await t.evaluate(yt)):await t.evaluate(bt)}async showHints(){await this.toggleHints({state:"on"});let e=async()=>{try{await this.toggleHints({state:"off"})}catch(t){this.logger.debug({err:t},"Failed to remove vision hints")}};setTimeout(()=>{e()},3e3)}async cleanup(){await this.page.close(),await this.context.close(),this.browser&&await this.browser.close()}get closed(){return this.page.isClosed()||!!this.browser&&!this.browser.isConnected()}async html(){return(await this.getUserPageOrFrame()).content()}async url(){return(await this.getUserPageOrFrame()).url()}async screenshotWithHints(e=100,t="device",o="/tmp/screenshots/test.jpg"){let i=o?.split("."),s=i?.slice(0,-1).join("."),l=i?.slice(-1)[0],n=Buffer.from("");await this.showHints();let c=await this.screenshot(e,t,o?`${s}-after-hint.${l}`:void 0);return{before:n,after:c}}async screenshot(e=100,t="device",o){let i={fullPage:!1,quality:e,scale:t,type:"jpeg",caret:"initial",path:o};return!this.localMode||!this.activeFrame?this.page.screenshot(i):this.page.locator(`iframe[name="${this.activeFrame}"]`).screenshot(i)}async viewport(){if(this.localMode&&this.activeFrame){let t=await this.page.locator(`iframe[name="${this.activeFrame}"]`).boundingBox();if(!t)throw new Error(`Failed to get bounding box for frame: ${this.activeFrame}`);return t}let e=this.page.viewportSize();if(!e)throw new Error("failed to get viewport");return e}async navigate({url:e,wrapPossibleNavigation:t=!0,initialNavigation:o=!1}){this.logger.debug(`Navigating to ${e}`);let i=Date.now(),s=async()=>{try{await(await this.getUserPageOrFrame()).goto(e,{waitUntil:"load",timeout:3e3}),this.logger.debug({url:e},`Got load event in ${Math.floor(Date.now()-i)}ms`)}catch{this.logger.warn({url:e},"Timeout elapsed waiting for page to fire load event, continuing anyways...")}finally{await this.initCDPSession()}};t?await this.wrapPossibleNavigation(s):await s();let l=await this.url();if(nt.has(l)&&process.env.NODE_ENV==="production")throw new Error(`${e} took too long to load \u{1F61E}. Please ensure the site and your internet are working.`);await this.pageSetup(),this.logger.info({url:e},"Navigation complete")}async type(e,t={}){let{clearContent:o=!0,pressKeysSequentially:i=!1}=t;o&&(process.platform==="darwin"?await this.page.keyboard.press("Meta+A"):await this.page.keyboard.press("Control+A"),await this.page.keyboard.press("Backspace")),i?await this.page.keyboard.type(e):await this.page.keyboard.insertText(e)}async clickByA11yID(e,t={}){let o=this.a11yIdToNodeMap.get(e);if(!o)throw new Error(`Could not find DOM node during click: ${e}`);let i=await this.clickUsingCDP(o,t);return await this.highlightNode(i),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async selectOptionByA11yID(e,t){let o=this.a11yIdToNodeMap.get(e);if(!o)throw new Error(`Could not find DOM node while selecting option: ${e}`);if(!o.backendNodeID)throw new Error(`Select target missing backend node id: ${o.getLogForm()}`);return await(await this.getLocatorFromBackendID(o.backendNodeID)).selectOption(t,{timeout:8e3}),await this.highlightNode(o),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async scrollIntoView(e){let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find node in DOM with a11y id: ${t}`);if(!o.backendNodeID)throw new Error(`Focus target missing backend node id: ${o.getLogForm()}`);await(await this.getLocatorFromBackendID(o.backendNodeID)).scrollIntoViewIfNeeded({timeout:8e3})}async highlight(e){try{let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find DOM node during highlight: ${t}`);if(!o.backendNodeID)throw new Error(`Select target missing backend node id: ${o.getLogForm()}`);await this.highlightNode(o)}catch(t){this.logger.warn({err:t,target:e},"Failed to highlight target")}}async highlightNode(e){try{await this.cdpClient.send("Overlay.highlightNode",{highlightConfig:gt,backendNodeId:e.backendNodeID})}catch{this.logger.warn("Failed to add node highlight, a page navigation likely occurred. This is non-fatal for tests.")}let t=async()=>{try{await this.cdpClient.send("Overlay.hideHighlight",{backendNodeId:e.backendNodeID})}catch(o){this.logger.debug({err:o},"Failed to remove node highlight")}};setTimeout(()=>{t()},3e3)}async wrapPossibleNavigation(e,t=8e3,o=!0){let i=Date.now(),s=await this.url(),l=Date.now(),n=new Map,c=new Map,m=f=>{let S=Pe(f.request());c.set(S,(c.get(S)??0)+1);let se=f.status();se>=500&&this.logger.warn({request:S,status:se},"Received 500 level response")},g=f=>{if(!Et(f,s))return;let S=Pe(f);n.set(S,(n.get(S)??0)+1),l=Date.now()};this.page.on("response",m),this.page.on("request",g);let p=[];o&&(p=this.context.pages().map(f=>f.url()));let L=!1,y=e().catch(f=>(L=!0,f instanceof Error?f:new Error(`${f}`)));await U(250);let w=async f=>{let S=await f;if(S instanceof Error)throw S;return S},A=new Set,C=!1,N=await(async()=>{for(;!L&&!(!C&&Date.now()-i>t);){if(await U(250),C=!1,A=new Set,Date.now()-l<=1250)continue;let f=!1;for(let S of n.keys())n.get(S)!==c.get(S)&&(Ct(S)&&(C=!0),f=!0,A.add(S));if(!f)return this.logger.debug({url:await this.url(),requests:JSON.stringify(Array.from(n.entries()))},`Network idle in ${Math.floor(Date.now()-i)}ms`),!0}return!L&&A.size>0&&this.logger.warn({url:await this.url(),unfinishedRequests:JSON.stringify(Array.from(A.entries()))},"Timeout elapsed waiting for network idle, continuing anyways..."),!1})();if(this.page.off("response",m),this.page.off("request",g),!N)return w(y);let u=await this.url();if(!L&&W(u,s)){this.logger.debug({startUrl:s,newUrl:u},"Detected url change in wrapPossibleNavigation, waiting for load state");let f=Math.max(t-(Date.now()-i),0);if(f>0)try{await(await this.getUserPageOrFrame()).waitForLoadState("load",{timeout:f})}catch{this.logger.warn({url:await this.url()},"Timeout elapsed waiting for load state, continuing anyways...")}}if(o){let f=this.context.pages().map(S=>S.url());if(f.length>p.length)for(let S of f)S!==u&&await this.switchToPage(S)}return w(y)}async resolveCachedTargetToID(e){if(!le(e)){let n=this.a11yIdToNodeMap.get(e.id);if(!n)throw new Error(`Resolving target failed, fresh value did not exist in node map: ${e.id}`);return ie(n,e),e.id}let t=(await this.getA11yTree()).serialize();this.logger.debug({tree:t},"Refreshed a11y tree before resolving target");let o=this.a11yIdToNodeMap.get(e.id);if(o){let n=ze(o,e);if(n>=5)return this.logger.debug({target:e,proposedNode:o.getLogForm(),comparisonScore:n},"Resolved cached a11y target to node with exact same id"),ie(o,e),e.id}let i=1/0,s=1/0,l;for(let n of this.a11yIdToNodeMap.values()){let c=ze(n,e);if(c>=5)return this.logger.debug({newNode:n.getLogForm(),target:e,comparisonScore:c},"Resolved cached a11y target to new node with field comparison"),ie(n,e),n.id;if(!e.serializedForm)continue;let m=n.serialize({noID:!0,maxLevel:1,neighbors:1});if(Math.abs(m.length-e.serializedForm.length)>15)continue;let g=Ho(e.serializedForm,m),p=g/Math.min(e.serializedForm.length,m.length);g<i&&p<.2&&(i=g,s=p,l=n)}if(l&&i<15)return this.logger.debug({newNode:l.getLogForm(),target:e,distance:i,ratio:s},"Resolved cached a11y target to new node with pure levenshtein distance"),ie(l,e),l.id;throw new Error(`Could not find any relevant node given cached target: ${JSON.stringify(e)}`)}async click(e,t={}){let o=await this.resolveCachedTargetToID(e);return await this.wrapPossibleNavigation(()=>this.clickByA11yID(o,t))}async hover(e){let t=await this.resolveCachedTargetToID(e),o=this.a11yIdToNodeMap.get(t);if(!o)throw new Error(`Could not find DOM node for hover: ${t}`);if(!o.backendNodeID)throw new Error(`Hover target missing backend node id: ${o.getLogForm()}`);return await(await this.getLocatorFromBackendID(o.backendNodeID)).hover({timeout:8e3}),await this.highlightNode(o),o.serialize({noChildren:!0,noProperties:!0,noID:!0})}async selectOption(e,t){let o=await this.resolveCachedTargetToID(e);return this.selectOptionByA11yID(o,t)}async press(e){await this.wrapPossibleNavigation(()=>this.page.keyboard.press(e))}async refresh(){if(this.localMode&&this.activeFrame){let t=(await this.getUserPageOrFrame()).url();await this.navigate({url:t,wrapPossibleNavigation:!0})}else await this.page.reload({timeout:3e3}),await this.pageSetup()}async getA11yTree(){await this.initCDPSession();let e=null,t=0,o=await this.url();for(;!e;)try{let i=await this.getRawA11yTree();if(!i.root||i.allNodes.length===0)throw new Error("No a11y tree found on page");e=ht(i,this.logger)}catch(i){if(this.logger.error({err:i,url:o},"Error fetching a11y tree"),t===0)await U(1e3),t++;else throw new Error(`Max retries exceeded fetching a11y tree: ${i}`)}return e.root||this.logger.warn("A11y tree was pruned entirely"),this.a11yIdToNodeMap=e.a11yIdNodeMap,this.dataMomenticIdToNodeMap=e.dataMomenticIdMap,e}getA11yIdFromDataMomenticId(e){return this.dataMomenticIdToNodeMap.get(e)?.id}async getRawA11yTree(){let e=await this.url(),t=Date.now(),o=()=>{t=Date.now()};this.cdpClient.addListener("Accessibility.nodesUpdated",o);let i=!1,s=()=>{this.logger.info({url:e},"Load event fired on page"),i=!0,t=Date.now()};this.cdpClient.addListener("Accessibility.loadComplete",s);let l=Date.now(),n=!0;for(;Date.now()-l<3e3;){if(await U(250),!i&&Date.now()-l<1e3){process.env.NODE_ENV!=="production"&&this.logger.debug({url:e},"A11y tree not loaded yet, waiting...");continue}if(Date.now()-t>=1250){n=!1;break}this.logger.debug({url:e},"A11y tree not stable yet, waiting...")}this.logger.debug({duration:Date.now()-l,eventReceived:i,timeoutTriggered:n},"A11y wait phase completed"),await(await this.getUserPageOrFrame()).evaluate(wt);let c;if(this.localMode&&this.activeFrame){let{result:{objectId:g}}=await this.cdpClient.send("Runtime.evaluate",{expression:`document.querySelector("#${this.activeFrame}")`}),p=await this.cdpClient.send("DOM.describeNode",{objectId:g});c=(await this.cdpClient.send("Accessibility.getRootAXNode",{frameId:p.node.frameId})).node.backendDOMNodeId}else{let{node:g}=await this.cdpClient.send("Accessibility.getRootAXNode");c=g.backendDOMNodeId}let{nodes:m}=await this.cdpClient.send("Accessibility.queryAXTree",{backendNodeId:c});return this.cdpClient.removeListener("Accessibility.loadComplete",s),this.cdpClient.removeListener("Accessibility.nodesUpdated",o),{root:m[0],allNodes:m}}async clickUsingVisualCoordinates(e){let t=await this.getElementLocation(e);if(!t)throw new Error(`Could not find element location with backend node id: ${e}`);this.logger.debug({location:t},"Executing mouse click"),await this.page.mouse.click(t.centerX,t.centerY)}async getIDAttributeUsingCDP(e){await this.cdpClient.send("DOM.getDocument",{depth:0});let t=await this.cdpClient.send("DOM.requestNode",{objectId:e}),i=(await this.cdpClient.send("DOM.getAttributes",{nodeId:t.nodeId})).attributes,s=i.findIndex(l=>l==="data-momentic-id");return s===-1?"":i[s+1]||""}async getLocatorFromBackendID(e){let t=await this.cdpClient.send("DOM.resolveNode",{backendNodeId:e});if(!t||!t.object.objectId)throw new Error(`Could not resolve backend node ${e}`);try{let o=await this.getIDAttributeUsingCDP(t.object.objectId);if(!o)throw new Error("Failed getting data-momentic-id attribute using CDP");return(await this.getUserPageOrFrame()).locator(`[data-momentic-id="${o}"]`)}catch(o){throw this.logger.error({err:o},"Failed to get ID attribute"),o}}async clickUsingCDP(e,t={}){let o=0,i=e;for(;o<st;){if(!i||i.role==="RootWebArea")throw new Error(`Attempted to click node with no clickable surrounding elements: ${e.getLogForm()}`);if(i.role==="StaticText"){i=i.parent;continue}let s=i.backendNodeID;if(!s){this.logger.warn({node:i.getLogForm()},"Click candidate had no backend node ID"),i=i.parent;continue}try{let l=await this.getLocatorFromBackendID(s);return t.doubleClick?await l.dblclick({timeout:8e3}):await l.click({timeout:8e3,button:t.rightClick?"right":"left",force:t.force}),i.id!==e.id&&this.logger.info({oldNode:e.getLogForm(),newNode:i.getLogForm()},"Redirected click successfully to new element"),i}catch(l){this.logger.error({err:l,node:i.getLogForm()},"Failed click or click timed out"),o++,i=i.parent}}throw new Error(`Max click redirection attempts exhausted on original element: ${e.getLogForm()}`)}async getElementLocation(e){let t=await this.cdpClient.send("DOMSnapshot.captureSnapshot",{computedStyles:[],includeDOMRects:!0,includePaintOrder:!0}),o=await this.page.evaluate(()=>window.devicePixelRatio);process.platform==="darwin"&&o===1&&(o=2);let i=t.documents[0],s=i.layout,l=i.nodes,n=l.nodeName||[],c=l.backendNodeId||[],m=s.nodeIndex,g=s.bounds,p=-1;for(let N=0;N<n.length;N++)if(c[N]===e){p=m.indexOf(N);break}if(p===-1)throw new Error(`Could not find any backend node with ID ${e}`);let[L=0,y=0,w=0,A=0]=g[p];L/=o,y/=o,w/=o,A/=o;let C=L+w/2,B=y+A/2;return{centerX:C,centerY:B}}async scrollUp(e){await this.page.mouse.wheel(0,-(e??r.VIEWPORT.height))}async scrollDown(e){await this.page.mouse.wheel(0,e??r.VIEWPORT.height)}async goForward(){await this.wrapPossibleNavigation(async()=>this.localMode&&this.activeFrame?(await this.getUserPageOrFrame()).evaluate(e=>{let t=e().contentWindow;t?t.history.forward():console.error("Failed to get content window for frame")},()=>document.querySelector(`iframe[name="${this.activeFrame}"]`)):this.page.goForward({timeout:8e3})),await this.pageSetup()}async goBack(){await this.wrapPossibleNavigation(async()=>this.localMode&&this.activeFrame?(await this.getUserPageOrFrame()).evaluate(e=>{let t=e().contentWindow;t?t.history.back():console.error("Failed to get content window for frame")},()=>document.querySelector(`iframe[name="${this.activeFrame}"]`)):this.page.goBack({timeout:8e3})),await this.pageSetup()}async switchToPage(e){let t=this.context.pages();for(let o=0;o<t.length;o++){let i=t[o];if(i.url().includes(e)){this.logger.info(`Switching to tab ${o} with url ${i.url()}`),this.page=i;try{await i.waitForLoadState("load",{timeout:3e3})}catch{this.logger.warn({url:await this.url()},"Timeout elapsed waiting for load state during tab switch, continuing anyways...")}await this.pageSetup(),await this.initCDPSession();return}}throw new Error(`Could not find page with url containing ${e}`)}async setCookie(e){let t=qe(e);await this.context.addCookies([t])}async setLocalStorage(e,t){await(await this.getUserPageOrFrame()).evaluate(([i,s])=>{i&&localStorage.setItem(i,s||"")},[e,t])}async solveCaptcha(){await this.getA11yTree();let e;for(let n of this.a11yIdToNodeMap.values())if(n.role==="image"&&n.name.toLowerCase().includes("captcha")){if(!n.backendNodeID)continue;e=await this.getLocatorFromBackendID(n.backendNodeID);break}if(!e){let n=await(await this.getUserPageOrFrame()).solveRecaptchas();if(!n.captchas||!n.captchas.length)throw new Error("No captchas found on the page");return}let t=await e.screenshot({type:"jpeg",animations:"allow",quality:100}),o=await fetch("https://api.2captcha.com/createTask",{method:"POST",body:JSON.stringify({clientKey:process.env.TWO_CAPTCHA_KEY,task:{type:"ImageToTextTask",body:t.toString("base64"),case:!0},languagePool:"en"})});if(!o.ok){let n=`Captcha solver API returned error response: ${o.statusText}`;throw this.logger.error({text:await o.text()},n),new Error(n)}let{taskId:i}=await o.json(),s=Date.now(),l="";for(;Date.now()-s<6e4;){await U(2500);let n=await fetch("https://api.2captcha.com/getTaskResult",{method:"POST",body:JSON.stringify({clientKey:process.env.TWO_CAPTCHA_KEY,taskId:i})});if(!n.ok){let m=`Captcha solution API returned error response: ${n.statusText}`;throw this.logger.error({text:await n.text()},m),new Error(m)}let c=await n.json();if(c.errorId){let m=`Captcha solution API returned error ID ${c.errorId}`;throw this.logger.error(m),new Error(m)}if(c.status==="ready"){l=c.solution.text;break}}if(!l)throw new Error("Captcha solution timed out");return l}getActiveFrame(){return this.activeFrame}};var Ko={type:"a11y",version:"1.0.0",useHistory:"diff",useGoalSplitter:!0},qo=Ko;import Xo from"dedent";import Yo from"diff-lines";var Jo=1e4,Ue=class{browser;pendingInstructions;generator;commandHistory;config;closed=!1;logger;constructor({browser:e,config:t,generator:o,logger:i}){this.browser=e,this.generator=o,this.config=t,this.logger=i,this.pendingInstructions=[],this.commandHistory=[]}get history(){return this.commandHistory.filter(e=>e.state==="DONE")}get lastExecutedCommand(){let e=this.history;return e.length===0?null:e[e.length-1]}setOpen(){this.closed=!1}isClosed(){return this.closed}setLogger(e){this.logger=e}resetHistory(){this.commandHistory=[],this.pendingInstructions=[]}async resetState(e){this.resetHistory(),this.closed=!0,await this.browser.reset(e)}async getBrowserState(){let t=await(await this.browser.getA11yTree()).serialize();return this.logger.debug({tree:t,activeFrame:this.browser.getActiveFrame()},"Got a11y tree"),t}getSerializedHistory(e,t){let o;return this.config.useHistory==="diff"?o=this.getDiffHistory(e,t):o=this.getListHistory(),o}async splitUserGoal(e,t,o){if(e==="AI_ACTION"&&t.match(/[,!;.]|(?:and)|(?:then)/)&&this.config.useGoalSplitter){let i=await this.generator.getGranularGoals({goal:t,url:await this.browser.url()},o);this.pendingInstructions=i.reverse()}else this.pendingInstructions=[t]}async promptToCommand(e,t,o){try{return await this.promptToCommandHelper(e,t,o)}catch(i){throw i instanceof x?i:new x("InternalWebAgentError",i instanceof Error?i.message:`${i}`,{cause:i})}}async promptToCommandHelper(e,t,o){if(this.pendingInstructions.length===0){if(!t.trim())throw new Error("Cannot generate commands for empty goal");await this.splitUserGoal(e,t,o)}let i=this.pendingInstructions[this.pendingInstructions.length-1];this.logger.info({goal:i},"Starting prompt translation");let s=Date.now(),l=await this.browser.url(),n=await this.getBrowserState();this.logger.info({duration:Date.now()-s,url:l},"Got browser state");let c=this.commandHistory.length;this.commandHistory.push({state:"PENDING",browserStateBeforeCommand:n,urlBeforeCommand:l,type:e});let m=this.getSerializedHistory(l,n),g={url:l,numPrevious:c,browserState:n,history:m,goal:i,lastCommand:this.lastExecutedCommand},p=await this.generator.getProposedCommand(g,o);if(this.logger.info({type:p.type,thoughts:p.thoughts},"Got proposed command"),p.type==="SUCCESS"){let L=this.pendingInstructions.pop();if(this.logger.info({finishedInstruction:L,remainingInstructions:this.pendingInstructions},"Removing pending instruction due to SUCCESS"),this.pendingInstructions.length!==0)return this.commandHistory=[],this.promptToCommand(e,"",o)}else p.type==="FAILURE"&&(this.logger.info({remainingInstructions:this.pendingInstructions},"Removing pending instructions due to FAILURE"),this.pendingInstructions=[]);return{context:g,command:p}}async locateElement(e,t,o){if(!e)throw new x("ActionFailureError","Cannot locate element with empty description");let i=await this.getBrowserState(),s;if(t){let{before:l,after:n}=await this.browser.screenshotWithHints();if(s=await this.generator.getElementLocationWithVision({goal:e,screenshot:l,hintActivatedScreenshot:n},o),s.id>0){let c=this.browser.getA11yIdFromDataMomenticId(s.id);if(!c)throw new x("InternalWebAgentError",`Unable to find corresponding DOM node for id ${s.id}`);s.id=c}}else s=await this.generator.getElementLocation({browserState:i,goal:e},o);if(s.id<0)throw new x("ActionFailureError",`Unable to locate element: ${s.thoughts?s.thoughts:"please ensure the element is visible and conforms to Accessibility guidelines"}`);return s}getDiffHistory(e,t){let o=this.history.filter(s=>s.type==="AI_ACTION");if(o.length===0)return"<NONE/>";let i=[`
|
|
19
|
+
You have already executed the following commands successfully (most recent listed first)`,"-".repeat(10)];return o.reverse().forEach((s,l)=>{if(i.push(`COMMAND ${o.length-l}${l===0?" (command just executed)":""}: ${s.serializedCommand}`),l===0)if(W(s.urlBeforeCommand,e))i.push(` URL CHANGE: '${s.urlBeforeCommand}' -> '${e}'`);else{let n=Yo(s.browserStateBeforeCommand,t,{n_surrounding:1});n?n.length<Jo?(i.push("PAGE CONTENT CHANGE:"),n.split(`
|
|
20
|
+
`).forEach(c=>i.push(` ${c}`))):i.push("PAGE CONTENT CHANGE: <TOO_LONG_TO_DISPLAY/>"):i.push("PAGE CONTENT CHANGE: <NONE/>")}i.push("-".repeat(10))}),i.push(`STARTING URL: ${this.browser.baseURL}`),i.join(`
|
|
21
|
+
`)}getListHistory(){return Xo`Here are the commands that you have successfully executed:
|
|
22
22
|
${this.commandHistory.filter(e=>e.type==="AI_ACTION").map(e=>`- ${e.serializedCommand}`).join(`
|
|
23
|
-
`)}`}async executeCommand(e,t,o=!1){let
|
|
23
|
+
`)}`}async executeCommand(e,t,o=!1){let i=this.commandHistory[this.commandHistory.length-1];if(!o&&(!i||i.state!=="PENDING"))throw new x("InternalWebAgentError","Executing command but there is no pending entry in the history");if(this.closed)throw new Error("Attempting to execute command on a closed controller");let s;try{let l=Date.now();s=await this.executePresetStep(e,t);let n=Date.now()-l;this.logger.debug({result:s,duration:n},"Got execution result")}catch(l){throw l instanceof Error?new re(`Failed to execute command: ${l}`,{cause:l}):new re("Unexpected throw from executing command",{cause:new Error(`${l}`)})}return s.succeedImmediately&&!o&&(this.pendingInstructions.pop(),this.pendingInstructions.length>0&&(s.succeedImmediately=!1)),s.elementInteracted&&"target"in e&&e.target&&!e.target.elementDescriptor&&(e.target.elementDescriptor=s.elementInteracted.trim()),o||(i.generatedStep=e,i.serializedCommand=ve(e),i.state="DONE"),s}async executeAssertion(e){let t=await this.getBrowserState(),o=await this.browser.url(),i;if(e.useVision)i={goal:e.assertion,url:o,screenshot:await this.browser.screenshot(),browserState:"",history:"",numPrevious:-1,lastCommand:null};else{let l=this.getSerializedHistory(o,t);i={goal:e.assertion,url:o,browserState:t,history:l,lastCommand:this.lastExecutedCommand,numPrevious:this.commandHistory.length}}let s=await this.generator.getAssertionResult(i,e.useVision,e.disableCache);if(s.relevantElements&&Promise.all(s.relevantElements.map(l=>this.browser.highlight({id:l}))),!s.result)throw new x("AssertionFailureError",s.thoughts);return{succeedImmediately:!1,thoughts:s.thoughts,urlAfterCommand:o}}async wrapElementTargetingCommand(e,t,o,i,s=1){if(!e.a11yData&&!e.elementDescriptor)throw new x("ActionFailureError","Cannot target element with no target data or element descriptor");let l=e.a11yData&&le(e.a11yData);e.a11yData||(this.logger.debug("No cached locator data for target, prompting AI for fresh location"),s--,e.a11yData=ae.parse(await this.locateElement(e.elementDescriptor,t,o)));try{let n=await i(e.a11yData);return l?this.logger.debug({target:e},"Successfully used cached target to perform action"):this.logger.debug({target:e},"Successfully generated and used new a11y target information"),n}catch(n){if(s>0&&e.elementDescriptor)return this.logger.warn({err:n,target:e},"Failed to execute action with cached target, retrying with AI"),e.a11yData=void 0,this.wrapElementTargetingCommand(e,t,o,i,s);if(n instanceof x)throw n;let c=`Failed to find ${e.elementDescriptor?`${e.elementDescriptor}`:"element"}: ${n instanceof Error?n.message:n}`;throw this.logger.error({err:n,target:e},c),new x("ActionFailureError",c,{cause:n})}}async executePresetStep(e,t){try{return await this.executePresetStepHelper(e,t)}catch(o){throw o instanceof x?o:new x("InternalWebAgentError",o instanceof Error?o.message:`${o}`,{cause:o})}}async executePresetStepHelper(e,t){switch(e.type){case"SUCCESS":return e.condition?.assertion.trim()?this.executeAssertion(e.condition):{succeedImmediately:!1,urlAfterCommand:await this.browser.url()};case"AI_ASSERTION":return this.executeAssertion(e);case"NAVIGATE":if(!Ne(e.url)&&!Oe(e.url,this.browser.baseURL))throw new x("ActionFailureError",`Invalid URL: ${e.url}`);await this.browser.navigate({url:e.url});break;case"CAPTCHA":let o=await this.browser.solveCaptcha();o&&(await this.wrapElementTargetingCommand({elementDescriptor:"the captcha image solution input"},e.useVision,t,c=>this.browser.click(c)),await this.browser.type(o,{clearContent:!0,pressKeysSequentially:!1}));break;case"GO_BACK":await this.browser.goBack();break;case"GO_FORWARD":await this.browser.goForward();break;case"SCROLL_DOWN":case"SCROLL_UP":let i;return e.target&&(e.target.elementDescriptor.trim()||e.target.a11yData)&&(i=await this.wrapElementTargetingCommand(e.target,e.useVision,t,c=>this.browser.hover(c))),e.type==="SCROLL_UP"?await this.browser.scrollUp(e.deltaY):await this.browser.scrollDown(e.deltaY),{succeedImmediately:!1,urlAfterCommand:await this.browser.url(),elementInteracted:i};case"WAIT":await this.browser.wait(e.delay*1e3);break;case"REFRESH":await this.browser.refresh();break;case"CLICK":{let c=await this.browser.url(),m=await this.wrapElementTargetingCommand(e.target,e.useVision,t,p=>this.browser.click(p,{doubleClick:e.doubleClick,rightClick:e.rightClick,force:e.force})),g={urlAfterCommand:await this.browser.url(),succeedImmediately:!1,elementInteracted:m};return W(c,g.urlAfterCommand)&&(g.succeedImmediately=!0,g.succeedImmediatelyReason="URL changed"),g}case"SELECT_OPTION":{let c=await this.wrapElementTargetingCommand(e.target,!1,t,m=>this.browser.selectOption(m,e.option));return{succeedImmediately:!1,urlAfterCommand:await this.browser.url(),elementInteracted:c}}case"TAB":await this.browser.switchToPage(e.url);break;case"COOKIE":if(!e.value)break;await this.browser.setCookie(e.value);break;case"LOCAL_STORAGE":if(!e.value||!e.key)break;await this.browser.setLocalStorage(e.key,e.value);break;case"TYPE":{let c=await this.browser.url(),m=await this.wrapElementTargetingCommand(e.target,e.useVision,t,p=>this.browser.click(p,{force:e.force}));await this.browser.type(e.value,{clearContent:e.clearContent,pressKeysSequentially:e.pressKeysSequentially}),e.pressEnter&&await this.browser.press("Enter");let g={urlAfterCommand:await this.browser.url(),succeedImmediately:!1,elementInteracted:m};return W(c,g.urlAfterCommand)&&(g.succeedImmediately=!0,g.succeedImmediatelyReason="URL changed"),g}case"HOVER":{let c=await this.wrapElementTargetingCommand(e.target,e.useVision,t,m=>this.browser.hover(m));return{succeedImmediately:!1,urlAfterCommand:await this.browser.url(),elementInteracted:c}}case"PRESS":let s=await this.browser.url();await this.browser.press(e.value);let l={urlAfterCommand:await this.browser.url(),succeedImmediately:!1};return W(s,l.urlAfterCommand)&&(l.succeedImmediately=!0,l.succeedImmediatelyReason="URL changed"),l;case"REQUEST":{let c=e.timeout??30,m=null,g=new AbortController,p=Object.fromEntries(Object.entries(e.headers||{}).filter(([u,f])=>u&&f)),L=new URLSearchParams;Object.entries(e.params||{}).filter(([u,f])=>u&&f).forEach(([u,f])=>{L.append(u,f)});let y;if(Ne(e.url)&&(y=e.url),Oe(e.url,this.browser.baseURL)&&(y=new URL(e.url,this.browser.baseURL).toString()),!y)throw new x("ActionFailureError",`Invalid URL: ${e.url}`);let w=async()=>{try{m=await fetch(`${y}?${L.toString()}`,{headers:p,method:e.method,body:e.body,signal:g.signal})}catch(u){this.logger.error({err:u},"Failed to make fetch request")}},A=async()=>{await new Promise(u=>setTimeout(u,c*1e3)),g.abort()};await Promise.race([A(),w()]);let C=m;if(!C)throw new x("ActionFailureError",`Fetch request timed out after ${c} seconds`);if(!C.ok)throw new x("ActionFailureError",`Fetch request failed with status ${C.status}`);let B={};C.headers.forEach((u,f)=>{B[f]=u});let N={status:C.status,headers:B};return C.headers.get("content-type")?.includes("json")?N.json=await C.json():C.headers.get("content-type")?.includes("text")&&(N.text=await C.text()),{succeedImmediately:!1,urlAfterCommand:await this.browser.url(),data:N}}default:return(c=>{throw"If Typescript complains about the line below, you missed a case or break in the switch above"})(e)}return{succeedImmediately:!1,urlAfterCommand:await this.browser.url()}}async getReverseMappedTarget(e,t,o){return(await this.generator.getReverseMappedDescription({browserState:e.browserState,goal:`${t}`},o)).phrase}};import Qo from"fetch-retry";var Zo=Qo(global.fetch),q="v1",Fe=class{baseURL;apiKey;constructor(e){this.baseURL=e.baseURL,this.apiKey=e.apiKey}async getElementLocation(e,t){let o=await this.sendRequest(`/${q}/web-agent/locate-element`,{browserState:e.browserState,goal:e.goal,disableCache:t});return Ie.parse(o)}async getElementLocationWithVision(e,t){let o=await this.sendRequest(`/${q}/web-agent/visual-locate`,{goal:e.goal,screenshot:e.screenshot?.toString("base64"),hintActivatedScreenshot:e.hintActivatedScreenshot?.toString("base64"),disableCache:t});return Ie.parse(o)}async getAssertionResult(e,t,o){if(t){let s=await this.sendRequest(`/${q}/web-agent/assertion`,{url:e.url,goal:e.goal,screenshot:e.screenshot?.toString("base64"),disableCache:o,vision:!0});return xe.parse(s)}let i=await this.sendRequest(`/${q}/web-agent/assertion`,{url:e.url,browserState:e.browserState,goal:e.goal,history:e.history,numPrevious:e.numPrevious,lastCommand:e.lastCommand,disableCache:o,vision:!1});return xe.parse(i)}async getProposedCommand(e,t){let o=await this.sendRequest(`/${q}/web-agent/next-command`,{url:e.url,browserState:e.browserState,goal:e.goal,history:e.history,numPrevious:e.numPrevious,lastCommand:e.lastCommand,disableCache:t});return ot.parse(o)}async getGranularGoals(e,t){let o=await this.sendRequest(`/${q}/web-agent/split-goal`,{url:e.url,goal:e.goal,disableCache:t});return rt.parse(o)}async getReverseMappedDescription(e,t){let o=await this.sendRequest(`/${q}/web-agent/reverse-mapped-description`,{goal:e.goal,browserState:e.browserState,disableCache:t});return it.parse(o)}async sendRequest(e,t){let o=await Zo(`${this.baseURL}${e}`,{retries:1,retryDelay:1e3,method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}});if(!o.ok)throw new Error(`Request to ${e} failed with status ${o.status}: ${await o.text()}`);return o.json()}};export{Fe as APIGenerator,Ue as AgentController,ke as ChromeBrowser,F as CommandType,qo as DEFAULT_CONTROLLER_CONFIG,P as StepType};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "momentic",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "The Momentic SDK for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/**/*",
|
|
13
13
|
"bin/**/*",
|
|
14
|
-
"static/**/*"
|
|
14
|
+
"static/**/*",
|
|
15
|
+
"extensions/**/*"
|
|
15
16
|
],
|
|
16
17
|
"license": "MIT",
|
|
17
18
|
"publishConfig": {
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"express": "^4.18.2",
|
|
51
52
|
"fastest-levenshtein": "^1.0.16",
|
|
52
53
|
"fetch-retry": "^5.0.6",
|
|
54
|
+
"open": "^10.0.3",
|
|
53
55
|
"playwright": "1.40.1",
|
|
54
56
|
"playwright-core": "1.40.1",
|
|
55
57
|
"playwright-extra": "^4.3.6",
|