mobileboost-cli 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/index-B9xOUxIH.js +492 -0
  3. package/.output/public/assets/{main-BOWxdROu.js → main-Dc24NDnw.js} +1 -1
  4. package/.output/server/chunks/_/{_tanstack-start-manifest_v-CUvi9Zok.mjs → _tanstack-start-manifest_v-DWF0_Gj8.mjs} +1 -1
  5. package/.output/server/chunks/_/actions-AXnOoTLJ.mjs +1 -0
  6. package/.output/server/chunks/_/agent-CUyzfc4e.mjs +1 -0
  7. package/.output/server/chunks/_/ai-client-waGeh-P8.mjs +1 -0
  8. package/.output/server/chunks/_/{appium-BbkeYpmk.mjs → appium-C-D6h2jM.mjs} +1 -1
  9. package/.output/server/chunks/_/appium-client-Dxm_q6FS.mjs +1 -0
  10. package/.output/server/chunks/_/cache-CtBF0d8x.mjs +1 -0
  11. package/.output/server/chunks/_/client-CM5hUS2d.mjs +1 -0
  12. package/.output/server/chunks/_/constants-Dh9o88yr.mjs +1 -0
  13. package/.output/server/chunks/_/describe-BfbyupMJ.mjs +1 -0
  14. package/.output/server/chunks/_/device-CWFVkH1s.mjs +1 -0
  15. package/.output/server/chunks/_/files-hj9HVaKT.mjs +1 -0
  16. package/.output/server/chunks/_/hierarchy-D3NdBpb6.mjs +1 -0
  17. package/.output/server/chunks/_/hierarchy-helpers-BaGN7WBn.mjs +3 -0
  18. package/.output/server/chunks/_/index-CLteVPoM.mjs +474 -0
  19. package/.output/server/chunks/_/{router-Bufjq1jN.mjs → router-CnslKYM2.mjs} +1 -1
  20. package/.output/server/chunks/_/{screenshot-BD59si87.mjs → screenshot-Csbvymnl.mjs} +1 -1
  21. package/.output/server/chunks/_/server.mjs +3 -3
  22. package/.output/server/chunks/_/step-D2WQqd4J.mjs +1 -0
  23. package/.output/server/chunks/_/stores-03HL60eP.mjs +1 -0
  24. package/.output/server/index.mjs +6 -6
  25. package/.output/server/package.json +8 -0
  26. package/dist/cli.js +3 -2
  27. package/dist/cli.js.map +1 -1
  28. package/dist/commands/studio.js +29 -18
  29. package/dist/commands/studio.js.map +1 -1
  30. package/package.json +5 -3
  31. package/.output/public/assets/index-Bu1akwRM.js +0 -437
  32. package/.output/server/chunks/_/actions-2SMY1JO3.mjs +0 -1
  33. package/.output/server/chunks/_/agent-CeaBVldB.mjs +0 -1
  34. package/.output/server/chunks/_/ai-client-BtI1TeHN.mjs +0 -1
  35. package/.output/server/chunks/_/appium-client-D-NjeB35.mjs +0 -1
  36. package/.output/server/chunks/_/cache-D_LOBxSY.mjs +0 -1
  37. package/.output/server/chunks/_/client-DG3m9828.mjs +0 -1
  38. package/.output/server/chunks/_/describe-NXd8kuzS.mjs +0 -1
  39. package/.output/server/chunks/_/device-8ONaG49P.mjs +0 -1
  40. package/.output/server/chunks/_/files-CIdgnUJn.mjs +0 -1
  41. package/.output/server/chunks/_/hierarchy-Q35yGKlr.mjs +0 -1
  42. package/.output/server/chunks/_/hierarchy-helpers-DF8QSYE6.mjs +0 -1
  43. package/.output/server/chunks/_/index-Cz7u2rY_.mjs +0 -419
  44. package/.output/server/chunks/_/step-CEQtT3SD.mjs +0 -1
  45. package/.output/server/chunks/_/stores-C1dCcTeV.mjs +0 -1
@@ -1 +0,0 @@
1
- import{c as a,a as t}from"./server.mjs";import{A as p,l as f,x as u,r as h,h as S,d as _}from"./device-8ONaG49P.mjs";import{performDeepLink as $,performScroll as l,getPageSource as g,performSwipe as x,performTap as b,performType as y}from"./appium-client-D-NjeB35.mjs";import{h as P,c as w,l as v}from"./hierarchy-helpers-DF8QSYE6.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:fs";import"node:url";import"node:path";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"zod";import"./step-CEQtT3SD.mjs";import"webdriverio";import"xml2js";const F=a("605c05774def700303f9889c0f8a28fed026e0b5c36a1563cff2835ee01d26b1",(e,r)=>T.__executeServer(e,r)),T=t({method:"POST"}).inputValidator(S).handler(F,async({data:e})=>(console.log(`Performing tap at ${e.x}, ${e.y}`),await b(e),{success:!0})),O=a("07e23aa87e88d53c6c9e3d8e88de788d27d7b10930150bc4fd510d4447aaf3de",(e,r)=>V.__executeServer(e,r)),V=t({method:"POST"}).inputValidator(_).handler(O,async({data:e})=>(console.log(`Performing type: "${e.text}"`),await y(e),{success:!0})),k=a("5c526b678a7596f28beca76784df0ac58acd292627c5770c0c8029e38e4681ec",(e,r)=>L.__executeServer(e,r)),L=t({method:"POST"}).inputValidator(f).handler(k,async({data:e})=>(console.log(`Performing scroll: ${e.direction}`),await l(e),{success:!0})),A=a("2b4a002699960d578addbcf4dd83fedcec62444d7da4bf7c2359be991ed6207e",(e,r)=>I.__executeServer(e,r)),I=t({method:"POST"}).inputValidator(h).handler(A,async({data:e})=>(console.log(`Performing swipe: ${e.x1},${e.y1} -> ${e.x2},${e.y2}`),await x(e),{success:!0})),U=a("10b616f4aacf11bb275166e4ae03f441f1d7c9a68a670dfadb03b74e1d012900",(e,r)=>D.__executeServer(e,r)),D=t({method:"POST"}).inputValidator(u).handler(U,async({data:e})=>{console.log(`Performing scroll until: text="${e.text}", id="${e.elementId}", dir=${e.direction}`);for(let r=0;r<(e.maxScrolls??15);r++){console.log(`Scroll Until Loop: ${r+1}/${e.maxScrolls}`);const m=await g(),n=await P(m);let i=n.hierarchy?.node?.[0];const s=n.hierarchy?.node;if(s){const c=s.find(d=>d.$&&d.$.package!=="com.android.systemui");c&&(i=c)}let o=!1;if(e.elementId&&w(i,e.elementId)&&(o=!0),!o&&e.text&&v(i,e.text)&&(o=!0),o)return console.log("Target found!"),{success:!0,scrolls:r};r<(e.maxScrolls??15)-1&&(await l({direction:e.direction}),await new Promise(c=>setTimeout(c,1e3)))}return console.log("Target NOT found after max scrolls"),{success:!1}}),B=a("566ee4344553ab6300f847f5de346e037f92d986cb824ba1c313346e62345fbe",(e,r)=>E.__executeServer(e,r)),E=t({method:"POST"}).inputValidator(p).handler(B,async({data:e})=>(console.log(`Performing deep link: "${e.url}"`),await $(e.url),{success:!0}));export{B as deepLinkFn_createServerFn_handler,k as scrollFn_createServerFn_handler,U as scrollUntilFn_createServerFn_handler,A as swipeFn_createServerFn_handler,F as tapFn_createServerFn_handler,O as typeFn_createServerFn_handler};
@@ -1 +0,0 @@
1
- import{c as o,a as i}from"./server.mjs";import{j as m,E as p}from"./ai-client-BtI1TeHN.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:fs";import"node:url";import"node:path";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"zod";import"sharp";const e=o("5918013064f9b88efb265b30a770275d6c9d52bf42318f451bab8a47bc850917",(t,r)=>a.__executeServer(t,r)),a=i({method:"POST"}).inputValidator(m).handler(e,async({data:t})=>await p(t));export{e as executeAgentStepFn_createServerFn_handler};
@@ -1 +0,0 @@
1
- import{z as e}from"zod";import m from"node:fs";import u from"node:path";import b from"sharp";const j=e.object({fullImage:e.string(),croppedImage:e.string(),targetImage:e.string(),type:e.enum(["interaction","assert","tap"]).optional()}),S=e.object({base64_screenshot:e.string(),instruction:e.string(),action_history:e.array(e.any()).optional(),executionId:e.string().optional()});function f(){const t=u.join(process.cwd(),"mobileboost.config.json");if(!m.existsSync(t))throw new Error('mobileboost.config.json not found. Run "mobileboost init" first.');const i=m.readFileSync(t,"utf-8");return JSON.parse(i)}function g(t){return t.replace(/^data:image\/\w+;base64,/,"")}async function x(t){const{fullImage:i,croppedImage:n,targetImage:s,type:r}=t,a=f().apiKey;if(!a)throw new Error("apiKey not configured in mobileboost.config.json");const c=r==="assert"?"assert":"interaction",l={org_id:a,full_image:g(i),cropped_image:g(n),target_image:g(s),type:c},o=await fetch("https://api.mobileboost.io/cli/describe_interaction",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!o.ok){const d=await o.text();throw new Error(`Describe interaction failed: ${o.status} ${d}`)}const p=await o.json();return p.description||p.assertion_description||JSON.stringify(p)}async function I(t){const i="https://api.mobileboost.io/call_lambda",n=f().apiKey;if(!n)throw new Error("apiKey not configured in mobileboost.config.json");const s=Buffer.from(t.base64_screenshot,"base64"),r=await b(s).metadata(),a=r.width??1080,c=r.height??1920,l={lambda_flow:"get_next_step",current_date:new Date().toLocaleDateString("en-GB",{day:"numeric",month:"long",year:"numeric"}),base64_screenshot:t.base64_screenshot,getUI_elements:[],uiHierarchy:[],test_task_string:JSON.stringify([{id:"step-1",text:`1. ${t.instruction}`,plainText:t.instruction}]),image_width:a,image_height:c,action_history:t.action_history??[],orgKey:n,template_images:{},model_provider:"vellum",model_version:"claude-agent",fallbackModel:"claude-agent",utilize_fullTextAnnotation:!1,enableSortingOCR:!0,enableActionHistoryCut:!0,removeOverlappingText:!1,currentAndPreviousScreenMatch:!1,popupDetectionEnabled:!0,ocrProvider:"gcp",modelResponseDoubleCheckEnabled:!1},o=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!o.ok)throw new Error(`Agent endpoint failed with status ${o.status}`);return await o.json()}export{I as E,x as I,S as j,j as x};
@@ -1 +0,0 @@
1
- import{remote as d}from"webdriverio";let n=null;function m(t,e){return!(!n||n.platform!==t||e&&n.deviceId!==e)}async function p(t="android",e){if(n&&n.platform===t&&(!e||n.deviceId===e))return n.client;if(n){console.log("Switching session from",n.platform,"to",t);try{await n.client.deleteSession()}catch(a){console.warn("Failed to close previous session",a)}n=null}console.log(`Initializing Appium session for ${t} ${e?`(${e})`:""}...`);const o={platformName:"Android","appium:automationName":"UiAutomator2","appium:ensureWebviewsHavePages":!0,"appium:nativeWebScreenshot":!0,"appium:newCommandTimeout":3600,...e?{"appium:udid":e}:{}},i={platformName:"iOS","appium:automationName":"XCUITest","appium:newCommandTimeout":3600,...e?{"appium:udid":e}:{}};try{const a=await d({protocol:"http",hostname:"127.0.0.1",port:4723,path:"/",capabilities:t==="ios"?i:o});return n={client:a,platform:t,deviceId:e},console.log("Appium session initialized"),a}catch(a){throw console.error("Failed to initialize Appium session:",a),a}}async function s(t,e){try{return await t()}catch(o){const i=o?.message||"";if(i.includes("instrumentation process is not running")||i.includes("invalid session id")||i.includes("Session")||i.includes("ended")||i.includes("closed")){if(console.warn(`[${e}] Encountered session error: "${i}". Retrying with new session...`),n){try{await n.client.deleteSession().catch(()=>{})}catch{}n=null}return await t()}throw o}}async function y(t){await s(async()=>{const e=await p(t.platform,t.deviceId);let o=Math.round(t.x),i=Math.round(t.y);const a=t.platform??"android";if(console.log(`[Tap] Platform: ${a}, Input: ${o},${i}, Screen: ${t.screenWidth}x${t.screenHeight}`),a==="ios"){const r=await e.getWindowRect();if(console.log(`[Tap] Window Size: ${r.width}x${r.height}`),t.screenWidth&&r.width){const c=t.screenWidth/r.width,u=t.screenHeight?t.screenHeight/r.height:c;console.log(`[Tap] Calculated Scale: X=${c.toFixed(2)}, Y=${u.toFixed(2)}`),o=Math.round(o/c),i=Math.round(i/u),console.log(`[iOS] Scaling tap: ${t.x},${t.y} (px) -> ${o},${i} (pt)`)}else console.warn("[Tap] Missing screenWidth or windowSize, skipping scale calculation."),(o>r.width||i>r.height)&&(o=Math.round(o/3),i=Math.round(i/3),console.log(`[iOS] Scaling tap (heuristic 3x): ${t.x},${t.y} -> ${o},${i}`))}await e.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:o,y:i},{type:"pointerDown",button:0},{type:"pause",duration:100},{type:"pointerUp",button:0}]}])},"performTap")}async function w(t){await s(async()=>{await(await p(t.platform,t.deviceId)).keys(t.text.split(""))},"performType")}async function f(t){await s(async()=>{const e=await p(t.platform,t.deviceId);let o=540,i=1500,a=540,r=500;t.direction==="up"&&(i=500,r=1500),await e.performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:o,y:i},{type:"pointerDown",button:0},{type:"pause",duration:100},{type:"pointerMove",duration:500,x:a,y:r},{type:"pointerUp",button:0}]}])},"performScroll")}async function h(t){await s(async()=>{await(await p(t.platform,t.deviceId)).performActions([{type:"pointer",id:"finger1",parameters:{pointerType:"touch"},actions:[{type:"pointerMove",duration:0,x:Math.round(t.x1),y:Math.round(t.y1)},{type:"pointerDown",button:0},{type:"pause",duration:100},{type:"pointerMove",duration:t.duration??500,x:Math.round(t.x2),y:Math.round(t.y2)},{type:"pointerUp",button:0}]}])},"performSwipe")}async function g(t){await s(async()=>{await(await p(t.platform,t.deviceId)).execute("mobile: deepLink",{url:t.url})},"performDeepLink")}async function S(){return await s(async()=>await(await p()).getPageSource(),"getPageSource")}export{p as ensureAppiumSession,S as getPageSource,m as isAppiumConnected,g as performDeepLink,f as performScroll,h as performSwipe,y as performTap,w as performType};
@@ -1 +0,0 @@
1
- import{z as n}from"zod";const o=n.object({stepNumber:n.number(),stepDescription:n.string(),filepath:n.string().optional(),screenshot:n.string(),interactionCoordinates:n.object({x:n.number(),y:n.number(),action:n.string().optional()}),platform:n.string().optional(),screenResolution:n.object({width:n.number(),height:n.number()}).optional()}),e=n.object({stepNumber:n.number(),stepDescription:n.string(),filepath:n.string().optional(),screenshot:n.string(),platform:n.string().optional(),highest_used_index:n.number().nullable().optional(),screenResolution:n.object({width:n.number(),height:n.number()}).optional()}),i=n.object({found:n.boolean(),interactionCoordinates:n.object({x:n.number(),y:n.number(),action:n.string().optional()}).optional(),cacheCommands:n.array(n.string()).optional(),cacheIndex:n.number().optional(),timings:n.any().optional()});export{i,o as n,e as o};
@@ -1 +0,0 @@
1
- import{c as p,a as d}from"./server.mjs";import c from"node:fs";import f from"node:path";import l from"node:crypto";import{o as b,i as g,n as w}from"./cache-D_LOBxSY.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:url";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"zod";const h="https://cache.mobileboost.io";function m(){const e=f.join(process.cwd(),"mobileboost.config.json");if(!c.existsSync(e))throw new Error("mobileboost.config.json not found");const t=c.readFileSync(e,"utf-8");return JSON.parse(t)}function u(e,t,a,r,o,n){const s=n?`${n.width}x${n.height}`:"",i=`${e}${t||""}${a}${r}${o||""}${s}`;return l.createHash("sha256").update(i).digest("hex")}function y(e){const t=atob(e.replace(/^data:image\/\w+;base64,/,"")),a=new ArrayBuffer(t.length),r=new Uint8Array(a);for(let o=0;o<t.length;o++)r[o]=t.charCodeAt(o);return new Blob([a],{type:"image/png"})}const x=p("fcbe7e11d05240fa28a1dd79ec8c395f6c03682edbaeb19f469bd78d6399cdde",(e,t)=>_.__executeServer(e,t)),_=d({method:"POST"}).inputValidator(e=>w.parse(e)).handler(x,async({data:e})=>{try{const t=m().apiKey;if(!t)throw new Error("API Key missing");const a=u(t,e.filepath,e.stepNumber,e.stepDescription,e.platform,e.screenResolution),r=e.screenshot.replace(/^data:image\/\w+;base64,/,""),o=`tap on x=${e.interactionCoordinates.x} y=${e.interactionCoordinates.y}`,n=[{screenshot:r,commands:[o]}],s=await fetch(`${h}/populate-cache?hash=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});return s.ok?{success:!0}:(console.error("Failed to populate cache:",await s.text()),{success:!1})}catch(t){return console.error("Error populating cache:",t),{success:!1,error:String(t)}}}),S=p("7d2aacaab26ab11cdc66f03a4ed01b8b38186abf16ab1f9306801ea7769aaa2a",(e,t)=>$.__executeServer(e,t)),$=d({method:"POST"}).inputValidator(e=>b.parse(e)).handler(S,async({data:e})=>{try{const t=m().apiKey;if(!t)throw new Error("API Key missing");const a=u(t,e.filepath,e.stepNumber,e.stepDescription,e.platform,e.screenResolution),r=new FormData;r.append("hash",a),r.append("screenshot",y(e.screenshot),"screenshot.png"),e.highest_used_index!==void 0&&e.highest_used_index!==null&&r.append("highest_used_index",String(e.highest_used_index));const o=await fetch(`${h}/execute-from-cache`,{method:"POST",body:r});if(!o.ok){const i=await o.text();return console.warn("Cache lookup failed:",i),{found:!1}}const n=await o.json(),s=g.safeParse(n);return s.success?s.data:(console.error("Invalid cache response:",n),{found:!1})}catch(t){return console.error("Error executing from cache:",t),{found:!1,error:String(t)}}});export{S as executeFromCacheMutation_createServerFn_handler,x as populateCacheMutation_createServerFn_handler};
@@ -1 +0,0 @@
1
- import{c as o,a as i}from"./server.mjs";import{x as m,I as p}from"./ai-client-BtI1TeHN.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:fs";import"node:url";import"node:path";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"zod";import"sharp";const e=o("f8084cb106c8126bb2deaeef7c98992d9ff9475ad3dc85c6ced04f08c3962b6e",(r,t)=>a.__executeServer(r,t)),a=i({method:"POST"}).inputValidator(m).handler(e,async({data:r})=>({description:await p(r)}));export{e as describeInteractionFn_createServerFn_handler};
@@ -1 +0,0 @@
1
- import{z as t}from"zod";import{r as o,c as a,m as d,a as n,t as p,o as r,i}from"./step-CEQtT3SD.mjs";const e=t.object({platform:t.enum(["android","ios"]).optional().default("android"),deviceId:t.string().optional()}),x=p.extend(e.shape),h=r.extend(e.shape),c=a.extend(e.shape),l=n.extend(e.shape),f=d.extend(e.shape),u=o.extend(e.shape);i.extend(e.shape);t.object({mode:t.enum(["adb","appium"])});export{u as A,h as d,e,x as h,c as l,l as r,f as x};
@@ -1 +0,0 @@
1
- import{c as s,a as d}from"./server.mjs";import n from"node:path";import o from"fs-extra";import{z as a}from"zod";import{j as w}from"./stores-C1dCcTeV.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:fs";import"node:url";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"@tanstack/react-store";import"./step-CEQtT3SD.mjs";async function p(){const e=n.join(process.cwd(),"mobileboost.config.json");let t="./tests";if(await o.pathExists(e))try{const r=await o.readJSON(e);r.testDir&&(t=r.testDir)}catch(r){console.error("Error reading config, using default testDir",r)}return n.resolve(process.cwd(),t)}async function h(e){const t=await p(),r=n.resolve(t,e);if(!r.startsWith(t))throw new Error("Invalid path: must be within test directory");return r}a.object({name:a.string(),type:a.enum(["file","directory"]),path:a.string()});const u=s("00fb1fe03e9689cf8c179ba0d5cadc5eeaa6879def224ac38037d70a1a51300d",(e,t)=>b.__executeServer(e,t)),b=d({method:"GET"}).handler(u,async()=>{const e=await p();await o.ensureDir(e);async function t(r){let i=[];const f=await o.readdir(r,{withFileTypes:!0});for(const c of f){const l=n.join(r,c.name),m=n.relative(e,l);c.isDirectory()?(i.push({name:c.name,type:"directory",path:m}),i=i.concat(await t(l))):i.push({name:c.name,type:"file",path:m})}return i}return{files:await t(e)}}),v=a.object({name:a.string(),type:a.enum(["file","directory"]),parentPath:a.string().optional()}),y=s("ac7bf7f1d727949cd28713a8f36bb77e7bd8fc0e48854ed8cb1ee93ce80fb6d0",(e,t)=>_.__executeServer(e,t)),_=d({method:"POST"}).inputValidator(v).handler(y,async({data:e})=>{const t=await p(),r=e.parentPath?n.join(t,e.parentPath):t;if(!n.resolve(r).startsWith(t))throw new Error("Invalid parent path");const i=n.join(r,e.name);if(e.type==="directory")await o.ensureDir(i);else{if(await o.pathExists(i))throw new Error("File already exists");await o.writeJSON(i,[],{spaces:2})}return{success:!0}}),F=a.object({path:a.string()}),S=s("b41e844ce533c224e7c720e69d821468deffcbf208fc008a7f5af83cb0596b15",(e,t)=>g.__executeServer(e,t)),g=d({method:"POST"}).inputValidator(F).handler(S,async({data:e})=>{const t=await h(e.path);try{return{content:await o.readJSON(t),path:e.path}}catch(r){throw console.error("Failed to read file",r),new Error("Failed to read file or invalid format")}}),P=a.object({path:a.string(),content:w}),j=s("1b2a0d276d9ce90b2a1d72134c1bf95b9f6b7b049a8f415e8f0da3e6fc5ce4ae",(e,t)=>x.__executeServer(e,t)),x=d({method:"POST"}).inputValidator(P).handler(j,async({data:e})=>{const t=await h(e.path);return await o.writeJSON(t,e.content,{spaces:2}),{success:!0}}),E=a.object({oldPath:a.string(),newPath:a.string()}),O=s("098d52adf25ea567d43facba347871f887828c6ab804021bbfa0f2759209c0c6",(e,t)=>D.__executeServer(e,t)),D=d({method:"POST"}).inputValidator(E).handler(O,async({data:e})=>{const t=await h(e.oldPath),r=await p(),i=n.resolve(r,e.newPath);if(!i.startsWith(r))throw new Error("Invalid new path");return await o.rename(t,i),{success:!0}}),T=a.object({sourcePath:a.string(),targetPath:a.string()}),V=s("efbbc22c41cf491631b07076417c9ec65d5ac71debfcc00b5a7e0d368772104f",(e,t)=>N.__executeServer(e,t)),N=d({method:"POST"}).inputValidator(T).handler(V,async({data:e})=>{const t=await h(e.sourcePath),r=await p(),i=n.resolve(r,e.targetPath);if(!i.startsWith(r))throw new Error("Invalid target path");await o.ensureDir(i);const f=n.basename(t),c=n.join(i,f);return await o.move(t,c,{overwrite:!1}),{success:!0}});export{y as createFileFn_createServerFn_handler,u as fetchFilesFn_createServerFn_handler,V as moveFileFn_createServerFn_handler,S as readFileFn_createServerFn_handler,O as renameFileFn_createServerFn_handler,j as saveFileFn_createServerFn_handler};
@@ -1 +0,0 @@
1
- import{c as d,a as m}from"./server.mjs";import{i as u,n as f}from"./step-CEQtT3SD.mjs";import{getPageSource as c}from"./appium-client-D-NjeB35.mjs";import{h as s,a as p,c as $,$ as g,i as h,m as I}from"./hierarchy-helpers-DF8QSYE6.mjs";import"@tanstack/history";import"@tanstack/router-core/ssr/client";import"@tanstack/router-core";import"node:async_hooks";import"@tanstack/router-core/ssr/server";import"../../index.mjs";import"node:http";import"node:stream";import"node:https";import"node:http2";import"node:fs";import"node:url";import"node:path";import"tiny-invariant";import"seroval";import"react/jsx-runtime";import"@tanstack/react-router/ssr/server";import"@tanstack/react-router";import"zod";import"webdriverio";import"xml2js";const x=d("05faf0772038a170c70083fd8de4a8b77a40e4ec46e0bbf6878670f02621b5df",(e,r)=>b.__executeServer(e,r)),b=m({method:"POST"}).inputValidator(f).handler(x,async({data:e})=>{console.log(`Getting element ID at ${e.x}, ${e.y}`);const r=await c(),i=(await s(r))?.hierarchy?.node?.[0];if(!i)return console.log("No root node found in hierarchy"),{elementId:""};const t=h(i,e.x,e.y);if(!t)return console.log("No element found at coordinates"),{elementId:""};if(t.$&&t.$["resource-id"]?.trim()){let o=t.$["resource-id"];const l=I(i,t,o);return l>=0?(o=`${o}[${l}]`,console.log(`Found duplicate IDs, using indexed ID: ${o}`)):console.log("Found unique element ID:",o),{elementId:o}}return console.log("Element found but has no resource-id"),{elementId:""}}),y=d("9bcbf5303827d2a25f347c2054b0121655a82322fa07108653f43246875348f7",(e,r)=>S.__executeServer(e,r)),S=m({method:"POST"}).inputValidator(u).handler(y,async({data:e})=>{console.log(`Looking for element with ID: ${e.elementId}`);const r=await c(),i=(await s(r))?.hierarchy?.node?.[0];if(!i)return{found:!1};let t=e.elementId,o=null;const l=e.elementId.match(/^(.+)\[(\d+)\]$/);l&&(t=l[1],o=parseInt(l[2]),console.log(`Parsed indexed ID: base="${t}", index=${o}`));let a=null;if(o!==null){const n=p(i,t);o<n.length&&(a=n[o],console.log(`Found element at index ${o}`))}else a=$(i,e.elementId);if(a){const n=g(a);if(n)return console.log(`Found element at center: ${n.x}, ${n.y}`),{found:!0,x:n.x,y:n.y}}return console.log("Element not found or no bounds"),{found:!1}});export{y as findElementByIdFn_createServerFn_handler,x as getElementIdFn_createServerFn_handler};
@@ -1 +0,0 @@
1
- import f from"xml2js";async function $(n){return new Promise((r,e)=>{f.parseString(n,(t,o)=>{t?e(t):r(o)})})}function s(n){if(!n)return null;const r=n.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);return r?{x1:parseInt(r[1]),y1:parseInt(r[2]),x2:parseInt(r[3]),y2:parseInt(r[4])}:null}function i(n,r,e){if(!n)return null;if(n.$&&n.$.bounds){const o=s(n.$.bounds);if(o&&(r<o.x1||r>o.x2||e<o.y1||e>o.y2))return null}let t=null;if(n.node)for(const o of n.node){const u=i(o,r,e);u&&(t=u)}return t??n}function c(n,r){if(!n)return null;if(n.$&&n.$["resource-id"]===r)return n;if(n.node)for(const e of n.node){const t=c(e,r);if(t)return t}return null}function l(n,r){if(!n)return null;const e=n.$?.text??"",t=n.$?.["content-desc"]??"";if(e&&e.toLowerCase().includes(r.toLowerCase())||t&&t.toLowerCase().includes(r.toLowerCase()))return n;if(n.node)for(const o of n.node){const u=l(o,r);if(u)return u}return null}function d(n,r){const e=[];function t(o){if(o&&(o.$&&o.$["resource-id"]===r&&e.push(o),o.node))for(const u of o.node)t(u)}return t(n),e}function x(n,r,e){const t=d(n,e);return t.length<=1?-1:t.indexOf(r)}function p(n){if(!n.$||!n.$.bounds)return null;const r=s(n.$.bounds);return r?{x:Math.round((r.x1+r.x2)/2),y:Math.round((r.y1+r.y2)/2)}:null}export{p as $,d as a,c,$ as h,i,l,x as m};