@vpxa/aikit 0.1.395 → 0.1.396

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.395",
3
+ "version": "0.1.396",
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{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_process";import{copyFileSync as i,existsSync as a,mkdirSync as o,readFileSync as s,readdirSync as c,unlinkSync as l,writeFileSync as u}from"node:fs";import{homedir as d,platform as f,tmpdir as p}from"node:os";import{dirname as m,join as h}from"node:path";import{z as g}from"zod";const _=`0.26.0`,v=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function y(){return h(d(),`.aikit`,`browsers`)}function b(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??y()}function x(){try{let e=r(`${f()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,windowsHide:!0,stdio:`pipe`,timeout:3e3}).trim().split(/\r?\n/).filter(Boolean);if(e.length===0)return null;if(f()===`win32`){for(let t of e){if(t.endsWith(`.exe`)&&a(t))return t;let e=h(m(t),`node_modules`,`agent-browser`,`bin`,`agent-browser-win32-x64.exe`);if(a(e))return e}for(let t of e){if(a(`${t}.exe`))return`${t}.exe`;if(a(`${t}.cmd`))return`${t}.cmd`;if(a(`${t}.bat`))return`${t}.bat`}}let t=e[0];return a(t)?t:null}catch{return null}}function S(e){return h(e,`agent-browser`,te())}function te(){switch(f()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function ne(e,t){try{u(h(e,v),t,`utf8`)}catch{}}function re(e){try{return s(h(e,v),`utf8`).trim()}catch{return null}}function ie(e){let t=re(e);return t?ae(t,_)>=0:!1}function ae(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<Math.max(n.length,r.length);e++){let t=n[e]||0,i=r[e]||0;if(t!==i)return t-i}return 0}function oe(e){return!!(a(h(e,`chrome`))||a(h(d(),`.cache`,`agent-browser`,`chrome`)))}async function se(t,n){let s=x();if(s)return n?.(`Using globally installed agent-browser`),s;let l=b(t);a(l)||o(l,{recursive:!0});let u=S(l);if(a(u)&&ie(l))return n?.(`Using cached agent-browser at ${u}`),u;n?.(`Downloading agent-browser (first use)...`),await new Promise((t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),12e4),a=e(`npx -y agent-browser@latest install --install-dir "${l}"`,{timeout:12e4,windowsHide:!0,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:l},signal:r.signal},(e,r,a)=>{if(clearTimeout(i),e){let t=ee(a)||e.message||`Unknown agent-browser install failure`;n(Error(`Failed to install agent-browser: ${t}`));return}t()});a.stdin&&a.stdin.destroy()});let d=u;try{let e=r(f()===`win32`?`npx -y -p agent-browser node -e "process.stdout.write(__dirname)"`:`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:15e3,windowsHide:!0,stdio:`pipe`}).trim(),t=f()===`win32`?`agent-browser-win32-x64.exe`:f()===`darwin`?process.arch===`arm64`?`agent-browser-darwin-arm64`:`agent-browser-darwin-x64`:`agent-browser-linux-${process.arch===`arm64`?`arm64`:`x64`}`,s=[];e&&!e.includes(`MODULE_NOT_FOUND`)&&(s.push(e),s.push(h(e,`..`)));try{let e=h(r(`npm config get cache`,{encoding:`utf8`,timeout:5e3,windowsHide:!0,stdio:`pipe`}).trim(),`_npx`);if(a(e)){let n=c(e,{withFileTypes:!0});for(let r of n){if(!r.isDirectory())continue;let n=h(e,r.name,`node_modules`,`agent-browser`);if(a(h(n,`bin`,t))){s.push(n);break}}}}catch{}for(let e of s){let r=h(e,`bin`,t);if(a(r)){let t=h(l,`agent-browser`);a(t)||o(t,{recursive:!0});let s=S(l);i(r,s);let c=h(e,`bin`,`agent-browser.js`);a(c)&&i(c,h(t,`agent-browser.js`)),ne(l,_),d=s,n?.(`Cached agent-browser at ${s}`);break}}}catch{}return n?.(`agent-browser ready`),d}async function ce(e){try{return n(e,[`--version`],{encoding:`utf8`,windowsHide:!0,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function le(e){if(x())return!0;let t=b(e);return oe(t)||a(S(t))}const ue=[`ui`,`headless`];function de(e){return ue.includes(e)?e:`headless`}function fe(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function pe(e){return{headless:e===`headless`,args:fe(e)}}var C=class{tabs=new Map;labelToId=new Map;register(e,t,n,r){return this.tabs.set(e,{tabId:e,url:t,title:n??t,label:r,createdAt:new Date}),r&&this.labelToId.set(r,e),e}resolve(e){return this.tabs.has(e)?e:this.labelToId.get(e)||e}getTab(e){let t=this.tabs.get(e);if(!t)throw Error(`Tab not found: ${e}`);return t}updateTabInfo(e,t,n){let r=this.tabs.get(e);r&&this.tabs.set(e,{...r,url:t,title:n})}setSnapshot(e,t){let n=this.tabs.get(e);n&&this.tabs.set(e,{...n,snapshot:t})}getSnapshot(e){return this.tabs.get(e)?.snapshot}async removeTab(e){let t=this.tabs.get(e);t&&(t.label&&this.labelToId.delete(t.label),this.tabs.delete(e))}listTabs(){return[...this.tabs.values()]}listPages(){return this.listTabs().map(e=>({pageId:e.tabId,url:e.url,title:e.title,label:e.label,createdAt:e.createdAt}))}async closeAll(){this.tabs.clear(),this.labelToId.clear()}clear(){this.tabs.clear(),this.labelToId.clear()}get size(){return this.tabs.size}},me=class{tabs=new C;registerPage(e,t,n,r){return this.tabs.register(e,t,n,r)}getPage(e){throw Error(`Direct Playwright Page access no longer supported with agent-browser. Use engine.exec() or engine.tabExec() for browser operations.`)}getPageInfo(e){let t=this.tabs.getTab(e);return{pageId:t.tabId,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}}resolvePageId(e){return this.tabs.resolve(e)}setSnapshot(e,t){this.tabs.setSnapshot(e,t)}getSnapshot(e){return this.tabs.getSnapshot(e)}updatePageInfo(e,t,n){this.tabs.updateTabInfo(e,t,n)}async removePage(e){await this.tabs.removeTab(e)}listPages(){return this.tabs.listPages()}async closeAll(){await this.tabs.closeAll()}get size(){return this.tabs.size}};const w={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:0,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:3e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var T=class{binaryPath=null;_currentMode=null;_isLaunched=!1;idleTimer=null;tabs=new C;config;constructor(e={}){this.config={...w,...e}}get currentMode(){return this._currentMode}async launch(e,t){let n=de(e??this.config.defaultMode);if(!(this._isLaunched&&this._currentMode===n)){this._isLaunched&&this._currentMode!==n&&await this.close(),this._currentMode=n,this.binaryPath=await se(this.config,t);try{let e=await this.exec(`--version`);t?.(`agent-browser ${e.stdout.trim()}`)}catch(e){throw Error(`agent-browser binary failed: ${e instanceof Error?e.message:String(e)}`)}n===`ui`&&await this.closeRuntimeSession(),this._isLaunched=!0,this.resetIdleTimer()}}async exec(e,...t){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let n=this.binaryPath;f()===`win32`&&!n.endsWith(`.cmd`)&&!n.endsWith(`.bat`)&&!n.endsWith(`.exe`)&&a(`${n}.cmd`)&&(n=`${n}.cmd`);let r=[e,...t];if(f()===`win32`&&(n.endsWith(`.cmd`)||n.endsWith(`.bat`))){let e=`"${n}" ${r.map(e=>/[^\w/:@.\-_{}()/\\]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e).join(` `)}`;return await this.execViaShell(e)}return await this.execViaExecFile(n,r)}execViaExecFile(e,n){return new Promise((r,i)=>{t(e,n,{timeout:this.config.evalTimeoutMs,windowsHide:!0},(t,a,o)=>{if(t){let s=t;if(s.code===`ENOENT`){i(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(s.killed||s.signal){i(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${e} ${n.join(` `)}`));return}r({stdout:a??``,stderr:o??``,exitCode:typeof s.code==`number`?s.code:1});return}r({stdout:a??``,stderr:o??``,exitCode:0})}).stdin?.end()})}execViaShell(t){return new Promise((n,r)=>{e(t,{timeout:this.config.evalTimeoutMs,windowsHide:!0},(e,i,a)=>{if(e){let o=e;if(o.code===`ENOENT`){r(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(o.killed||o.signal){r(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${t}`));return}n({stdout:i??``,stderr:a??``,exitCode:typeof o.code==`number`?o.code:1});return}n({stdout:i??``,stderr:a??``,exitCode:0})})})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=this._currentMode===`ui`,i=this.tabs.size===0,a=r&&i?[`open`,e,`--headed`,`--json`]:[`tab`,`new`,e,`--json`],o=await this.exec(...a);if(o.exitCode!==0)throw Error(`agent-browser failed to open URL (exit ${o.exitCode}): ${o.stderr||o.stdout||`Unknown error`}`);let s=E(o.stdout)??await this.readActiveTabId()??this.nextLocalTabId();return this.tabs.register(s,e,o.stdout.trim(),n),this.resetIdleTimer(),s}async screenshot(e,t){let n=t?.format??`png`,r=n===`jpeg`?`image/jpeg`:`image/png`,i=n===`jpeg`?`jpg`:`png`,a=h(t?.screenshotDir??p(),`aikit-screenshot-${Date.now()}.${i}`),o=[a];t?.fullPage&&o.push(`--full`),t?.screenshotDir&&o.push(`--screenshot-dir`,t.screenshotDir),t?.format===`jpeg`&&o.push(`--screenshot-format`,`jpeg`),t?.quality&&o.push(`--screenshot-quality`,String(t.quality)),t?.annotate&&o.push(`--annotate`),await this.tabExec(e,`screenshot`,...o);let c=s(a),u=c.toString(`base64`);try{l(a)}catch{}return this.resetIdleTimer(),{base64:u,mimeType:r,bytes:c.length}}async screenshotActiveTab(e){let t=e?.format??`png`,n=t===`jpeg`?`image/jpeg`:`image/png`,r=t===`jpeg`?`jpg`:`png`,i=h(e?.screenshotDir??p(),`aikit-screenshot-${Date.now()}.${r}`),a=[i];e?.fullPage&&a.push(`--full`),e?.screenshotDir&&a.push(`--screenshot-dir`,e.screenshotDir),e?.format===`jpeg`&&a.push(`--screenshot-format`,`jpeg`),e?.quality&&a.push(`--screenshot-quality`,String(e.quality)),e?.annotate&&a.push(`--annotate`),e?.selector&&a.push(`--element`,e.selector),await this.exec(`screenshot`,...a);let o=s(i),c=o.toString(`base64`);try{l(i)}catch{}return this.resetIdleTimer(),{base64:c,mimeType:n,bytes:o.length}}async readSnapshot(e,t=!1){let n=t?[`-c`,`--json`]:[`-i`,`--json`],r=await this.tabExec(e,`snapshot`,...n);return this.resetIdleTimer(),r.stdout}async navigate(e,t){let n=await this.tabExec(e,`goto`,t);return this.resetIdleTimer(),n}async close(){this.stopIdleTimer(),this._isLaunched&&(await this.closeRuntimeSession(),this.tabs.clear(),this._isLaunched=!1,this._currentMode=null)}isLaunched(){return this._isLaunched}getConfig(){return this.config}getBinaryPath(){return this.binaryPath}resolvePageId(e){return this.tabs.resolve(e)}resetIdleTimer(){if(this.stopIdleTimer(),!Number.isFinite(this.config.idleShutdownMinutes)||this.config.idleShutdownMinutes<=0)return;let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);this._currentMode!==`ui`&&e.unref?.(),this.idleTimer=e}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}async closeRuntimeSession(){try{await this.exec(`close`,`--all`).catch(()=>{})}catch{}}async readActiveTabId(){let e=await this.exec(`tab`,`list`,`--json`).catch(()=>null);return e?.exitCode===0?E(e.stdout):null}nextLocalTabId(){let e=this.tabs.listTabs().map(e=>/^t(\d+)$/.exec(e.tabId)?.[1]).filter(e=>e!==void 0).map(Number);return`t${e.length===0?1:Math.max(...e)+1}`}};function E(e){try{let t=JSON.parse(e);if(typeof t.data?.tabId==`string`)return t.data.tabId;let n=t.data?.tabs?.find(e=>e.active===!0);if(typeof n?.tabId==`string`)return n.tabId}catch{}return null}let D=null;function O(e){return D||=new T(e),D}async function he(){D&&=(await D.close(),null)}function k(e,t){try{let n=new URL(e),r=n.hostname.toLowerCase(),i=n.protocol.toLowerCase();return[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`].includes(i)?t?.allowInternalSchemes?{allowed:!0}:{allowed:!1,reason:`Scheme '${i}' is blocked for security`}:[`169.254.169.254`,`metadata.google.internal`,`metadata.instance`].includes(r)?{allowed:!1,reason:`Cloud metadata endpoint '${r}' is blocked`}:n.hostname===`localhost`||r===`127.0.0.1`||r===`::1`||r.startsWith(`10.`)||r.startsWith(`172.`)||r.startsWith(`192.168.`)?t?.allowLoopback?{allowed:!0}:{allowed:!1,reason:`Internal host '${r}' requires allowLoopback=true`}:{allowed:!0}}catch{return{allowed:!1,reason:`Invalid URL`}}}function A(e,t){return Buffer.byteLength(e,`utf8`)<=t?{valid:!0,result:e,truncated:!1}:{valid:!0,result:`${Buffer.from(e).subarray(0,t).toString(`utf8`)}\n... [truncated]`,truncated:!0,reason:`Result exceeded ${t} bytes, truncated to ${t} bytes`}}const ge=[`ui`,`headless`];function _e(e){return typeof e==`object`&&e?e:null}function j(e){return typeof e==`string`&&e.length>0?e:void 0}function M(e){return typeof e==`boolean`?e:void 0}function N(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function P(e){return typeof e==`string`&&ge.includes(e)?e:void 0}function F(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function ve(e){let t=_e(e.browser)??{};return{...w,defaultMode:P(process.env.AIKIT_BROWSER_DEFAULT_MODE)??P(t.defaultMode)??w.defaultMode,browsersPath:j(process.env.AIKIT_BROWSER_PATH)??j(process.env.AIKIT_BROWSER_BROWSERS_PATH)??j(t.browsersPath)??w.browsersPath,userDataDirRoot:j(t.userDataDirRoot)??w.userDataDirRoot,idleShutdownMinutes:F(`AIKIT_BROWSER_IDLE_MINUTES`)??N(t.idleShutdownMinutes)??w.idleShutdownMinutes,allowInternalSchemes:M(t.allowInternalSchemes)??w.allowInternalSchemes,allowLoopback:M(t.allowLoopback)??w.allowLoopback,evalTimeoutMs:F(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??N(t.evalTimeoutMs)??w.evalTimeoutMs,evalMaxResultBytes:N(t.evalMaxResultBytes)??w.evalMaxResultBytes,redactPasswordFieldsInScreenshots:M(t.redactPasswordFieldsInScreenshots)??w.redactPasswordFieldsInScreenshots,engine:j(t.engine)??w.engine,proxy:j(t.proxy),viewport:j(t.viewport)}}function I(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function L(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}function R(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`){let e=z(t);if(e.length>0)return e.join(`
1
+ import{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_process";import{copyFileSync as i,existsSync as a,mkdirSync as o,readFileSync as s,readdirSync as c,unlinkSync as l,writeFileSync as u}from"node:fs";import{homedir as d,platform as f,tmpdir as p}from"node:os";import{dirname as m,join as h}from"node:path";import{z as g}from"zod";const _=`0.26.0`,v=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function y(){return h(d(),`.aikit`,`browsers`)}function b(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??y()}function x(){try{let e=r(`${f()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,windowsHide:!0,stdio:`pipe`,timeout:3e3}).trim().split(/\r?\n/).filter(Boolean);if(e.length===0)return null;if(f()===`win32`){for(let t of e){if(t.endsWith(`.exe`)&&a(t))return t;let e=h(m(t),`node_modules`,`agent-browser`,`bin`,`agent-browser-win32-x64.exe`);if(a(e))return e}for(let t of e){if(a(`${t}.exe`))return`${t}.exe`;if(a(`${t}.cmd`))return`${t}.cmd`;if(a(`${t}.bat`))return`${t}.bat`}}let t=e[0];return a(t)?t:null}catch{return null}}function S(e){return h(e,`agent-browser`,te())}function te(){switch(f()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function ne(e,t){try{u(h(e,v),t,`utf8`)}catch{}}function re(e){try{return s(h(e,v),`utf8`).trim()}catch{return null}}function ie(e){let t=re(e);return t?ae(t,_)>=0:!1}function ae(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<Math.max(n.length,r.length);e++){let t=n[e]||0,i=r[e]||0;if(t!==i)return t-i}return 0}function oe(e){return!!(a(h(e,`chrome`))||a(h(d(),`.cache`,`agent-browser`,`chrome`)))}async function se(t,n){let s=x();if(s)return n?.(`Using globally installed agent-browser`),s;let l=b(t);a(l)||o(l,{recursive:!0});let u=S(l);if(a(u)&&ie(l))return n?.(`Using cached agent-browser at ${u}`),u;n?.(`Downloading agent-browser (first use)...`),await new Promise((t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),12e4),a=e(`npx -y agent-browser@latest install --install-dir "${l}"`,{timeout:12e4,windowsHide:!0,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:l},signal:r.signal},(e,r,a)=>{if(clearTimeout(i),e){let t=ee(a)||e.message||`Unknown agent-browser install failure`;n(Error(`Failed to install agent-browser: ${t}`));return}t()});a.stdin&&a.stdin.destroy()});let d=u;try{let e=r(f()===`win32`?`npx -y -p agent-browser node -e "process.stdout.write(__dirname)"`:`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:15e3,windowsHide:!0,stdio:`pipe`}).trim(),t=f()===`win32`?`agent-browser-win32-x64.exe`:f()===`darwin`?process.arch===`arm64`?`agent-browser-darwin-arm64`:`agent-browser-darwin-x64`:`agent-browser-linux-${process.arch===`arm64`?`arm64`:`x64`}`,s=[];e&&!e.includes(`MODULE_NOT_FOUND`)&&(s.push(e),s.push(h(e,`..`)));try{let e=h(r(`npm config get cache`,{encoding:`utf8`,timeout:5e3,windowsHide:!0,stdio:`pipe`}).trim(),`_npx`);if(a(e)){let n=c(e,{withFileTypes:!0});for(let r of n){if(!r.isDirectory())continue;let n=h(e,r.name,`node_modules`,`agent-browser`);if(a(h(n,`bin`,t))){s.push(n);break}}}}catch{}for(let e of s){let r=h(e,`bin`,t);if(a(r)){let t=h(l,`agent-browser`);a(t)||o(t,{recursive:!0});let s=S(l);i(r,s);let c=h(e,`bin`,`agent-browser.js`);a(c)&&i(c,h(t,`agent-browser.js`)),ne(l,_),d=s,n?.(`Cached agent-browser at ${s}`);break}}}catch{}return n?.(`agent-browser ready`),d}async function ce(e){try{return n(e,[`--version`],{encoding:`utf8`,windowsHide:!0,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function le(e){if(x())return!0;let t=b(e);return oe(t)||a(S(t))}const ue=[`ui`,`headless`];function de(e){return ue.includes(e)?e:`headless`}function fe(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function pe(e){return{headless:e===`headless`,args:fe(e)}}var C=class{tabs=new Map;labelToId=new Map;register(e,t,n,r){return this.tabs.set(e,{tabId:e,url:t,title:n??t,label:r,createdAt:new Date}),r&&this.labelToId.set(r,e),e}resolve(e){return this.tabs.has(e)?e:this.labelToId.get(e)||e}getTab(e){let t=this.tabs.get(e);if(!t)throw Error(`Tab not found: ${e}`);return t}updateTabInfo(e,t,n){let r=this.tabs.get(e);r&&this.tabs.set(e,{...r,url:t,title:n})}setSnapshot(e,t){let n=this.tabs.get(e);n&&this.tabs.set(e,{...n,snapshot:t})}getSnapshot(e){return this.tabs.get(e)?.snapshot}async removeTab(e){let t=this.tabs.get(e);t&&(t.label&&this.labelToId.delete(t.label),this.tabs.delete(e))}listTabs(){return[...this.tabs.values()]}listPages(){return this.listTabs().map(e=>({pageId:e.tabId,url:e.url,title:e.title,label:e.label,createdAt:e.createdAt}))}async closeAll(){this.tabs.clear(),this.labelToId.clear()}clear(){this.tabs.clear(),this.labelToId.clear()}get size(){return this.tabs.size}},me=class{tabs=new C;registerPage(e,t,n,r){return this.tabs.register(e,t,n,r)}getPage(e){throw Error(`Direct Playwright Page access no longer supported with agent-browser. Use engine.exec() or engine.tabExec() for browser operations.`)}getPageInfo(e){let t=this.tabs.getTab(e);return{pageId:t.tabId,url:t.url,title:t.title,label:t.label,createdAt:t.createdAt}}resolvePageId(e){return this.tabs.resolve(e)}setSnapshot(e,t){this.tabs.setSnapshot(e,t)}getSnapshot(e){return this.tabs.getSnapshot(e)}updatePageInfo(e,t,n){this.tabs.updateTabInfo(e,t,n)}async removePage(e){await this.tabs.removeTab(e)}listPages(){return this.tabs.listPages()}async closeAll(){await this.tabs.closeAll()}get size(){return this.tabs.size}};const w={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:0,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:3e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var T=class{binaryPath=null;_currentMode=null;_isLaunched=!1;idleTimer=null;tabs=new C;config;constructor(e={}){this.config={...w,...e}}get currentMode(){return this._currentMode}async launch(e,t){let n=de(e??this.config.defaultMode);if(!(this._isLaunched&&this._currentMode===n)){this._isLaunched&&this._currentMode!==n&&await this.close(),this._currentMode=n,this.binaryPath=await se(this.config,t);try{let e=await this.exec(`--version`);t?.(`agent-browser ${e.stdout.trim()}`)}catch(e){throw Error(`agent-browser binary failed: ${e instanceof Error?e.message:String(e)}`)}n===`ui`&&await this.closeRuntimeSession(),this._isLaunched=!0,this.resetIdleTimer()}}async exec(e,...t){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let n=this.binaryPath;f()===`win32`&&!n.endsWith(`.cmd`)&&!n.endsWith(`.bat`)&&!n.endsWith(`.exe`)&&a(`${n}.cmd`)&&(n=`${n}.cmd`);let r=[e,...t];if(f()===`win32`&&(n.endsWith(`.cmd`)||n.endsWith(`.bat`))){let e=`"${n}" ${r.map(e=>/[^\w/:@.\-_{}()/\\]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e).join(` `)}`;return await this.execViaShell(e)}return await this.execViaExecFile(n,r)}execViaExecFile(e,n){return new Promise((r,i)=>{t(e,n,{timeout:this.config.evalTimeoutMs,windowsHide:!0},(t,a,o)=>{if(t){let s=t;if(s.code===`ENOENT`){i(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(s.killed||s.signal){i(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${e} ${n.join(` `)}`));return}r({stdout:a??``,stderr:o??``,exitCode:typeof s.code==`number`?s.code:1});return}r({stdout:a??``,stderr:o??``,exitCode:0})}).stdin?.end()})}execViaShell(t){return new Promise((n,r)=>{e(t,{timeout:this.config.evalTimeoutMs,windowsHide:!0},(e,i,a)=>{if(e){let o=e;if(o.code===`ENOENT`){r(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(o.killed||o.signal){r(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${t}`));return}n({stdout:i??``,stderr:a??``,exitCode:typeof o.code==`number`?o.code:1});return}n({stdout:i??``,stderr:a??``,exitCode:0})})})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=this._currentMode===`ui`,i=this.tabs.size===0,a=r&&i?[`open`,e,`--headed`,`--json`]:[`tab`,`new`,e,`--json`],o=await this.exec(...a);if(o.exitCode!==0)throw Error(`agent-browser failed to open URL (exit ${o.exitCode}): ${o.stderr||o.stdout||`Unknown error`}`);let s=E(o.stdout)??await this.readActiveTabId()??this.nextLocalTabId();return this.tabs.register(s,e,o.stdout.trim(),n),this.resetIdleTimer(),s}async screenshot(e,t){let n=t?.format??`png`,r=n===`jpeg`?`image/jpeg`:`image/png`,i=n===`jpeg`?`jpg`:`png`,a=h(t?.screenshotDir??p(),`aikit-screenshot-${Date.now()}.${i}`),o=[a];t?.fullPage&&o.push(`--full`),t?.screenshotDir&&o.push(`--screenshot-dir`,t.screenshotDir),t?.format===`jpeg`&&o.push(`--screenshot-format`,`jpeg`),t?.quality&&o.push(`--screenshot-quality`,String(t.quality)),t?.annotate&&o.push(`--annotate`),await this.tabExec(e,`screenshot`,...o);let c=s(a),u=c.toString(`base64`);try{l(a)}catch{}return this.resetIdleTimer(),{base64:u,mimeType:r,bytes:c.length}}async screenshotActiveTab(e){let t=e?.format??`png`,n=t===`jpeg`?`image/jpeg`:`image/png`,r=t===`jpeg`?`jpg`:`png`,i=h(e?.screenshotDir??p(),`aikit-screenshot-${Date.now()}.${r}`),a=[i];e?.fullPage&&a.push(`--full`),e?.screenshotDir&&a.push(`--screenshot-dir`,e.screenshotDir),e?.format===`jpeg`&&a.push(`--screenshot-format`,`jpeg`),e?.quality&&a.push(`--screenshot-quality`,String(e.quality)),e?.annotate&&a.push(`--annotate`),e?.selector&&a.push(`--element`,e.selector),await this.exec(`screenshot`,...a);let o=s(i),c=o.toString(`base64`);try{l(i)}catch{}return this.resetIdleTimer(),{base64:c,mimeType:n,bytes:o.length}}async readSnapshot(e,t=!1){let n=t?[`-c`,`--json`]:[`-i`,`--json`],r=await this.tabExec(e,`snapshot`,...n);return this.resetIdleTimer(),r.stdout}async navigate(e,t){let n=await this.tabExec(e,`goto`,t);return this.resetIdleTimer(),n}async close(){this.stopIdleTimer(),this._isLaunched&&(await this.closeRuntimeSession(),this.tabs.clear(),this._isLaunched=!1,this._currentMode=null)}isLaunched(){return this._isLaunched}getConfig(){return this.config}getBinaryPath(){return this.binaryPath}resolvePageId(e){return this.tabs.resolve(e)}resetIdleTimer(){if(this.stopIdleTimer(),!Number.isFinite(this.config.idleShutdownMinutes)||this.config.idleShutdownMinutes<=0){this._currentMode===`ui`&&(this.idleTimer=setInterval(()=>{},6e4));return}let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);this._currentMode!==`ui`&&e.unref?.(),this.idleTimer=e}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}async closeRuntimeSession(){try{await this.exec(`close`,`--all`).catch(()=>{})}catch{}}async readActiveTabId(){let e=await this.exec(`tab`,`list`,`--json`).catch(()=>null);return e?.exitCode===0?E(e.stdout):null}nextLocalTabId(){let e=this.tabs.listTabs().map(e=>/^t(\d+)$/.exec(e.tabId)?.[1]).filter(e=>e!==void 0).map(Number);return`t${e.length===0?1:Math.max(...e)+1}`}};function E(e){try{let t=JSON.parse(e);if(typeof t.data?.tabId==`string`)return t.data.tabId;let n=t.data?.tabs?.find(e=>e.active===!0);if(typeof n?.tabId==`string`)return n.tabId}catch{}return null}let D=null;function O(e){return D||=new T(e),D}async function he(){D&&=(await D.close(),null)}function k(e,t){try{let n=new URL(e),r=n.hostname.toLowerCase(),i=n.protocol.toLowerCase();return[`file:`,`chrome:`,`chrome-extension:`,`data:`,`javascript:`].includes(i)?t?.allowInternalSchemes?{allowed:!0}:{allowed:!1,reason:`Scheme '${i}' is blocked for security`}:[`169.254.169.254`,`metadata.google.internal`,`metadata.instance`].includes(r)?{allowed:!1,reason:`Cloud metadata endpoint '${r}' is blocked`}:n.hostname===`localhost`||r===`127.0.0.1`||r===`::1`||r.startsWith(`10.`)||r.startsWith(`172.`)||r.startsWith(`192.168.`)?t?.allowLoopback?{allowed:!0}:{allowed:!1,reason:`Internal host '${r}' requires allowLoopback=true`}:{allowed:!0}}catch{return{allowed:!1,reason:`Invalid URL`}}}function A(e,t){return Buffer.byteLength(e,`utf8`)<=t?{valid:!0,result:e,truncated:!1}:{valid:!0,result:`${Buffer.from(e).subarray(0,t).toString(`utf8`)}\n... [truncated]`,truncated:!0,reason:`Result exceeded ${t} bytes, truncated to ${t} bytes`}}const ge=[`ui`,`headless`];function _e(e){return typeof e==`object`&&e?e:null}function j(e){return typeof e==`string`&&e.length>0?e:void 0}function M(e){return typeof e==`boolean`?e:void 0}function N(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function P(e){return typeof e==`string`&&ge.includes(e)?e:void 0}function F(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function ve(e){let t=_e(e.browser)??{};return{...w,defaultMode:P(process.env.AIKIT_BROWSER_DEFAULT_MODE)??P(t.defaultMode)??w.defaultMode,browsersPath:j(process.env.AIKIT_BROWSER_PATH)??j(process.env.AIKIT_BROWSER_BROWSERS_PATH)??j(t.browsersPath)??w.browsersPath,userDataDirRoot:j(t.userDataDirRoot)??w.userDataDirRoot,idleShutdownMinutes:F(`AIKIT_BROWSER_IDLE_MINUTES`)??N(t.idleShutdownMinutes)??w.idleShutdownMinutes,allowInternalSchemes:M(t.allowInternalSchemes)??w.allowInternalSchemes,allowLoopback:M(t.allowLoopback)??w.allowLoopback,evalTimeoutMs:F(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??N(t.evalTimeoutMs)??w.evalTimeoutMs,evalMaxResultBytes:N(t.evalMaxResultBytes)??w.evalMaxResultBytes,redactPasswordFieldsInScreenshots:M(t.redactPasswordFieldsInScreenshots)??w.redactPasswordFieldsInScreenshots,engine:j(t.engine)??w.engine,proxy:j(t.proxy),viewport:j(t.viewport)}}function I(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function L(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}function R(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`){let e=z(t);if(e.length>0)return e.join(`
2
2
  `)}return JSON.stringify(t,null,2)}catch{return e}}function z(e,t=0,n=[]){let r=` `.repeat(t),i=typeof e.role==`string`?e.role.toUpperCase():``,a=typeof e.ref==`string`?e.ref:``,o=typeof e.name==`string`?e.name:``,s=typeof e.value==`string`?`="${e.value}"`:``,c=Array.isArray(e.children)?e.children:[];if(i&&a){let e=ye(i),t=o||s||``;n.push(`${r}[${e}] [${a}] ${t}`.trimEnd())}else if(o||i){let e=i.toLowerCase();n.push(`${r}${e}: ${o}`.trimEnd())}for(let e of c)typeof e==`object`&&e&&z(e,t+1,n);return n}function ye(e){return{BUTTON:`BUTTON`,LINK:`LINK`,TEXT_FIELD:`TEXTFIELD`,TEXTBOX:`TEXTFIELD`,COMBOBOX:`SELECT`,CHECKBOX:`CHECKBOX`,RADIO:`RADIO`,SWITCH:`SWITCH`,SLIDER:`SLIDER`,TAB:`TAB`,MENU_ITEM:`MENUITEM`,LISTBOX:`LIST`,GRID:`GRID`,TABLE:`TABLE`,HEADING:`HEADING`,IMAGE:`IMAGE`,IMG:`IMAGE`,PROGRESSBAR:`PROGRESS`,DIALOG:`DIALOG`,TOOLTIP:`TOOLTIP`,ALERT:`ALERT`,MENU:`MENU`,NAVIGATION:`NAV`,SEARCH:`SEARCH`,MAIN:`MAIN`,COMPLEMENTARY:`COMPLEMENT`,CONTENTINFO:`INFO`,REGION:`REGION`}[e]??e.slice(0,8)}function be(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=O(e),m=p.resolvePageId(t);switch(n){case`click`:{let e=L({ref:r,selector:i,element:a},`browser_act(click)`);await p.tabExec(m,`click`,e);break}case`type`:{let e=L({ref:r,selector:i,element:a},`browser_act(type)`);await p.tabExec(m,`fill`,e,o??``);break}case`press`:{let e=L({ref:r,selector:i,element:a},`browser_act(press)`);if(!s)throw Error(`browser_act(press) requires key`);await p.tabExec(m,`press`,e,s);break}case`hover`:{let e=L({ref:r,selector:i,element:a},`browser_act(hover)`);await p.tabExec(m,`hover`,e);break}case`drag`:{let e=L({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=L({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await p.tabExec(m,`drag`,e,t);break}case`select`:{let e=L({ref:r,selector:i,element:a},`browser_act(select)`);if(c===void 0)throw Error(`browser_act(select) requires value`);await p.tabExec(m,`select`,e,c);break}case`scroll`:{if(i||r||a){let e=L({ref:r,selector:i,element:a},`browser_act(scroll)`);await p.tabExec(m,`scrollintoview`,e);break}let e=c??`down 500`;await p.tabExec(m,`scroll`,e);break}case`upload`:{let e=L({ref:r,selector:i,element:a},`browser_act(upload)`);if(!c)throw Error(`value (file path) required for upload`);await p.tabExec(m,`upload`,e,c);break}}return p.resetIdleTimer(),I(`ok`,{ok:!0})}}function xe(e){return async({pageId:t,subAction:n,level:r,bufferSize:i,expression:a})=>{let o=O(e),s=o.resolvePageId(t);switch(n){case`enable`:{let e=[`--enable`];return i&&e.push(`--buffer-size`,String(i)),r&&e.push(`--level`,r),await o.tabExec(s,`console`,...e),o.resetIdleTimer(),I(`Console capture enabled`,{enabled:!0})}case`get`:{let t=[`--json`];r&&t.push(`--level`,r);let n=await o.tabExec(s,`console`,...t);o.resetIdleTimer();let i=[];try{i=JSON.parse(n.stdout)}catch{i=[{raw:n.stdout}]}let c,l;if(a)try{c=(await o.tabExec(s,`evaluate`,`--timeout=${e.evalTimeoutMs}`,`--`,a)).stdout}catch(e){l=e instanceof Error?e.message:String(e)}return I(c===void 0?`Console has ${i.length} entries`:`Console has ${i.length} entries\nEvaluation: ${c}`,{entries:i,count:i.length,expression:a,evalResult:c,evalError:l})}case`clear`:return await o.tabExec(s,`console`,`clear`),o.resetIdleTimer(),I(`Console cleared`,{cleared:!0});default:return I(`Unknown console sub-action`,{error:`Unknown console sub-action`})}}}function Se(e){return async({pageId:t,accept:n,promptText:r})=>{let i=O(e),a=i.resolvePageId(t);if(n){let e=r?[`accept`,`--text`,r]:[`accept`];await i.tabExec(a,`dialog`,...e)}else await i.tabExec(a,`dialog`,`dismiss`);return i.resetIdleTimer(),I(`Dialog ${n?`accepted`:`dismissed`}`,{accepted:n})}}function Ce(e){return async({pageId:t})=>{let n=O(e),r=n.resolvePageId(t),i=await n.tabExec(r,`diff`,`snapshot`);return n.resetIdleTimer(),I(i.stdout,{pageId:r,diff:i.stdout})}}function we(e){return async({pageId:t,code:n,timeoutMs:r})=>{let i=O(e),a=i.resolvePageId(t),o=r??e.evalTimeoutMs,s=await i.tabExec(a,`evaluate`,`--timeout=${o}`,`--`,n);i.resetIdleTimer();let c=A(s.stdout,e.evalMaxResultBytes);return I(c.result,{pageId:a,result:c.result,truncated:c.truncated})}}function Te(e){return async({pageId:t,url:n,method:r,headers:i,body:a,timeoutMs:o,includeHeaders:s})=>{let c=O(e),l=c.resolvePageId(t),u=o??e.evalTimeoutMs,d=Ee(n,r??`GET`,s??!0,i,a),f=await c.tabExec(l,`evaluate`,`--timeout=${u}`,`--`,d);return c.resetIdleTimer(),I(f.stdout,{pageId:l,response:f.stdout})}}function Ee(e,t,n,r,i){let a={method:t,headers:r??{}};i&&[`POST`,`PUT`,`PATCH`].includes(t.toUpperCase())&&(a.body=i);let o=JSON.stringify(a);return n?`fetch(${JSON.stringify(e)}, ${o}).then(async r => {
3
3
  const text = await r.text();
4
4
  const headers = {};
@@ -2,7 +2,7 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "aikit",
4
4
  "display_name": "AI Kit",
5
- "version": "0.1.395",
5
+ "version": "0.1.396",
6
6
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
7
7
  "author": {
8
8
  "name": "AnVPX",