@vpxa/aikit 0.1.318 → 0.1.320
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 +1 -1
- package/packages/browser/dist/index.js +2 -3
- package/packages/present/dist/annotation-layer.js +27 -5
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{server-DGrB9gzR.js → server-BYY6wi6v.js} +1 -1
- package/packages/server/dist/{server-BlGKtu2S.js → server-DyYCi71H.js} +1 -1
- package/packages/server/dist/{server-http-DthccA1O.js → server-http-BTLSMqqO.js} +1 -1
- package/packages/server/dist/{server-http-BNOrj77q.js → server-http-BwK7mqRs.js} +1 -1
- package/packages/server/dist/{server-stdio-Bw3pRZal.js → server-stdio-BOx_iUYc.js} +1 -1
- package/packages/server/dist/{server-stdio-4mzpbJ_M.js → server-stdio-ksLTYwSm.js} +1 -1
package/package.json
CHANGED
|
@@ -110,7 +110,7 @@ declare class TabRegistry {
|
|
|
110
110
|
declare class SessionRegistry {
|
|
111
111
|
private tabs;
|
|
112
112
|
registerPage(pageId: string, url: string, title: string, label?: string): string;
|
|
113
|
-
getPage(
|
|
113
|
+
getPage(_pageId: string): never;
|
|
114
114
|
getPageInfo(pageId: string): PageInfo;
|
|
115
115
|
resolvePageId(pageIdOrLabel: string): string;
|
|
116
116
|
setSnapshot(pageId: string, snapshot: string): void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import{execFile as e,execFileSync as t,execSync as n}from"node:child_process";import{existsSync as r,mkdirSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"node:fs";import{homedir as c,platform as l,tmpdir as u}from"node:os";import{join as d}from"node:path";import{z as f}from"zod";const p=`0.26.0`,m=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function h(){return d(c(),`.aikit`,`browsers`)}function g(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??h()}function _(){try{return n(`${l()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,stdio:`pipe`,timeout:3e3}).trim().split(`
|
|
2
|
-
`)[0]}catch{return null}}function v(e){return d(e,`agent-browser`,te())}function te(){switch(l()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function y(e,t){try{s(d(e,m),t,`utf8`)}catch{}}function ne(e){try{return a(d(e,m),`utf8`).trim()}catch{return null}}function re(e){let t=ne(e);return t?ie(t,p)>=0:!1}function ie(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 ae(e){return!!(r(d(e,`chrome`))||r(d(c(),`.cache`,`agent-browser`,`chrome`)))}async function b(e,t){let a=_();if(a)return t?.(`Using globally installed agent-browser`),a;let o=g(e);r(o)||i(o,{recursive:!0});let s=v(o);if(r(s)&&re(o))return t?.(`Using cached agent-browser at ${s}`),s;t?.(`Downloading agent-browser (first use)...`);try{n(`npx -y agent-browser@latest install --install-dir "${o}"`,{stdio:`pipe`,timeout:12e4,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:o}})}catch(e){let t=e,n=ee(t.stderr)||ee(t.stdout)||t.message||`Unknown agent-browser install failure`;throw Error(`Failed to install agent-browser: ${n}`)}let c=s;try{let e=n(`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&r(e)&&(c=e,y(o,p))}catch{try{let e=n(`npx -y agent-browser --version`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&y(o,e)}catch{}}return t?.(`agent-browser ready`),c}async function oe(e){try{return t(e,[`--version`],{encoding:`utf8`,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function se(e){if(_())return!0;let t=g(e);return ae(t)||r(v(t))}const ce=[`ui`,`headless`];function x(e){return ce.includes(e)?e:`headless`}function S(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function le(e){return{headless:e===`headless`,args:S(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}},ue=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:10,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var de=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){if(!this._isLaunched){this._currentMode=x(e??this.config.defaultMode),this.binaryPath=await b(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(t,...n){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let r=[t,...n];return new Promise((t,n)=>{e(this.binaryPath,r,{timeout:this.config.evalTimeoutMs,env:{...process.env,AGENT_BROWSER_IDLE_TIMEOUT_MS:String(this.config.idleShutdownMinutes*60*1e3)}},(e,r,i)=>{if(e&&e.code===`ENOENT`){n(Error(`agent-browser binary not found at ${this.binaryPath}`));return}t({stdout:r??``,stderr:i??``,exitCode:e?.code?Number(e.code):0})}).stdin?.end()})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=await this.exec(`open`,e);return this.tabs.register(`t0`,e,r.stdout.trim(),n),this.resetIdleTimer(),`t0`}async screenshot(e,t){let n=t?.format??`png`,r=n===`jpeg`?`image/jpeg`:`image/png`,i=n===`jpeg`?`jpg`:`png`,s=d(u(),`aikit-screenshot-${Date.now()}.${i}`),c=[s];t?.fullPage&&c.push(`--full`),t?.format===`jpeg`&&c.push(`--screenshot-format`,`jpeg`),t?.quality&&c.push(`--screenshot-quality`,String(t.quality)),await this.tabExec(e,`screenshot`,...c);let l=a(s),f=l.toString(`base64`);try{o(s)}catch{}return this.resetIdleTimer(),{base64:f,mimeType:r,bytes:l.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._isLaunched=!1,this._currentMode=null}}isLaunched(){return this._isLaunched}getConfig(){return this.config}resolvePageId(e){return this.tabs.resolve(e)}resetIdleTimer(){this.stopIdleTimer();let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);e.unref?.(),this.idleTimer=e}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}};let T=null;function E(e){return T||=new de(e),T}async function fe(){T&&=(await T.close(),null)}function D(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 pe(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`)+`
|
|
3
|
-
... [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 O(e){return typeof e==`string`&&e.length>0?e:void 0}function k(e){return typeof e==`boolean`?e:void 0}function A(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function j(e){return typeof e==`string`&&me.includes(e)?e:void 0}function M(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{...w,defaultMode:j(process.env.AIKIT_BROWSER_DEFAULT_MODE)??j(t.defaultMode)??w.defaultMode,browsersPath:O(process.env.AIKIT_BROWSER_PATH)??O(process.env.AIKIT_BROWSER_BROWSERS_PATH)??O(t.browsersPath)??w.browsersPath,userDataDirRoot:O(t.userDataDirRoot)??w.userDataDirRoot,idleShutdownMinutes:M(`AIKIT_BROWSER_IDLE_MINUTES`)??A(t.idleShutdownMinutes)??w.idleShutdownMinutes,allowInternalSchemes:k(t.allowInternalSchemes)??w.allowInternalSchemes,allowLoopback:k(t.allowLoopback)??w.allowLoopback,evalTimeoutMs:M(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??A(t.evalTimeoutMs)??w.evalTimeoutMs,evalMaxResultBytes:A(t.evalMaxResultBytes)??w.evalMaxResultBytes,redactPasswordFieldsInScreenshots:k(t.redactPasswordFieldsInScreenshots)??w.redactPasswordFieldsInScreenshots,engine:O(t.engine)??w.engine,proxy:O(t.proxy),viewport:O(t.viewport)}}function N(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function P(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 _e(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=E(e),m=p.resolvePageId(t);switch(n){case`click`:{let e=P({ref:r,selector:i,element:a},`browser_act(click)`);await p.tabExec(m,`click`,e);break}case`type`:{let e=P({ref:r,selector:i,element:a},`browser_act(type)`);await p.tabExec(m,`fill`,e,o??``);break}case`press`:{let e=P({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=P({ref:r,selector:i,element:a},`browser_act(hover)`);await p.tabExec(m,`hover`,e);break}case`drag`:{let e=P({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=P({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await p.tabExec(m,`drag`,e,t);break}case`select`:{let e=P({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=P({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=P({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(),N(`ok`,{ok:!0})}}function ve(e){return async({pageId:t,subAction:n,level:r,bufferSize:i})=>{let a=E(e),o=a.resolvePageId(t);switch(n){case`enable`:{let e=[`--enable`];return i&&e.push(`--buffer-size`,String(i)),r&&e.push(`--level`,r),await a.tabExec(o,`console`,...e),a.resetIdleTimer(),N(`Console capture enabled`,{enabled:!0})}case`get`:{let e=[`--json`];r&&e.push(`--level`,r);let t=await a.tabExec(o,`console`,...e);a.resetIdleTimer();let n=[];try{n=JSON.parse(t.stdout)}catch{n=[{raw:t.stdout}]}return N(`Console has ${n.length} entries`,{entries:n,count:n.length})}case`clear`:return await a.tabExec(o,`console`,`clear`),a.resetIdleTimer(),N(`Console cleared`,{cleared:!0});default:return N(`Unknown console sub-action`,{error:`Unknown console sub-action`})}}}function ye(e){return async({pageId:t,accept:n,promptText:r})=>{let i=E(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(),N(`Dialog ${n?`accepted`:`dismissed`}`,{accepted:n})}}function be(e){return async({pageId:t})=>{let n=E(e),r=n.resolvePageId(t),i=await n.tabExec(r,`diff`,`snapshot`);return n.resetIdleTimer(),N(i.stdout,{pageId:r,diff:i.stdout})}}function xe(e){return async({pageId:t,code:n,timeoutMs:r})=>{let i=E(e),a=i.resolvePageId(t),o=r??e.evalTimeoutMs,s=await i.tabExec(a,`evaluate`,`--timeout=${o}`,`--`,n);i.resetIdleTimer();let c=pe(s.stdout,e.evalMaxResultBytes);return N(c.result,{pageId:a,result:c.result,truncated:c.truncated})}}function Se(e){return async({pageId:t,url:n,method:r,headers:i,body:a,timeoutMs:o,includeHeaders:s})=>{let c=E(e),l=c.resolvePageId(t),u=o??e.evalTimeoutMs,d=Ce(n,r??`GET`,s??!0,i,a),f=await c.tabExec(l,`evaluate`,`--timeout=${u}`,`--`,d);return c.resetIdleTimer(),N(f.stdout,{pageId:l,response:f.stdout})}}function Ce(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 => {
|
|
2
|
+
`)[0]}catch{return null}}function v(e){return d(e,`agent-browser`,te())}function te(){switch(l()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function y(e,t){try{s(d(e,m),t,`utf8`)}catch{}}function ne(e){try{return a(d(e,m),`utf8`).trim()}catch{return null}}function re(e){let t=ne(e);return t?ie(t,p)>=0:!1}function ie(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 ae(e){return!!(r(d(e,`chrome`))||r(d(c(),`.cache`,`agent-browser`,`chrome`)))}async function b(e,t){let a=_();if(a)return t?.(`Using globally installed agent-browser`),a;let o=g(e);r(o)||i(o,{recursive:!0});let s=v(o);if(r(s)&&re(o))return t?.(`Using cached agent-browser at ${s}`),s;t?.(`Downloading agent-browser (first use)...`);try{n(`npx -y agent-browser@latest install --install-dir "${o}"`,{stdio:`pipe`,timeout:12e4,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:o}})}catch(e){let t=e,n=ee(t.stderr)||ee(t.stdout)||t.message||`Unknown agent-browser install failure`;throw Error(`Failed to install agent-browser: ${n}`)}let c=s;try{let e=n(`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&r(e)&&(c=e,y(o,p))}catch{try{let e=n(`npx -y agent-browser --version`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&y(o,e)}catch{}}return t?.(`agent-browser ready`),c}async function oe(e){try{return t(e,[`--version`],{encoding:`utf8`,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function se(e){if(_())return!0;let t=g(e);return ae(t)||r(v(t))}const ce=[`ui`,`headless`];function x(e){return ce.includes(e)?e:`headless`}function S(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function le(e){return{headless:e===`headless`,args:S(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}},ue=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:10,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:1e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var de=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){if(!this._isLaunched){this._currentMode=x(e??this.config.defaultMode),this.binaryPath=await b(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(t,...n){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let r=[t,...n];return new Promise((t,n)=>{e(this.binaryPath,r,{timeout:this.config.evalTimeoutMs,env:{...process.env,AGENT_BROWSER_IDLE_TIMEOUT_MS:String(this.config.idleShutdownMinutes*60*1e3)}},(e,r,i)=>{if(e&&e.code===`ENOENT`){n(Error(`agent-browser binary not found at ${this.binaryPath}`));return}t({stdout:r??``,stderr:i??``,exitCode:e?.code?Number(e.code):0})}).stdin?.end()})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=await this.exec(`open`,e);return this.tabs.register(`t0`,e,r.stdout.trim(),n),this.resetIdleTimer(),`t0`}async screenshot(e,t){let n=t?.format??`png`,r=n===`jpeg`?`image/jpeg`:`image/png`,i=n===`jpeg`?`jpg`:`png`,s=d(u(),`aikit-screenshot-${Date.now()}.${i}`),c=[s];t?.fullPage&&c.push(`--full`),t?.format===`jpeg`&&c.push(`--screenshot-format`,`jpeg`),t?.quality&&c.push(`--screenshot-quality`,String(t.quality)),await this.tabExec(e,`screenshot`,...c);let l=a(s),f=l.toString(`base64`);try{o(s)}catch{}return this.resetIdleTimer(),{base64:f,mimeType:r,bytes:l.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._isLaunched=!1,this._currentMode=null}}isLaunched(){return this._isLaunched}getConfig(){return this.config}resolvePageId(e){return this.tabs.resolve(e)}resetIdleTimer(){this.stopIdleTimer();let e=setTimeout(()=>{this.close()},this.config.idleShutdownMinutes*6e4);e.unref?.(),this.idleTimer=e}stopIdleTimer(){this.idleTimer&&=(clearTimeout(this.idleTimer),null)}};let T=null;function E(e){return T||=new de(e),T}async function fe(){T&&=(await T.close(),null)}function D(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 pe(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 O(e){return typeof e==`string`&&e.length>0?e:void 0}function k(e){return typeof e==`boolean`?e:void 0}function A(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function j(e){return typeof e==`string`&&me.includes(e)?e:void 0}function M(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{...w,defaultMode:j(process.env.AIKIT_BROWSER_DEFAULT_MODE)??j(t.defaultMode)??w.defaultMode,browsersPath:O(process.env.AIKIT_BROWSER_PATH)??O(process.env.AIKIT_BROWSER_BROWSERS_PATH)??O(t.browsersPath)??w.browsersPath,userDataDirRoot:O(t.userDataDirRoot)??w.userDataDirRoot,idleShutdownMinutes:M(`AIKIT_BROWSER_IDLE_MINUTES`)??A(t.idleShutdownMinutes)??w.idleShutdownMinutes,allowInternalSchemes:k(t.allowInternalSchemes)??w.allowInternalSchemes,allowLoopback:k(t.allowLoopback)??w.allowLoopback,evalTimeoutMs:M(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??A(t.evalTimeoutMs)??w.evalTimeoutMs,evalMaxResultBytes:A(t.evalMaxResultBytes)??w.evalMaxResultBytes,redactPasswordFieldsInScreenshots:k(t.redactPasswordFieldsInScreenshots)??w.redactPasswordFieldsInScreenshots,engine:O(t.engine)??w.engine,proxy:O(t.proxy),viewport:O(t.viewport)}}function N(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function P(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 _e(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=E(e),m=p.resolvePageId(t);switch(n){case`click`:{let e=P({ref:r,selector:i,element:a},`browser_act(click)`);await p.tabExec(m,`click`,e);break}case`type`:{let e=P({ref:r,selector:i,element:a},`browser_act(type)`);await p.tabExec(m,`fill`,e,o??``);break}case`press`:{let e=P({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=P({ref:r,selector:i,element:a},`browser_act(hover)`);await p.tabExec(m,`hover`,e);break}case`drag`:{let e=P({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=P({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await p.tabExec(m,`drag`,e,t);break}case`select`:{let e=P({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=P({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=P({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(),N(`ok`,{ok:!0})}}function ve(e){return async({pageId:t,subAction:n,level:r,bufferSize:i})=>{let a=E(e),o=a.resolvePageId(t);switch(n){case`enable`:{let e=[`--enable`];return i&&e.push(`--buffer-size`,String(i)),r&&e.push(`--level`,r),await a.tabExec(o,`console`,...e),a.resetIdleTimer(),N(`Console capture enabled`,{enabled:!0})}case`get`:{let e=[`--json`];r&&e.push(`--level`,r);let t=await a.tabExec(o,`console`,...e);a.resetIdleTimer();let n=[];try{n=JSON.parse(t.stdout)}catch{n=[{raw:t.stdout}]}return N(`Console has ${n.length} entries`,{entries:n,count:n.length})}case`clear`:return await a.tabExec(o,`console`,`clear`),a.resetIdleTimer(),N(`Console cleared`,{cleared:!0});default:return N(`Unknown console sub-action`,{error:`Unknown console sub-action`})}}}function ye(e){return async({pageId:t,accept:n,promptText:r})=>{let i=E(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(),N(`Dialog ${n?`accepted`:`dismissed`}`,{accepted:n})}}function be(e){return async({pageId:t})=>{let n=E(e),r=n.resolvePageId(t),i=await n.tabExec(r,`diff`,`snapshot`);return n.resetIdleTimer(),N(i.stdout,{pageId:r,diff:i.stdout})}}function xe(e){return async({pageId:t,code:n,timeoutMs:r})=>{let i=E(e),a=i.resolvePageId(t),o=r??e.evalTimeoutMs,s=await i.tabExec(a,`evaluate`,`--timeout=${o}`,`--`,n);i.resetIdleTimer();let c=pe(s.stdout,e.evalMaxResultBytes);return N(c.result,{pageId:a,result:c.result,truncated:c.truncated})}}function Se(e){return async({pageId:t,url:n,method:r,headers:i,body:a,timeoutMs:o,includeHeaders:s})=>{let c=E(e),l=c.resolvePageId(t),u=o??e.evalTimeoutMs,d=Ce(n,r??`GET`,s??!0,i,a),f=await c.tabExec(l,`evaluate`,`--timeout=${u}`,`--`,d);return c.resetIdleTimer(),N(f.stdout,{pageId:l,response:f.stdout})}}function Ce(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 => {
|
|
4
3
|
const text = await r.text();
|
|
5
4
|
const headers = {};
|
|
6
5
|
r.headers.forEach((v, k) => { headers[k] = v; });
|
|
@@ -8,5 +7,5 @@ import{execFile as e,execFileSync as t,execSync as n}from"node:child_process";im
|
|
|
8
7
|
})`:`fetch(${JSON.stringify(e)}, ${o}).then(async r => {
|
|
9
8
|
const text = await r.text();
|
|
10
9
|
return JSON.stringify({ status: r.status, statusText: r.statusText, body: text.slice(0, 100000) });
|
|
11
|
-
})`}function we(e){return async({pageId:t,url:n,type:r,selector:i,timeoutMs:a})=>{let o=E(e),s=o.resolvePageId(t);if(n){let t=D(n,e);if(!t.allowed)return N(`Navigation blocked: ${t.reason}`,{blocked:!0,pageId:s,reason:t.reason});await o.tabExec(s,`goto`,n)}else if(!r)return N(`Navigation requires url or type`,{error:`Navigation requires url or type`,pageId:s});else if(r===`back`)await o.tabExec(s,`back`);else if(r===`forward`)await o.tabExec(s,`forward`);else if(r===`reload`)await o.tabExec(s,`reload`);else if(r===`waitFor`){if(!i)throw Error(`browser_navigate(waitFor) requires selector`);let e=a?[i,String(a)]:[i];await o.tabExec(s,`wait`,...e)}let c=await o.tabExec(s,`get`,`text`).catch(()=>({stdout:n??``})),l=await o.tabExec(s,`get`,`attr`,`title`).catch(()=>({stdout:``})),u=c.stdout.trim()||n||``,d=l.stdout.trim()||u;return o.tabs.updateTabInfo(s,u,d),o.resetIdleTimer(),N(`${d||u}\n${u}`,{pageId:s,url:u,title:d})}}function Te(e){return async({pageId:t,subAction:n,filter:r,includeBody:i,bufferSize:a})=>{let o=E(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(),N(`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 N(`Captured ${t.length} network requests`,{entries:t,count:t.length})}case`clear`:return await o.tabExec(s,`network`,`clear`),o.resetIdleTimer(),N(`Network capture cleared`,{cleared:!0});case`export-har`:{let e=await o.tabExec(s,`network`,`har`);return o.resetIdleTimer(),N(e.stdout,{har:e.stdout})}default:return N(`Unknown network sub-action`,{error:`Unknown network sub-action`})}}}function Ee(e){return async({url:t,mode:n,label:r,waitUntil:i,forceNew:a,autoDialog:o})=>{let s=D(t,e);if(!s.allowed)return N(`Navigation blocked: ${s.reason}`,{blocked:!0,reason:s.reason});let c=E(e);await c.launch(n);let l=await c.exec(`open`,t);c.tabs.register(`t0`,t,r??l.stdout.trim(),r),c.resetIdleTimer();let u=[];return i===`networkidle`&&u.push(`--wait-until`,`networkidle`),i===`domcontentloaded`&&u.push(`--wait-until`,`domcontentloaded`),u.length>0&&await c.tabExec(`t0`,`wait`,...u).catch(()=>{}),N(`Opened ${t}\nTab: t0`,{pageId:`t0`,url:t,tabId:`t0`,label:r})}}function De(e){return async({pageId:t,mode:n,selector:r})=>{let i=E(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(),N(t.stdout,{pageId:a,mode:`snapshot`,content:t.stdout})}case`dom`:{let e=await i.tabExec(a,`get`,`html`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`dom`,content:e.stdout})}case`markdown`:{let e=await i.tabExec(a,`snapshot`,`-c`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`markdown`,content:e.stdout})}case`text`:{let e=await i.tabExec(a,`get`,`text`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`text`,content:e.stdout})}default:return N(`Unknown read mode`,{error:`Unknown read mode`,pageId:a})}}}function Oe(e){return async({pageId:t,ref:n,selector:r,fullPage:i,clip:a,format:o,quality:s})=>{let c=E(e),l=c.resolvePageId(t);if(
|
|
10
|
+
})`}function we(e){return async({pageId:t,url:n,type:r,selector:i,timeoutMs:a})=>{let o=E(e),s=o.resolvePageId(t);if(n){let t=D(n,e);if(!t.allowed)return N(`Navigation blocked: ${t.reason}`,{blocked:!0,pageId:s,reason:t.reason});await o.tabExec(s,`goto`,n)}else if(!r)return N(`Navigation requires url or type`,{error:`Navigation requires url or type`,pageId:s});else if(r===`back`)await o.tabExec(s,`back`);else if(r===`forward`)await o.tabExec(s,`forward`);else if(r===`reload`)await o.tabExec(s,`reload`);else if(r===`waitFor`){if(!i)throw Error(`browser_navigate(waitFor) requires selector`);let e=a?[i,String(a)]:[i];await o.tabExec(s,`wait`,...e)}let c=await o.tabExec(s,`get`,`text`).catch(()=>({stdout:n??``})),l=await o.tabExec(s,`get`,`attr`,`title`).catch(()=>({stdout:``})),u=c.stdout.trim()||n||``,d=l.stdout.trim()||u;return o.tabs.updateTabInfo(s,u,d),o.resetIdleTimer(),N(`${d||u}\n${u}`,{pageId:s,url:u,title:d})}}function Te(e){return async({pageId:t,subAction:n,filter:r,includeBody:i,bufferSize:a})=>{let o=E(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(),N(`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 N(`Captured ${t.length} network requests`,{entries:t,count:t.length})}case`clear`:return await o.tabExec(s,`network`,`clear`),o.resetIdleTimer(),N(`Network capture cleared`,{cleared:!0});case`export-har`:{let e=await o.tabExec(s,`network`,`har`);return o.resetIdleTimer(),N(e.stdout,{har:e.stdout})}default:return N(`Unknown network sub-action`,{error:`Unknown network sub-action`})}}}function Ee(e){return async({url:t,mode:n,label:r,waitUntil:i,forceNew:a,autoDialog:o})=>{let s=D(t,e);if(!s.allowed)return N(`Navigation blocked: ${s.reason}`,{blocked:!0,reason:s.reason});let c=E(e);await c.launch(n);let l=await c.exec(`open`,t);c.tabs.register(`t0`,t,r??l.stdout.trim(),r),c.resetIdleTimer();let u=[];return i===`networkidle`&&u.push(`--wait-until`,`networkidle`),i===`domcontentloaded`&&u.push(`--wait-until`,`domcontentloaded`),u.length>0&&await c.tabExec(`t0`,`wait`,...u).catch(()=>{}),N(`Opened ${t}\nTab: t0`,{pageId:`t0`,url:t,tabId:`t0`,label:r})}}function De(e){return async({pageId:t,mode:n,selector:r})=>{let i=E(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(),N(t.stdout,{pageId:a,mode:`snapshot`,content:t.stdout})}case`dom`:{let e=await i.tabExec(a,`get`,`html`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`dom`,content:e.stdout})}case`markdown`:{let e=await i.tabExec(a,`snapshot`,`-c`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`markdown`,content:e.stdout})}case`text`:{let e=await i.tabExec(a,`get`,`text`);return i.resetIdleTimer(),N(e.stdout,{pageId:a,mode:`text`,content:e.stdout})}default:return N(`Unknown read mode`,{error:`Unknown read mode`,pageId:a})}}}function Oe(e){return async({pageId:t,ref:n,selector:r,fullPage:i,clip:a,format:o,quality:s})=>{let c=E(e),l=c.resolvePageId(t),u=r??n;if(u){let e=await c.tabExec(l,`screenshot`,`--element`,u);return c.resetIdleTimer(),N(`Screenshot captured for element ${u}`,{element:u,pageId:l,screenshot:e.stdout})}let d=await c.screenshot(l,{fullPage:i,format:o,quality:s});return c.resetIdleTimer(),N(`Screenshot captured (${d.bytes} bytes)`,{pageId:l,base64:d.base64,mimeType:d.mimeType,bytes:d.bytes})}}function ke(e){return async({sessionAction:t,pageId:n,confirm:r,cookies:i,name:a,storageType:o,storageKey:s,storageValue:c})=>{let l=E(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 N(`Open tabs: ${e.length}\n${e.map(e=>` ${e.pageId}: ${e.title||e.url}`).join(`
|
|
12
11
|
`)}`,{pages:e})}case`close`:return u?(await l.tabExec(u,`close`).catch(()=>{}),await l.tabs.removeTab(u),l.resetIdleTimer(),N(`Closed tab ${u}`,{closed:u})):N(`close requires pageId`,{error:`pageId required`});case`cookies`:{if(!r)return N(`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 N(`Exported ${t.length} cookies`,{cookies:t,count:t.length})}case`set-cookie`:{if(!i||i.length===0)return N(`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(),N(`Set ${i.length} cookies`,{count:i.length})}case`delete-cookie`:return a?(await l.tabExec(u??`t0`,`cookies`,`clear`,a),l.resetIdleTimer(),N(`Deleted cookie ${a}`,{deleted:a})):N(`delete-cookie requires name`,{error:`name required`});case`clear-cookies`:return await l.tabExec(u??`t0`,`cookies`,`clear`),l.resetIdleTimer(),N(`Cookies cleared`,{cleared:!0});case`get-storage`:{if(!o||!s)return N(`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(),N(e.stdout,{value:e.stdout})}case`set-storage`:return!o||!s||c===void 0?N(`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(),N(`Storage key ${s} set`,{key:s}));case`clear-storage`:return o?(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`clear`),l.resetIdleTimer(),N(`Storage cleared`,{cleared:!0})):N(`clear-storage requires storageType`,{error:`storageType required`});default:return N(`Unknown session action`,{error:`Unknown session action`})}}}const F=[`open`,`batch`,`read`,`act`,`navigate`,`network`,`console`,`fetch`,`eval`,`diff`,`screenshot`,`dialog`,`session`],I=[`ui`,`headless`],L=[`load`,`domcontentloaded`,`networkidle`],R=[`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`],z=[`back`,`forward`,`reload`,`waitFor`],B=[`enable`,`get`,`clear`,`export-har`],V=[`enable`,`get`,`clear`],H=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],U=[`list`,`close`,`cookies`,`set-cookie`,`delete-cookie`,`clear-cookies`,`get-storage`,`set-storage`,`clear-storage`],Ae={action:f.enum(F).describe(`Browser action to perform`),pageId:f.string().optional().describe(`Tracked browser page identifier`),label:f.string().optional().describe(`Human-readable label for the page (used as alternative to pageId)`),url:f.string().url().optional().describe(`URL to open or navigate to`),mode:f.enum(I).optional().describe(`Browser launch mode (open only)`),forceNew:f.boolean().optional().describe(`Reserved for future tab reuse`),autoDialog:f.boolean().optional().describe(`Auto-accept alert/beforeunload dialogs (default: true). Set false to handle all dialogs manually.`),waitUntil:f.enum(L).optional().describe(`Navigation readiness event`),kind:f.enum(R).optional().describe(`Interaction kind (act only)`),ref:f.string().optional().describe(`Target ref alias`),selector:f.string().optional().describe(`CSS selector for targeting`),element:f.string().optional().describe(`Human-readable element label. Prefer selector for precision.`),text:f.string().optional().describe(`Text to type`),key:f.string().optional().describe(`Key to press`),value:f.string().optional().describe(`Option value or drag target`),fromRef:f.string().optional().describe(`Drag source ref`),fromSelector:f.string().optional().describe(`Drag source selector`),toRef:f.string().optional().describe(`Drag target ref`),toSelector:f.string().optional().describe(`Drag target selector`),type:f.enum(z).optional().describe(`Navigation type`),subAction:f.enum(B).optional().describe(`Network sub-action: enable, get, clear, or export-har`),code:f.string().optional().describe(`JavaScript expression or IIFE evaluated in page context.`),timeoutMs:f.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),filter:f.object({resourceTypes:f.array(f.string()).optional(),urlPattern:f.string().optional(),excludeUrls:f.array(f.string()).optional()}).optional().describe(`Network capture filter for resource types and URL patterns`),showSensitive:f.boolean().optional().describe(`Include sensitive headers instead of redacting them`),includeBody:f.boolean().optional().describe(`Include truncated request bodies in captured entries`),bufferSize:f.number().int().min(1).max(1e4).optional().describe(`Buffer capacity (1-10000, default varies by action)`),consoleSubAction:f.enum(V).optional().describe(`Console sub-action: enable, get, or clear`),level:f.string().optional().describe(`Filter console entries by level (log/info/warn/error/debug)`),fetchUrl:f.string().optional().describe(`URL for fetch action (http/https only). Uses page cookies/session.`),fetchMethod:f.enum(H).optional().describe(`HTTP method for fetch action (default: GET)`),fetchHeaders:f.record(f.string(),f.string()).optional().describe(`Custom headers for fetch action`),fetchBody:f.string().optional().describe(`Request body for fetch action (POST/PUT/PATCH)`),includeResponseHeaders:f.boolean().optional().describe(`Include response headers in fetch output (default: true)`),fullPage:f.boolean().optional().describe(`Capture full page`),redactPasswords:f.boolean().optional().describe(`Mask password fields`),readMode:f.enum([`snapshot`,`dom`,`markdown`,`text`]).optional().describe(`Extraction mode for read action: snapshot (ARIA tree), dom (HTML), markdown (clean MD), text (plain text)`),clip:f.object({x:f.number(),y:f.number(),width:f.number(),height:f.number()}).optional().describe(`Capture a specific page region { x, y, width, height }`),format:f.enum([`png`,`jpeg`]).optional().describe(`Screenshot image format (default: png)`),quality:f.number().min(0).max(100).optional().describe(`JPEG quality 0-100 (only for jpeg format)`),cookies:f.array(f.object({name:f.string(),value:f.string(),url:f.string().optional(),domain:f.string().optional(),path:f.string().optional(),expires:f.number().optional(),httpOnly:f.boolean().optional(),secure:f.boolean().optional(),sameSite:f.enum([`Lax`,`None`,`Strict`]).optional()})).optional().describe(`Cookies to set (for session set-cookie action)`),name:f.string().optional().describe(`Cookie name for delete-cookie action`),storageType:f.enum([`localStorage`,`sessionStorage`]).optional().describe(`Storage type for get/set/clear-storage actions`),storageKey:f.string().optional().describe(`Storage key to get or set`),storageValue:f.string().optional().describe(`Value to set in storage`),accept:f.boolean().optional().describe(`Accept or dismiss dialog`),promptText:f.string().optional().describe(`Text for prompt dialog`),sessionAction:f.enum(U).optional().describe(`Session sub-action (session only)`),confirm:f.boolean().optional().describe(`Explicit confirmation for cookie export`),steps:f.array(f.record(f.string(),f.unknown())).optional().describe(`Array of action steps for batch execution. Each step is an object with action + action-specific params.`)};function W(e,t){return typeof e==`string`&&t.includes(e)}function G(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function je(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function K(e,t){let n=e[t];return typeof n==`string`?n:void 0}function q(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function J(e,t){let n=e[t];return typeof n==`number`?n:void 0}function Y(e,t){let n=e[t];return typeof n==`object`&&n?n:void 0}function Me(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 X(e,t,n,r){let i=e[t];if(!W(i,n))throw Error(`${r} requires ${t}`);return i}function Z(e,t,n,r){let i=e[t];if(i!==void 0){if(!W(i,n))throw Error(`${r} received invalid ${t}`);return i}}function Ne(e,t){let n=K(e,`pageId`);if(n)return E(t).resolvePageId(n)}function Q(e,t,n){let r=K(e,`pageId`);if(!r)throw Error(`${n} requires pageId`);return E(t).resolvePageId(r)}async function $(e,t,n){let r=X(e,`action`,F,`browser`);switch(r){case`open`:return t.openHandler({url:G(e,`url`,`browser(open)`),mode:Z(e,`mode`,I,`browser(open)`),forceNew:q(e,`forceNew`),label:K(e,`label`),autoDialog:q(e,`autoDialog`),waitUntil:Z(e,`waitUntil`,L,`browser(open)`)});case`batch`:{let r=Me(e,`browser(batch)`),i=[],a=0;for(let e=0;e<r.length;e+=1){let o=r[e],s=K(o,`action`)??`unknown`;try{let r=await $(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 N(`Batch completed: ${a}/${r.length} steps succeeded`,{total:r.length,succeeded:a,steps:i})}case`read`:return t.readHandler({pageId:Q(e,n,`browser(read)`),mode:Z(e,`readMode`,[`snapshot`,`dom`,`markdown`,`text`],`browser(read)`),selector:K(e,`selector`)});case`act`:return t.actHandler({pageId:Q(e,n,`browser(act)`),kind:X(e,`kind`,R,`browser(act)`),ref:K(e,`ref`),selector:K(e,`selector`),element:K(e,`element`),text:K(e,`text`),key:K(e,`key`),value:K(e,`value`),fromRef:K(e,`fromRef`),fromSelector:K(e,`fromSelector`),toRef:K(e,`toRef`),toSelector:K(e,`toSelector`)});case`navigate`:return t.navigateHandler({pageId:Q(e,n,`browser(navigate)`),url:K(e,`url`),type:Z(e,`type`,z,`browser(navigate)`),selector:K(e,`selector`),timeoutMs:J(e,`timeoutMs`)});case`network`:return t.networkHandler({pageId:Q(e,n,`browser(network)`),subAction:X(e,`subAction`,B,`browser(network)`),filter:Y(e,`filter`),showSensitive:q(e,`showSensitive`),includeBody:q(e,`includeBody`),bufferSize:J(e,`bufferSize`)});case`console`:return t.consoleHandler({pageId:Q(e,n,`browser(console)`),subAction:X(e,`consoleSubAction`,V,`browser(console)`),level:K(e,`level`),bufferSize:J(e,`bufferSize`)});case`fetch`:return t.fetchHandler({pageId:Q(e,n,`browser(fetch)`),url:G(e,`fetchUrl`,`browser(fetch)`),method:Z(e,`fetchMethod`,H,`browser(fetch)`),headers:Y(e,`fetchHeaders`),body:K(e,`fetchBody`),timeoutMs:J(e,`timeoutMs`),includeHeaders:q(e,`includeResponseHeaders`)});case`eval`:return t.evalHandler({pageId:Q(e,n,`browser(eval)`),code:G(e,`code`,`browser(eval)`),timeoutMs:J(e,`timeoutMs`)});case`diff`:return t.diffHandler({pageId:Q(e,n,`browser(diff)`)});case`screenshot`:{let r=Y(e,`clip`);return t.screenshotHandler({pageId:Q(e,n,`browser(screenshot)`),ref:K(e,`ref`),selector:K(e,`selector`),fullPage:q(e,`fullPage`),redactPasswords:q(e,`redactPasswords`),clip:r,format:Z(e,`format`,[`png`,`jpeg`],`browser(screenshot)`),quality:J(e,`quality`)})}case`dialog`:return t.dialogHandler({pageId:Q(e,n,`browser(dialog)`),accept:je(e,`accept`,`browser(dialog)`),promptText:K(e,`promptText`)});case`session`:return t.sessionHandler({sessionAction:X(e,`sessionAction`,U,`browser(session)`),pageId:K(e,`pageId`)&&Ne(e,n),confirm:q(e,`confirm`),cookies:Y(e,`cookies`),name:K(e,`name`),storageType:Z(e,`storageType`,[`localStorage`,`sessionStorage`],`browser(session)`),storageKey:K(e,`storageKey`),storageValue:K(e,`storageValue`)});default:return N(`Unknown action: ${r}`,{error:`Unknown action: ${r}`})}}function Pe(e,t){let n=ge(t),r={openHandler:Ee(n),readHandler:De(n),actHandler:_e(n),navigateHandler:we(n),networkHandler:Te(n),consoleHandler:ve(n),fetchHandler:Se(n),evalHandler:xe(n),diffHandler:be(n),screenshotHandler:Oe(n),dialogHandler:ye(n),sessionHandler:ke(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.`,Ae,async e=>{try{let t=await $(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{de as BrowserEngine,w as DEFAULT_BROWSER_CONFIG,ue as SessionRegistry,C as TabRegistry,x as autoSelectMode,fe as closeEngine,b as ensureAgentBrowserInstalled,oe as getAgentBrowserVersion,S as getDaemonArgs,h as getDefaultBrowsersPath,E as getEngine,le as getLaunchArgs,se as isBrowserReady,D as isUrlAllowed,Pe as registerBrowserTools,g as resolveBrowsersPath,pe as validateEvalResult};
|
|
@@ -151,7 +151,7 @@ ${n}
|
|
|
151
151
|
50% { transform: scale(1.05); }
|
|
152
152
|
100% { transform: scale(1); }
|
|
153
153
|
}
|
|
154
|
-
`,document.head.appendChild(l)}var y=class{constructor(t,e){d(this,"container");d(this,"store");d(this,"unsubscribe",null);this.container=t,this.store=e}start(){B(),this.unsubscribe=this.store.subscribe(t=>{switch(t.type){case"annotation-added":this.createHighlight(t.annotation);break;case"annotation-removed":this.removeHighlight(t.id);break;case"selection-changed":this.updateSelection(t.id),t.id!==null&&this.scrollToAnnotation(t.id);break}})}stop(){this.unsubscribe?.(),this.unsubscribe=null,this.clearAll()}findTextNodeRange(t,e,n){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,null),r=0,o=null,i=0,s=null,p=0,c=a.nextNode();for(;c;){let f=(c.textContent||"").length,
|
|
154
|
+
`,document.head.appendChild(l)}var y=class{constructor(t,e){d(this,"container");d(this,"store");d(this,"unsubscribe",null);this.container=t,this.store=e}start(){B(),this.unsubscribe=this.store.subscribe(t=>{switch(t.type){case"annotation-added":this.createHighlight(t.annotation);break;case"annotation-removed":this.removeHighlight(t.id);break;case"selection-changed":this.updateSelection(t.id),t.id!==null&&this.scrollToAnnotation(t.id);break}})}stop(){this.unsubscribe?.(),this.unsubscribe=null,this.clearAll()}findTextNodeRange(t,e,n){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,null),r=0,o=null,i=0,s=null,p=0,c=a.nextNode();for(;c;){let f=(c.textContent||"").length,m=r+f;if(o===null&&m>e&&(o=c,i=e-r),m>=n){s=c,p=n-r;break}r=m,c=a.nextNode()}if(!o||!s)return null;let u=document.createRange();return u.setStart(o,Math.min(i,(o.textContent||"").length)),u.setEnd(s,Math.min(p,(s.textContent||"").length)),u}createHighlight(t){let e=this.container.querySelector(`[data-block-id="${t.blockId}"]`);if(!e){console.warn(`[HighlightManager] Block not found for annotation ${t.id}: ${t.blockId}`);return}let n=this.findTextNodeRange(e,t.startOffset,t.endOffset);if(!n){console.warn(`[HighlightManager] Could not resolve text range for annotation ${t.id}`);return}let a=document.createElement("mark");a.className=`hl-${t.type}`,a.dataset.annotationId=t.id,a.addEventListener("click",()=>{this.store.select(t.id)});try{n.surroundContents(a)}catch{try{if(n.endContainer.nodeType===Node.TEXT_NODE&&n.endContainer.splitText(n.endOffset),n.startContainer.nodeType===Node.TEXT_NODE){let r=n.startContainer;n.startOffset>0&&r.splitText(n.startOffset);let o=document.createRange();o.setStart(r.nextSibling||r,0),o.setEnd(n.endContainer.nodeType===Node.TEXT_NODE&&n.endContainer.previousSibling||n.endContainer,n.endOffset),o.surroundContents(a)}else throw new Error("Non-text range")}catch{let r=n.extractContents();a.append(r),n.insertNode(a)}}}removeHighlight(t){let e=this.container.querySelector(`mark[data-annotation-id="${t}"]`);if(!e)return;let n=e.parentNode;if(n){for(;e.firstChild;)n.insertBefore(e.firstChild,e);n.removeChild(e),n.nodeType===Node.ELEMENT_NODE&&n.normalize()}}updateSelection(t){let e=this.container.querySelectorAll("mark[data-annotation-id]");for(let n of e)n.classList.toggle("hl-selected",n.dataset.annotationId===t)}scrollToAnnotation(t){let e=this.container.querySelector(`mark[data-annotation-id="${t}"]`);e&&(e.scrollIntoView({behavior:"smooth",block:"center"}),e.classList.add("annotation-pulse"),setTimeout(()=>{e.classList.remove("annotation-pulse")},600))}clearAll(){let t=this.container.querySelectorAll("mark[data-annotation-id]");for(let e of t){let n=e.parentNode;if(n){for(;e.firstChild;)n.insertBefore(e.firstChild,e);n.removeChild(e),n.nodeType===Node.ELEMENT_NODE&&n.normalize()}}}};var z=new Set(["button","input","textarea","select"]),E=class{constructor(t){d(this,"options");d(this,"boundHandleMouseUp");this.options=t,this.boundHandleMouseUp=this.handleMouseUp.bind(this),this.options.container.addEventListener("mouseup",this.boundHandleMouseUp,{passive:!0})}destroy(){this.options.container.removeEventListener("mouseup",this.boundHandleMouseUp)}handleMouseUp(t){if(this.options.mode()==="selection")return;let e=t.target;if(!e||this.isExcludedElement(e))return;let n=this.getSelectionRange();if(!n)return;let a=this.findBlockId(n.startContainer);if(!a)return;let r=this.findBlockContainer(n.startContainer),o=this.findBlockContainer(n.endContainer);if(r!==o)return;let i=this.computeBlockOffset(n.startContainer,n.startOffset),s=this.computeBlockOffset(n.endContainer,n.endOffset);if(i===null||s===null)return;let p={blockId:a,startOffset:i,endOffset:s,text:n.toString(),range:n};this.options.onSelection(p),this.clearSelection()}getSelectionRange(){let t=window.getSelection();return!t||t.isCollapsed||t.rangeCount===0?null:t.getRangeAt(0)}findBlockId(t){let e=t;for(;e;){if(e instanceof HTMLElement&&e.hasAttribute("data-block-id"))return e.getAttribute("data-block-id");e=e.parentNode}return null}computeBlockOffset(t,e){let n=this.findBlockContainer(t);if(!n)return null;let a=document.createTreeWalker(n,NodeFilter.SHOW_TEXT,null),r=0,o=a.nextNode();for(;o;){if(o===t)return r+e;r+=(o.textContent||"").length,o=a.nextNode()}return null}findBlockContainer(t){let e=t;for(;e;){if(e instanceof HTMLElement&&e.hasAttribute("data-block-id"))return e;e=e.parentNode}return null}clearSelection(){let t=window.getSelection();t&&t.removeAllRanges()}isExcludedElement(t){let e=t;for(;e&&!(e instanceof HTMLElement);)e=e.parentNode;return e?z.has(e.tagName.toLowerCase()):!1}};var I="aikit-annotation-sidebar",D=`
|
|
155
155
|
.as-sidebar {
|
|
156
156
|
width: var(--dt-annotation-sidebar-width, 300px);
|
|
157
157
|
background: var(--dt-bg-secondary);
|
|
@@ -333,12 +333,12 @@ ${n}
|
|
|
333
333
|
font-size: var(--dt-font-size-sm);
|
|
334
334
|
padding: var(--dt-space-6) var(--dt-space-2);
|
|
335
335
|
}
|
|
336
|
-
`,
|
|
336
|
+
`,R='<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>',k=class{constructor(t){d(this,"el");d(this,"store");d(this,"exporter");d(this,"unsubscribe",null);d(this,"listEl");d(this,"modeToggleBtn");this.store=t.store,this.exporter=t.exporter,this.el=this.render(),this.listEl=this.el.querySelector(".as-list"),this.modeToggleBtn=this.el.querySelector(".as-mode-toggle"),this.unsubscribe=this.store.subscribe(n=>{switch(n.type){case"annotation-added":case"annotation-removed":case"annotation-updated":this.renderList(),this.updateHeader();break;case"selection-changed":this.updateCardSelection(n.id);break;case"sidebar-toggled":this.updateVisibility();break;case"mode-changed":this.updateModeToggle();break}}),(t.mountTarget??document.body).appendChild(this.el),this.updateVisibility(),this.updateModeToggle()}destroy(){this.unsubscribe?.(),this.el.remove()}render(){b(I,D);let t=document.createElement("div");t.className="as-sidebar",t.setAttribute("role","complementary"),t.setAttribute("aria-label","Annotations");let e=this.exporter.getTotalCount();return t.innerHTML=`
|
|
337
337
|
<div class="as-header">
|
|
338
338
|
<span class="as-header-title">Annotations</span>
|
|
339
339
|
<span class="as-count-badge" aria-live="polite">${e.total}</span>
|
|
340
340
|
<span class="as-header-spacer"></span>
|
|
341
|
-
<button class="as-mode-toggle" aria-label="Toggle annotation mode">${
|
|
341
|
+
<button class="as-mode-toggle" aria-label="Toggle annotation mode">${R} Feedback</button>
|
|
342
342
|
<button class="as-close-btn" aria-label="Close sidebar">×</button>
|
|
343
343
|
</div>
|
|
344
344
|
<div class="as-list" role="list" aria-label="Annotation list"></div>
|
|
@@ -364,7 +364,7 @@ ${n}
|
|
|
364
364
|
.as-guide--visible {
|
|
365
365
|
display: block;
|
|
366
366
|
}
|
|
367
|
-
`;function _(l){let{range:t}=l,e,n=t.startContainer;for(;n;){if(n instanceof HTMLElement&&n.tagName.toLowerCase().match(/^h[1-6]$/)){e=n.textContent?.trim()||void 0;break}n=n.parentNode}let a,r;try{if(t.startContainer.nodeType===Node.TEXT_NODE&&t.startOffset>0){let o=t.startContainer.textContent||"",i=Math.max(0,t.startOffset-L);a=o.slice(i,t.startOffset)}if(t.endContainer.nodeType===Node.TEXT_NODE&&t.endOffset<(t.endContainer.textContent?.length||0)){let o=t.endContainer.textContent||"",i=Math.min(o.length,t.endOffset+L);r=o.slice(t.endOffset,i)}}catch{}return{section:e,contextBefore:a,contextAfter:r}}function w(l){let{container:t,mountTarget:e}=l,n=null,a=new T;a.setMode("feedback");let r=new x(a);b($,q);let o=document.createElement("div");o.className="as-guide",o.textContent="\u27B3 Ready. Select text to annotate or disable Feedback in the sidebar.",t.prepend(o);let i=()=>{let
|
|
367
|
+
`;function _(l){let{range:t}=l,e,n=t.startContainer;for(;n;){if(n instanceof HTMLElement&&n.tagName.toLowerCase().match(/^h[1-6]$/)){e=n.textContent?.trim()||void 0;break}n=n.parentNode}let a,r;try{if(t.startContainer.nodeType===Node.TEXT_NODE&&t.startOffset>0){let o=t.startContainer.textContent||"",i=Math.max(0,t.startOffset-L);a=o.slice(i,t.startOffset)}if(t.endContainer.nodeType===Node.TEXT_NODE&&t.endOffset<(t.endContainer.textContent?.length||0)){let o=t.endContainer.textContent||"",i=Math.min(o.length,t.endOffset+L);r=o.slice(t.endOffset,i)}}catch{}return{section:e,contextBefore:a,contextAfter:r}}function w(l){let{container:t,mountTarget:e}=l,n=null,a=new T;a.setMode("feedback");let r=new x(a);b($,q);let o=document.createElement("div");o.className="as-guide",o.textContent="\u27B3 Ready. Select text to annotate or disable Feedback in the sidebar.",t.prepend(o);let i=()=>{let u=a.getState();o.classList.toggle("as-guide--visible",u.mode==="feedback"&&u.annotations.length===0)};i(),a.subscribe(()=>i());let s=new y(t,a);s.start();let p=new E({container:t,mode:()=>a.getState().mode,onSelection:u=>{let f=_(u);n?.destroy();let m=new v(u,{onSubmit:(h,S)=>{a.add("COMMENT",h.blockId,h.startOffset,h.endOffset,h.text,S||void 0,f.section,f.contextBefore,f.contextAfter),m.destroy(),n===m&&(n=null)},onRemove:(h,S)=>{a.add("DELETION",h.blockId,h.startOffset,h.endOffset,h.text,S||void 0,f.section,f.contextBefore,f.contextAfter),m.destroy(),n===m&&(n=null)},onDismiss:()=>{m.destroy(),n===m&&(n=null)}});n=m}}),c=new k({store:a,exporter:r,mountTarget:e});return a.openSidebar(),{destroy(){n?.destroy(),n=null,o.remove(),p.destroy(),s.stop(),c.destroy(),a.destroy()},getStore(){return a},getExporter(){return r}}}document.addEventListener("DOMContentLoaded",()=>{let l=document.querySelector(".content")||document.querySelector("main"),t=l||document.body;if(!l)return;let e=t.parentElement;e?.classList.contains("shell-layout")||(e=document.createElement("div"),e.className="shell-layout",t.parentNode?.insertBefore(e,t),e.appendChild(t));let n="aikit-shell-layout";if(!document.getElementById(n)){let o=document.createElement("style");o.id=n,o.textContent=`
|
|
368
368
|
.shell-layout {
|
|
369
369
|
flex: 1;
|
|
370
370
|
display: flex;
|
|
@@ -385,8 +385,9 @@ ${n}
|
|
|
385
385
|
[data-annotation-sidebar="open"] .shell-layout > .content {
|
|
386
386
|
max-width: none;
|
|
387
387
|
}
|
|
388
|
-
/* Sticky bottom action bar */
|
|
388
|
+
/* Sticky bottom action bar \u2014 docked to bottom of scrollable main */
|
|
389
389
|
.action-bar {
|
|
390
|
+
margin-top: auto;
|
|
390
391
|
position: sticky;
|
|
391
392
|
bottom: 0;
|
|
392
393
|
display: flex;
|
|
@@ -399,6 +400,7 @@ ${n}
|
|
|
399
400
|
backdrop-filter: blur(12px);
|
|
400
401
|
-webkit-backdrop-filter: blur(12px);
|
|
401
402
|
flex-shrink: 0;
|
|
403
|
+
z-index: 10;
|
|
402
404
|
}
|
|
403
405
|
.action-bar:empty {
|
|
404
406
|
display: none;
|
|
@@ -413,4 +415,24 @@ ${n}
|
|
|
413
415
|
border: none;
|
|
414
416
|
background: none;
|
|
415
417
|
}
|
|
418
|
+
/* Size action bar controls consistently */
|
|
419
|
+
.action-bar .present-action-btn {
|
|
420
|
+
padding: 0.375rem 0.75rem;
|
|
421
|
+
font-size: var(--dt-font-size-sm);
|
|
422
|
+
min-height: 2rem;
|
|
423
|
+
}
|
|
424
|
+
.action-bar .present-action-field select {
|
|
425
|
+
font-size: var(--dt-font-size-sm);
|
|
426
|
+
min-height: 2rem;
|
|
427
|
+
padding: 0 0.5rem;
|
|
428
|
+
}
|
|
429
|
+
.action-bar .present-action-field span {
|
|
430
|
+
font-size: var(--dt-font-size-xs);
|
|
431
|
+
}
|
|
432
|
+
.action-bar .present-text-input {
|
|
433
|
+
font-size: var(--dt-font-size-sm);
|
|
434
|
+
min-height: 2rem;
|
|
435
|
+
padding: 0 0.5rem;
|
|
436
|
+
min-width: 140px;
|
|
437
|
+
}
|
|
416
438
|
`,document.head.appendChild(o)}let a=w({container:t,mountTarget:e});a.getStore().subscribe(o=>{o.type==="sidebar-toggled"&&document.documentElement.setAttribute("data-annotation-sidebar",o.open?"open":"")}),a.getStore().getState().isSidebarOpen&&document.documentElement.setAttribute("data-annotation-sidebar","open"),window.__annotationLayer=a;let r=document.querySelectorAll(".bk-actions");if(r.length>0){let o=document.createElement("div");o.className="action-bar";let i=!1;for(let s of r)if(!s.querySelector('input[type="text"], input:not([type]), textarea')){for(;s.firstChild;)o.appendChild(s.firstChild);s.remove(),i=!0}if(i){let s=document.querySelector("main")||document.querySelector(".content");s&&(s.appendChild(o),s.style.paddingBottom="0")}}});})();
|
|
@@ -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){R.error(`Failed to upsert curated batch`,{batchSize:e.length,...a(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return R.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...a(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;R.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...a(r)});let i=Math.ceil(e.length/2),o=e.slice(0,i),s=e.slice(i);return await this.embedAndUpsertBatch(o,t,n)+await this.embedAndUpsertBatch(s,t,n)}}gitCommitKnowledge(e,t,n){try{if(!p(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;m(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!p(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;h([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>g(e)).join(`/`);return t.split(`/`).every(e=>f.test(e))?`${L}/${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`)){R.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:i,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){R.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:i,...a(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||c(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`)>I)throw Error(`Content exceeds maximum size of ${I/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 d(`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 B=i(`server`);function V(e,t){return t?{version:e,...a(t)}:{version:e}}function H(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function U(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function W(){return U()?n({allowPositionals:!0,options:{transport:{type:`string`,default:H()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:H(),port:process.env.AIKIT_PORT??`3210`}}async function G(){let e=C(),t=W();if(process.on(`unhandledRejection`,t=>{B.error(`Unhandled rejection`,V(e,t))}),process.on(`uncaughtException`,t=>{B.error(`Uncaught exception — exiting`,V(e,t)),process.exit(1)}),B.info(`Starting MCP AI Kit server`,{version:e}),t.transport===`http`){let{startHttpMode:n}=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 B=i(`server`);function V(e,t){return t?{version:e,...a(t)}:{version:e}}function H(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function U(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function W(){return U()?n({allowPositionals:!0,options:{transport:{type:`string`,default:H()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:H(),port:process.env.AIKIT_PORT??`3210`}}async function G(){let e=C(),t=W();if(process.on(`unhandledRejection`,t=>{B.error(`Unhandled rejection`,V(e,t))}),process.on(`uncaughtException`,t=>{B.error(`Uncaught exception — exiting`,V(e,t)),process.exit(1)}),B.info(`Starting MCP AI Kit server`,{version:e}),t.transport===`http`){let{startHttpMode:n}=await import(`./server-http-BTLSMqqO.js`);await n(e,t.port)}else{let{startStdioMode:t}=await import(`./server-stdio-BOx_iUYc.js`);await t(e)}}G();export{w as a,O as i,F as n,T as o,P as r,D as s,z as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,n,r,t as i}from"./server-utils-De-aZNQa.js";import{n as a,r as o,t as s}from"./workspace-bootstrap-DupGrGox.js";import{t as c}from"./curated-manager-BrgM_znO.js";import{pathToFileURL as l}from"node:url";import{parseArgs as u}from"node:util";import{createLogger as d,serializeError as f}from"../../core/dist/index.js";const p=d(`server`);function m(e,t){return t?{version:e,...f(t)}:{version:e}}function h(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function g(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function _(){return g()?u({allowPositionals:!0,options:{transport:{type:`string`,default:h()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:h(),port:process.env.AIKIT_PORT??`3210`}}async function v(){let e=t(),n=_();if(process.on(`unhandledRejection`,t=>{p.error(`Unhandled rejection`,m(e,t))}),process.on(`uncaughtException`,t=>{p.error(`Uncaught exception — exiting`,m(e,t)),process.exit(1)}),p.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let{startHttpMode:t}=await import(`./server-http-
|
|
1
|
+
import{a as e,i as t,n,r,t as i}from"./server-utils-De-aZNQa.js";import{n as a,r as o,t as s}from"./workspace-bootstrap-DupGrGox.js";import{t as c}from"./curated-manager-BrgM_znO.js";import{pathToFileURL as l}from"node:url";import{parseArgs as u}from"node:util";import{createLogger as d,serializeError as f}from"../../core/dist/index.js";const p=d(`server`);function m(e,t){return t?{version:e,...f(t)}:{version:e}}function h(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function g(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function _(){return g()?u({allowPositionals:!0,options:{transport:{type:`string`,default:h()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:h(),port:process.env.AIKIT_PORT??`3210`}}async function v(){let e=t(),n=_();if(process.on(`unhandledRejection`,t=>{p.error(`Unhandled rejection`,m(e,t))}),process.on(`uncaughtException`,t=>{p.error(`Uncaught exception — exiting`,m(e,t)),process.exit(1)}),p.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let{startHttpMode:t}=await import(`./server-http-BwK7mqRs.js`);await t(e,n.port)}else{let{startStdioMode:t}=await import(`./server-stdio-ksLTYwSm.js`);await t(e)}}export{c as CuratedKnowledgeManager,s as applyWorkspaceRoots,a as bootstrapWorkspaceRoots,i as createSlidingWindowRateLimiter,n as getSessionIdHeader,v as main,r as readPositiveIntEnv,t as readVersion,e as resolveCorsOrigin,o as selectWorkspaceRoot};
|
|
@@ -292,7 +292,7 @@ None.`:`### Stale Lessons\n${u.map(e=>`- **${e.title}** (\`${e.path}\`) — effe
|
|
|
292
292
|
{ path: 'docs/api.md', title: 'API Reference', status: 'stale' },
|
|
293
293
|
],
|
|
294
294
|
},
|
|
295
|
-
}`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`},{type:`diff`,category:`content`,description:`Diff view with +/- lines for showing changes between text.`,valueShape:`string | { content: string } | { before: string; after: string }`},{type:`finding`,category:`content`,description:`Finding with severity pill showing title, severity, and detail.`,valueShape:`{ title?: string; severity?: string; detail?: unknown }`},{type:`kv`,category:`data`,description:`Key-value pairs rendered as labeled entries.`,valueShape:`Array<{ key: string; value: unknown }> | Record<string, unknown>`},{type:`tags`,category:`data`,description:`Tag pills rendered with optional tone/color.`,valueShape:`Array<string | { text?: string; label?: string; status?: string; tone?: string; color?: string }> | { items: Array<...> }`},{type:`list`,category:`content`,description:`Bullet list items rendered as an unordered list.`,valueShape:`string[]`},{type:`lifecycle-flow`,category:`visualization`,description:`SVG flow diagram with labeled steps, edges, and status colors.`,valueShape:`{ title?: string; steps: Array<{ id: string; label: string; type?: string; status?: string; description?: string }>; edges?: Array<{ from: string; to: string; label?: string }> }`},{type:`component-detail`,category:`visualization`,description:`Component detail view with name, type, technology, responsibilities, interfaces, dependencies, metrics, and code links.`,valueShape:`{ name: string; description?: string; type?: string; technology?: string; responsibilities?: string[]; interfaces?: Array<{ name: string; type: string; description?: string }>; dependencies?: Array<{ name: string; relationship?: string }>; metrics?: Record<string, string | number>; codeLinks?: Array<{ href: string; label: string }> }`},{type:`data-table-schema`,category:`data`,description:`Schema table with field names, types, constraints, and indexes.`,valueShape:`{ name: string; description?: string; fields: Array<{ name: string; type: string; required?: boolean; default?: unknown; constraints?: string[]; description?: string }>; indexes?: Array<{ name: string; columns: string[]; unique?: boolean }> }`},{type:`annotation`,category:`interactive`,description:`Annotation groups with COMMENT, DELETION, and GLOBAL_COMMENT types.`,valueShape:`Array<{ id: string; type: "COMMENT" | "DELETION" | "GLOBAL_COMMENT"; body: string; author?: string; createdAt?: string }>`},{type:`approval`,category:`interactive`,description:`Approval widget with radio options and optional comment textarea.`,valueShape:`{ prompt: string; options: Array<{ id: string; label: string; description?: string }>; requireComment?: boolean }`},{type:`docs-hub`,category:`content`,description:`Doc hub card grid with titled pages, descriptions, categories, and statuses.`,valueShape:`{ title?: string; description?: string; pages?: Array<{ title: string; description?: string; href?: string; icon?: string; category?: string; status?: "draft" | "published" | "deprecated" }> }`}].map(e=>[e.type,{...e}]));function qm(){let e={};for(let[t,n]of Km)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const X={TIMEOUT:`timeout`,DUPLICATE_CALLBACK:`duplicate_callback`,INVALID_NONCE:`invalid_nonce`,INVALID_ORIGIN:`invalid_origin`,SESSION_NOT_FOUND:`session_not_found`,SESSION_LIMIT_REACHED:`session_limit_reached`,ASSET_NOT_FOUND:`asset_not_found`,ASSET_FORBIDDEN:`asset_forbidden`,RATE_LIMITED:`rate_limited`,PAYLOAD_TOO_LARGE:`payload_too_large`,UNSUPPORTED_MEDIA_TYPE:`unsupported_media_type`,INVALID_TRANSITION:`invalid_transition`,ANNOTATION_CAP_EXCEEDED:`annotation_cap_exceeded`},Jm={[X.TIMEOUT]:408,[X.DUPLICATE_CALLBACK]:409,[X.INVALID_NONCE]:400,[X.INVALID_ORIGIN]:403,[X.SESSION_NOT_FOUND]:404,[X.SESSION_LIMIT_REACHED]:429,[X.ASSET_NOT_FOUND]:404,[X.ASSET_FORBIDDEN]:403,[X.RATE_LIMITED]:429,[X.PAYLOAD_TOO_LARGE]:413,[X.UNSUPPORTED_MEDIA_TYPE]:415,[X.INVALID_TRANSITION]:400,[X.ANNOTATION_CAP_EXCEEDED]:403};function Ym(e,t,n){return{code:e,message:t,httpStatus:n??Jm[e]}}const Xm={created:[`rendering`,`errored`,`cleaned_up`,`timed_out`,`cancelled`,`responded`],rendering:[`listening`,`errored`,`cleaned_up`,`timed_out`,`cancelled`],listening:[`connected`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],connected:[`responded`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],responded:[`cleaned_up`],timed_out:[`cleaned_up`],cancelled:[`cleaned_up`],errored:[`cleaned_up`],cleaned_up:[]};function Zm(e,t,n,r){return Xm[e].includes(t)?{ok:!0,to:t,entry:{from:e,to:t,timestamp:Date.now(),trigger:r}}:{ok:!1,error:{code:`invalid_transition`,message:`Cannot transition from "${e}" to "${t}"`,from:e,to:t}}}function Qm(e){return Xm[e].length===0}const $m=1024,eh=new Set([`user-closed`,`host-dismissed`,`replaced`]);function th(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nh(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function rh(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function ih(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function ah(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`hex`),r=Buffer.from(t,`hex`);return n.length===r.length?Re(n,r):!1}function oh(e,t){let n=e.headers.origin;if(n!=null)return n===t;let r=e.headers.referer;return r==null?!1:r.startsWith(t)}function sh(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function ch(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function lh(e){return Array.isArray(e)&&e.length>$m?`Selection exceeds ${$m} items (got ${e.length})`:null}function uh(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return nh(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=th(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function dh(e){switch(e.kind){case`timeout`:return`timed_out`;case`cancelled`:return`cancelled`;case`error`:return`errored`;case`result`:return`responded`;default:return`errored`}}function fh(e,t,n,r,i){let a=i??Ie(16).toString(`hex`),o=`created`,s=[],c=!1,l,u,d=new Promise(e=>{u=e}),f=e=>{if(Qm(o))return l;let t=dh(e),i=Zm(o,t,s,`resolve`);return i.ok?(o=t,s.push(i.entry),l=e,u?.(e),n&&r&&n.transitionSession(r,t,`resolve`),e):l};return{nonce:a,promise:d,get state(){return o},get stateHistory(){return s},settleTimeout(e){return f({kind:`timeout`,waitedMs:e})},settleCancelled(e){return f({kind:`cancelled`,reason:e})},settleError(e,t,n){return f(nh(e,t,n))},async handle(n,r,i){if(!sh(n)){let e=f(nh(X.UNSUPPORTED_MEDIA_TYPE,`Content-Type must be application/json`));return rh(r,415,{ok:!1,error:X.UNSUPPORTED_MEDIA_TYPE},i),e}if(!oh(n,i)){let e=n.headers.origin??n.headers.referer??`(missing)`,t=f(nh(X.INVALID_ORIGIN,`Unexpected callback origin: ${e}`));return rh(r,403,{ok:!1,error:X.INVALID_ORIGIN},i),t}let o=``;try{o=await ih(n)}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return rh(r,413,{ok:!1,error:X.PAYLOAD_TOO_LARGE},i),t}let s;try{let e=JSON.parse(o);if(!th(e))throw Error(`Callback payload must be an object`);s=e}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return rh(r,400,{ok:!1,error:`invalid-json`},i),t}if(c){let e=nh(X.DUPLICATE_CALLBACK,`Nonce has already been used`);return rh(r,403,{ok:!1,error:X.DUPLICATE_CALLBACK},i),e}if(!ah(typeof s.nonce==`string`?s.nonce:``,a)){let e=f(nh(X.INVALID_NONCE,`Callback nonce did not match`));return rh(r,403,{ok:!1,error:X.INVALID_NONCE},i),e}c=!0;let l=lh(s.selection);if(l){let e=f(nh(`SELECTION_TOO_LARGE`,l));return rh(r,413,{ok:!1,error:`selection-too-large`},i),e}if(th(s.formData)){let e=ch(s.formData);if(e){let t=f(nh(`PAYLOAD_FIELD_TOO_LARGE`,e));return rh(r,413,{ok:!1,error:`field-too-large`},i),t}}if(s.kind===`cancelled`){let e=typeof s.reason==`string`?s.reason:``;if(!eh.has(e)){let t=f(nh(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return rh(r,400,{ok:!1,error:`invalid-cancel-reason`},i),t}let t=f({kind:`cancelled`,reason:e});return rh(r,200,{ok:!0,kind:`cancelled`},i),t}let u=f(uh(s,e,t));return rh(r,u.kind===`error`?400:200,{ok:u.kind!==`error`,kind:u.kind},i),u}}}const ph=`Install AI Kit with <code>${Y(`npx -y @vpxa/aikit@latest init --user`)}</code>.`;function mh(e){let t=Date.now();return{id:e.id,state:`created`,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport,createdAt:t,updatedAt:t,stateHistory:[],responsePromise:null,resolveOutcome:null,cleanupCallbacks:[],nonceConsumed:!1}}var hh=class{sessions;maxSessions;rejectedCount;constructor(e=16){this.sessions=new Map,this.maxSessions=e,this.rejectedCount=0}createSession(e){if(this.sessions.size>=this.maxSessions)return this.rejectedCount++,{ok:!1,error:Ym(X.SESSION_LIMIT_REACHED,`Session limit reached`)};let t=Le(),n=mh({id:t,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport});return this.sessions.set(t,n),{ok:!0,session:n}}getSession(e){return this.sessions.get(e)||Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}transitionSession(e,t,n){let r=this.sessions.get(e);if(!r)return{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)};let i=Zm(r.state,t,r.stateHistory,n);return i.ok?(r.state=i.to,r.stateHistory.push(i.entry),r.updatedAt=Date.now(),{ok:!0,record:r}):{ok:!1,error:Ym(X.INVALID_TRANSITION,i.error.message)}}consumeNonce(e){let t=this.sessions.get(e);return t?t.nonceConsumed?{ok:!1,error:Ym(X.DUPLICATE_CALLBACK,`Nonce already consumed`)}:(t.nonceConsumed=!0,t.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}removeSession(e){return this.sessions.delete(e)}cleanupStale(e){let t=Date.now(),n=0;for(let[r,i]of this.sessions.entries())i.state!==`connected`&&t-i.updatedAt>e&&(i.resolveOutcome&&(i.resolveOutcome({outcome:`timeout`}),i.resolveOutcome=null,i.responsePromise=null),this.sessions.delete(r),n++);return n}shutdown(){for(let[,e]of this.sessions.entries()){e.resolveOutcome&&(e.resolveOutcome({outcome:`shutdown`}),e.resolveOutcome=null,e.responsePromise=null);for(let t of e.cleanupCallbacks)try{t()}catch{}e.cleanupCallbacks=[]}this.sessions.clear()}get activeCount(){return this.sessions.size}get rejectedSessionCount(){return this.rejectedCount}setResponseResolver(e,t){let n=this.sessions.get(e);return n?(n.resolveOutcome=t,n.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}};const gh=String.raw`(function(){
|
|
295
|
+
}`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`},{type:`diff`,category:`content`,description:`Diff view with +/- lines for showing changes between text.`,valueShape:`string | { content: string } | { before: string; after: string }`},{type:`finding`,category:`content`,description:`Finding with severity pill showing title, severity, and detail.`,valueShape:`{ title?: string; severity?: string; detail?: unknown }`},{type:`kv`,category:`data`,description:`Key-value pairs rendered as labeled entries.`,valueShape:`Array<{ key: string; value: unknown }> | Record<string, unknown>`},{type:`tags`,category:`data`,description:`Tag pills rendered with optional tone/color.`,valueShape:`Array<string | { text?: string; label?: string; status?: string; tone?: string; color?: string }> | { items: Array<...> }`},{type:`list`,category:`content`,description:`Bullet list items rendered as an unordered list.`,valueShape:`string[]`},{type:`lifecycle-flow`,category:`visualization`,description:`SVG flow diagram with labeled steps, edges, and status colors.`,valueShape:`{ title?: string; steps: Array<{ id: string; label: string; type?: string; status?: string; description?: string }>; edges?: Array<{ from: string; to: string; label?: string }> }`},{type:`component-detail`,category:`visualization`,description:`Component detail view with name, type, technology, responsibilities, interfaces, dependencies, metrics, and code links.`,valueShape:`{ name: string; description?: string; type?: string; technology?: string; responsibilities?: string[]; interfaces?: Array<{ name: string; type: string; description?: string }>; dependencies?: Array<{ name: string; relationship?: string }>; metrics?: Record<string, string | number>; codeLinks?: Array<{ href: string; label: string }> }`},{type:`data-table-schema`,category:`data`,description:`Schema table with field names, types, constraints, and indexes.`,valueShape:`{ name: string; description?: string; fields: Array<{ name: string; type: string; required?: boolean; default?: unknown; constraints?: string[]; description?: string }>; indexes?: Array<{ name: string; columns: string[]; unique?: boolean }> }`},{type:`annotation`,category:`interactive`,description:`Annotation groups with COMMENT, DELETION, and GLOBAL_COMMENT types.`,valueShape:`Array<{ id: string; type: "COMMENT" | "DELETION" | "GLOBAL_COMMENT"; body: string; author?: string; createdAt?: string }>`},{type:`approval`,category:`interactive`,description:`Approval widget with radio options and optional comment textarea.`,valueShape:`{ prompt: string; options: Array<{ id: string; label: string; description?: string }>; requireComment?: boolean }`},{type:`docs-hub`,category:`content`,description:`Doc hub card grid with titled pages, descriptions, categories, and statuses.`,valueShape:`{ title?: string; description?: string; pages?: Array<{ title: string; description?: string; href?: string; icon?: string; category?: string; status?: "draft" | "published" | "deprecated" }> }`}].map(e=>[e.type,{...e}]));function qm(){let e={};for(let[t,n]of Km)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const X={TIMEOUT:`timeout`,DUPLICATE_CALLBACK:`duplicate_callback`,INVALID_NONCE:`invalid_nonce`,INVALID_ORIGIN:`invalid_origin`,SESSION_NOT_FOUND:`session_not_found`,SESSION_LIMIT_REACHED:`session_limit_reached`,ASSET_NOT_FOUND:`asset_not_found`,ASSET_FORBIDDEN:`asset_forbidden`,RATE_LIMITED:`rate_limited`,PAYLOAD_TOO_LARGE:`payload_too_large`,UNSUPPORTED_MEDIA_TYPE:`unsupported_media_type`,INVALID_TRANSITION:`invalid_transition`,ANNOTATION_CAP_EXCEEDED:`annotation_cap_exceeded`},Jm={[X.TIMEOUT]:408,[X.DUPLICATE_CALLBACK]:409,[X.INVALID_NONCE]:400,[X.INVALID_ORIGIN]:403,[X.SESSION_NOT_FOUND]:404,[X.SESSION_LIMIT_REACHED]:429,[X.ASSET_NOT_FOUND]:404,[X.ASSET_FORBIDDEN]:403,[X.RATE_LIMITED]:429,[X.PAYLOAD_TOO_LARGE]:413,[X.UNSUPPORTED_MEDIA_TYPE]:415,[X.INVALID_TRANSITION]:400,[X.ANNOTATION_CAP_EXCEEDED]:403};function Ym(e,t,n){return{code:e,message:t,httpStatus:n??Jm[e]}}const Xm={created:[`rendering`,`errored`,`cleaned_up`,`timed_out`,`cancelled`,`responded`],rendering:[`listening`,`errored`,`cleaned_up`,`timed_out`,`cancelled`],listening:[`connected`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],connected:[`responded`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],responded:[`cleaned_up`],timed_out:[`cleaned_up`],cancelled:[`cleaned_up`],errored:[`cleaned_up`],cleaned_up:[]};function Zm(e,t,n,r){return Xm[e].includes(t)?{ok:!0,to:t,entry:{from:e,to:t,timestamp:Date.now(),trigger:r}}:{ok:!1,error:{code:`invalid_transition`,message:`Cannot transition from "${e}" to "${t}"`,from:e,to:t}}}function Qm(e){return Xm[e].length===0}const $m=1024,eh=new Set([`user-closed`,`host-dismissed`,`replaced`]);function th(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nh(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function rh(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function ih(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function ah(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`hex`),r=Buffer.from(t,`hex`);return n.length===r.length?Re(n,r):!1}function oh(e,t){let n=e.headers.origin;if(n!==void 0)return n===t;let r=e.headers.referer;return r==null?!0:r.startsWith(t)}function sh(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function ch(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function lh(e){return Array.isArray(e)&&e.length>$m?`Selection exceeds ${$m} items (got ${e.length})`:null}function uh(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return nh(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=th(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function dh(e){switch(e.kind){case`timeout`:return`timed_out`;case`cancelled`:return`cancelled`;case`error`:return`errored`;case`result`:return`responded`;default:return`errored`}}function fh(e,t,n,r,i){let a=i??Ie(16).toString(`hex`),o=`created`,s=[],c=!1,l,u,d=new Promise(e=>{u=e}),f=e=>{if(Qm(o))return l;let t=dh(e),i=Zm(o,t,s,`resolve`);return i.ok?(o=t,s.push(i.entry),l=e,u?.(e),n&&r&&n.transitionSession(r,t,`resolve`),e):l};return{nonce:a,promise:d,get state(){return o},get stateHistory(){return s},settleTimeout(e){return f({kind:`timeout`,waitedMs:e})},settleCancelled(e){return f({kind:`cancelled`,reason:e})},settleError(e,t,n){return f(nh(e,t,n))},async handle(n,r,i){if(!sh(n)){let e=f(nh(X.UNSUPPORTED_MEDIA_TYPE,`Content-Type must be application/json`));return rh(r,415,{ok:!1,error:X.UNSUPPORTED_MEDIA_TYPE},i),e}if(!oh(n,i)){let e=n.headers.origin??n.headers.referer??`(missing)`,t=f(nh(X.INVALID_ORIGIN,`Unexpected callback origin: ${e}`));return rh(r,403,{ok:!1,error:X.INVALID_ORIGIN},i),t}let o=``;try{o=await ih(n)}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return rh(r,413,{ok:!1,error:X.PAYLOAD_TOO_LARGE},i),t}let s;try{let e=JSON.parse(o);if(!th(e))throw Error(`Callback payload must be an object`);s=e}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return rh(r,400,{ok:!1,error:`invalid-json`},i),t}if(c){let e=nh(X.DUPLICATE_CALLBACK,`Nonce has already been used`);return rh(r,403,{ok:!1,error:X.DUPLICATE_CALLBACK},i),e}if(!ah(typeof s.nonce==`string`?s.nonce:``,a)){let e=f(nh(X.INVALID_NONCE,`Callback nonce did not match`));return rh(r,403,{ok:!1,error:X.INVALID_NONCE},i),e}c=!0;let l=lh(s.selection);if(l){let e=f(nh(`SELECTION_TOO_LARGE`,l));return rh(r,413,{ok:!1,error:`selection-too-large`},i),e}if(th(s.formData)){let e=ch(s.formData);if(e){let t=f(nh(`PAYLOAD_FIELD_TOO_LARGE`,e));return rh(r,413,{ok:!1,error:`field-too-large`},i),t}}if(s.kind===`cancelled`){let e=typeof s.reason==`string`?s.reason:``;if(!eh.has(e)){let t=f(nh(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return rh(r,400,{ok:!1,error:`invalid-cancel-reason`},i),t}let t=f({kind:`cancelled`,reason:e});return rh(r,200,{ok:!0,kind:`cancelled`},i),t}let u=f(uh(s,e,t));return rh(r,u.kind===`error`?400:200,{ok:u.kind!==`error`,kind:u.kind},i),u}}}const ph=`Install AI Kit with <code>${Y(`npx -y @vpxa/aikit@latest init --user`)}</code>.`;function mh(e){let t=Date.now();return{id:e.id,state:`created`,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport,createdAt:t,updatedAt:t,stateHistory:[],responsePromise:null,resolveOutcome:null,cleanupCallbacks:[],nonceConsumed:!1}}var hh=class{sessions;maxSessions;rejectedCount;constructor(e=16){this.sessions=new Map,this.maxSessions=e,this.rejectedCount=0}createSession(e){if(this.sessions.size>=this.maxSessions)return this.rejectedCount++,{ok:!1,error:Ym(X.SESSION_LIMIT_REACHED,`Session limit reached`)};let t=Le(),n=mh({id:t,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport});return this.sessions.set(t,n),{ok:!0,session:n}}getSession(e){return this.sessions.get(e)||Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}transitionSession(e,t,n){let r=this.sessions.get(e);if(!r)return{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)};let i=Zm(r.state,t,r.stateHistory,n);return i.ok?(r.state=i.to,r.stateHistory.push(i.entry),r.updatedAt=Date.now(),{ok:!0,record:r}):{ok:!1,error:Ym(X.INVALID_TRANSITION,i.error.message)}}consumeNonce(e){let t=this.sessions.get(e);return t?t.nonceConsumed?{ok:!1,error:Ym(X.DUPLICATE_CALLBACK,`Nonce already consumed`)}:(t.nonceConsumed=!0,t.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}removeSession(e){return this.sessions.delete(e)}cleanupStale(e){let t=Date.now(),n=0;for(let[r,i]of this.sessions.entries())i.state!==`connected`&&t-i.updatedAt>e&&(i.resolveOutcome&&(i.resolveOutcome({outcome:`timeout`}),i.resolveOutcome=null,i.responsePromise=null),this.sessions.delete(r),n++);return n}shutdown(){for(let[,e]of this.sessions.entries()){e.resolveOutcome&&(e.resolveOutcome({outcome:`shutdown`}),e.resolveOutcome=null,e.responsePromise=null);for(let t of e.cleanupCallbacks)try{t()}catch{}e.cleanupCallbacks=[]}this.sessions.clear()}get activeCount(){return this.sessions.size}get rejectedSessionCount(){return this.rejectedCount}setResponseResolver(e,t){let n=this.sessions.get(e);return n?(n.resolveOutcome=t,n.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}};const gh=String.raw`(function(){
|
|
296
296
|
'use strict';
|
|
297
297
|
|
|
298
298
|
var SVG_NS = 'http://www.w3.org/2000/svg';
|
|
@@ -293,7 +293,7 @@ None.`:`### Stale Lessons\n${u.map(e=>`- **${e.title}** (\`${e.path}\`) — effe
|
|
|
293
293
|
{ path: 'docs/api.md', title: 'API Reference', status: 'stale' },
|
|
294
294
|
],
|
|
295
295
|
},
|
|
296
|
-
}`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`},{type:`diff`,category:`content`,description:`Diff view with +/- lines for showing changes between text.`,valueShape:`string | { content: string } | { before: string; after: string }`},{type:`finding`,category:`content`,description:`Finding with severity pill showing title, severity, and detail.`,valueShape:`{ title?: string; severity?: string; detail?: unknown }`},{type:`kv`,category:`data`,description:`Key-value pairs rendered as labeled entries.`,valueShape:`Array<{ key: string; value: unknown }> | Record<string, unknown>`},{type:`tags`,category:`data`,description:`Tag pills rendered with optional tone/color.`,valueShape:`Array<string | { text?: string; label?: string; status?: string; tone?: string; color?: string }> | { items: Array<...> }`},{type:`list`,category:`content`,description:`Bullet list items rendered as an unordered list.`,valueShape:`string[]`},{type:`lifecycle-flow`,category:`visualization`,description:`SVG flow diagram with labeled steps, edges, and status colors.`,valueShape:`{ title?: string; steps: Array<{ id: string; label: string; type?: string; status?: string; description?: string }>; edges?: Array<{ from: string; to: string; label?: string }> }`},{type:`component-detail`,category:`visualization`,description:`Component detail view with name, type, technology, responsibilities, interfaces, dependencies, metrics, and code links.`,valueShape:`{ name: string; description?: string; type?: string; technology?: string; responsibilities?: string[]; interfaces?: Array<{ name: string; type: string; description?: string }>; dependencies?: Array<{ name: string; relationship?: string }>; metrics?: Record<string, string | number>; codeLinks?: Array<{ href: string; label: string }> }`},{type:`data-table-schema`,category:`data`,description:`Schema table with field names, types, constraints, and indexes.`,valueShape:`{ name: string; description?: string; fields: Array<{ name: string; type: string; required?: boolean; default?: unknown; constraints?: string[]; description?: string }>; indexes?: Array<{ name: string; columns: string[]; unique?: boolean }> }`},{type:`annotation`,category:`interactive`,description:`Annotation groups with COMMENT, DELETION, and GLOBAL_COMMENT types.`,valueShape:`Array<{ id: string; type: "COMMENT" | "DELETION" | "GLOBAL_COMMENT"; body: string; author?: string; createdAt?: string }>`},{type:`approval`,category:`interactive`,description:`Approval widget with radio options and optional comment textarea.`,valueShape:`{ prompt: string; options: Array<{ id: string; label: string; description?: string }>; requireComment?: boolean }`},{type:`docs-hub`,category:`content`,description:`Doc hub card grid with titled pages, descriptions, categories, and statuses.`,valueShape:`{ title?: string; description?: string; pages?: Array<{ title: string; description?: string; href?: string; icon?: string; category?: string; status?: "draft" | "published" | "deprecated" }> }`}].map(e=>[e.type,{...e}]));function qm(){let e={};for(let[t,n]of Km)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const X={TIMEOUT:`timeout`,DUPLICATE_CALLBACK:`duplicate_callback`,INVALID_NONCE:`invalid_nonce`,INVALID_ORIGIN:`invalid_origin`,SESSION_NOT_FOUND:`session_not_found`,SESSION_LIMIT_REACHED:`session_limit_reached`,ASSET_NOT_FOUND:`asset_not_found`,ASSET_FORBIDDEN:`asset_forbidden`,RATE_LIMITED:`rate_limited`,PAYLOAD_TOO_LARGE:`payload_too_large`,UNSUPPORTED_MEDIA_TYPE:`unsupported_media_type`,INVALID_TRANSITION:`invalid_transition`,ANNOTATION_CAP_EXCEEDED:`annotation_cap_exceeded`},Jm={[X.TIMEOUT]:408,[X.DUPLICATE_CALLBACK]:409,[X.INVALID_NONCE]:400,[X.INVALID_ORIGIN]:403,[X.SESSION_NOT_FOUND]:404,[X.SESSION_LIMIT_REACHED]:429,[X.ASSET_NOT_FOUND]:404,[X.ASSET_FORBIDDEN]:403,[X.RATE_LIMITED]:429,[X.PAYLOAD_TOO_LARGE]:413,[X.UNSUPPORTED_MEDIA_TYPE]:415,[X.INVALID_TRANSITION]:400,[X.ANNOTATION_CAP_EXCEEDED]:403};function Ym(e,t,n){return{code:e,message:t,httpStatus:n??Jm[e]}}const Xm={created:[`rendering`,`errored`,`cleaned_up`,`timed_out`,`cancelled`,`responded`],rendering:[`listening`,`errored`,`cleaned_up`,`timed_out`,`cancelled`],listening:[`connected`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],connected:[`responded`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],responded:[`cleaned_up`],timed_out:[`cleaned_up`],cancelled:[`cleaned_up`],errored:[`cleaned_up`],cleaned_up:[]};function Zm(e,t,n,r){return Xm[e].includes(t)?{ok:!0,to:t,entry:{from:e,to:t,timestamp:Date.now(),trigger:r}}:{ok:!1,error:{code:`invalid_transition`,message:`Cannot transition from "${e}" to "${t}"`,from:e,to:t}}}function Qm(e){return Xm[e].length===0}const $m=1024,eh=new Set([`user-closed`,`host-dismissed`,`replaced`]);function th(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nh(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function rh(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function ih(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function ah(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`hex`),r=Buffer.from(t,`hex`);return n.length===r.length?Re(n,r):!1}function oh(e,t){let n=e.headers.origin;if(n!=null)return n===t;let r=e.headers.referer;return r==null?!1:r.startsWith(t)}function sh(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function ch(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function lh(e){return Array.isArray(e)&&e.length>$m?`Selection exceeds ${$m} items (got ${e.length})`:null}function uh(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return nh(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=th(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function dh(e){switch(e.kind){case`timeout`:return`timed_out`;case`cancelled`:return`cancelled`;case`error`:return`errored`;case`result`:return`responded`;default:return`errored`}}function fh(e,t,n,r,i){let a=i??Ie(16).toString(`hex`),o=`created`,s=[],c=!1,l,u,d=new Promise(e=>{u=e}),f=e=>{if(Qm(o))return l;let t=dh(e),i=Zm(o,t,s,`resolve`);return i.ok?(o=t,s.push(i.entry),l=e,u?.(e),n&&r&&n.transitionSession(r,t,`resolve`),e):l};return{nonce:a,promise:d,get state(){return o},get stateHistory(){return s},settleTimeout(e){return f({kind:`timeout`,waitedMs:e})},settleCancelled(e){return f({kind:`cancelled`,reason:e})},settleError(e,t,n){return f(nh(e,t,n))},async handle(n,r,i){if(!sh(n)){let e=f(nh(X.UNSUPPORTED_MEDIA_TYPE,`Content-Type must be application/json`));return rh(r,415,{ok:!1,error:X.UNSUPPORTED_MEDIA_TYPE},i),e}if(!oh(n,i)){let e=n.headers.origin??n.headers.referer??`(missing)`,t=f(nh(X.INVALID_ORIGIN,`Unexpected callback origin: ${e}`));return rh(r,403,{ok:!1,error:X.INVALID_ORIGIN},i),t}let o=``;try{o=await ih(n)}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return rh(r,413,{ok:!1,error:X.PAYLOAD_TOO_LARGE},i),t}let s;try{let e=JSON.parse(o);if(!th(e))throw Error(`Callback payload must be an object`);s=e}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return rh(r,400,{ok:!1,error:`invalid-json`},i),t}if(c){let e=nh(X.DUPLICATE_CALLBACK,`Nonce has already been used`);return rh(r,403,{ok:!1,error:X.DUPLICATE_CALLBACK},i),e}if(!ah(typeof s.nonce==`string`?s.nonce:``,a)){let e=f(nh(X.INVALID_NONCE,`Callback nonce did not match`));return rh(r,403,{ok:!1,error:X.INVALID_NONCE},i),e}c=!0;let l=lh(s.selection);if(l){let e=f(nh(`SELECTION_TOO_LARGE`,l));return rh(r,413,{ok:!1,error:`selection-too-large`},i),e}if(th(s.formData)){let e=ch(s.formData);if(e){let t=f(nh(`PAYLOAD_FIELD_TOO_LARGE`,e));return rh(r,413,{ok:!1,error:`field-too-large`},i),t}}if(s.kind===`cancelled`){let e=typeof s.reason==`string`?s.reason:``;if(!eh.has(e)){let t=f(nh(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return rh(r,400,{ok:!1,error:`invalid-cancel-reason`},i),t}let t=f({kind:`cancelled`,reason:e});return rh(r,200,{ok:!0,kind:`cancelled`},i),t}let u=f(uh(s,e,t));return rh(r,u.kind===`error`?400:200,{ok:u.kind!==`error`,kind:u.kind},i),u}}}const ph=`Install AI Kit with <code>${Y(`npx -y @vpxa/aikit@latest init --user`)}</code>.`;function mh(e){let t=Date.now();return{id:e.id,state:`created`,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport,createdAt:t,updatedAt:t,stateHistory:[],responsePromise:null,resolveOutcome:null,cleanupCallbacks:[],nonceConsumed:!1}}var hh=class{sessions;maxSessions;rejectedCount;constructor(e=16){this.sessions=new Map,this.maxSessions=e,this.rejectedCount=0}createSession(e){if(this.sessions.size>=this.maxSessions)return this.rejectedCount++,{ok:!1,error:Ym(X.SESSION_LIMIT_REACHED,`Session limit reached`)};let t=Le(),n=mh({id:t,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport});return this.sessions.set(t,n),{ok:!0,session:n}}getSession(e){return this.sessions.get(e)||Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}transitionSession(e,t,n){let r=this.sessions.get(e);if(!r)return{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)};let i=Zm(r.state,t,r.stateHistory,n);return i.ok?(r.state=i.to,r.stateHistory.push(i.entry),r.updatedAt=Date.now(),{ok:!0,record:r}):{ok:!1,error:Ym(X.INVALID_TRANSITION,i.error.message)}}consumeNonce(e){let t=this.sessions.get(e);return t?t.nonceConsumed?{ok:!1,error:Ym(X.DUPLICATE_CALLBACK,`Nonce already consumed`)}:(t.nonceConsumed=!0,t.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}removeSession(e){return this.sessions.delete(e)}cleanupStale(e){let t=Date.now(),n=0;for(let[r,i]of this.sessions.entries())i.state!==`connected`&&t-i.updatedAt>e&&(i.resolveOutcome&&(i.resolveOutcome({outcome:`timeout`}),i.resolveOutcome=null,i.responsePromise=null),this.sessions.delete(r),n++);return n}shutdown(){for(let[,e]of this.sessions.entries()){e.resolveOutcome&&(e.resolveOutcome({outcome:`shutdown`}),e.resolveOutcome=null,e.responsePromise=null);for(let t of e.cleanupCallbacks)try{t()}catch{}e.cleanupCallbacks=[]}this.sessions.clear()}get activeCount(){return this.sessions.size}get rejectedSessionCount(){return this.rejectedCount}setResponseResolver(e,t){let n=this.sessions.get(e);return n?(n.resolveOutcome=t,n.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}};const gh=String.raw`(function(){
|
|
296
|
+
}`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`},{type:`diff`,category:`content`,description:`Diff view with +/- lines for showing changes between text.`,valueShape:`string | { content: string } | { before: string; after: string }`},{type:`finding`,category:`content`,description:`Finding with severity pill showing title, severity, and detail.`,valueShape:`{ title?: string; severity?: string; detail?: unknown }`},{type:`kv`,category:`data`,description:`Key-value pairs rendered as labeled entries.`,valueShape:`Array<{ key: string; value: unknown }> | Record<string, unknown>`},{type:`tags`,category:`data`,description:`Tag pills rendered with optional tone/color.`,valueShape:`Array<string | { text?: string; label?: string; status?: string; tone?: string; color?: string }> | { items: Array<...> }`},{type:`list`,category:`content`,description:`Bullet list items rendered as an unordered list.`,valueShape:`string[]`},{type:`lifecycle-flow`,category:`visualization`,description:`SVG flow diagram with labeled steps, edges, and status colors.`,valueShape:`{ title?: string; steps: Array<{ id: string; label: string; type?: string; status?: string; description?: string }>; edges?: Array<{ from: string; to: string; label?: string }> }`},{type:`component-detail`,category:`visualization`,description:`Component detail view with name, type, technology, responsibilities, interfaces, dependencies, metrics, and code links.`,valueShape:`{ name: string; description?: string; type?: string; technology?: string; responsibilities?: string[]; interfaces?: Array<{ name: string; type: string; description?: string }>; dependencies?: Array<{ name: string; relationship?: string }>; metrics?: Record<string, string | number>; codeLinks?: Array<{ href: string; label: string }> }`},{type:`data-table-schema`,category:`data`,description:`Schema table with field names, types, constraints, and indexes.`,valueShape:`{ name: string; description?: string; fields: Array<{ name: string; type: string; required?: boolean; default?: unknown; constraints?: string[]; description?: string }>; indexes?: Array<{ name: string; columns: string[]; unique?: boolean }> }`},{type:`annotation`,category:`interactive`,description:`Annotation groups with COMMENT, DELETION, and GLOBAL_COMMENT types.`,valueShape:`Array<{ id: string; type: "COMMENT" | "DELETION" | "GLOBAL_COMMENT"; body: string; author?: string; createdAt?: string }>`},{type:`approval`,category:`interactive`,description:`Approval widget with radio options and optional comment textarea.`,valueShape:`{ prompt: string; options: Array<{ id: string; label: string; description?: string }>; requireComment?: boolean }`},{type:`docs-hub`,category:`content`,description:`Doc hub card grid with titled pages, descriptions, categories, and statuses.`,valueShape:`{ title?: string; description?: string; pages?: Array<{ title: string; description?: string; href?: string; icon?: string; category?: string; status?: "draft" | "published" | "deprecated" }> }`}].map(e=>[e.type,{...e}]));function qm(){let e={};for(let[t,n]of Km)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const X={TIMEOUT:`timeout`,DUPLICATE_CALLBACK:`duplicate_callback`,INVALID_NONCE:`invalid_nonce`,INVALID_ORIGIN:`invalid_origin`,SESSION_NOT_FOUND:`session_not_found`,SESSION_LIMIT_REACHED:`session_limit_reached`,ASSET_NOT_FOUND:`asset_not_found`,ASSET_FORBIDDEN:`asset_forbidden`,RATE_LIMITED:`rate_limited`,PAYLOAD_TOO_LARGE:`payload_too_large`,UNSUPPORTED_MEDIA_TYPE:`unsupported_media_type`,INVALID_TRANSITION:`invalid_transition`,ANNOTATION_CAP_EXCEEDED:`annotation_cap_exceeded`},Jm={[X.TIMEOUT]:408,[X.DUPLICATE_CALLBACK]:409,[X.INVALID_NONCE]:400,[X.INVALID_ORIGIN]:403,[X.SESSION_NOT_FOUND]:404,[X.SESSION_LIMIT_REACHED]:429,[X.ASSET_NOT_FOUND]:404,[X.ASSET_FORBIDDEN]:403,[X.RATE_LIMITED]:429,[X.PAYLOAD_TOO_LARGE]:413,[X.UNSUPPORTED_MEDIA_TYPE]:415,[X.INVALID_TRANSITION]:400,[X.ANNOTATION_CAP_EXCEEDED]:403};function Ym(e,t,n){return{code:e,message:t,httpStatus:n??Jm[e]}}const Xm={created:[`rendering`,`errored`,`cleaned_up`,`timed_out`,`cancelled`,`responded`],rendering:[`listening`,`errored`,`cleaned_up`,`timed_out`,`cancelled`],listening:[`connected`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],connected:[`responded`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],responded:[`cleaned_up`],timed_out:[`cleaned_up`],cancelled:[`cleaned_up`],errored:[`cleaned_up`],cleaned_up:[]};function Zm(e,t,n,r){return Xm[e].includes(t)?{ok:!0,to:t,entry:{from:e,to:t,timestamp:Date.now(),trigger:r}}:{ok:!1,error:{code:`invalid_transition`,message:`Cannot transition from "${e}" to "${t}"`,from:e,to:t}}}function Qm(e){return Xm[e].length===0}const $m=1024,eh=new Set([`user-closed`,`host-dismissed`,`replaced`]);function th(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nh(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function rh(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function ih(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function ah(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`hex`),r=Buffer.from(t,`hex`);return n.length===r.length?Re(n,r):!1}function oh(e,t){let n=e.headers.origin;if(n!==void 0)return n===t;let r=e.headers.referer;return r==null?!0:r.startsWith(t)}function sh(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function ch(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function lh(e){return Array.isArray(e)&&e.length>$m?`Selection exceeds ${$m} items (got ${e.length})`:null}function uh(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return nh(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=th(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function dh(e){switch(e.kind){case`timeout`:return`timed_out`;case`cancelled`:return`cancelled`;case`error`:return`errored`;case`result`:return`responded`;default:return`errored`}}function fh(e,t,n,r,i){let a=i??Ie(16).toString(`hex`),o=`created`,s=[],c=!1,l,u,d=new Promise(e=>{u=e}),f=e=>{if(Qm(o))return l;let t=dh(e),i=Zm(o,t,s,`resolve`);return i.ok?(o=t,s.push(i.entry),l=e,u?.(e),n&&r&&n.transitionSession(r,t,`resolve`),e):l};return{nonce:a,promise:d,get state(){return o},get stateHistory(){return s},settleTimeout(e){return f({kind:`timeout`,waitedMs:e})},settleCancelled(e){return f({kind:`cancelled`,reason:e})},settleError(e,t,n){return f(nh(e,t,n))},async handle(n,r,i){if(!sh(n)){let e=f(nh(X.UNSUPPORTED_MEDIA_TYPE,`Content-Type must be application/json`));return rh(r,415,{ok:!1,error:X.UNSUPPORTED_MEDIA_TYPE},i),e}if(!oh(n,i)){let e=n.headers.origin??n.headers.referer??`(missing)`,t=f(nh(X.INVALID_ORIGIN,`Unexpected callback origin: ${e}`));return rh(r,403,{ok:!1,error:X.INVALID_ORIGIN},i),t}let o=``;try{o=await ih(n)}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return rh(r,413,{ok:!1,error:X.PAYLOAD_TOO_LARGE},i),t}let s;try{let e=JSON.parse(o);if(!th(e))throw Error(`Callback payload must be an object`);s=e}catch(e){let t=f(nh(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return rh(r,400,{ok:!1,error:`invalid-json`},i),t}if(c){let e=nh(X.DUPLICATE_CALLBACK,`Nonce has already been used`);return rh(r,403,{ok:!1,error:X.DUPLICATE_CALLBACK},i),e}if(!ah(typeof s.nonce==`string`?s.nonce:``,a)){let e=f(nh(X.INVALID_NONCE,`Callback nonce did not match`));return rh(r,403,{ok:!1,error:X.INVALID_NONCE},i),e}c=!0;let l=lh(s.selection);if(l){let e=f(nh(`SELECTION_TOO_LARGE`,l));return rh(r,413,{ok:!1,error:`selection-too-large`},i),e}if(th(s.formData)){let e=ch(s.formData);if(e){let t=f(nh(`PAYLOAD_FIELD_TOO_LARGE`,e));return rh(r,413,{ok:!1,error:`field-too-large`},i),t}}if(s.kind===`cancelled`){let e=typeof s.reason==`string`?s.reason:``;if(!eh.has(e)){let t=f(nh(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return rh(r,400,{ok:!1,error:`invalid-cancel-reason`},i),t}let t=f({kind:`cancelled`,reason:e});return rh(r,200,{ok:!0,kind:`cancelled`},i),t}let u=f(uh(s,e,t));return rh(r,u.kind===`error`?400:200,{ok:u.kind!==`error`,kind:u.kind},i),u}}}const ph=`Install AI Kit with <code>${Y(`npx -y @vpxa/aikit@latest init --user`)}</code>.`;function mh(e){let t=Date.now();return{id:e.id,state:`created`,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport,createdAt:t,updatedAt:t,stateHistory:[],responsePromise:null,resolveOutcome:null,cleanupCallbacks:[],nonceConsumed:!1}}var hh=class{sessions;maxSessions;rejectedCount;constructor(e=16){this.sessions=new Map,this.maxSessions=e,this.rejectedCount=0}createSession(e){if(this.sessions.size>=this.maxSessions)return this.rejectedCount++,{ok:!1,error:Ym(X.SESSION_LIMIT_REACHED,`Session limit reached`)};let t=Le(),n=mh({id:t,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport});return this.sessions.set(t,n),{ok:!0,session:n}}getSession(e){return this.sessions.get(e)||Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}transitionSession(e,t,n){let r=this.sessions.get(e);if(!r)return{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)};let i=Zm(r.state,t,r.stateHistory,n);return i.ok?(r.state=i.to,r.stateHistory.push(i.entry),r.updatedAt=Date.now(),{ok:!0,record:r}):{ok:!1,error:Ym(X.INVALID_TRANSITION,i.error.message)}}consumeNonce(e){let t=this.sessions.get(e);return t?t.nonceConsumed?{ok:!1,error:Ym(X.DUPLICATE_CALLBACK,`Nonce already consumed`)}:(t.nonceConsumed=!0,t.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}removeSession(e){return this.sessions.delete(e)}cleanupStale(e){let t=Date.now(),n=0;for(let[r,i]of this.sessions.entries())i.state!==`connected`&&t-i.updatedAt>e&&(i.resolveOutcome&&(i.resolveOutcome({outcome:`timeout`}),i.resolveOutcome=null,i.responsePromise=null),this.sessions.delete(r),n++);return n}shutdown(){for(let[,e]of this.sessions.entries()){e.resolveOutcome&&(e.resolveOutcome({outcome:`shutdown`}),e.resolveOutcome=null,e.responsePromise=null);for(let t of e.cleanupCallbacks)try{t()}catch{}e.cleanupCallbacks=[]}this.sessions.clear()}get activeCount(){return this.sessions.size}get rejectedSessionCount(){return this.rejectedCount}setResponseResolver(e,t){let n=this.sessions.get(e);return n?(n.resolveOutcome=t,n.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Ym(X.SESSION_NOT_FOUND,`Session ${e} not found`)}}};const gh=String.raw`(function(){
|
|
297
297
|
'use strict';
|
|
298
298
|
|
|
299
299
|
var SVG_NS = 'http://www.w3.org/2000/svg';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,i as t,o as n,s as r}from"./bin.js";import{n as i,t as a}from"./startup-maintenance-L9NUOBVy.js";import{createLogger as o,serializeError as s,setDetailedErrorLoggingEnabled as c}from"../../core/dist/index.js";import{randomUUID as l}from"node:crypto";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${u}${l()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const _=o(`server`);async function v(o,u){let[{default:d},{loadConfig:f,resolveIndexMode:p},{registerDashboardRoutes:h,resolveDashboardDir:v},{registerSettingsRoutes:y,resolveSettingsDir:b},{createSettingsRouter:x},{authMiddleware:S,getOrCreateToken:C}]=await Promise.all([import(`express`),import(`./config-Bx85fwRX.js`),import(`./dashboard-static-dPnij4uF.js`),import(`./settings-static-MepJZjer.js`),import(`./routes-CfG5gdSR.js`),import(`./auth-bEP-6uqy.js`)]),w=f();c(w.logging?.errorDetails===!0),w.configError&&_.warn(`Config load failure`,{error:w.configError}),_.info(`Config loaded`,{sourceCount:w.sources.length,storePath:w.store.path});let T=d();T.use(d.json({limit:`1mb`}));let E=Number(u),D=`http://localhost:${E}`,O=process.env.AIKIT_CORS_ORIGIN??D,k=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,A=n(`AIKIT_HTTP_MAX_SESSIONS`,8),j=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),M=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),N=t({limit:100,windowMs:6e4}),P=!1;T.use((e,t,n)=>{let i=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,a=r({requestOrigin:i,configuredOrigin:O,allowAnyOrigin:k,fallbackOrigin:D});if(a.warn&&!P&&(P=!0,_.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let F=C();T.use(S(F)),T.use(`/mcp`,(t,n,r)=>{let i=e(t)??t.ip??t.socket.remoteAddress??`anonymous`;if(N.allow(i)){r();return}let a=Math.max(1,Math.ceil(N.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let I;T.use(`/mcp`,(e,t,n)=>{if(!I){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(I=t,_.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),h(T,v(),_);let L=new Date().toISOString();T.use(`/settings/api`,x({log:_,mcpInfo:()=>({transport:`http`,port:E,pid:process.pid,startedAt:L})})),y(T,b(),_),T.get(`/health`,(e,t)=>{t.json({status:`ok`})});let R=!1,z=null,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=Promise.resolve(),J=async(t,n)=>{if(!R||!V||!H){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=q,i;q=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[t.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(e=>{let n=setTimeout(()=>{_.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:t.method,timeoutMs:a}),e(!1)},a);n.unref&&n.unref()})])&&(q=Promise.resolve(),i=()=>{},W)){let e=W;W=null,G=null,e.close().catch(()=>{})}try{let r=e(t);if(!W){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new H({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{G=e,B?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&B?.onSessionEnd(e),G=null}});e.onclose=()=>{W===e&&(W=null),G===e.sessionId&&(G=null)},W=e,await V.connect(e)}let i=W;await i.handleRequest(t,n,t.body),t.method!==`DELETE`&&(!r&&i.sessionId?(G=i.sessionId,B?.onSessionStart(i.sessionId,{transport:`http`}),B?.onSessionActivity(i.sessionId)):r&&B?.onSessionActivity(r))}catch(e){if(_.error(`MCP handler error`,s(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},Y=async(t,n)=>{let r=e(t);if(U&&(!W||r!==G)){await U.handleRequest(t,n,t.body);return}await J(t,n)};T.post(`/mcp`,Y),T.get(`/mcp`,Y),T.delete(`/mcp`,Y);let X=T.listen(E,`127.0.0.1`,()=>{_.info(`MCP server listening`,{url:`http://127.0.0.1:${E}/mcp`,port:E}),setTimeout(async()=>{try{typeof I==`string`&&I.length>0&&(w.sources[0]={path:I,excludePatterns:w.sources[0]?.excludePatterns??[]},w.allRoots=[I],_.debug(`Workspace root applied from proxy header`,{wsRoot:I}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:c,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-BlGKtu2S.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CdBHTxtt.js`)]);c(),l(),setInterval(c,1440*60*1e3).unref();let u=!1,d=p(w),f=e(w,d);K=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},V=f.server,H=r,R=!0,_.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);B=new g(f.aikit.stateStore,{staleTimeoutMinutes:j,gcIntervalMinutes:M,onBeforeSessionDelete:e=>{if(G===e&&W){let e=W;W=null,G=null,e.close().catch(()=>void 0)}U?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&_.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),U=new m({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,w)},createTransport:e=>new r(e),maxSessions:A,sessionTimeoutMinutes:j,onSessionStart:e=>B?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>B?.onSessionActivity(e),onSessionEnd:e=>B?.onSessionEnd(e)}),B.startGC(),G&&(B.onSessionStart(G,{transport:`http`}),B.onSessionActivity(G)),_.info(`HTTP session runtime ready`,{maxSessions:A,sessionTimeoutMinutes:j,gcIntervalMinutes:M})}catch(e){_.error(`Failed to start session manager`,s(e)),R=!1,u=!0,V=null,H=null,K=null}}),d===`auto`?f.ready.then(async()=>{try{let e=w.sources.map(e=>e.path).join(`, `);_.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),_.info(`Initial index complete`)}catch(e){_.error(`Initial index failed; will retry on aikit_reindex`,i(o,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,w,f.aikit.store),n=f.aikit.store;z=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),_.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){_.error(`Failed to start smart index scheduler`,i(o,e))}}):_.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{_.error(`AI Kit initialization failed`,i(o,e)),R=!1,u=!0,V=null,H=null,K=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,o)}catch(e){_.error(`Failed to load server modules`,i(o,e)),R=!1,K=null}},100)}),Z=!1,Q=async e=>{Z||(Z=!0,_.info(`Shutdown signal received`,{signal:e}),z?.stop(),B?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await U?.closeAll().catch(()=>void 0),G&&B?.onSessionEnd(G),W&&(await W.close().catch(()=>void 0),W=null,G=null),X.close(),V&&await V.close(),await K?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>Q(`SIGINT`)),process.on(`SIGTERM`,()=>Q(`SIGTERM`))}export{v as startHttpMode};
|
|
2
|
+
import{a as e,i as t,o as n,s as r}from"./bin.js";import{n as i,t as a}from"./startup-maintenance-L9NUOBVy.js";import{createLogger as o,serializeError as s,setDetailedErrorLoggingEnabled as c}from"../../core/dist/index.js";import{randomUUID as l}from"node:crypto";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${u}${l()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const _=o(`server`);async function v(o,u){let[{default:d},{loadConfig:f,resolveIndexMode:p},{registerDashboardRoutes:h,resolveDashboardDir:v},{registerSettingsRoutes:y,resolveSettingsDir:b},{createSettingsRouter:x},{authMiddleware:S,getOrCreateToken:C}]=await Promise.all([import(`express`),import(`./config-Bx85fwRX.js`),import(`./dashboard-static-dPnij4uF.js`),import(`./settings-static-MepJZjer.js`),import(`./routes-CfG5gdSR.js`),import(`./auth-bEP-6uqy.js`)]),w=f();c(w.logging?.errorDetails===!0),w.configError&&_.warn(`Config load failure`,{error:w.configError}),_.info(`Config loaded`,{sourceCount:w.sources.length,storePath:w.store.path});let T=d();T.use(d.json({limit:`1mb`}));let E=Number(u),D=`http://localhost:${E}`,O=process.env.AIKIT_CORS_ORIGIN??D,k=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,A=n(`AIKIT_HTTP_MAX_SESSIONS`,8),j=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),M=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),N=t({limit:100,windowMs:6e4}),P=!1;T.use((e,t,n)=>{let i=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,a=r({requestOrigin:i,configuredOrigin:O,allowAnyOrigin:k,fallbackOrigin:D});if(a.warn&&!P&&(P=!0,_.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let F=C();T.use(S(F)),T.use(`/mcp`,(t,n,r)=>{let i=e(t)??t.ip??t.socket.remoteAddress??`anonymous`;if(N.allow(i)){r();return}let a=Math.max(1,Math.ceil(N.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let I;T.use(`/mcp`,(e,t,n)=>{if(!I){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(I=t,_.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),h(T,v(),_);let L=new Date().toISOString();T.use(`/settings/api`,x({log:_,mcpInfo:()=>({transport:`http`,port:E,pid:process.pid,startedAt:L})})),y(T,b(),_),T.get(`/health`,(e,t)=>{t.json({status:`ok`})});let R=!1,z=null,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=Promise.resolve(),J=async(t,n)=>{if(!R||!V||!H){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=q,i;q=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[t.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(e=>{let n=setTimeout(()=>{_.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:t.method,timeoutMs:a}),e(!1)},a);n.unref&&n.unref()})])&&(q=Promise.resolve(),i=()=>{},W)){let e=W;W=null,G=null,e.close().catch(()=>{})}try{let r=e(t);if(!W){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new H({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{G=e,B?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&B?.onSessionEnd(e),G=null}});e.onclose=()=>{W===e&&(W=null),G===e.sessionId&&(G=null)},W=e,await V.connect(e)}let i=W;await i.handleRequest(t,n,t.body),t.method!==`DELETE`&&(!r&&i.sessionId?(G=i.sessionId,B?.onSessionStart(i.sessionId,{transport:`http`}),B?.onSessionActivity(i.sessionId)):r&&B?.onSessionActivity(r))}catch(e){if(_.error(`MCP handler error`,s(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},Y=async(t,n)=>{let r=e(t);if(U&&(!W||r!==G)){await U.handleRequest(t,n,t.body);return}await J(t,n)};T.post(`/mcp`,Y),T.get(`/mcp`,Y),T.delete(`/mcp`,Y);let X=T.listen(E,`127.0.0.1`,()=>{_.info(`MCP server listening`,{url:`http://127.0.0.1:${E}/mcp`,port:E}),setTimeout(async()=>{try{typeof I==`string`&&I.length>0&&(w.sources[0]={path:I,excludePatterns:w.sources[0]?.excludePatterns??[]},w.allRoots=[I],_.debug(`Workspace root applied from proxy header`,{wsRoot:I}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:c,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-DyYCi71H.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CdBHTxtt.js`)]);c(),l(),setInterval(c,1440*60*1e3).unref();let u=!1,d=p(w),f=e(w,d);K=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},V=f.server,H=r,R=!0,_.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);B=new g(f.aikit.stateStore,{staleTimeoutMinutes:j,gcIntervalMinutes:M,onBeforeSessionDelete:e=>{if(G===e&&W){let e=W;W=null,G=null,e.close().catch(()=>void 0)}U?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&_.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),U=new m({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,w)},createTransport:e=>new r(e),maxSessions:A,sessionTimeoutMinutes:j,onSessionStart:e=>B?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>B?.onSessionActivity(e),onSessionEnd:e=>B?.onSessionEnd(e)}),B.startGC(),G&&(B.onSessionStart(G,{transport:`http`}),B.onSessionActivity(G)),_.info(`HTTP session runtime ready`,{maxSessions:A,sessionTimeoutMinutes:j,gcIntervalMinutes:M})}catch(e){_.error(`Failed to start session manager`,s(e)),R=!1,u=!0,V=null,H=null,K=null}}),d===`auto`?f.ready.then(async()=>{try{let e=w.sources.map(e=>e.path).join(`, `);_.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),_.info(`Initial index complete`)}catch(e){_.error(`Initial index failed; will retry on aikit_reindex`,i(o,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,w,f.aikit.store),n=f.aikit.store;z=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),_.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){_.error(`Failed to start smart index scheduler`,i(o,e))}}):_.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{_.error(`AI Kit initialization failed`,i(o,e)),R=!1,u=!0,V=null,H=null,K=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,o)}catch(e){_.error(`Failed to load server modules`,i(o,e)),R=!1,K=null}},100)}),Z=!1,Q=async e=>{Z||(Z=!0,_.info(`Shutdown signal received`,{signal:e}),z?.stop(),B?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await U?.closeAll().catch(()=>void 0),G&&B?.onSessionEnd(G),W&&(await W.close().catch(()=>void 0),W=null,G=null),X.close(),V&&await V.close(),await K?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>Q(`SIGINT`)),process.on(`SIGTERM`,()=>Q(`SIGTERM`))}export{v as startHttpMode};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./server-utils-De-aZNQa.js";import{n as i,t as a}from"./startup-maintenance-D0Uhpi3k.js";import{createLogger as o,serializeError as s,setDetailedErrorLoggingEnabled as c}from"../../core/dist/index.js";import{randomUUID as l}from"node:crypto";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${u}${l()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const _=o(`server`);async function v(o,u){let[{default:d},{loadConfig:f,resolveIndexMode:p},{registerDashboardRoutes:h,resolveDashboardDir:v},{registerSettingsRoutes:y,resolveSettingsDir:b},{createSettingsRouter:x},{authMiddleware:S,getOrCreateToken:C}]=await Promise.all([import(`express`),import(`./config-B-wvmMyo.js`),import(`./dashboard-static-Dw7Nsq4f.js`),import(`./settings-static-BpQgaMRs.js`),import(`./routes-C7bDyCOW.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),w=f();c(w.logging?.errorDetails===!0),w.configError&&_.warn(`Config load failure`,{error:w.configError}),_.info(`Config loaded`,{sourceCount:w.sources.length,storePath:w.store.path});let T=d();T.use(d.json({limit:`1mb`}));let E=Number(u),D=`http://localhost:${E}`,O=process.env.AIKIT_CORS_ORIGIN??D,k=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,A=n(`AIKIT_HTTP_MAX_SESSIONS`,8),j=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),M=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),N=r({limit:100,windowMs:6e4}),P=!1;T.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:O,allowAnyOrigin:k,fallbackOrigin:D});if(a.warn&&!P&&(P=!0,_.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){n.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&n.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),n.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),n.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),n.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),t.method===`OPTIONS`){n.status(204).end();return}r()});let F=C();T.use(S(F)),T.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(N.allow(i)){r();return}let a=Math.max(1,Math.ceil(N.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let I;T.use(`/mcp`,(e,t,n)=>{if(!I){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(I=t,_.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),h(T,v(),_);let L=new Date().toISOString();T.use(`/settings/api`,x({log:_,mcpInfo:()=>({transport:`http`,port:E,pid:process.pid,startedAt:L})})),y(T,b(),_),T.get(`/health`,(e,t)=>{t.json({status:`ok`})});let R=!1,z=null,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=Promise.resolve(),J=async(e,n)=>{if(!R||!V||!H){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=q,i;q=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{_.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(q=Promise.resolve(),i=()=>{},W)){let e=W;W=null,G=null,e.close().catch(()=>{})}try{let r=t(e);if(!W){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new H({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{G=e,B?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&B?.onSessionEnd(e),G=null}});e.onclose=()=>{W===e&&(W=null),G===e.sessionId&&(G=null)},W=e,await V.connect(e)}let i=W;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(G=i.sessionId,B?.onSessionStart(i.sessionId,{transport:`http`}),B?.onSessionActivity(i.sessionId)):r&&B?.onSessionActivity(r))}catch(e){if(_.error(`MCP handler error`,s(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},Y=async(e,n)=>{let r=t(e);if(U&&(!W||r!==G)){await U.handleRequest(e,n,e.body);return}await J(e,n)};T.post(`/mcp`,Y),T.get(`/mcp`,Y),T.delete(`/mcp`,Y);let X=T.listen(E,`127.0.0.1`,()=>{_.info(`MCP server listening`,{url:`http://127.0.0.1:${E}/mcp`,port:E}),setTimeout(async()=>{try{typeof I==`string`&&I.length>0&&(w.sources[0]={path:I,excludePatterns:w.sources[0]?.excludePatterns??[]},w.allRoots=[I],_.debug(`Workspace root applied from proxy header`,{wsRoot:I}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:c,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-DGrB9gzR.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CggUKvv8.js`)]);c(),l(),setInterval(c,1440*60*1e3).unref();let u=!1,d=p(w),f=e(w,d);K=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},V=f.server,H=r,R=!0,_.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);B=new g(f.aikit.stateStore,{staleTimeoutMinutes:j,gcIntervalMinutes:M,onBeforeSessionDelete:e=>{if(G===e&&W){let e=W;W=null,G=null,e.close().catch(()=>void 0)}U?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&_.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),U=new m({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,w)},createTransport:e=>new r(e),maxSessions:A,sessionTimeoutMinutes:j,onSessionStart:e=>B?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>B?.onSessionActivity(e),onSessionEnd:e=>B?.onSessionEnd(e)}),B.startGC(),G&&(B.onSessionStart(G,{transport:`http`}),B.onSessionActivity(G)),_.info(`HTTP session runtime ready`,{maxSessions:A,sessionTimeoutMinutes:j,gcIntervalMinutes:M})}catch(e){_.error(`Failed to start session manager`,s(e)),R=!1,u=!0,V=null,H=null,K=null}}),d===`auto`?f.ready.then(async()=>{try{let e=w.sources.map(e=>e.path).join(`, `);_.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),_.info(`Initial index complete`)}catch(e){_.error(`Initial index failed; will retry on aikit_reindex`,i(o,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,w,f.aikit.store),n=f.aikit.store;z=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),_.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){_.error(`Failed to start smart index scheduler`,i(o,e))}}):_.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{_.error(`AI Kit initialization failed`,i(o,e)),R=!1,u=!0,V=null,H=null,K=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,o)}catch(e){_.error(`Failed to load server modules`,i(o,e)),R=!1,K=null}},100)}),Z=!1,Q=async e=>{Z||(Z=!0,_.info(`Shutdown signal received`,{signal:e}),z?.stop(),B?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await U?.closeAll().catch(()=>void 0),G&&B?.onSessionEnd(G),W&&(await W.close().catch(()=>void 0),W=null,G=null),X.close(),V&&await V.close(),await K?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>Q(`SIGINT`)),process.on(`SIGTERM`,()=>Q(`SIGTERM`))}export{v as startHttpMode};
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./server-utils-De-aZNQa.js";import{n as i,t as a}from"./startup-maintenance-D0Uhpi3k.js";import{createLogger as o,serializeError as s,setDetailedErrorLoggingEnabled as c}from"../../core/dist/index.js";import{randomUUID as l}from"node:crypto";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${u}${l()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const _=o(`server`);async function v(o,u){let[{default:d},{loadConfig:f,resolveIndexMode:p},{registerDashboardRoutes:h,resolveDashboardDir:v},{registerSettingsRoutes:y,resolveSettingsDir:b},{createSettingsRouter:x},{authMiddleware:S,getOrCreateToken:C}]=await Promise.all([import(`express`),import(`./config-B-wvmMyo.js`),import(`./dashboard-static-Dw7Nsq4f.js`),import(`./settings-static-BpQgaMRs.js`),import(`./routes-C7bDyCOW.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),w=f();c(w.logging?.errorDetails===!0),w.configError&&_.warn(`Config load failure`,{error:w.configError}),_.info(`Config loaded`,{sourceCount:w.sources.length,storePath:w.store.path});let T=d();T.use(d.json({limit:`1mb`}));let E=Number(u),D=`http://localhost:${E}`,O=process.env.AIKIT_CORS_ORIGIN??D,k=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,A=n(`AIKIT_HTTP_MAX_SESSIONS`,8),j=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),M=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),N=r({limit:100,windowMs:6e4}),P=!1;T.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:O,allowAnyOrigin:k,fallbackOrigin:D});if(a.warn&&!P&&(P=!0,_.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){n.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&n.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),n.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),n.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),n.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),t.method===`OPTIONS`){n.status(204).end();return}r()});let F=C();T.use(S(F)),T.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(N.allow(i)){r();return}let a=Math.max(1,Math.ceil(N.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let I;T.use(`/mcp`,(e,t,n)=>{if(!I){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(I=t,_.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),h(T,v(),_);let L=new Date().toISOString();T.use(`/settings/api`,x({log:_,mcpInfo:()=>({transport:`http`,port:E,pid:process.pid,startedAt:L})})),y(T,b(),_),T.get(`/health`,(e,t)=>{t.json({status:`ok`})});let R=!1,z=null,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=Promise.resolve(),J=async(e,n)=>{if(!R||!V||!H){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=q,i;q=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{_.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(q=Promise.resolve(),i=()=>{},W)){let e=W;W=null,G=null,e.close().catch(()=>{})}try{let r=t(e);if(!W){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new H({sessionIdGenerator:()=>l(),onsessioninitialized:async e=>{G=e,B?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&B?.onSessionEnd(e),G=null}});e.onclose=()=>{W===e&&(W=null),G===e.sessionId&&(G=null)},W=e,await V.connect(e)}let i=W;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(G=i.sessionId,B?.onSessionStart(i.sessionId,{transport:`http`}),B?.onSessionActivity(i.sessionId)):r&&B?.onSessionActivity(r))}catch(e){if(_.error(`MCP handler error`,s(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},Y=async(e,n)=>{let r=t(e);if(U&&(!W||r!==G)){await U.handleRequest(e,n,e.body);return}await J(e,n)};T.post(`/mcp`,Y),T.get(`/mcp`,Y),T.delete(`/mcp`,Y);let X=T.listen(E,`127.0.0.1`,()=>{_.info(`MCP server listening`,{url:`http://127.0.0.1:${E}/mcp`,port:E}),setTimeout(async()=>{try{typeof I==`string`&&I.length>0&&(w.sources[0]={path:I,excludePatterns:w.sources[0]?.excludePatterns??[]},w.allRoots=[I],_.debug(`Workspace root applied from proxy header`,{wsRoot:I}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:c,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-BYY6wi6v.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CggUKvv8.js`)]);c(),l(),setInterval(c,1440*60*1e3).unref();let u=!1,d=p(w),f=e(w,d);K=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},V=f.server,H=r,R=!0,_.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);B=new g(f.aikit.stateStore,{staleTimeoutMinutes:j,gcIntervalMinutes:M,onBeforeSessionDelete:e=>{if(G===e&&W){let e=W;W=null,G=null,e.close().catch(()=>void 0)}U?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&_.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),U=new m({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,w)},createTransport:e=>new r(e),maxSessions:A,sessionTimeoutMinutes:j,onSessionStart:e=>B?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>B?.onSessionActivity(e),onSessionEnd:e=>B?.onSessionEnd(e)}),B.startGC(),G&&(B.onSessionStart(G,{transport:`http`}),B.onSessionActivity(G)),_.info(`HTTP session runtime ready`,{maxSessions:A,sessionTimeoutMinutes:j,gcIntervalMinutes:M})}catch(e){_.error(`Failed to start session manager`,s(e)),R=!1,u=!0,V=null,H=null,K=null}}),d===`auto`?f.ready.then(async()=>{try{let e=w.sources.map(e=>e.path).join(`, `);_.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),_.info(`Initial index complete`)}catch(e){_.error(`Initial index failed; will retry on aikit_reindex`,i(o,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,w,f.aikit.store),n=f.aikit.store;z=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),_.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){_.error(`Failed to start smart index scheduler`,i(o,e))}}):_.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{_.error(`AI Kit initialization failed`,i(o,e)),R=!1,u=!0,V=null,H=null,K=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,o)}catch(e){_.error(`Failed to load server modules`,i(o,e)),R=!1,K=null}},100)}),Z=!1,Q=async e=>{Z||(Z=!0,_.info(`Shutdown signal received`,{signal:e}),z?.stop(),B?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await U?.closeAll().catch(()=>void 0),G&&B?.onSessionEnd(G),W&&(await W.close().catch(()=>void 0),W=null,G=null),X.close(),V&&await V.close(),await K?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>Q(`SIGINT`)),process.on(`SIGTERM`,()=>Q(`SIGTERM`))}export{v as startHttpMode};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{r as e}from"./bin.js";import{n as t,t as n}from"./startup-maintenance-L9NUOBVy.js";import{t as r}from"./repair-json-D4mft_HA.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-Bx85fwRX.js`),import(`./server-
|
|
2
|
+
import{r as e}from"./bin.js";import{n as t,t as n}from"./startup-maintenance-L9NUOBVy.js";import{t as r}from"./repair-json-D4mft_HA.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-Bx85fwRX.js`),import(`./server-DyYCi71H.js`),import(`./version-check-CdBHTxtt.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./workspace-bootstrap-DupGrGox.js";import{n as t,t as n}from"./startup-maintenance-D0Uhpi3k.js";import{t as r}from"./repair-json-B6Q_HRoP.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-B-wvmMyo.js`),import(`./server-
|
|
1
|
+
import{n as e}from"./workspace-bootstrap-DupGrGox.js";import{n as t,t as n}from"./startup-maintenance-D0Uhpi3k.js";import{t as r}from"./repair-json-B6Q_HRoP.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-B-wvmMyo.js`),import(`./server-BYY6wi6v.js`),import(`./version-check-CggUKvv8.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
|