@vpxa/aikit 0.1.185 → 0.1.186
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/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{createHash as t,randomUUID as n}from"node:crypto";import{homedir as r}from"node:os";import{join as i}from"node:path";import{execFileSync as a}from"node:child_process";import{existsSync as o,readdirSync as s}from"node:fs";import{Buffer as c}from"node:buffer";import{z as l}from"zod";var u=class{#e;#t;#n=0;#r=0;constructor(e=200){if(!Number.isInteger(e)||e<1)throw RangeError(`CircularBuffer capacity must be a positive integer.`);this.#e=e,this.#t=Array(e)}push(e){this.#t[this.#n]=e,this.#n=(this.#n+1)%this.#e,this.#r<this.#e&&(this.#r+=1)}toArray(){if(this.#r===0)return[];let e=(this.#n-this.#r+this.#e)%this.#e,t=[];for(let n=0;n<this.#r;n+=1)t.push(this.#t[(e+n)%this.#e]);return t}clear(){this.#t=Array(this.#e),this.#n=0,this.#r=0}get size(){return this.#r}get capacity(){return this.#e}isEmpty(){return this.#r===0}};const d=[`xhr`,`fetch`,`websocket`,`document`],f=[/^authorization$/i,/^cookie$/i,/^set-cookie$/i,/^x-api-key$/i,/^x-access-token$/i,/^x-auth-token$/i,/^x-session$/i,/^x-secret$/i,/^x-password$/i,/^proxy-authorization$/i,/^www-authenticate$/i,/^x-csrf-token$/i,/^x-xsrf-token$/i];function p(e,t){if(t?.showSensitive)return{...e};let n=[...f,...t?.additionalPatterns??[]],r={};for(let[t,i]of Object.entries(e))r[t]=n.some(e=>e.test(t))?`[REDACTED]`:i;return r}function m(e,t=512){if(e)return e.length<=t?e:`${e.slice(0,t)}...[truncated]`}function ee(){return{networkBuffer:new u(200),consoleBuffer:new u(1e3),networkEnabled:!1,consoleEnabled:!1,networkFilter:{},nextRequestSequence:0,pendingRequests:new Map}}function te(e,t){if(e.capacity===t)return e;let n=new u(t),r=e.toArray(),i=Math.max(0,r.length-t);for(let e of r.slice(i))n.push(e);return n}function ne(e){switch(e){case`error`:case`info`:case`log`:case`debug`:return e;case`warning`:return`warn`;default:return`log`}}function re(e){if(e)return Buffer.byteLength(e)<=5242880?m(e):void 0}function ie(e){if(!e)return{};let t=Buffer.byteLength(e);return{bodySize:t,bodyPreview:t<=5242880?m(e):void 0}}function ae(e,t){return!t.resourceTypes.has(e.resourceType)||t.urlPattern&&!t.urlPattern.test(e.url)?!1:!t.excludeUrls.some(t=>t.test(e.url))}function h(e){if(e.length>200)throw Error(`Network filter regex patterns must be 200 characters or fewer`);try{let t=new RegExp(e);return t.test(`a`.repeat(100)),t}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Invalid network filter regex pattern: ${t}`)}}function g(e={}){return{resourceTypes:new Set(e.resourceTypes??d),urlPattern:e.urlPattern?h(e.urlPattern):void 0,excludeUrls:(e.excludeUrls??[]).map(e=>h(e))}}function oe(e){return e.nextRequestSequence+=1,`req-${e.nextRequestSequence}`}function se(e,t,n){let r={request:t,previous:e.pendingRequestTail};e.pendingRequestTail?e.pendingRequestTail.next=r:e.pendingRequestHead=r,e.pendingRequestTail=r,e.pendingRequests.set(t,{entry:n,node:r})}function _(e,t){t.previous?t.previous.next=t.next:e.pendingRequestHead=t.next,t.next?t.next.previous=t.previous:e.pendingRequestTail=t.previous,delete t.previous,delete t.next}function ce(e){for(;e.pendingRequests.size>e.networkBuffer.capacity;){let t=e.pendingRequestHead;if(!t)return;_(e,t),e.pendingRequests.delete(t.request)}}function v(e){e.pendingRequests.clear(),e.pendingRequestHead=void 0,e.pendingRequestTail=void 0}var le=class{states=new Map;getOrCreate(e){let t=this.states.get(e);if(t)return t;let n=ee();return this.states.set(e,n),n}get(e){return this.states.get(e)}remove(e){let t=this.states.get(e);t&&(t.networkEnabled=!1,t.consoleEnabled=!1,this.detachNetworkListeners(t),this.detachConsoleListeners(t),v(t),this.states.delete(e))}clear(){for(let e of this.states.values())e.networkEnabled=!1,e.consoleEnabled=!1,this.detachNetworkListeners(e),this.detachConsoleListeners(e),v(e);this.states.clear()}enableNetwork(e,t,n,r){let i=this.getOrCreate(e);i.networkEnabled&&this.disableNetwork(e,t),i.page=t,i.networkEnabled=!0,i.networkFilter=n?{...n}:{},i.compiledNetworkFilter=g(i.networkFilter),r?.bufferSize&&(i.networkBuffer=te(i.networkBuffer,r.bufferSize));let a=e=>{let t=i.compiledNetworkFilter??g(i.networkFilter),n={resourceType:e.resourceType(),url:e.url()};if(!ae(n,t))return;let a={...e.headers()},o=Date.now(),s={id:oe(i),url:n.url,method:e.method(),resourceType:n.resourceType,headers:r?.showSensitive?a:p(a),postData:r?.includeBody?re(e.postData()??void 0):void 0,timestamp:o};i.networkBuffer.push(s),se(i,e,s),ce(i)},o=async e=>{let t=e.request(),n=i.pendingRequests.get(t);if(!n)return;i.pendingRequests.delete(t),_(i,n.node);let a;if(r?.includeBody)try{a=ie(await e.text())}catch{a=void 0}let o={...e.headers()};n.entry.response={status:e.status(),statusText:e.statusText(),headers:r?.showSensitive?o:p(o),bodySize:a?.bodySize,bodyPreview:a?.bodyPreview,timing:Date.now()-n.entry.timestamp}};i.listenerRefs={...i.listenerRefs,requestHandler:a,responseHandler:o},this.ensurePageCloseHandler(e,i,t),t.on(`request`,a),t.on(`response`,o)}disableNetwork(e,t){let n=this.states.get(e);n&&(n.page=n.page??t,n.networkEnabled=!1,this.detachNetworkListeners(n),v(n))}enableConsole(e,t,n){let r=this.getOrCreate(e);r.consoleEnabled&&this.disableConsole(e,t),r.page=t,r.consoleEnabled=!0,n?.bufferSize&&(r.consoleBuffer=te(r.consoleBuffer,n.bufferSize));let i=e=>{let t=e.location();r.consoleBuffer.push({level:ne(e.type()),text:e.text(),timestamp:Date.now(),location:t.url?{url:t.url,line:t.lineNumber,column:t.columnNumber}:void 0,args:e.args().map(e=>e.toString())})};r.listenerRefs={...r.listenerRefs,consoleHandler:i},this.ensurePageCloseHandler(e,r,t),t.on(`console`,i)}disableConsole(e,t){let n=this.states.get(e);n&&(n.page=n.page??t,n.consoleEnabled=!1,this.detachConsoleListeners(n))}detachNetworkListeners(e){let t=e.page,n=e.listenerRefs?.requestHandler,r=e.listenerRefs?.responseHandler;t&&n&&t.off(`request`,n),t&&r&&t.off(`response`,r),e.listenerRefs&&(delete e.listenerRefs.requestHandler,delete e.listenerRefs.responseHandler),this.detachPageCloseHandlerIfUnused(e)}detachConsoleListeners(e){let t=e.page,n=e.listenerRefs?.consoleHandler;t&&n&&t.off(`console`,n),e.listenerRefs&&delete e.listenerRefs.consoleHandler,this.detachPageCloseHandlerIfUnused(e)}ensurePageCloseHandler(e,t,n){if(t.listenerRefs?.pageCloseHandler)return;let r=()=>{this.remove(e)};t.listenerRefs={...t.listenerRefs,pageCloseHandler:r},n.on(`close`,r)}detachPageCloseHandlerIfUnused(e){if(e.networkEnabled||e.consoleEnabled)return;let t=e.page,n=e.listenerRefs?.pageCloseHandler;t&&n&&t.off(`close`,n),e.listenerRefs&&delete e.listenerRefs.pageCloseHandler,e.listenerRefs&&!e.listenerRefs.requestHandler&&!e.listenerRefs.responseHandler&&!e.listenerRefs.consoleHandler&&!e.listenerRefs.pageCloseHandler&&delete e.listenerRefs}};let ue=null;function y(){return ue||=new le,ue}const de=e(import.meta.url);function fe(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function pe(e){process.env.PLAYWRIGHT_BROWSERS_PATH=e}async function me(e){pe(e);let{chromium:t}=await import(`playwright-core`),n=t.executablePath();if(!n)throw Error(`Chromium executable not found in ${e}`);return n}function he(){return i(r(),`.aikit`,`browsers`)}function b(e){return e.browsersPath??process.env.PLAYWRIGHT_BROWSERS_PATH??he()}function x(e){return o(e)?s(e,{withFileTypes:!0}).some(e=>e.isDirectory()&&e.name.toLowerCase().startsWith(`chromium-`)):!1}async function S(e,t){let n=b(e);if(pe(n),t?.(`Using Chromium cache at ${n}`),x(n))return t?.(`Chromium already installed`),me(n);let r=i(de.resolve(`playwright-core`),`..`,`cli.js`);t?.(`Installing Chromium via playwright-core`);try{a(process.execPath,[r,`install`,`chromium`],{env:{...process.env,PLAYWRIGHT_BROWSERS_PATH:n},encoding:`utf8`,stdio:`pipe`})}catch(e){let t=e,n=fe(t.stderr),r=fe(t.stdout),i=n||r||t.message||`Unknown playwright install failure`;throw Error(`Failed to install Chromium: ${i}`)}return t?.(`Chromium install complete`),me(n)}function C(){return process.platform===`win32`||process.platform===`darwin`?!0:!!(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)}function w(e){return e===`headless`||!C()?`headless`:e}function T(e){switch(e){case`headless`:return{headless:!0,args:[]};default:return{headless:!1,args:[]}}}var E=class{pages=new Map;registerPage(e,t,r,i){let a=n();return this.pages.set(a,{page:e,url:t,title:r,label:i,createdAt:new Date}),a}getPageByLabel(e){for(let t of this.pages.values())if(t.label===e)return t.page;throw Error(`Page not found: ${e}`)}resolvePageId(e){if(this.pages.has(e))return e;for(let[t,n]of this.pages.entries())if(n.label===e)return t;throw Error(`Page not found: ${e}`)}getPage(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return t.page}getPageInfo(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return{pageId:e,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}}setSnapshot(e,t){let n=this.pages.get(e);if(!n)throw Error(`Page not found: ${e}`);this.pages.set(e,{...n,lastSnapshot:t})}getSnapshot(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return t.lastSnapshot}updatePageInfo(e,t,n){let r=this.pages.get(e);if(!r)throw Error(`Page not found: ${e}`);this.pages.set(e,{...r,url:t,title:n})}async removePage(e){let t=this.pages.get(e);t&&(await t.page.close(),this.pages.delete(e))}listPages(){return[...this.pages.entries()].map(([e,t])=>({pageId:e,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}))}async closeAll(){await Promise.allSettled([...this.pages.keys()].map(async e=>this.removePage(e)))}get size(){return this.pages.size}};const D={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0};var O=class{browser=null;context=null;idleTimer=null;launchPromise=null;currentMode=null;session=new E;config;constructor(e={}){this.config={...D,...e}}async launch(e,t){let n=w(e??this.config.defaultMode);if(this.context&&this.currentMode!==n&&await this.close(),!this.context){if(this.launchPromise)return this.launchPromise;this.launchPromise=this.doLaunch(n,t);try{await this.launchPromise}finally{this.launchPromise=null}}}async doLaunch(e,n){if(this.browser&&this.context)return;let a=b(this.config);process.env.PLAYWRIGHT_BROWSERS_PATH=a;let{chromium:o}=await import(`playwright-core`),s=await S(this.config,n),c=T(e),l=t(`sha256`).update(process.cwd()).digest(`hex`).slice(0,12),u=i(this.config.userDataDirRoot??i(r(),`.aikit`,`profiles`),l);if(n?.(`Launching Chromium in ${e} mode`),this.context=await o.launchPersistentContext(u,{headless:c.headless,args:c.args,executablePath:s}),this.browser=this.context.browser(),!this.browser)throw await this.context.close(),this.context=null,Error(`Failed to acquire Chromium browser instance`);this.currentMode=e,this.browser.on(`disconnected`,()=>{this.browser=null,this.context=null,this.currentMode=null,y().clear(),this.session.closeAll().catch(()=>{}),this.stopIdleTimer()}),this.resetIdleTimer()}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}resetIdleTimer(){this.stopIdleTimer();let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);e.unref?.(),this.idleTimer=e}async close(){this.stopIdleTimer(),this.launchPromise=null;let e=this.context,t=this.browser;this.context=null,this.browser=null,this.currentMode=null;let n;try{y().clear()}catch(e){n=e}try{await this.session.closeAll()}catch(e){n??=e}try{e&&await e.close()}catch(e){n??=e}finally{try{t&&await t.close()}catch(e){n??=e}}if(n)throw n}getContext(){if(!this.context)throw Error(`Browser not launched. Call launch() first.`);return this.context}getConfig(){return this.config}isLaunched(){return this.browser!==null}};let k=null;function A(e){return k||=new O(e),k}async function ge(){k&&=(await k.close(),null)}const _e=[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`],ve=[`169.254.169.254`,`metadata.google.internal`,`metadata.google.com`],j=[`localhost`,`127.0.0.1`,`::1`,`[::1]`];function ye(e){return e.replace(/^\[(.*)\]$/,`$1`).toLowerCase()}function be(e){let t=new WeakSet,n=JSON.stringify(e,(e,n)=>{if(typeof n==`bigint`)return n.toString();if(typeof n==`function`)return`[Function ${n.name||`anonymous`}]`;if(typeof n==`symbol`)return n.toString();if(n instanceof Error)return{name:n.name,message:n.message,stack:n.stack};if(typeof n==`object`&&n){if(t.has(n))return`[Circular]`;t.add(n)}return n});return n===void 0?e===void 0?`undefined`:String(e):n}function xe(e,t){let n=c.from(e,`utf8`);return n.byteLength<=t?e:n.subarray(0,t).toString(`utf8`)}function M(e,t){let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`Invalid URL: ${e}`}}let r=n.protocol.toLowerCase();if(_e.includes(r)&&!t.allowInternalSchemes)return{allowed:!1,reason:`Blocked URL scheme: ${r}`};let i=ye(n.hostname);return ve.includes(i)?{allowed:!1,reason:`Blocked host: ${n.hostname}`}:(j.includes(i)||j.includes(n.hostname),{allowed:!0})}function N(e){return e?{allowed:!0}:{allowed:!1,reason:`Cookie access requires explicit confirmation (confirm: true)`}}function P(e,t){if(t<=0)return{valid:!1,reason:`maxBytes must be greater than 0`};try{let n=be(e);return c.byteLength(n,`utf8`)<=t?{valid:!0,result:n,truncated:!1}:{valid:!0,result:`${xe(n,Math.max(t-3,0))}...`,truncated:!0,reason:`Result exceeded ${t} bytes and was truncated`}}catch(e){return{valid:!1,reason:`Unable to serialize eval result: ${e instanceof Error?e.message:String(e)}`}}}function Se(e){return e.replace(/<input\b[^>]*>/gi,e=>/\btype\s*=\s*(["'])password\1/i.test(e)?/\bvalue\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i.test(e)?e.replace(/\bvalue\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i,`value="***"`):e.replace(/\s*\/?>$/,e=>` value="***"${e}`):e)}const Ce=[`ui`,`headless`];function we(e){return typeof e==`object`&&e?e:null}function F(e){return typeof e==`string`&&e.length>0?e:void 0}function I(e){return typeof e==`boolean`?e:void 0}function L(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function R(e){return typeof e==`string`&&Ce.includes(e)?e:void 0}function z(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function Te(e){let t=we(e.browser)??{};return{...D,defaultMode:R(process.env.AIKIT_BROWSER_DEFAULT_MODE)??R(t.defaultMode)??D.defaultMode,browsersPath:F(process.env.AIKIT_BROWSER_PATH)??F(process.env.AIKIT_BROWSER_BROWSERS_PATH)??F(t.browsersPath)??D.browsersPath,userDataDirRoot:F(t.userDataDirRoot)??D.userDataDirRoot,idleShutdownMinutes:z(`AIKIT_BROWSER_IDLE_MINUTES`)??L(t.idleShutdownMinutes)??D.idleShutdownMinutes,allowInternalSchemes:I(t.allowInternalSchemes)??D.allowInternalSchemes,evalTimeoutMs:z(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??L(t.evalTimeoutMs)??D.evalTimeoutMs,evalMaxResultBytes:L(t.evalMaxResultBytes)??D.evalMaxResultBytes,redactPasswordFieldsInScreenshots:I(t.redactPasswordFieldsInScreenshots)??D.redactPasswordFieldsInScreenshots}}function B(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function V(e,t){let n=e.selector??e.ref??(e.element?`text=${e.element}`:void 0);if(!n)throw Error(`${t} requires selector, ref, or element`);return n}async function Ee(e,t,n){let r=null;try{return await Promise.race([e,new Promise((e,i)=>{r=setTimeout(()=>{i(Error(`${n} timed out after ${t}ms`))},t)})])}finally{r&&clearTimeout(r)}}l.string().describe(`Tracked browser page identifier`),l.enum([`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`]).describe(`Interaction kind: click, type, press, hover, drag, select, scroll, upload`),l.string().optional().describe(`Target ref alias`),l.string().optional().describe(`Playwright selector`),l.string().optional().describe(`Human-readable element label`),l.string().optional().describe(`Text to type`),l.string().optional().describe(`Key to press`),l.string().optional().describe(`Option value, drag target, scroll spec, or file path(s)`),l.string().optional().describe(`Drag source ref`),l.string().optional().describe(`Drag source selector`),l.string().optional().describe(`Drag target ref`),l.string().optional().describe(`Drag target selector`);function De(e){return async({pageId:t,kind:n,ref:r,selector:i,element:a,text:o,key:s,value:c,fromRef:l,fromSelector:u,toRef:d,toSelector:f})=>{let p=A(e),m=p.session.getPage(t);switch(n){case`click`:{let e=V({ref:r,selector:i,element:a},`browser_act(click)`);await m.click(e);break}case`type`:{let e=V({ref:r,selector:i,element:a},`browser_act(type)`);await m.fill(e,o??``);break}case`press`:{let e=V({ref:r,selector:i,element:a},`browser_act(press)`);if(!s)throw Error(`browser_act(press) requires key`);await m.press(e,s);break}case`hover`:{let e=V({ref:r,selector:i,element:a},`browser_act(hover)`);await m.hover(e);break}case`drag`:{let e=V({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=V({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await m.dragAndDrop(e,t);break}case`select`:{let e=V({ref:r,selector:i,element:a},`browser_act(select)`);if(c===void 0)throw Error(`browser_act(select) requires value`);await m.selectOption(e,c);break}case`scroll`:{if(i||r||a){let e=V({ref:r,selector:i,element:a},`browser_act(scroll)`);await m.locator(e).scrollIntoViewIfNeeded();break}let e=c??`down 500`;await m.evaluate(e=>{if(e===`bottom`){window.scrollTo(0,document.body.scrollHeight);return}if(e===`top`){window.scrollTo(0,0);return}let t=e.split(` `),n=t[0]||`down`,r=Number.parseInt(t[1]||`500`,10),i=n===`left`?-r:n===`right`?r:0,a=n===`up`?-r:n===`down`?r:0;window.scrollBy(i,a)},e);break}case`upload`:{let e=V({ref:r,selector:i,element:a},`browser_act(upload)`);if(!c)throw Error(`value (file path or JSON array of paths) required for upload`);let t;try{let e=JSON.parse(c);t=Array.isArray(e)?e:[c]}catch{t=[c]}await m.locator(e).setInputFiles(t);break}}return p.resetIdleTimer(),B(`ok`,{ok:!0})}}function Oe(e,t){return t?e.filter(e=>e.level===t):e}function ke(e){return e.map(e=>{let t=e.location?` (${e.location.url}:${e.location.line})`:``;return`[${e.level.toUpperCase()}] ${e.text}${t}`}).join(`
|
|
1
|
+
import{createRequire as e}from"node:module";import{createHash as t,randomUUID as n}from"node:crypto";import{homedir as r}from"node:os";import{join as i}from"node:path";import{execFileSync as a}from"node:child_process";import{existsSync as o,readdirSync as s}from"node:fs";import{Buffer as c}from"node:buffer";import{z as l}from"zod";var u=class{#e;#t;#n=0;#r=0;constructor(e=200){if(!Number.isInteger(e)||e<1)throw RangeError(`CircularBuffer capacity must be a positive integer.`);this.#e=e,this.#t=Array(e)}push(e){this.#t[this.#n]=e,this.#n=(this.#n+1)%this.#e,this.#r<this.#e&&(this.#r+=1)}toArray(){if(this.#r===0)return[];let e=(this.#n-this.#r+this.#e)%this.#e,t=[];for(let n=0;n<this.#r;n+=1)t.push(this.#t[(e+n)%this.#e]);return t}clear(){this.#t=Array(this.#e),this.#n=0,this.#r=0}get size(){return this.#r}get capacity(){return this.#e}isEmpty(){return this.#r===0}};const d=[`xhr`,`fetch`,`websocket`,`document`],f=[/^authorization$/i,/^cookie$/i,/^set-cookie$/i,/^x-api-key$/i,/^x-access-token$/i,/^x-auth-token$/i,/^x-session$/i,/^x-secret$/i,/^x-password$/i,/^proxy-authorization$/i,/^www-authenticate$/i,/^x-csrf-token$/i,/^x-xsrf-token$/i];function p(e,t){if(t?.showSensitive)return{...e};let n=[...f,...t?.additionalPatterns??[]],r={};for(let[t,i]of Object.entries(e))r[t]=n.some(e=>e.test(t))?`[REDACTED]`:i;return r}function m(e,t=512){if(e)return e.length<=t?e:`${e.slice(0,t)}...[truncated]`}function ee(){return{networkBuffer:new u(200),consoleBuffer:new u(1e3),networkEnabled:!1,consoleEnabled:!1,networkFilter:{},nextRequestSequence:0,pendingRequests:new Map}}function te(e,t){if(e.capacity===t)return e;let n=new u(t),r=e.toArray(),i=Math.max(0,r.length-t);for(let e of r.slice(i))n.push(e);return n}function ne(e){switch(e){case`error`:case`info`:case`log`:case`debug`:return e;case`warning`:return`warn`;default:return`log`}}function re(e){if(e)return Buffer.byteLength(e)<=5242880?m(e):void 0}function ie(e){if(!e)return{};let t=Buffer.byteLength(e);return{bodySize:t,bodyPreview:t<=5242880?m(e):void 0}}function ae(e,t){return!t.resourceTypes.has(e.resourceType)||t.urlPattern&&!t.urlPattern.test(e.url)?!1:!t.excludeUrls.some(t=>t.test(e.url))}function h(e){if(e.length>200)throw Error(`Network filter regex patterns must be 200 characters or fewer`);try{let t=new RegExp(e);return t.test(`a`.repeat(100)),t}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Invalid network filter regex pattern: ${t}`)}}function g(e={}){return{resourceTypes:new Set(e.resourceTypes??d),urlPattern:e.urlPattern?h(e.urlPattern):void 0,excludeUrls:(e.excludeUrls??[]).map(e=>h(e))}}function oe(e){return e.nextRequestSequence+=1,`req-${e.nextRequestSequence}`}function se(e,t,n){let r={request:t,previous:e.pendingRequestTail};e.pendingRequestTail?e.pendingRequestTail.next=r:e.pendingRequestHead=r,e.pendingRequestTail=r,e.pendingRequests.set(t,{entry:n,node:r})}function _(e,t){t.previous?t.previous.next=t.next:e.pendingRequestHead=t.next,t.next?t.next.previous=t.previous:e.pendingRequestTail=t.previous,delete t.previous,delete t.next}function ce(e){for(;e.pendingRequests.size>e.networkBuffer.capacity;){let t=e.pendingRequestHead;if(!t)return;_(e,t),e.pendingRequests.delete(t.request)}}function v(e){e.pendingRequests.clear(),e.pendingRequestHead=void 0,e.pendingRequestTail=void 0}var le=class{states=new Map;getOrCreate(e){let t=this.states.get(e);if(t)return t;let n=ee();return this.states.set(e,n),n}get(e){return this.states.get(e)}remove(e){let t=this.states.get(e);t&&(t.networkEnabled=!1,t.consoleEnabled=!1,this.detachNetworkListeners(t),this.detachConsoleListeners(t),v(t),this.states.delete(e))}clear(){for(let e of this.states.values())e.networkEnabled=!1,e.consoleEnabled=!1,this.detachNetworkListeners(e),this.detachConsoleListeners(e),v(e);this.states.clear()}enableNetwork(e,t,n,r){let i=this.getOrCreate(e);i.networkEnabled&&this.disableNetwork(e,t),i.page=t,i.networkEnabled=!0,i.networkFilter=n?{...n}:{},i.compiledNetworkFilter=g(i.networkFilter),r?.bufferSize&&(i.networkBuffer=te(i.networkBuffer,r.bufferSize));let a=e=>{let t=i.compiledNetworkFilter??g(i.networkFilter),n={resourceType:e.resourceType(),url:e.url()};if(!ae(n,t))return;let a={...e.headers()},o=Date.now(),s={id:oe(i),url:n.url,method:e.method(),resourceType:n.resourceType,headers:r?.showSensitive?a:p(a),postData:r?.includeBody?re(e.postData()??void 0):void 0,timestamp:o};i.networkBuffer.push(s),se(i,e,s),ce(i)},o=async e=>{let t=e.request(),n=i.pendingRequests.get(t);if(!n)return;i.pendingRequests.delete(t),_(i,n.node);let a;if(r?.includeBody)try{a=ie(await e.text())}catch{a=void 0}let o={...e.headers()};n.entry.response={status:e.status(),statusText:e.statusText(),headers:r?.showSensitive?o:p(o),bodySize:a?.bodySize,bodyPreview:a?.bodyPreview,timing:Date.now()-n.entry.timestamp}};i.listenerRefs={...i.listenerRefs,requestHandler:a,responseHandler:o},this.ensurePageCloseHandler(e,i,t),t.on(`request`,a),t.on(`response`,o)}disableNetwork(e,t){let n=this.states.get(e);n&&(n.page=n.page??t,n.networkEnabled=!1,this.detachNetworkListeners(n),v(n))}enableConsole(e,t,n){let r=this.getOrCreate(e);r.consoleEnabled&&this.disableConsole(e,t),r.page=t,r.consoleEnabled=!0,n?.bufferSize&&(r.consoleBuffer=te(r.consoleBuffer,n.bufferSize));let i=e=>{let t=e.location();r.consoleBuffer.push({level:ne(e.type()),text:e.text(),timestamp:Date.now(),location:t.url?{url:t.url,line:t.lineNumber,column:t.columnNumber}:void 0,args:e.args().map(e=>e.toString())})};r.listenerRefs={...r.listenerRefs,consoleHandler:i},this.ensurePageCloseHandler(e,r,t),t.on(`console`,i)}disableConsole(e,t){let n=this.states.get(e);n&&(n.page=n.page??t,n.consoleEnabled=!1,this.detachConsoleListeners(n))}detachNetworkListeners(e){let t=e.page,n=e.listenerRefs?.requestHandler,r=e.listenerRefs?.responseHandler;t&&n&&t.off(`request`,n),t&&r&&t.off(`response`,r),e.listenerRefs&&(delete e.listenerRefs.requestHandler,delete e.listenerRefs.responseHandler),this.detachPageCloseHandlerIfUnused(e)}detachConsoleListeners(e){let t=e.page,n=e.listenerRefs?.consoleHandler;t&&n&&t.off(`console`,n),e.listenerRefs&&delete e.listenerRefs.consoleHandler,this.detachPageCloseHandlerIfUnused(e)}ensurePageCloseHandler(e,t,n){if(t.listenerRefs?.pageCloseHandler)return;let r=()=>{this.remove(e)};t.listenerRefs={...t.listenerRefs,pageCloseHandler:r},n.on(`close`,r)}detachPageCloseHandlerIfUnused(e){if(e.networkEnabled||e.consoleEnabled)return;let t=e.page,n=e.listenerRefs?.pageCloseHandler;t&&n&&t.off(`close`,n),e.listenerRefs&&delete e.listenerRefs.pageCloseHandler,e.listenerRefs&&!e.listenerRefs.requestHandler&&!e.listenerRefs.responseHandler&&!e.listenerRefs.consoleHandler&&!e.listenerRefs.pageCloseHandler&&delete e.listenerRefs}};let ue=null;function y(){return ue||=new le,ue}const de=e(import.meta.url);function fe(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function pe(e){process.env.PLAYWRIGHT_BROWSERS_PATH=e}async function me(e){pe(e);let{chromium:t}=await import(`playwright-core`),n=t.executablePath();if(!n)throw Error(`Chromium executable not found in ${e}`);return n}function he(){return i(r(),`.aikit`,`browsers`)}function b(e){return e.browsersPath??process.env.PLAYWRIGHT_BROWSERS_PATH??he()}function x(e){return o(e)?s(e,{withFileTypes:!0}).some(e=>e.isDirectory()&&e.name.toLowerCase().startsWith(`chromium-`)):!1}async function S(e,t){let n=b(e);if(pe(n),t?.(`Using Chromium cache at ${n}`),x(n))return t?.(`Chromium already installed`),me(n);let r=i(de.resolve(`playwright-core`),`..`,`cli.js`);t?.(`Installing Chromium via playwright-core`);try{a(process.execPath,[r,`install`,`chromium`],{env:{...process.env,PLAYWRIGHT_BROWSERS_PATH:n},encoding:`utf8`,stdio:`pipe`})}catch(e){let t=e,n=fe(t.stderr),r=fe(t.stdout),i=n||r||t.message||`Unknown playwright install failure`;throw Error(`Failed to install Chromium: ${i}`)}return t?.(`Chromium install complete`),me(n)}function C(){return process.platform===`win32`||process.platform===`darwin`?!0:!!(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)}function w(e){return e===`headless`||!C()?`headless`:e}function T(e){switch(e){case`headless`:return{headless:!0,args:[]};default:return{headless:!1,args:[]}}}var E=class{pages=new Map;registerPage(e,t,r,i){let a=n();return this.pages.set(a,{page:e,url:t,title:r,label:i,createdAt:new Date}),a}getPageByLabel(e){for(let t of this.pages.values())if(t.label===e)return t.page;throw Error(`Page not found: ${e}`)}resolvePageId(e){if(this.pages.has(e))return e;for(let[t,n]of this.pages.entries())if(n.label===e)return t;throw Error(`Page not found: ${e}`)}getPage(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return t.page}getPageInfo(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return{pageId:e,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}}setSnapshot(e,t){let n=this.pages.get(e);if(!n)throw Error(`Page not found: ${e}`);this.pages.set(e,{...n,lastSnapshot:t})}getSnapshot(e){let t=this.pages.get(e);if(!t)throw Error(`Page not found: ${e}`);return t.lastSnapshot}updatePageInfo(e,t,n){let r=this.pages.get(e);if(!r)throw Error(`Page not found: ${e}`);this.pages.set(e,{...r,url:t,title:n})}async removePage(e){let t=this.pages.get(e);t&&(await t.page.close(),this.pages.delete(e))}listPages(){return[...this.pages.entries()].map(([e,t])=>({pageId:e,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}))}async closeAll(){await Promise.allSettled([...this.pages.keys()].map(async e=>this.removePage(e)))}get size(){return this.pages.size}};const D={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0};var O=class{browser=null;context=null;idleTimer=null;launchPromise=null;currentMode=null;session=new E;config;constructor(e={}){this.config={...D,...e}}async launch(e,t){let n=w(e??this.config.defaultMode);if(this.context&&this.currentMode!==n&&await this.close(),!this.context){if(this.launchPromise)return this.launchPromise;this.launchPromise=this.doLaunch(n,t);try{await this.launchPromise}finally{this.launchPromise=null}}}async doLaunch(e,n){if(this.browser&&this.context)return;let a=b(this.config);process.env.PLAYWRIGHT_BROWSERS_PATH=a;let{chromium:o}=await import(`playwright-core`),s=await S(this.config,n),c=T(e),l=t(`sha256`).update(process.cwd()).digest(`hex`).slice(0,12),u=i(this.config.userDataDirRoot??i(r(),`.aikit`,`profiles`),l);if(n?.(`Launching Chromium in ${e} mode`),this.context=await o.launchPersistentContext(u,{headless:c.headless,args:c.args,executablePath:s,viewport:null}),this.browser=this.context.browser(),!this.browser)throw await this.context.close(),this.context=null,Error(`Failed to acquire Chromium browser instance`);this.currentMode=e,this.browser.on(`disconnected`,()=>{this.browser=null,this.context=null,this.currentMode=null,y().clear(),this.session.closeAll().catch(()=>{}),this.stopIdleTimer()}),this.resetIdleTimer()}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}resetIdleTimer(){this.stopIdleTimer();let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);e.unref?.(),this.idleTimer=e}async close(){this.stopIdleTimer(),this.launchPromise=null;let e=this.context,t=this.browser;this.context=null,this.browser=null,this.currentMode=null;let n;try{y().clear()}catch(e){n=e}try{await this.session.closeAll()}catch(e){n??=e}try{e&&await e.close()}catch(e){n??=e}finally{try{t&&await t.close()}catch(e){n??=e}}if(n)throw n}getContext(){if(!this.context)throw Error(`Browser not launched. Call launch() first.`);return this.context}getConfig(){return this.config}isLaunched(){return this.browser!==null}};let k=null;function A(e){return k||=new O(e),k}async function ge(){k&&=(await k.close(),null)}const _e=[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`],ve=[`169.254.169.254`,`metadata.google.internal`,`metadata.google.com`],j=[`localhost`,`127.0.0.1`,`::1`,`[::1]`];function ye(e){return e.replace(/^\[(.*)\]$/,`$1`).toLowerCase()}function be(e){let t=new WeakSet,n=JSON.stringify(e,(e,n)=>{if(typeof n==`bigint`)return n.toString();if(typeof n==`function`)return`[Function ${n.name||`anonymous`}]`;if(typeof n==`symbol`)return n.toString();if(n instanceof Error)return{name:n.name,message:n.message,stack:n.stack};if(typeof n==`object`&&n){if(t.has(n))return`[Circular]`;t.add(n)}return n});return n===void 0?e===void 0?`undefined`:String(e):n}function xe(e,t){let n=c.from(e,`utf8`);return n.byteLength<=t?e:n.subarray(0,t).toString(`utf8`)}function M(e,t){let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`Invalid URL: ${e}`}}let r=n.protocol.toLowerCase();if(_e.includes(r)&&!t.allowInternalSchemes)return{allowed:!1,reason:`Blocked URL scheme: ${r}`};let i=ye(n.hostname);return ve.includes(i)?{allowed:!1,reason:`Blocked host: ${n.hostname}`}:(j.includes(i)||j.includes(n.hostname),{allowed:!0})}function N(e){return e?{allowed:!0}:{allowed:!1,reason:`Cookie access requires explicit confirmation (confirm: true)`}}function P(e,t){if(t<=0)return{valid:!1,reason:`maxBytes must be greater than 0`};try{let n=be(e);return c.byteLength(n,`utf8`)<=t?{valid:!0,result:n,truncated:!1}:{valid:!0,result:`${xe(n,Math.max(t-3,0))}...`,truncated:!0,reason:`Result exceeded ${t} bytes and was truncated`}}catch(e){return{valid:!1,reason:`Unable to serialize eval result: ${e instanceof Error?e.message:String(e)}`}}}function Se(e){return e.replace(/<input\b[^>]*>/gi,e=>/\btype\s*=\s*(["'])password\1/i.test(e)?/\bvalue\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i.test(e)?e.replace(/\bvalue\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i,`value="***"`):e.replace(/\s*\/?>$/,e=>` value="***"${e}`):e)}const Ce=[`ui`,`headless`];function we(e){return typeof e==`object`&&e?e:null}function F(e){return typeof e==`string`&&e.length>0?e:void 0}function I(e){return typeof e==`boolean`?e:void 0}function L(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function R(e){return typeof e==`string`&&Ce.includes(e)?e:void 0}function z(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function Te(e){let t=we(e.browser)??{};return{...D,defaultMode:R(process.env.AIKIT_BROWSER_DEFAULT_MODE)??R(t.defaultMode)??D.defaultMode,browsersPath:F(process.env.AIKIT_BROWSER_PATH)??F(process.env.AIKIT_BROWSER_BROWSERS_PATH)??F(t.browsersPath)??D.browsersPath,userDataDirRoot:F(t.userDataDirRoot)??D.userDataDirRoot,idleShutdownMinutes:z(`AIKIT_BROWSER_IDLE_MINUTES`)??L(t.idleShutdownMinutes)??D.idleShutdownMinutes,allowInternalSchemes:I(t.allowInternalSchemes)??D.allowInternalSchemes,evalTimeoutMs:z(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??L(t.evalTimeoutMs)??D.evalTimeoutMs,evalMaxResultBytes:L(t.evalMaxResultBytes)??D.evalMaxResultBytes,redactPasswordFieldsInScreenshots:I(t.redactPasswordFieldsInScreenshots)??D.redactPasswordFieldsInScreenshots}}function B(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function V(e,t){let n=e.selector??e.ref??(e.element?`text=${e.element}`:void 0);if(!n)throw Error(`${t} requires selector, ref, or element`);return n}async function Ee(e,t,n){let r=null;try{return await Promise.race([e,new Promise((e,i)=>{r=setTimeout(()=>{i(Error(`${n} timed out after ${t}ms`))},t)})])}finally{r&&clearTimeout(r)}}l.string().describe(`Tracked browser page identifier`),l.enum([`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`]).describe(`Interaction kind: click, type, press, hover, drag, select, scroll, upload`),l.string().optional().describe(`Target ref alias`),l.string().optional().describe(`Playwright selector`),l.string().optional().describe(`Human-readable element label`),l.string().optional().describe(`Text to type`),l.string().optional().describe(`Key to press`),l.string().optional().describe(`Option value, drag target, scroll spec, or file path(s)`),l.string().optional().describe(`Drag source ref`),l.string().optional().describe(`Drag source selector`),l.string().optional().describe(`Drag target ref`),l.string().optional().describe(`Drag target selector`);function De(e){return async({pageId:t,kind:n,ref:r,selector:i,element:a,text:o,key:s,value:c,fromRef:l,fromSelector:u,toRef:d,toSelector:f})=>{let p=A(e),m=p.session.getPage(t);switch(n){case`click`:{let e=V({ref:r,selector:i,element:a},`browser_act(click)`);await m.click(e);break}case`type`:{let e=V({ref:r,selector:i,element:a},`browser_act(type)`);await m.fill(e,o??``);break}case`press`:{let e=V({ref:r,selector:i,element:a},`browser_act(press)`);if(!s)throw Error(`browser_act(press) requires key`);await m.press(e,s);break}case`hover`:{let e=V({ref:r,selector:i,element:a},`browser_act(hover)`);await m.hover(e);break}case`drag`:{let e=V({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=V({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await m.dragAndDrop(e,t);break}case`select`:{let e=V({ref:r,selector:i,element:a},`browser_act(select)`);if(c===void 0)throw Error(`browser_act(select) requires value`);await m.selectOption(e,c);break}case`scroll`:{if(i||r||a){let e=V({ref:r,selector:i,element:a},`browser_act(scroll)`);await m.locator(e).scrollIntoViewIfNeeded();break}let e=c??`down 500`;await m.evaluate(e=>{if(e===`bottom`){window.scrollTo(0,document.body.scrollHeight);return}if(e===`top`){window.scrollTo(0,0);return}let t=e.split(` `),n=t[0]||`down`,r=Number.parseInt(t[1]||`500`,10),i=n===`left`?-r:n===`right`?r:0,a=n===`up`?-r:n===`down`?r:0;window.scrollBy(i,a)},e);break}case`upload`:{let e=V({ref:r,selector:i,element:a},`browser_act(upload)`);if(!c)throw Error(`value (file path or JSON array of paths) required for upload`);let t;try{let e=JSON.parse(c);t=Array.isArray(e)?e:[c]}catch{t=[c]}await m.locator(e).setInputFiles(t);break}}return p.resetIdleTimer(),B(`ok`,{ok:!0})}}function Oe(e,t){return t?e.filter(e=>e.level===t):e}function ke(e){return e.map(e=>{let t=e.location?` (${e.location.url}:${e.location.line})`:``;return`[${e.level.toUpperCase()}] ${e.text}${t}`}).join(`
|
|
2
2
|
`)}async function Ae(e,t){let n=y();switch(t.subAction){case`enable`:return n.enableConsole(t.pageId,e,{bufferSize:t.bufferSize}),B(`Console capture enabled for page ${t.pageId}`,{enabled:!0,bufferSize:t.bufferSize??1e3});case`get`:{let e=n.get(t.pageId);if(!e?.consoleEnabled)return B(`Console capture not enabled. Call with subAction: "enable" first.`,{enabled:!1,entries:[]});let r=Oe(e.consoleBuffer.toArray(),t.level);return B(ke(r)||`No console messages captured yet.`,{enabled:!0,count:r.length,entries:r})}case`clear`:{let e=n.get(t.pageId);return e&&e.consoleBuffer.clear(),B(`Console buffer cleared.`,{cleared:!0})}}}function je(e){return async t=>{let n=A(e),r=await Ae(n.session.getPage(t.pageId),t);return n.resetIdleTimer(),r}}l.string().describe(`Tracked browser page identifier`),l.boolean().describe(`Whether to accept the next dialog`),l.string().optional().describe(`Text to provide when accepting a prompt dialog`);function Me(e){return async({pageId:t,accept:n,promptText:r})=>{let i=A(e);return i.session.getPage(t).once(`dialog`,async e=>{n?await e.accept(r):await e.dismiss()}),i.resetIdleTimer(),B(`ok`,{ok:!0})}}function Ne(e){return async({pageId:t})=>{let n=A(e),r=await n.session.getPage(t).accessibility.snapshot()??{},i=JSON.stringify(r,null,2),a=n.session.getSnapshot(t);if(n.session.setSnapshot(t,i),n.resetIdleTimer(),!a)return B(`First snapshot captured (no previous to diff against).\n${i}`,{pageId:t,hasChanges:!1,isFirst:!0,snapshot:r});if(a===i)return B(`No changes detected.`,{pageId:t,hasChanges:!1});let o=a.split(`
|
|
3
3
|
`),s=i.split(`
|
|
4
4
|
`),c=new Set(o),l=new Set(s),u=s.filter(e=>!c.has(e)),d=o.filter(e=>!l.has(e)),f=u.length>0||d.length>0;return B([u.length>0?`Added:\n${u.join(`
|