@vpxa/aikit 0.1.393 → 0.1.395
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 +1 -1
- package/packages/browser/dist/index.d.ts +6 -4
- package/packages/browser/dist/index.js +4 -4
- package/packages/claude-desktop/dist/manifest.json +1 -1
- package/packages/cli/dist/index.js +1 -1
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{register-tools-D-t3eTvs.js → register-tools-B8PeQx0Y.js} +129 -129
- package/packages/server/dist/{register-tools-DRmi-AmC.js → register-tools-DLENgNAW.js} +129 -129
- package/packages/server/dist/{server-Bn3ZMDux.js → server-Ba2YVf_M.js} +1 -1
- package/packages/server/dist/{server-BcG-7PjG.js → server-BmxvSBgJ.js} +1 -1
- package/packages/server/dist/{server-http-TUEuRgF6.js → server-http-B-Shfkdx.js} +1 -1
- package/packages/server/dist/{server-http-CqY0asOU.js → server-http-BaCFoBkv.js} +1 -1
- package/packages/server/dist/{server-stdio-CadvzL7g.js → server-stdio-BRLNHMrk.js} +1 -1
- package/packages/server/dist/{server-stdio-DPoyLEXS.js → server-stdio-CU5MD6W_.js} +1 -1
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ interface BrowserConfig {
|
|
|
9
9
|
browsersPath: string | null;
|
|
10
10
|
/** User data directory for persistent browser profiles */
|
|
11
11
|
userDataDirRoot: string | null;
|
|
12
|
-
/** Minutes of inactivity before the browser session is closed */
|
|
12
|
+
/** Minutes of inactivity before the browser session is closed. 0 disables idle shutdown. */
|
|
13
13
|
idleShutdownMinutes: number;
|
|
14
14
|
/** Allow internal browser schemes (file:, chrome:, etc.) */
|
|
15
15
|
allowInternalSchemes: boolean;
|
|
@@ -69,7 +69,7 @@ interface AgentBrowserResult {
|
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region packages/browser/src/session.d.ts
|
|
71
71
|
/**
|
|
72
|
-
* TabRegistry manages agent-browser's stable tab IDs (
|
|
72
|
+
* TabRegistry manages agent-browser's stable tab IDs (t1, t2...).
|
|
73
73
|
*
|
|
74
74
|
* agent-browser assigns stable string IDs to tabs that don't shift on close.
|
|
75
75
|
* We track tab metadata alongside these IDs.
|
|
@@ -138,7 +138,6 @@ declare class BrowserEngine {
|
|
|
138
138
|
private binaryPath;
|
|
139
139
|
private _currentMode;
|
|
140
140
|
private _isLaunched;
|
|
141
|
-
private _nextTabIndex;
|
|
142
141
|
private idleTimer;
|
|
143
142
|
readonly tabs: TabRegistry;
|
|
144
143
|
private config;
|
|
@@ -161,7 +160,7 @@ declare class BrowserEngine {
|
|
|
161
160
|
tabExec(tabId: string, command: string, ...args: string[]): Promise<AgentBrowserResult>;
|
|
162
161
|
/**
|
|
163
162
|
* Open a URL in a new tab and register it.
|
|
164
|
-
* Returns the tab ID (
|
|
163
|
+
* Returns the tab ID assigned by agent-browser (t1, t2...).
|
|
165
164
|
*/
|
|
166
165
|
open(url: string, mode?: BrowserMode, label?: string): Promise<string>;
|
|
167
166
|
/**
|
|
@@ -217,6 +216,9 @@ declare class BrowserEngine {
|
|
|
217
216
|
resolvePageId(pageIdOrLabel: string): string;
|
|
218
217
|
resetIdleTimer(): void;
|
|
219
218
|
private stopIdleTimer;
|
|
219
|
+
private closeRuntimeSession;
|
|
220
|
+
private readActiveTabId;
|
|
221
|
+
private nextLocalTabId;
|
|
220
222
|
}
|
|
221
223
|
declare function getEngine(config?: Partial<BrowserConfig>): BrowserEngine;
|
|
222
224
|
declare function closeEngine(): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
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{join as m}from"node:path";import{z as h}from"zod";const g=`0.26.0`,_=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function v(){return m(d(),`.aikit`,`browsers`)}function y(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??v()}function te(){try{let e=r(`${f()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,windowsHide:!0,stdio:`pipe`,timeout:3e3}).trim().split(/\r?\n/)[0];if(!e)return null;if(f()===`win32`){if(a(`${e}.cmd`))return`${e}.cmd`;if(a(`${e}.bat`))return`${e}.bat`;if(a(`${e}.exe`))return`${e}.exe`}return a(e)?e:null}catch{return null}}function b(e){return m(e,`agent-browser`,ne())}function ne(){switch(f()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function re(e,t){try{u(m(e,_),t,`utf8`)}catch{}}function ie(e){try{return s(m(e,_),`utf8`).trim()}catch{return null}}function ae(e){let t=ie(e);return t?oe(t,g)>=0:!1}function oe(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 se(e){return!!(a(m(e,`chrome`))||a(m(d(),`.cache`,`agent-browser`,`chrome`)))}async function x(t,n){let s=te();if(s)return n?.(`Using globally installed agent-browser`),s;let l=y(t);a(l)||o(l,{recursive:!0});let u=b(l);if(a(u)&&ae(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(m(e,`..`)));try{let e=m(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=m(e,r.name,`node_modules`,`agent-browser`);if(a(m(n,`bin`,t))){s.push(n);break}}}}catch{}for(let e of s){let r=m(e,`bin`,t);if(a(r)){let t=m(l,`agent-browser`);a(t)||o(t,{recursive:!0});let s=b(l);i(r,s);let c=m(e,`bin`,`agent-browser.js`);a(c)&&i(c,m(t,`agent-browser.js`)),re(l,g),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(te())return!0;let t=y(e);return se(t)||a(b(t))}const ue=[`ui`,`headless`];function S(e){return ue.includes(e)?e:`headless`}function C(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function de(e){return{headless:e===`headless`,args:C(e)}}var w=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}},fe=class{tabs=new w;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 T={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:3e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var E=class{binaryPath=null;_currentMode=null;_isLaunched=!1;_nextTabIndex=0;idleTimer=null;tabs=new w;config;constructor(e={}){this.config={...T,...e}}get currentMode(){return this._currentMode}async launch(e,t){let n=S(e??this.config.defaultMode);if(!(this._isLaunched&&this._currentMode===n)){this._isLaunched&&this._currentMode!==n&&await this.close(),this._currentMode=n,this.binaryPath=await x(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)}`)}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`?[`tab`,`new`,e,`--headed`]:[`tab`,`new`,e],i=await this.exec(...r);if(i.exitCode!==0)throw Error(`agent-browser failed to open URL (exit ${i.exitCode}): ${i.stderr||i.stdout||`Unknown error`}`);let a=`t${this._nextTabIndex++}`;return this.tabs.register(a,e,i.stdout.trim(),n),this.resetIdleTimer(),a}async screenshot(e,t){let n=t?.format??`png`,r=n===`jpeg`?`image/jpeg`:`image/png`,i=n===`jpeg`?`jpg`:`png`,a=m(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=m(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(){if(this.stopIdleTimer(),this._isLaunched){try{await this.exec(`close`).catch(()=>{})}catch{}this.tabs.clear(),this._nextTabIndex=0,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(){this.stopIdleTimer();let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);this._currentMode!==`ui`&&e.unref?.(),this.idleTimer=e}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}};let D=null;function O(e){return D||=new E(e),D}async function pe(){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 me=[`ui`,`headless`];function he(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`&&me.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 ge(e){let t=he(e.browser)??{};return{...T,defaultMode:P(process.env.AIKIT_BROWSER_DEFAULT_MODE)??P(t.defaultMode)??T.defaultMode,browsersPath:j(process.env.AIKIT_BROWSER_PATH)??j(process.env.AIKIT_BROWSER_BROWSERS_PATH)??j(t.browsersPath)??T.browsersPath,userDataDirRoot:j(t.userDataDirRoot)??T.userDataDirRoot,idleShutdownMinutes:F(`AIKIT_BROWSER_IDLE_MINUTES`)??N(t.idleShutdownMinutes)??T.idleShutdownMinutes,allowInternalSchemes:M(t.allowInternalSchemes)??T.allowInternalSchemes,allowLoopback:M(t.allowLoopback)??T.allowLoopback,evalTimeoutMs:F(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??N(t.evalTimeoutMs)??T.evalTimeoutMs,evalMaxResultBytes:N(t.evalMaxResultBytes)??T.evalMaxResultBytes,redactPasswordFieldsInScreenshots:M(t.redactPasswordFieldsInScreenshots)??T.redactPasswordFieldsInScreenshots,engine:j(t.engine)??T.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
|
-
`)}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=
|
|
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(`
|
|
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 = {};
|
|
5
5
|
r.headers.forEach((v, k) => { headers[k] = v; });
|
|
@@ -7,5 +7,5 @@ import{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_p
|
|
|
7
7
|
})`:`fetch(${JSON.stringify(e)}, ${o}).then(async r => {
|
|
8
8
|
const text = await r.text();
|
|
9
9
|
return JSON.stringify({ status: r.status, statusText: r.statusText, body: text.slice(0, 100000) });
|
|
10
|
-
})`}function
|
|
11
|
-
`)}`,{pages:e})}case`close`:return u?(await l.tabExec(u,`close`).catch(()=>{}),await l.tabs.removeTab(u),l.resetIdleTimer(),I(`Closed tab ${u}`,{closed:u})):I(`close requires pageId`,{error:`pageId required`});case`cookies`:{if(!r)return I(`Cookie export requires explicit confirmation. Set confirm: true to proceed.`,{confirmRequired:!0});let e=await l.tabExec(u??`t0`,`cookies`),t=[];try{t=JSON.parse(e.stdout)}catch{t=[{raw:e.stdout}]}return I(`Exported ${t.length} cookies`,{cookies:t,count:t.length})}case`set-cookie`:{if(!i||i.length===0)return I(`set-cookie requires cookies array`,{error:`cookies array required`});let e=i.map(e=>`${e.name}=${e.value}${e.domain?`; domain=${e.domain}`:``}${e.path?`; path=${e.path}`:``}`).join(` `);return await l.tabExec(u??`t0`,`cookies`,`set`,e),l.resetIdleTimer(),I(`Set ${i.length} cookies`,{count:i.length})}case`delete-cookie`:return a?(await l.tabExec(u??`t0`,`cookies`,`clear`,a),l.resetIdleTimer(),I(`Deleted cookie ${a}`,{deleted:a})):I(`delete-cookie requires name`,{error:`name required`});case`clear-cookies`:return await l.tabExec(u??`t0`,`cookies`,`clear`),l.resetIdleTimer(),I(`Cookies cleared`,{cleared:!0});case`get-storage`:{if(!o||!s)return I(`get-storage requires storageType and storageKey`,{error:`storageType and storageKey required`});let e=await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`get`,s);return l.resetIdleTimer(),I(e.stdout,{value:e.stdout})}case`set-storage`:return!o||!s||c===void 0?I(`set-storage requires storageType, storageKey, and storageValue`,{error:`storageType, storageKey, storageValue required`}):(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`set`,s,c),l.resetIdleTimer(),I(`Storage key ${s} set`,{key:s}));case`clear-storage`:return o?(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`clear`),l.resetIdleTimer(),I(`Storage cleared`,{cleared:!0})):I(`clear-storage requires storageType`,{error:`storageType required`});default:return I(`Unknown session action`,{error:`Unknown session action`})}}}const B=[`open`,`batch`,`read`,`act`,`navigate`,`network`,`console`,`fetch`,`eval`,`diff`,`screenshot`,`dialog`,`session`],V=[`ui`,`headless`],H=[`load`,`domcontentloaded`,`networkidle`],U=[`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`],W=[`back`,`forward`,`reload`,`waitFor`],G=[`enable`,`get`,`clear`,`export-har`],Me=[`enable`,`get`,`clear`],Ne=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],Pe=[`list`,`close`,`cookies`,`set-cookie`,`delete-cookie`,`clear-cookies`,`get-storage`,`set-storage`,`clear-storage`],Fe={action:h.enum(B).describe(`Browser action to perform`),pageId:h.string().optional().describe(`Tracked browser page identifier`),label:h.string().optional().describe(`Human-readable label for the page (used as alternative to pageId)`),url:h.string().url().optional().describe(`URL to open or navigate to`),mode:h.enum(V).optional().describe(`Browser launch mode (open only)`),forceNew:h.boolean().optional().describe(`Force a new tab instead of reusing existing. When true, creates a new browser tab even if one is already open.`),allowLoopback:h.boolean().optional().describe(`Allow loopback/localhost addresses for this call (default: false for security). Set true to navigate to http://127.0.0.1 or localhost URLs.`),autoDialog:h.boolean().optional().describe(`Auto-accept alert/beforeunload dialogs (default: true). Set false to handle all dialogs manually.`),includeSnapshot:h.boolean().optional().describe(`Include ARIA snapshot in response (default: true for open/navigate). Set false to skip snapshot for speed.`),waitUntil:h.enum(H).optional().describe(`Navigation readiness event`),kind:h.enum(U).optional().describe(`Interaction kind (act only)`),ref:h.string().optional().describe(`Target ref alias`),selector:h.string().optional().describe(`CSS selector for targeting`),element:h.string().optional().describe(`Human-readable element label. Prefer selector for precision.`),text:h.string().optional().describe(`Text to type`),key:h.string().optional().describe(`Key to press`),value:h.string().optional().describe(`Option value or drag target`),fromRef:h.string().optional().describe(`Drag source ref`),fromSelector:h.string().optional().describe(`Drag source selector`),toRef:h.string().optional().describe(`Drag target ref`),toSelector:h.string().optional().describe(`Drag target selector`),type:h.enum(W).optional().describe(`Navigation type`),subAction:h.enum(G).optional().describe(`Network sub-action: enable, get, clear, or export-har`),code:h.string().optional().describe(`JavaScript expression or IIFE evaluated in page context.`),timeoutMs:h.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),filter:h.object({resourceTypes:h.array(h.string()).optional(),urlPattern:h.string().optional(),excludeUrls:h.array(h.string()).optional()}).optional().describe(`Network capture filter for resource types and URL patterns`),showSensitive:h.boolean().optional().describe(`Include sensitive headers instead of redacting them`),includeBody:h.boolean().optional().describe(`Include truncated request bodies in captured entries`),bufferSize:h.number().int().min(1).max(1e4).optional().describe(`Buffer capacity (1-10000, default varies by action)`),consoleSubAction:h.enum(Me).optional().describe(`Console sub-action: enable, get, or clear`),expression:h.string().optional().describe(`JavaScript expression to evaluate in page context (console get only). Like browser_console expression in Hermes.`),level:h.string().optional().describe(`Filter console entries by level (log/info/warn/error/debug)`),fetchUrl:h.string().optional().describe(`URL for fetch action (http/https only). Uses page cookies/session.`),fetchMethod:h.enum(Ne).optional().describe(`HTTP method for fetch action (default: GET)`),fetchHeaders:h.record(h.string(),h.string()).optional().describe(`Custom headers for fetch action`),fetchBody:h.string().optional().describe(`Request body for fetch action (POST/PUT/PATCH)`),includeResponseHeaders:h.boolean().optional().describe(`Include response headers in fetch output (default: true)`),fullPage:h.boolean().optional().describe(`Capture full page`),annotate:h.boolean().optional().describe(`Overlay numbered [N] labels on interactive elements matching snapshot ref IDs (screenshot only).`),redactPasswords:h.boolean().optional().describe(`Mask password fields`),readMode:h.enum([`snapshot`,`dom`,`markdown`,`text`]).optional().describe(`Extraction mode for read action: snapshot (ARIA tree), dom (HTML), markdown (clean MD), text (plain text)`),clip:h.object({x:h.number(),y:h.number(),width:h.number(),height:h.number()}).optional().describe(`Capture a specific page region { x, y, width, height }`),format:h.enum([`png`,`jpeg`]).optional().describe(`Screenshot image format (default: png)`),quality:h.number().min(0).max(100).optional().describe(`JPEG quality 0-100 (only for jpeg format)`),cookies:h.array(h.object({name:h.string(),value:h.string(),url:h.string().optional(),domain:h.string().optional(),path:h.string().optional(),expires:h.number().optional(),httpOnly:h.boolean().optional(),secure:h.boolean().optional(),sameSite:h.enum([`Lax`,`None`,`Strict`]).optional()})).optional().describe(`Cookies to set (for session set-cookie action)`),name:h.string().optional().describe(`Cookie name for delete-cookie action`),storageType:h.enum([`localStorage`,`sessionStorage`]).optional().describe(`Storage type for get/set/clear-storage actions`),storageKey:h.string().optional().describe(`Storage key to get or set`),storageValue:h.string().optional().describe(`Value to set in storage`),accept:h.boolean().optional().describe(`Accept or dismiss dialog`),promptText:h.string().optional().describe(`Text for prompt dialog`),sessionAction:h.enum(Pe).optional().describe(`Session sub-action (session only)`),confirm:h.boolean().optional().describe(`Explicit confirmation for cookie export`),steps:h.array(h.record(h.string(),h.unknown())).optional().describe(`Array of action steps for batch execution. Each step is an object with action + action-specific params.`)};function Ie(e,t){return typeof e==`string`&&t.includes(e)}function K(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function Le(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function q(e,t){let n=e[t];return typeof n==`string`?n:void 0}function J(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function Y(e,t){let n=e[t];return typeof n==`number`?n:void 0}function X(e,t){let n=e[t];return typeof n==`object`&&n?n:void 0}function Re(e,t){let n=e.steps;if(!Array.isArray(n)||n.length===0)throw Error(`${t} requires non-empty steps`);return n.map((e,n)=>{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} step ${n+1} must be an object`);return e})}function Z(e,t,n,r){let i=e[t];if(!Ie(i,n))throw Error(`${r} requires ${t}`);return i}function Q(e,t,n,r){let i=e[t];if(i!==void 0){if(!Ie(i,n))throw Error(`${r} received invalid ${t}`);return i}}function ze(e,t){let n=q(e,`pageId`);if(n)return O(t).resolvePageId(n)}function $(e,t,n){let r=q(e,`pageId`);if(!r)throw Error(`${n} requires pageId`);return O(t).resolvePageId(r)}async function Be(e,t,n){let r=Z(e,`action`,B,`browser`);switch(r){case`open`:return t.openHandler({url:K(e,`url`,`browser(open)`),mode:Q(e,`mode`,V,`browser(open)`),forceNew:J(e,`forceNew`),label:q(e,`label`),allowLoopback:J(e,`allowLoopback`),autoDialog:J(e,`autoDialog`),waitUntil:Q(e,`waitUntil`,H,`browser(open)`),includeSnapshot:J(e,`includeSnapshot`)});case`batch`:{let r=Re(e,`browser(batch)`),i=[],a=0;for(let e=0;e<r.length;e+=1){let o=r[e],s=q(o,`action`)??`unknown`;try{let r=await Be(o,t,n);a+=1,i.push({index:e,action:s,ok:!0,result:r})}catch(t){i.push({index:e,action:s,ok:!1,error:t instanceof Error?t.message:String(t)})}}return I(`Batch completed: ${a}/${r.length} steps succeeded`,{total:r.length,succeeded:a,steps:i})}case`read`:return t.readHandler({pageId:$(e,n,`browser(read)`),mode:Q(e,`readMode`,[`snapshot`,`dom`,`markdown`,`text`],`browser(read)`),selector:q(e,`selector`)});case`act`:return t.actHandler({pageId:$(e,n,`browser(act)`),kind:Z(e,`kind`,U,`browser(act)`),ref:q(e,`ref`),selector:q(e,`selector`),element:q(e,`element`),text:q(e,`text`),key:q(e,`key`),value:q(e,`value`),fromRef:q(e,`fromRef`),fromSelector:q(e,`fromSelector`),toRef:q(e,`toRef`),toSelector:q(e,`toSelector`)});case`navigate`:return t.navigateHandler({pageId:$(e,n,`browser(navigate)`),url:q(e,`url`),type:Q(e,`type`,W,`browser(navigate)`),selector:q(e,`selector`),timeoutMs:Y(e,`timeoutMs`),includeSnapshot:J(e,`includeSnapshot`)});case`network`:return t.networkHandler({pageId:$(e,n,`browser(network)`),subAction:Z(e,`subAction`,G,`browser(network)`),filter:X(e,`filter`),showSensitive:J(e,`showSensitive`),includeBody:J(e,`includeBody`),bufferSize:Y(e,`bufferSize`)});case`console`:return t.consoleHandler({pageId:$(e,n,`browser(console)`),subAction:Z(e,`consoleSubAction`,Me,`browser(console)`),level:q(e,`level`),bufferSize:Y(e,`bufferSize`),expression:q(e,`expression`)});case`fetch`:return t.fetchHandler({pageId:$(e,n,`browser(fetch)`),url:K(e,`fetchUrl`,`browser(fetch)`),method:Q(e,`fetchMethod`,Ne,`browser(fetch)`),headers:X(e,`fetchHeaders`),body:q(e,`fetchBody`),timeoutMs:Y(e,`timeoutMs`),includeHeaders:J(e,`includeResponseHeaders`)});case`eval`:return t.evalHandler({pageId:$(e,n,`browser(eval)`),code:K(e,`code`,`browser(eval)`),timeoutMs:Y(e,`timeoutMs`)});case`diff`:return t.diffHandler({pageId:$(e,n,`browser(diff)`)});case`screenshot`:{let r=X(e,`clip`);return t.screenshotHandler({pageId:$(e,n,`browser(screenshot)`),ref:q(e,`ref`),selector:q(e,`selector`),fullPage:J(e,`fullPage`),annotate:J(e,`annotate`),redactPasswords:J(e,`redactPasswords`),clip:r,format:Q(e,`format`,[`png`,`jpeg`],`browser(screenshot)`),quality:Y(e,`quality`)})}case`dialog`:return t.dialogHandler({pageId:$(e,n,`browser(dialog)`),accept:Le(e,`accept`,`browser(dialog)`),promptText:q(e,`promptText`)});case`session`:return t.sessionHandler({sessionAction:Z(e,`sessionAction`,Pe,`browser(session)`),pageId:q(e,`pageId`)&&ze(e,n),confirm:J(e,`confirm`),cookies:X(e,`cookies`),name:q(e,`name`),storageType:Q(e,`storageType`,[`localStorage`,`sessionStorage`],`browser(session)`),storageKey:q(e,`storageKey`),storageValue:q(e,`storageValue`)});default:return I(`Unknown action: ${r}`,{error:`Unknown action: ${r}`})}}function Ve(e,t){let n=ge(t),r={openHandler:Oe(n),readHandler:ke(n),actHandler:ve(n),navigateHandler:Te(n),networkHandler:Ee(n),consoleHandler:ye(n),fetchHandler:Ce(n),evalHandler:Se(n),diffHandler:xe(n),screenshotHandler:Ae(n),dialogHandler:be(n),sessionHandler:je(n)};e.tool(`browser`,`Unified browser automation tool using agent-browser (Chrome DevTools Protocol). Provides open, read, act, navigate, screenshot, eval, dialog, network, console, fetch, diff, session actions. New: includeSnapshot (open/navigate auto-returns ARIA tree), annotate (numbered labels on screenshots), expression (evaluate JS in console action).`,Fe,async e=>{try{let t=await Be(e,r,n);return{content:t.content,structuredContent:t.structuredContent}}catch(e){return{content:[{type:`text`,text:`Browser error: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{E as BrowserEngine,T as DEFAULT_BROWSER_CONFIG,fe as SessionRegistry,w as TabRegistry,S as autoSelectMode,pe as closeEngine,x as ensureAgentBrowserInstalled,ce as getAgentBrowserVersion,C as getDaemonArgs,v as getDefaultBrowsersPath,O as getEngine,de as getLaunchArgs,le as isBrowserReady,k as isUrlAllowed,Ve as registerBrowserTools,y as resolveBrowsersPath,A as validateEvalResult};
|
|
10
|
+
})`}function De(e){return async({pageId:t,url:n,type:r,selector:i,timeoutMs:a,includeSnapshot:o})=>{let s=O(e),c=s.resolvePageId(t);if(n){let t=k(n,e);if(!t.allowed)return I(`Navigation blocked: ${t.reason}`,{blocked:!0,pageId:c,reason:t.reason});await s.tabExec(c,`goto`,n)}else if(!r)return I(`Navigation requires url or type`,{error:`Navigation requires url or type`,pageId:c});else if(r===`back`)await s.tabExec(c,`back`);else if(r===`forward`)await s.tabExec(c,`forward`);else if(r===`reload`)await s.tabExec(c,`reload`);else if(r===`waitFor`){if(!i)throw Error(`browser_navigate(waitFor) requires selector`);let e=a?[i,String(a)]:[i];await s.tabExec(c,`wait`,...e)}let l=await s.tabExec(c,`get`,`text`).catch(()=>({stdout:n??``})),u=await s.tabExec(c,`get`,`attr`,`title`).catch(()=>({stdout:``})),d=l.stdout.trim()||n||``,f=u.stdout.trim()||d;s.tabs.updateTabInfo(c,d,f),s.resetIdleTimer();let p;if(o!==!1)try{p=R(await s.readSnapshot(c))}catch{}return I(p?`${f||d}\n${d}\n\n${p}`:`${f||d}\n${d}`,{pageId:c,url:d,title:f,snapshot:p})}}function Oe(e){return async({pageId:t,subAction:n,filter:r,includeBody:i,bufferSize:a})=>{let o=O(e),s=o.resolvePageId(t);switch(n){case`enable`:{let e=[`--enable`];return r?.resourceTypes&&e.push(`--filter`,r.resourceTypes.join(`,`)),i&&e.push(`--include-body`),a&&e.push(`--buffer-size`,String(a)),await o.tabExec(s,`network`,...e),o.resetIdleTimer(),I(`Network capture enabled`,{enabled:!0,filter:r})}case`get`:{let e=await o.tabExec(s,`network`,`requests`,`--json`);o.resetIdleTimer();let t=[];try{t=JSON.parse(e.stdout)}catch{t=[{raw:e.stdout}]}return I(`Captured ${t.length} network requests`,{entries:t,count:t.length})}case`clear`:return await o.tabExec(s,`network`,`clear`),o.resetIdleTimer(),I(`Network capture cleared`,{cleared:!0});case`export-har`:{let e=await o.tabExec(s,`network`,`har`);return o.resetIdleTimer(),I(e.stdout,{har:e.stdout})}default:return I(`Unknown network sub-action`,{error:`Unknown network sub-action`})}}}const ke=/^https?:\/\/127\.0\.0\.1:\d+\/present\//;function Ae(e){return async({url:t,mode:n,label:r,waitUntil:i,includeSnapshot:a,forceNew:o,allowLoopback:s,autoDialog:c})=>{let l=k(t,s||ke.test(t)?{...e,allowLoopback:!0}:e);if(!l.allowed)return I(`Navigation blocked: ${l.reason}`,{blocked:!0,reason:l.reason});let u=O(e),d=n!==void 0&&n!==u.currentMode,f,p=u.tabs.listTabs();!o&&!d&&p.length>0?(f=p[0].tabId,(await u.navigate(f,t)).exitCode===0?u.tabs.updateTabInfo(f,t,r??t):(f=await u.open(t,n,r),p[0].tabId!==f&&await u.tabs.removeTab(p[0].tabId).catch(()=>{}))):f=await u.open(t,n,r);let m=[];i===`networkidle`&&m.push(`--wait-until`,`networkidle`),i===`domcontentloaded`&&m.push(`--wait-until`,`domcontentloaded`),m.length>0&&await u.tabExec(f,`wait`,...m).catch(()=>{});let h;if(a!==!1)try{h=R(await u.readSnapshot(f))}catch{}return I(h?`Opened ${t}\n\n${h}`:`Opened ${t}\nTab: ${f}`,{pageId:f,url:t,tabId:f,label:r,snapshot:h})}}function je(e){return async({pageId:t,mode:n,selector:r})=>{let i=O(e),a=i.resolvePageId(t);switch(n??`snapshot`){case`snapshot`:{let e=[`-i`,`--json`];r&&e.push(`-s`,r);let t=await i.tabExec(a,`snapshot`,...e);return i.tabs.setSnapshot(a,t.stdout),i.resetIdleTimer(),I(t.stdout,{pageId:a,mode:`snapshot`,content:t.stdout})}case`dom`:{let e=await i.tabExec(a,`get`,`html`);return i.resetIdleTimer(),I(e.stdout,{pageId:a,mode:`dom`,content:e.stdout})}case`markdown`:{let e=await i.tabExec(a,`snapshot`,`-c`);return i.resetIdleTimer(),I(e.stdout,{pageId:a,mode:`markdown`,content:e.stdout})}case`text`:{let e=await i.tabExec(a,`get`,`text`);return i.resetIdleTimer(),I(e.stdout,{pageId:a,mode:`text`,content:e.stdout})}default:return I(`Unknown read mode`,{error:`Unknown read mode`,pageId:a})}}}function Me(e){return async({pageId:t,ref:n,selector:r,fullPage:i,annotate:a,clip:o,format:s,quality:c})=>{let l=O(e),u=l.resolvePageId(t),d=r??n;if(d){let e=await l.tabExec(u,`screenshot`,`--element`,d);return l.resetIdleTimer(),I(`Screenshot captured for element ${d}`,{element:d,pageId:u,screenshot:e.stdout})}let f=await l.screenshot(u,{fullPage:i,format:s,quality:c,annotate:a});return l.resetIdleTimer(),I(`Screenshot captured (${f.bytes} bytes)`,{pageId:u,base64:f.base64,mimeType:f.mimeType,bytes:f.bytes})}}function Ne(e){return async({sessionAction:t,pageId:n,confirm:r,cookies:i,name:a,storageType:o,storageKey:s,storageValue:c})=>{let l=O(e),u=n?l.resolvePageId(n):void 0;switch(t){case`list`:{let e=l.tabs.listPages().map(e=>({pageId:e.pageId,url:e.url,title:e.title,label:e.label,createdAt:e.createdAt.toISOString()}));return I(`Open tabs: ${e.length}\n${e.map(e=>` ${e.pageId}: ${e.title||e.url}`).join(`
|
|
11
|
+
`)}`,{pages:e})}case`close`:return u?(await l.tabExec(u,`close`).catch(()=>{}),await l.tabs.removeTab(u),l.resetIdleTimer(),I(`Closed tab ${u}`,{closed:u})):I(`close requires pageId`,{error:`pageId required`});case`cookies`:{if(!r)return I(`Cookie export requires explicit confirmation. Set confirm: true to proceed.`,{confirmRequired:!0});let e=await l.tabExec(u??`t0`,`cookies`),t=[];try{t=JSON.parse(e.stdout)}catch{t=[{raw:e.stdout}]}return I(`Exported ${t.length} cookies`,{cookies:t,count:t.length})}case`set-cookie`:{if(!i||i.length===0)return I(`set-cookie requires cookies array`,{error:`cookies array required`});let e=i.map(e=>`${e.name}=${e.value}${e.domain?`; domain=${e.domain}`:``}${e.path?`; path=${e.path}`:``}`).join(` `);return await l.tabExec(u??`t0`,`cookies`,`set`,e),l.resetIdleTimer(),I(`Set ${i.length} cookies`,{count:i.length})}case`delete-cookie`:return a?(await l.tabExec(u??`t0`,`cookies`,`clear`,a),l.resetIdleTimer(),I(`Deleted cookie ${a}`,{deleted:a})):I(`delete-cookie requires name`,{error:`name required`});case`clear-cookies`:return await l.tabExec(u??`t0`,`cookies`,`clear`),l.resetIdleTimer(),I(`Cookies cleared`,{cleared:!0});case`get-storage`:{if(!o||!s)return I(`get-storage requires storageType and storageKey`,{error:`storageType and storageKey required`});let e=await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`get`,s);return l.resetIdleTimer(),I(e.stdout,{value:e.stdout})}case`set-storage`:return!o||!s||c===void 0?I(`set-storage requires storageType, storageKey, and storageValue`,{error:`storageType, storageKey, storageValue required`}):(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`set`,s,c),l.resetIdleTimer(),I(`Storage key ${s} set`,{key:s}));case`clear-storage`:return o?(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`clear`),l.resetIdleTimer(),I(`Storage cleared`,{cleared:!0})):I(`clear-storage requires storageType`,{error:`storageType required`});default:return I(`Unknown session action`,{error:`Unknown session action`})}}}const B=[`open`,`batch`,`read`,`act`,`navigate`,`network`,`console`,`fetch`,`eval`,`diff`,`screenshot`,`dialog`,`session`],V=[`ui`,`headless`],H=[`load`,`domcontentloaded`,`networkidle`],U=[`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`],W=[`back`,`forward`,`reload`,`waitFor`],Pe=[`enable`,`get`,`clear`,`export-har`],Fe=[`enable`,`get`,`clear`],Ie=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],Le=[`list`,`close`,`cookies`,`set-cookie`,`delete-cookie`,`clear-cookies`,`get-storage`,`set-storage`,`clear-storage`],Re={action:g.enum(B).describe(`Browser action to perform`),pageId:g.string().optional().describe(`Tracked browser page identifier`),label:g.string().optional().describe(`Human-readable label for the page (used as alternative to pageId)`),url:g.string().url().optional().describe(`URL to open or navigate to`),mode:g.enum(V).optional().describe(`Browser launch mode (open only)`),forceNew:g.boolean().optional().describe(`Force a new tab instead of reusing existing. When true, creates a new browser tab even if one is already open.`),allowLoopback:g.boolean().optional().describe(`Allow loopback/localhost addresses for this call (default: false for security). Set true to navigate to http://127.0.0.1 or localhost URLs.`),autoDialog:g.boolean().optional().describe(`Auto-accept alert/beforeunload dialogs (default: true). Set false to handle all dialogs manually.`),includeSnapshot:g.boolean().optional().describe(`Include ARIA snapshot in response (default: true for open/navigate). Set false to skip snapshot for speed.`),waitUntil:g.enum(H).optional().describe(`Navigation readiness event`),kind:g.enum(U).optional().describe(`Interaction kind (act only)`),ref:g.string().optional().describe(`Target ref alias`),selector:g.string().optional().describe(`CSS selector for targeting`),element:g.string().optional().describe(`Human-readable element label. Prefer selector for precision.`),text:g.string().optional().describe(`Text to type`),key:g.string().optional().describe(`Key to press`),value:g.string().optional().describe(`Option value or drag target`),fromRef:g.string().optional().describe(`Drag source ref`),fromSelector:g.string().optional().describe(`Drag source selector`),toRef:g.string().optional().describe(`Drag target ref`),toSelector:g.string().optional().describe(`Drag target selector`),type:g.enum(W).optional().describe(`Navigation type`),subAction:g.enum(Pe).optional().describe(`Network sub-action: enable, get, clear, or export-har`),code:g.string().optional().describe(`JavaScript expression or IIFE evaluated in page context.`),timeoutMs:g.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),filter:g.object({resourceTypes:g.array(g.string()).optional(),urlPattern:g.string().optional(),excludeUrls:g.array(g.string()).optional()}).optional().describe(`Network capture filter for resource types and URL patterns`),showSensitive:g.boolean().optional().describe(`Include sensitive headers instead of redacting them`),includeBody:g.boolean().optional().describe(`Include truncated request bodies in captured entries`),bufferSize:g.number().int().min(1).max(1e4).optional().describe(`Buffer capacity (1-10000, default varies by action)`),consoleSubAction:g.enum(Fe).optional().describe(`Console sub-action: enable, get, or clear`),expression:g.string().optional().describe(`JavaScript expression to evaluate in page context (console get only). Like browser_console expression in Hermes.`),level:g.string().optional().describe(`Filter console entries by level (log/info/warn/error/debug)`),fetchUrl:g.string().optional().describe(`URL for fetch action (http/https only). Uses page cookies/session.`),fetchMethod:g.enum(Ie).optional().describe(`HTTP method for fetch action (default: GET)`),fetchHeaders:g.record(g.string(),g.string()).optional().describe(`Custom headers for fetch action`),fetchBody:g.string().optional().describe(`Request body for fetch action (POST/PUT/PATCH)`),includeResponseHeaders:g.boolean().optional().describe(`Include response headers in fetch output (default: true)`),fullPage:g.boolean().optional().describe(`Capture full page`),annotate:g.boolean().optional().describe(`Overlay numbered [N] labels on interactive elements matching snapshot ref IDs (screenshot only).`),redactPasswords:g.boolean().optional().describe(`Mask password fields`),readMode:g.enum([`snapshot`,`dom`,`markdown`,`text`]).optional().describe(`Extraction mode for read action: snapshot (ARIA tree), dom (HTML), markdown (clean MD), text (plain text)`),clip:g.object({x:g.number(),y:g.number(),width:g.number(),height:g.number()}).optional().describe(`Capture a specific page region { x, y, width, height }`),format:g.enum([`png`,`jpeg`]).optional().describe(`Screenshot image format (default: png)`),quality:g.number().min(0).max(100).optional().describe(`JPEG quality 0-100 (only for jpeg format)`),cookies:g.array(g.object({name:g.string(),value:g.string(),url:g.string().optional(),domain:g.string().optional(),path:g.string().optional(),expires:g.number().optional(),httpOnly:g.boolean().optional(),secure:g.boolean().optional(),sameSite:g.enum([`Lax`,`None`,`Strict`]).optional()})).optional().describe(`Cookies to set (for session set-cookie action)`),name:g.string().optional().describe(`Cookie name for delete-cookie action`),storageType:g.enum([`localStorage`,`sessionStorage`]).optional().describe(`Storage type for get/set/clear-storage actions`),storageKey:g.string().optional().describe(`Storage key to get or set`),storageValue:g.string().optional().describe(`Value to set in storage`),accept:g.boolean().optional().describe(`Accept or dismiss dialog`),promptText:g.string().optional().describe(`Text for prompt dialog`),sessionAction:g.enum(Le).optional().describe(`Session sub-action (session only)`),confirm:g.boolean().optional().describe(`Explicit confirmation for cookie export`),steps:g.array(g.record(g.string(),g.unknown())).optional().describe(`Array of action steps for batch execution. Each step is an object with action + action-specific params.`)};function G(e,t){return typeof e==`string`&&t.includes(e)}function K(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function ze(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function q(e,t){let n=e[t];return typeof n==`string`?n:void 0}function J(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function Y(e,t){let n=e[t];return typeof n==`number`?n:void 0}function X(e,t){let n=e[t];return typeof n==`object`&&n?n:void 0}function Be(e,t){let n=e.steps;if(!Array.isArray(n)||n.length===0)throw Error(`${t} requires non-empty steps`);return n.map((e,n)=>{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} step ${n+1} must be an object`);return e})}function Z(e,t,n,r){let i=e[t];if(!G(i,n))throw Error(`${r} requires ${t}`);return i}function Q(e,t,n,r){let i=e[t];if(i!==void 0){if(!G(i,n))throw Error(`${r} received invalid ${t}`);return i}}function Ve(e,t){let n=q(e,`pageId`);if(n)return O(t).resolvePageId(n)}function $(e,t,n){let r=q(e,`pageId`);if(!r)throw Error(`${n} requires pageId`);return O(t).resolvePageId(r)}async function He(e,t,n){let r=Z(e,`action`,B,`browser`);switch(r){case`open`:return t.openHandler({url:K(e,`url`,`browser(open)`),mode:Q(e,`mode`,V,`browser(open)`),forceNew:J(e,`forceNew`),label:q(e,`label`),allowLoopback:J(e,`allowLoopback`),autoDialog:J(e,`autoDialog`),waitUntil:Q(e,`waitUntil`,H,`browser(open)`),includeSnapshot:J(e,`includeSnapshot`)});case`batch`:{let r=Be(e,`browser(batch)`),i=[],a=0;for(let e=0;e<r.length;e+=1){let o=r[e],s=q(o,`action`)??`unknown`;try{let r=await He(o,t,n);a+=1,i.push({index:e,action:s,ok:!0,result:r})}catch(t){i.push({index:e,action:s,ok:!1,error:t instanceof Error?t.message:String(t)})}}return I(`Batch completed: ${a}/${r.length} steps succeeded`,{total:r.length,succeeded:a,steps:i})}case`read`:return t.readHandler({pageId:$(e,n,`browser(read)`),mode:Q(e,`readMode`,[`snapshot`,`dom`,`markdown`,`text`],`browser(read)`),selector:q(e,`selector`)});case`act`:return t.actHandler({pageId:$(e,n,`browser(act)`),kind:Z(e,`kind`,U,`browser(act)`),ref:q(e,`ref`),selector:q(e,`selector`),element:q(e,`element`),text:q(e,`text`),key:q(e,`key`),value:q(e,`value`),fromRef:q(e,`fromRef`),fromSelector:q(e,`fromSelector`),toRef:q(e,`toRef`),toSelector:q(e,`toSelector`)});case`navigate`:return t.navigateHandler({pageId:$(e,n,`browser(navigate)`),url:q(e,`url`),type:Q(e,`type`,W,`browser(navigate)`),selector:q(e,`selector`),timeoutMs:Y(e,`timeoutMs`),includeSnapshot:J(e,`includeSnapshot`)});case`network`:return t.networkHandler({pageId:$(e,n,`browser(network)`),subAction:Z(e,`subAction`,Pe,`browser(network)`),filter:X(e,`filter`),showSensitive:J(e,`showSensitive`),includeBody:J(e,`includeBody`),bufferSize:Y(e,`bufferSize`)});case`console`:return t.consoleHandler({pageId:$(e,n,`browser(console)`),subAction:Z(e,`consoleSubAction`,Fe,`browser(console)`),level:q(e,`level`),bufferSize:Y(e,`bufferSize`),expression:q(e,`expression`)});case`fetch`:return t.fetchHandler({pageId:$(e,n,`browser(fetch)`),url:K(e,`fetchUrl`,`browser(fetch)`),method:Q(e,`fetchMethod`,Ie,`browser(fetch)`),headers:X(e,`fetchHeaders`),body:q(e,`fetchBody`),timeoutMs:Y(e,`timeoutMs`),includeHeaders:J(e,`includeResponseHeaders`)});case`eval`:return t.evalHandler({pageId:$(e,n,`browser(eval)`),code:K(e,`code`,`browser(eval)`),timeoutMs:Y(e,`timeoutMs`)});case`diff`:return t.diffHandler({pageId:$(e,n,`browser(diff)`)});case`screenshot`:{let r=X(e,`clip`);return t.screenshotHandler({pageId:$(e,n,`browser(screenshot)`),ref:q(e,`ref`),selector:q(e,`selector`),fullPage:J(e,`fullPage`),annotate:J(e,`annotate`),redactPasswords:J(e,`redactPasswords`),clip:r,format:Q(e,`format`,[`png`,`jpeg`],`browser(screenshot)`),quality:Y(e,`quality`)})}case`dialog`:return t.dialogHandler({pageId:$(e,n,`browser(dialog)`),accept:ze(e,`accept`,`browser(dialog)`),promptText:q(e,`promptText`)});case`session`:return t.sessionHandler({sessionAction:Z(e,`sessionAction`,Le,`browser(session)`),pageId:q(e,`pageId`)&&Ve(e,n),confirm:J(e,`confirm`),cookies:X(e,`cookies`),name:q(e,`name`),storageType:Q(e,`storageType`,[`localStorage`,`sessionStorage`],`browser(session)`),storageKey:q(e,`storageKey`),storageValue:q(e,`storageValue`)});default:return I(`Unknown action: ${r}`,{error:`Unknown action: ${r}`})}}function Ue(e,t){let n=ve(t),r={openHandler:Ae(n),readHandler:je(n),actHandler:be(n),navigateHandler:De(n),networkHandler:Oe(n),consoleHandler:xe(n),fetchHandler:Te(n),evalHandler:we(n),diffHandler:Ce(n),screenshotHandler:Me(n),dialogHandler:Se(n),sessionHandler:Ne(n)};e.tool(`browser`,`Unified browser automation tool using agent-browser (Chrome DevTools Protocol). Provides open, read, act, navigate, screenshot, eval, dialog, network, console, fetch, diff, session actions. New: includeSnapshot (open/navigate auto-returns ARIA tree), annotate (numbered labels on screenshots), expression (evaluate JS in console action).`,Re,async e=>{try{let t=await He(e,r,n);return{content:t.content,structuredContent:t.structuredContent}}catch(e){return{content:[{type:`text`,text:`Browser error: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{T as BrowserEngine,w as DEFAULT_BROWSER_CONFIG,me as SessionRegistry,C as TabRegistry,de as autoSelectMode,he as closeEngine,se as ensureAgentBrowserInstalled,ce as getAgentBrowserVersion,fe as getDaemonArgs,y as getDefaultBrowsersPath,O as getEngine,pe as getLaunchArgs,le as isBrowserReady,k as isUrlAllowed,Ue as registerBrowserTools,b as resolveBrowsersPath,A as validateEvalResult};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "aikit",
|
|
4
4
|
"display_name": "AI Kit",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.395",
|
|
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",
|
|
@@ -48,7 +48,7 @@ Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],ri=[{name:`pro
|
|
|
48
48
|
Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;if(!t)throw new g(`Usage: aikit graph <action>
|
|
49
49
|
Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=_(e,`--type`,``),i=_(e,`--name`,``),a=_(e,`--node-id`,``),o=_(e,`--edge-type`,``),s=_(e,`--direction`,`both`),c=v(e,`--depth`,2),l=v(e,`--limit`,50),u=_(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];if(!d)throw new g(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await Ct(n,{action:d,nodeType:r||void 0,namePattern:i||void 0,sourcePath:u||void 0,nodeId:a||void 0,edgeType:o||void 0,direction:s,maxDepth:c,limit:l});if(console.log(f.summary),f.nodes&&f.nodes.length>0){console.log(`
|
|
50
50
|
Nodes:`);for(let e of f.nodes){let t=Object.keys(e.properties).length>0?` ${JSON.stringify(e.properties)}`:``;console.log(` ${e.name} (${e.type}, id: ${e.id})${t}`)}}if(f.edges&&f.edges.length>0){console.log(`
|
|
51
|
-
Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],vi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=_(e,`--category`,``).trim(),n=s(_(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await p(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),c=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${c.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=_(e,`--category`,``).trim()||void 0,n=_(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await p();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=v(e,`--max-chars`,3e3),n=_(e,`--path`,``).trim()||void 0,r=_(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await p();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ut(o,{path:n,query:i,maxChars:t,segmentation:r}):await ut(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function yi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function bi(){let e=await ar({scope:`user`});if(e.length===0)return 0;let t=Dr(),n=0;for(let r of e)try{let e=await r.readConfig();if(e[r.configKey]?.[`AI Kit`]){await r.unregisterMcp(x),await r.registerMcp(F,t),n++;continue}let i=e[r.configKey]?.[F];if(!i||!yi(i))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(F,t),n++}catch{}return n}const xi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await bi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=I(`cli:rollback`),Si=k(N(),`.aikit`,`versions`),Ci=k(N(),`.aikit`,`current-version.json`),wi=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(Si,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(Si,`current-version.json.tmp`);await R(i,JSON.stringify({version:t},null,2),`utf-8`),await $e(i,Ci),Q.debug(`Switched to v${t}`)}}],Ti=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=h(e),n=v(e,`--limit`,5),r=_(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new g(`Usage: aikit search <query>`);let{embedder:s,store:c,graphStore:l}=await Z(),u=await s.embedQuery(a),d;if(r===`keyword`)d=await c.ftsSearch(a,{limit:n});else if(r===`semantic`)d=await c.search(u,{limit:n});else{let[e,t]=await Promise.all([c.search(u,{limit:n*2}),c.ftsSearch(a,{limit:n*2}).catch(()=>[])]);d=we(e,t).slice(0,n)}if(t){o({query:a,results:d,graphHops:i});return}if(d.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of d){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${d.length} result(s) found.`),i>0&&d.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(l,d.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=h(e),n=v(e,`--limit`,10),r=_(e,`--glob`,``).trim()||void 0,i=_(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new g(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:s,store:c}=await Z(),l=await vt(s,c,{query:a,glob:r,pattern:i,limit:n});if(t){o(l);return}if(l.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${l.strategies.join(`, `)}`),console.log(`Results: ${l.results.length} shown (${l.totalFound} total)`);for(let e of l.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=v(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await en(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${ce(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();te(await sn(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=_(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new g(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();d(await ln(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=v(e,`--limit`,5),n=_(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();l(await bt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=v(e,`--limit`,100),{embedder:n,store:r}=await Z();oe(await yt(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new g(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function Ei(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=ie(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new g(`Server failed to start within 30 seconds.`);let f=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${f}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}const Di=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=h(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:s}=await import(`../../core/dist/index.js`),{existsSync:c}=await import(`node:fs`),l=Ue(),u=a(),d=c(j(l,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=j(l,n.data);else if(u){let e=r(l);f.mode=c(j(l,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=j(l,n.data);u&&!d&&(f.workspaces=s().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){o(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=s();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!c(j(l,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
|
|
51
|
+
Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],vi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=_(e,`--category`,``).trim(),n=s(_(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await p(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),c=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${c.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=_(e,`--category`,``).trim()||void 0,n=_(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await p();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=v(e,`--max-chars`,3e3),n=_(e,`--path`,``).trim()||void 0,r=_(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await p();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ut(o,{path:n,query:i,maxChars:t,segmentation:r}):await ut(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function yi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function bi(){let e=await ar({scope:`user`});if(e.length===0)return 0;let t=Dr(),n=0;for(let r of e)try{let e=await r.readConfig();if(e[r.configKey]?.[`AI Kit`]){await r.unregisterMcp(x),await r.registerMcp(F,t),n++;continue}let i=e[r.configKey]?.[F];if(!i||!yi(i))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(F,t),n++}catch{}return n}const xi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await bi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=I(`cli:rollback`),Si=k(N(),`.aikit`,`versions`),Ci=k(N(),`.aikit`,`current-version.json`),wi=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(Si,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(Si,`current-version.json.tmp`);await R(i,JSON.stringify({version:t},null,2),`utf-8`),await $e(i,Ci),Q.debug(`Switched to v${t}`)}}],Ti=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=h(e),n=v(e,`--limit`,5),r=_(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new g(`Usage: aikit search <query>`);let{embedder:s,store:c,graphStore:l}=await Z(),u=await s.embedQuery(a),d;if(r===`keyword`)d=await c.ftsSearch(a,{limit:n});else if(r===`semantic`)d=await c.search(u,{limit:n});else{let[e,t]=await Promise.all([c.search(u,{limit:n*2}),c.ftsSearch(a,{limit:n*2}).catch(()=>[])]);d=we(e,t).slice(0,n)}if(t){o({query:a,results:d,graphHops:i});return}if(d.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of d){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${d.length} result(s) found.`),i>0&&d.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(l,d.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=h(e),n=v(e,`--limit`,10),r=_(e,`--glob`,``).trim()||void 0,i=_(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new g(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:s,store:c}=await Z(),l=await vt(s,c,{query:a,glob:r,pattern:i,limit:n});if(t){o(l);return}if(l.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${l.strategies.join(`, `)}`),console.log(`Results: ${l.results.length} shown (${l.totalFound} total)`);for(let e of l.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=v(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await en(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${ce(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();te(await sn(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=_(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new g(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();d(await ln(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=v(e,`--limit`,5),n=_(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();l(await bt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=v(e,`--limit`,100),{embedder:n,store:r}=await Z();oe(await yt(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new g(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function Ei(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=ie(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new g(`Server failed to start within 30 seconds.`);let f=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${f}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`rundll32`,[`url.dll,FileProtocolHandler`,l],{stdio:`ignore`,detached:!0,windowsHide:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}const Di=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=h(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:s}=await import(`../../core/dist/index.js`),{existsSync:c}=await import(`node:fs`),l=Ue(),u=a(),d=c(j(l,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=j(l,n.data);else if(u){let e=r(l);f.mode=c(j(l,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=j(l,n.data);u&&!d&&(f.workspaces=s().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){o(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=s();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!c(j(l,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
|
|
52
52
|
`)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=_(e,`--transport`,`stdio`),n=_(e,`--port`,`3210`),r=b(e,`--daemon`);try{await ti({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=mn(ie(),[],{cwd:N(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n)throw new g(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-DMj2ctyd.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-DMj2ctyd.js`);await e({force:a})}else if(t)await Pr({force:a});else if(n){let{initProject:e}=await import(`./init-DMj2ctyd.js`);await e({force:a})}else await Pr({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=_(e,`--cwd`,``).trim()||void 0,n=_(e,`--files`,``),r=_(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await it({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});c(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=h(e),n=Tt(e.shift());if(t){o(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
|
|
53
53
|
`:`🧹 Pruning storage...
|
|
54
54
|
`);let c=await t({dryRun:i,maxAgeDays:s});console.log(`Results:`),console.log(` Forge-ground orphans: ${c.forgeGroundOrphans.count} dirs (${n(c.forgeGroundOrphans.bytesFreed)})`),console.log(` Legacy LanceDB: ${c.legacyLance.count} dirs (${n(c.legacyLance.bytesFreed)})`),console.log(` Empty ephemeral dirs: ${c.emptyEphemeral.count} dirs`),console.log(` Stale partitions: ${c.stalePartitions.count} dirs (${n(c.stalePartitions.bytesFreed)})`),console.log(` Browser profiles: ${c.browserProfiles.count} dirs (${n(c.browserProfiles.bytesFreed)})`),console.log(`\n Total freed: ${n(c.totalBytesFreed)}`),i||(r(),console.log(`
|
|
@@ -5,4 +5,4 @@ import{fileURLToPath as e,pathToFileURL as t}from"node:url";import{parseArgs as
|
|
|
5
5
|
`).length,fileHash:this.hash(e.content),indexedAt:t,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});try{return await this.store.upsert(i,r),e.length}catch(t){z.error(`Failed to upsert curated batch`,{batchSize:e.length,...o(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return z.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...o(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;z.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...o(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),s=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(s,t,n)}}gitCommitKnowledge(e,t,n){try{if(!b(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;x(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!b(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;S([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>C(e)).join(`/`);return t.split(`/`).every(e=>y.test(e))?`${R}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
|
|
6
6
|
`).length,fileHash:this.hash(t),indexedAt:a,origin:`curated`,tags:n.tags,category:n.category,version:n.version};await this.store.upsert([o],[r])}async indexCuratedFileBestEffort(e,t,n,i){if(r.instance().isDegraded(`embedder`)){z.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:i,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){z.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:i,...o(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||l(t))throw Error(`Invalid path: ${t}. Must be relative within .ai/curated/ directory.`);let n=t.split(`/`)[0];return this.validateCategoryName(n),t}validateCategoryName(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid category name: "${e}". Must be lowercase kebab-case (e.g., "decisions", "api-contracts").`)}validateContentSize(e){if(Buffer.byteLength(e,`utf-8`)>L)throw Error(`Content exceeds maximum size of ${L/1024}KB`)}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)}normalizeTags(e){return[...new Set(e.map(e=>e.trim()).filter(Boolean))]}sameTags(e,t){if(e.length!==t.length)return!1;let n=new Set(e);return t.every(e=>n.has(e))}ensureCategoryPath(e,t){if(!e.startsWith(`${t}/`))throw Error(`Curated path "${e}" must stay within category "${t}"`)}async uniqueRelativePath(e,t){let n=`${e}/${t}.md`;if(!await this.adapter.exists(n))return n;for(let n=2;n<=100;n++){let r=`${e}/${t}-${n}.md`;if(!await this.adapter.exists(r))return r}throw Error(`Too many entries with slug "${t}" in category "${e}"`)}hash(e){return v(`sha256`).update(e).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
|
|
7
7
|
`)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
|
|
8
|
-
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
8
|
+
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-BaCFoBkv.js`);await e(t,n.port)}else{let{startStdioMode:e}=await import(`./server-stdio-BRLNHMrk.js`);await e(t)}}K();export{T as a,k as i,I as n,E as o,F as r,O as s,B as t};
|
|
@@ -351,4 +351,4 @@ svg text{fill:var(--body);font-family:var(--sans);font-size:12px}
|
|
|
351
351
|
<\/script>
|
|
352
352
|
</body>
|
|
353
353
|
</html>`}const U=`<!-- DIAGRAM:SVG -->`;function W(e){let t=e.indexOf(U);if(t===-1)return null;let n=t+20,r=e.indexOf(U,n);if(r===-1)return null;let i=e.slice(n,r).trim();if(i.startsWith(`<svg`))return i;let a=e.slice(Math.max(0,t),r+20),o=a.match(/viewBox="([^"]+)"/),s=o?o[1]:`0 0 1200 800`,c=a.match(/width="(\d+)"/),l=c?c[1]:`1200`,u=a.match(/height="(\d+)"/);return[`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${s}" width="${l}" height="${u?u[1]:`800`}">`,` <defs>`,` <style>`,` text { font-family: system-ui, -apple-system, sans-serif; }`,` .title { font-size: 20px; font-weight: 600; fill: #fff; }`,` .subtitle { font-size: 14px; fill: #94a3b8; }`,` </style>`,` </defs>`,i,`</svg>`].join(`
|
|
354
|
-
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
354
|
+
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-B-Shfkdx.js`);await e(n,r.port)}else{let{startStdioMode:e}=await import(`./server-stdio-CU5MD6W_.js`);await e(n)}}export{c as CuratedKnowledgeManager,s as applyWorkspaceRoots,a as bootstrapWorkspaceRoots,i as createSlidingWindowRateLimiter,ge as exportDiagram,W as extractSvg,n as getSessionIdHeader,Te as main,r as readPositiveIntEnv,t as readVersion,ye as renderHtml,be as renderMd,q as renderToResult,e as resolveCorsOrigin,Se as sanitizeTitle,o as selectWorkspaceRoot,xe as validate};
|