@vpxa/aikit 0.1.143 → 0.1.144

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.143",
3
+ "version": "0.1.144",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -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";const u=e(import.meta.url);function d(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function f(e){process.env.PLAYWRIGHT_BROWSERS_PATH=e}async function p(e){f(e);let{chromium:t}=await import(`playwright-core`),n=t.executablePath();if(!n)throw Error(`Chromium executable not found in ${e}`);return n}function m(){return i(r(),`.aikit`,`browsers`)}function h(e){return e.browsersPath??process.env.PLAYWRIGHT_BROWSERS_PATH??m()}function g(e){return o(e)?s(e,{withFileTypes:!0}).some(e=>e.isDirectory()&&e.name.toLowerCase().startsWith(`chromium-`)):!1}async function _(e,t){let n=h(e);if(f(n),t?.(`Using Chromium cache at ${n}`),g(n))return t?.(`Chromium already installed`),p(n);let r=u.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=d(t.stderr),r=d(t.stdout),i=n||r||t.message||`Unknown playwright install failure`;throw Error(`Failed to install Chromium: ${i}`)}return t?.(`Chromium install complete`),p(n)}function v(){return process.platform===`win32`||process.platform===`darwin`?!0:!!(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)}function y(e){return e===`headless`||!v()?`headless`:e}function b(e){switch(e){case`headless`:return{headless:!0,args:[]};case`panel`:return{headless:!1,args:[`--app=data:text/html,<title>aikit</title>`]};default:return{headless:!1,args:[]}}}var x=class{pages=new Map;registerPage(e,t,r){let i=n();return this.pages.set(i,{page:e,url:t,title:r,createdAt:new Date}),i}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,createdAt:t.createdAt}}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,createdAt:t.createdAt}))}async closeAll(){await Promise.allSettled([...this.pages.keys()].map(async e=>this.removePage(e)))}get size(){return this.pages.size}};const S={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0};var C=class{browser=null;context=null;idleTimer=null;launchPromise=null;session=new x;config;constructor(e={}){this.config={...S,...e}}async launch(e,t){if(!this.context){if(this.launchPromise)return this.launchPromise;this.launchPromise=this.doLaunch(e,t);try{await this.launchPromise}finally{this.launchPromise=null}}}async doLaunch(e,n){if(this.browser&&this.context)return;let a=y(e??this.config.defaultMode),o=h(this.config);process.env.PLAYWRIGHT_BROWSERS_PATH=o;let{chromium:s}=await import(`playwright-core`),c=await _(this.config,n),l=b(a),u=t(`sha256`).update(process.cwd()).digest(`hex`).slice(0,12),d=i(this.config.userDataDirRoot??i(r(),`.aikit`,`profiles`),u);if(n?.(`Launching Chromium in ${a} mode`),this.context=await s.launchPersistentContext(d,{headless:l.headless,args:l.args,executablePath:c}),this.browser=this.context.browser(),!this.browser)throw await this.context.close(),this.context=null,Error(`Failed to acquire Chromium browser instance`);this.browser.on(`disconnected`,()=>{this.browser=null,this.context=null,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;let n;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 w=null;function T(e){return w||=new C(e),w}async function ee(){w&&=(await w.close(),null)}const te=[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`],ne=[`169.254.169.254`,`metadata.google.internal`,`metadata.google.com`],E=[`localhost`,`127.0.0.1`,`::1`,`[::1]`];function re(e){return e.replace(/^\[(.*)\]$/,`$1`).toLowerCase()}function ie(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 ae(e,t){let n=c.from(e,`utf8`);return n.byteLength<=t?e:n.subarray(0,t).toString(`utf8`)}function D(e,t){let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`Invalid URL: ${e}`}}let r=n.protocol.toLowerCase();if(te.includes(r)&&!t.allowInternalSchemes)return{allowed:!1,reason:`Blocked URL scheme: ${r}`};let i=re(n.hostname);return ne.includes(i)?{allowed:!1,reason:`Blocked host: ${n.hostname}`}:(E.includes(i)||E.includes(n.hostname),{allowed:!0})}function O(e){return e?{allowed:!0}:{allowed:!1,reason:`Cookie access requires explicit confirmation (confirm: true)`}}function k(e,t){if(t<=0)return{valid:!1,reason:`maxBytes must be greater than 0`};try{let n=ie(e);return c.byteLength(n,`utf8`)<=t?{valid:!0,result:n,truncated:!1}:{valid:!0,result:`${ae(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 oe(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 se=[`ui`,`headless`,`panel`];function ce(e){return typeof e==`object`&&e?e:null}function A(e){return typeof e==`string`&&e.length>0?e:void 0}function j(e){return typeof e==`boolean`?e:void 0}function M(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function N(e){return typeof e==`string`&&se.includes(e)?e:void 0}function P(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function le(e){let t=ce(e.browser)??{};return{...S,defaultMode:N(process.env.AIKIT_BROWSER_DEFAULT_MODE)??N(t.defaultMode)??S.defaultMode,browsersPath:A(process.env.AIKIT_BROWSER_PATH)??A(process.env.AIKIT_BROWSER_BROWSERS_PATH)??A(t.browsersPath)??S.browsersPath,userDataDirRoot:A(t.userDataDirRoot)??S.userDataDirRoot,idleShutdownMinutes:P(`AIKIT_BROWSER_IDLE_MINUTES`)??M(t.idleShutdownMinutes)??S.idleShutdownMinutes,allowInternalSchemes:j(t.allowInternalSchemes)??S.allowInternalSchemes,evalTimeoutMs:P(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??M(t.evalTimeoutMs)??S.evalTimeoutMs,evalMaxResultBytes:M(t.evalMaxResultBytes)??S.evalMaxResultBytes,redactPasswordFieldsInScreenshots:j(t.redactPasswordFieldsInScreenshots)??S.redactPasswordFieldsInScreenshots}}function F(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function I(e,t){let n=e.selector??e.ref;if(!n)throw Error(`${t} requires selector or ref`);return n}function ue(e){if(!e)return`empty snapshot`;let t=[],n=(e,r)=>{let i=[e.role??`node`];e.name&&i.push(e.name),e.value!==void 0&&i.push(`value=${String(e.value)}`),e.description&&i.push(`description=${e.description}`),t.push(`${` `.repeat(r)}${i.join(`: `)}`);for(let t of e.children??[])n(t,r+1)};return n(e,0),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";const u=e(import.meta.url);function d(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function f(e){process.env.PLAYWRIGHT_BROWSERS_PATH=e}async function p(e){f(e);let{chromium:t}=await import(`playwright-core`),n=t.executablePath();if(!n)throw Error(`Chromium executable not found in ${e}`);return n}function m(){return i(r(),`.aikit`,`browsers`)}function h(e){return e.browsersPath??process.env.PLAYWRIGHT_BROWSERS_PATH??m()}function g(e){return o(e)?s(e,{withFileTypes:!0}).some(e=>e.isDirectory()&&e.name.toLowerCase().startsWith(`chromium-`)):!1}async function _(e,t){let n=h(e);if(f(n),t?.(`Using Chromium cache at ${n}`),g(n))return t?.(`Chromium already installed`),p(n);let r=i(u.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=d(t.stderr),r=d(t.stdout),i=n||r||t.message||`Unknown playwright install failure`;throw Error(`Failed to install Chromium: ${i}`)}return t?.(`Chromium install complete`),p(n)}function v(){return process.platform===`win32`||process.platform===`darwin`?!0:!!(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)}function y(e){return e===`headless`||!v()?`headless`:e}function b(e){switch(e){case`headless`:return{headless:!0,args:[]};case`panel`:return{headless:!1,args:[`--app=data:text/html,<title>aikit</title>`]};default:return{headless:!1,args:[]}}}var x=class{pages=new Map;registerPage(e,t,r){let i=n();return this.pages.set(i,{page:e,url:t,title:r,createdAt:new Date}),i}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,createdAt:t.createdAt}}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,createdAt:t.createdAt}))}async closeAll(){await Promise.allSettled([...this.pages.keys()].map(async e=>this.removePage(e)))}get size(){return this.pages.size}};const S={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0};var C=class{browser=null;context=null;idleTimer=null;launchPromise=null;session=new x;config;constructor(e={}){this.config={...S,...e}}async launch(e,t){if(!this.context){if(this.launchPromise)return this.launchPromise;this.launchPromise=this.doLaunch(e,t);try{await this.launchPromise}finally{this.launchPromise=null}}}async doLaunch(e,n){if(this.browser&&this.context)return;let a=y(e??this.config.defaultMode),o=h(this.config);process.env.PLAYWRIGHT_BROWSERS_PATH=o;let{chromium:s}=await import(`playwright-core`),c=await _(this.config,n),l=b(a),u=t(`sha256`).update(process.cwd()).digest(`hex`).slice(0,12),d=i(this.config.userDataDirRoot??i(r(),`.aikit`,`profiles`),u);if(n?.(`Launching Chromium in ${a} mode`),this.context=await s.launchPersistentContext(d,{headless:l.headless,args:l.args,executablePath:c}),this.browser=this.context.browser(),!this.browser)throw await this.context.close(),this.context=null,Error(`Failed to acquire Chromium browser instance`);this.browser.on(`disconnected`,()=>{this.browser=null,this.context=null,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;let n;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 w=null;function T(e){return w||=new C(e),w}async function ee(){w&&=(await w.close(),null)}const te=[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`],ne=[`169.254.169.254`,`metadata.google.internal`,`metadata.google.com`],E=[`localhost`,`127.0.0.1`,`::1`,`[::1]`];function re(e){return e.replace(/^\[(.*)\]$/,`$1`).toLowerCase()}function ie(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 ae(e,t){let n=c.from(e,`utf8`);return n.byteLength<=t?e:n.subarray(0,t).toString(`utf8`)}function D(e,t){let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`Invalid URL: ${e}`}}let r=n.protocol.toLowerCase();if(te.includes(r)&&!t.allowInternalSchemes)return{allowed:!1,reason:`Blocked URL scheme: ${r}`};let i=re(n.hostname);return ne.includes(i)?{allowed:!1,reason:`Blocked host: ${n.hostname}`}:(E.includes(i)||E.includes(n.hostname),{allowed:!0})}function O(e){return e?{allowed:!0}:{allowed:!1,reason:`Cookie access requires explicit confirmation (confirm: true)`}}function k(e,t){if(t<=0)return{valid:!1,reason:`maxBytes must be greater than 0`};try{let n=ie(e);return c.byteLength(n,`utf8`)<=t?{valid:!0,result:n,truncated:!1}:{valid:!0,result:`${ae(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 oe(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 se=[`ui`,`headless`,`panel`];function ce(e){return typeof e==`object`&&e?e:null}function A(e){return typeof e==`string`&&e.length>0?e:void 0}function j(e){return typeof e==`boolean`?e:void 0}function M(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function N(e){return typeof e==`string`&&se.includes(e)?e:void 0}function P(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function le(e){let t=ce(e.browser)??{};return{...S,defaultMode:N(process.env.AIKIT_BROWSER_DEFAULT_MODE)??N(t.defaultMode)??S.defaultMode,browsersPath:A(process.env.AIKIT_BROWSER_PATH)??A(process.env.AIKIT_BROWSER_BROWSERS_PATH)??A(t.browsersPath)??S.browsersPath,userDataDirRoot:A(t.userDataDirRoot)??S.userDataDirRoot,idleShutdownMinutes:P(`AIKIT_BROWSER_IDLE_MINUTES`)??M(t.idleShutdownMinutes)??S.idleShutdownMinutes,allowInternalSchemes:j(t.allowInternalSchemes)??S.allowInternalSchemes,evalTimeoutMs:P(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??M(t.evalTimeoutMs)??S.evalTimeoutMs,evalMaxResultBytes:M(t.evalMaxResultBytes)??S.evalMaxResultBytes,redactPasswordFieldsInScreenshots:j(t.redactPasswordFieldsInScreenshots)??S.redactPasswordFieldsInScreenshots}}function F(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function I(e,t){let n=e.selector??e.ref;if(!n)throw Error(`${t} requires selector or ref`);return n}function ue(e){if(!e)return`empty snapshot`;let t=[],n=(e,r)=>{let i=[e.role??`node`];e.name&&i.push(e.name),e.value!==void 0&&i.push(`value=${String(e.value)}`),e.description&&i.push(`description=${e.description}`),t.push(`${` `.repeat(r)}${i.join(`: `)}`);for(let t of e.children??[])n(t,r+1)};return n(e,0),t.join(`
2
2
  `)}async function de(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`]).describe(`Interaction kind`),l.string().optional().describe(`Optional target ref alias`),l.string().optional().describe(`Playwright selector for the target element`),l.string().optional().describe(`Human-readable element label`),l.string().optional().describe(`Text to type for kind="type"`),l.string().optional().describe(`Key or chord to press for kind="press"`),l.string().optional().describe(`Option value for kind="select" or drag target selector`),l.string().optional().describe(`Optional drag source ref alias`),l.string().optional().describe(`Optional drag source selector`),l.string().optional().describe(`Optional drag target ref alias`),l.string().optional().describe(`Optional drag target selector`);function fe(e){return async({pageId:t,kind:n,ref:r,selector:i,text:a,key:o,value:s,fromRef:c,fromSelector:l,toRef:u,toSelector:d})=>{let f=T(e),p=f.session.getPage(t);switch(n){case`click`:{let e=I({ref:r,selector:i},`browser_act(click)`);await p.click(e);break}case`type`:{let e=I({ref:r,selector:i},`browser_act(type)`);await p.fill(e,a??``);break}case`press`:{let e=I({ref:r,selector:i},`browser_act(press)`);if(!o)throw Error(`browser_act(press) requires key`);await p.press(e,o);break}case`hover`:{let e=I({ref:r,selector:i},`browser_act(hover)`);await p.hover(e);break}case`drag`:{let e=I({ref:c??r,selector:l??i},`browser_act(drag) source`),t=I({ref:u,selector:d??s},`browser_act(drag) target`);await p.dragAndDrop(e,t);break}case`select`:{let e=I({ref:r,selector:i},`browser_act(select)`);if(s===void 0)throw Error(`browser_act(select) requires value`);await p.selectOption(e,s);break}}return f.resetIdleTimer(),F(`ok`,{ok:!0})}}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 pe(e){return async({pageId:t,accept:n,promptText:r})=>{let i=T(e);return i.session.getPage(t).once(`dialog`,async e=>{n?await e.accept(r):await e.dismiss()}),i.resetIdleTimer(),F(`ok`,{ok:!0})}}l.string().describe(`Tracked browser page identifier`),l.string().describe(`JavaScript expression or function source evaluated in the page`),l.number().min(1).max(6e4).optional().describe(`Optional evaluation timeout`);function L(e){return async({pageId:t,code:n,timeoutMs:r})=>{let i=T(e),a=i.session.getPage(t),o=Math.min(r??e.evalTimeoutMs,6e4),s=k(await de(a.evaluate(e=>{let t=Function(`return (${e});`)();return typeof t==`function`?t():t},n),o,`browser_eval`),e.evalMaxResultBytes);if(!s.valid||s.result===void 0)throw Error(s.reason??`browser_eval result validation failed`);return i.resetIdleTimer(),F(s.result,{pageId:t,result:s.result,truncated:s.truncated??!1,reason:s.reason})}}l.string().describe(`Tracked browser page identifier`),l.string().url().optional().describe(`Optional URL to navigate to`),l.enum([`back`,`forward`,`reload`,`waitFor`]).optional().describe(`Navigation helper action`),l.string().optional().describe(`Selector to wait for when type="waitFor"`),l.number().min(1).max(6e4).optional().describe(`Optional wait timeout`);function R(e){return async({pageId:t,url:n,type:r,selector:i,timeoutMs:a})=>{let o=T(e),s=o.session.getPage(t);if(n){let r=D(n,e);if(!r.allowed)return F(`Navigation blocked: ${r.reason}`,{blocked:!0,pageId:t,reason:r.reason});await s.goto(n)}else if(!r)return F(`Navigation requires url or type`,{error:`Navigation requires url or type`,pageId:t});else if(r===`back`)await s.goBack();else if(r===`forward`)await s.goForward();else if(r===`reload`)await s.reload();else if(r===`waitFor`){if(!i)throw Error(`browser_navigate(waitFor) requires selector`);await s.waitForSelector(i,a?{timeout:a}:void 0)}let c=s.url(),l=await s.title();return o.session.updatePageInfo(t,c,l),o.resetIdleTimer(),F(`${l||c}\n${c}`,{pageId:t,url:c,title:l})}}l.string().url().describe(`Absolute URL to open`),l.enum([`ui`,`headless`,`panel`]).optional().describe(`Browser launch mode`),l.boolean().optional().describe(`Reserved for future tab reuse control`),l.enum([`load`,`domcontentloaded`,`networkidle`]).optional().describe(`Navigation readiness event`);function z(e){return async({url:t,mode:n,waitUntil:r})=>{let i=D(t,e);if(!i.allowed)throw Error(i.reason??`Blocked URL: ${t}`);let a=T(e);a.isLaunched()||await a.launch(n??e.defaultMode);let o=await a.getContext().newPage();r?await o.goto(t,{waitUntil:r}):await o.goto(t);let s=await o.title(),c=a.session.registerPage(o,t,s);return a.resetIdleTimer(),F(`Opened ${s||t}\npageId: ${c}`,{pageId:c,url:t,title:s})}}l.string().describe(`Tracked browser page identifier`);function me(e){return async({pageId:t})=>{let n=await T(e).session.getPage(t).accessibility.snapshot(),r=ue(n);return F(r,{pageId:t,snapshot:n,text:r})}}l.string().describe(`Tracked browser page identifier`),l.string().optional().describe(`Optional target ref alias`),l.string().optional().describe(`Optional target selector`),l.boolean().optional().describe(`Capture the full page when no selector is provided`),l.boolean().optional().describe(`Mask password fields before capture`);function he(e){return async({pageId:t,ref:n,selector:r,fullPage:i,redactPasswords:a})=>{let o=T(e),s=o.session.getPage(t),c=a??e.redactPasswordFieldsInScreenshots,l=[];c&&(l=await s.evaluate(()=>{let e=globalThis.document;return Array.from(e.querySelectorAll(`input[type="password"]`)).map((e,t)=>{let n=e,r=`data-aikit-password-mask-${t}`;return n.setAttribute(r,n.value),n.value=`***`,r})}));try{let e=r??n?await s.locator(I({ref:n,selector:r},`browser_screenshot`)).screenshot():await s.screenshot({fullPage:i??!1});return o.resetIdleTimer(),F(`Screenshot captured`,{pageId:t,base64:e.toString(`base64`)})}finally{c&&l.length>0&&await s.evaluate(e=>{let t=globalThis.document;for(let n of e){let e=t.querySelector(`input[${n}]`);e&&(e.value=e.getAttribute(n)??``,e.removeAttribute(n))}},l)}}}l.enum([`list`,`close`,`cookies`]).describe(`Browser session action`),l.string().optional().describe(`Optional tracked page identifier`),l.boolean().optional().describe(`Explicit confirmation required for cookie export`);function ge(e){return async({action:t,pageId:n,confirm:r})=>{let i=T(e);if(t===`list`){let e=i.session.listPages();return F(JSON.stringify(e,null,2),{pages:e})}if(t===`close`){if(!n)throw Error(`browser_session(close) requires pageId`);return await i.session.removePage(n),i.resetIdleTimer(),F(`ok`,{ok:!0,pageId:n})}let a=O(!!r);if(!a.allowed)throw Error(a.reason??`Cookie access denied`);let o=await i.getContext().cookies();return i.resetIdleTimer(),F(JSON.stringify(o,null,2),{cookies:o})}}const B=[`open`,`read`,`act`,`navigate`,`eval`,`screenshot`,`dialog`,`session`],V=[`ui`,`headless`,`panel`],H=[`load`,`domcontentloaded`,`networkidle`],U=[`click`,`type`,`press`,`hover`,`drag`,`select`],W=[`back`,`forward`,`reload`,`waitFor`],G=[`list`,`close`,`cookies`],_e={action:l.enum(B).describe(`Browser action to perform`),pageId:l.string().optional().describe(`Tracked browser page identifier`),url:l.string().url().optional().describe(`URL to open or navigate to`),mode:l.enum(V).optional().describe(`Browser launch mode (open only)`),forceNew:l.boolean().optional().describe(`Reserved for future tab reuse`),waitUntil:l.enum(H).optional().describe(`Navigation readiness event`),kind:l.enum(U).optional().describe(`Interaction kind (act only)`),ref:l.string().optional().describe(`Target ref alias`),selector:l.string().optional().describe(`Playwright selector`),element:l.string().optional().describe(`Human-readable element label`),text:l.string().optional().describe(`Text to type`),key:l.string().optional().describe(`Key to press`),value:l.string().optional().describe(`Option value or drag target`),fromRef:l.string().optional().describe(`Drag source ref`),fromSelector:l.string().optional().describe(`Drag source selector`),toRef:l.string().optional().describe(`Drag target ref`),toSelector:l.string().optional().describe(`Drag target selector`),type:l.enum(W).optional().describe(`Navigation type`),code:l.string().optional().describe(`JavaScript to evaluate in the page`),timeoutMs:l.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),fullPage:l.boolean().optional().describe(`Capture full page`),redactPasswords:l.boolean().optional().describe(`Mask password fields`),accept:l.boolean().optional().describe(`Accept or dismiss dialog`),promptText:l.string().optional().describe(`Text for prompt dialog`),sessionAction:l.enum(G).optional().describe(`Session sub-action (session only)`),confirm:l.boolean().optional().describe(`Explicit confirmation for cookie export`)};function K(e,t){return typeof e==`string`&&t.includes(e)}function q(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function J(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function Y(e,t){let n=e[t];return typeof n==`string`?n:void 0}function X(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function Z(e,t){let n=e[t];return typeof n==`number`?n:void 0}function Q(e,t,n,r){let i=e[t];if(!K(i,n))throw Error(`${r} requires ${t}`);return i}function $(e,t,n,r){let i=e[t];if(i!==void 0){if(!K(i,n))throw Error(`${r} received invalid ${t}`);return i}}function ve(e,t){let n=le(t),r=z(n),i=me(n),a=fe(n),o=R(n),s=L(n),c=he(n),l=pe(n),u=ge(n);e.registerTool(`browser`,{title:`Browser Automation`,description:`Unified browser automation tool. Actions:
3
3
  - open: Launch a browser page (url required, mode/waitUntil optional)
4
4
  - read: Get accessibility snapshot of a page (pageId required)