@vpxa/aikit 0.1.386 → 0.1.387
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.js +4 -4
- package/packages/claude-desktop/dist/manifest.json +1 -1
- package/packages/cli/dist/index.js +13 -13
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{register-tools-UK5us8_p.js → register-tools-CasJ5Lv1.js} +1 -1
- package/packages/server/dist/{register-tools-W0FlaHc5.js → register-tools-DYDI84K2.js} +1 -1
- package/packages/server/dist/{server-27qvW6G0.js → server-BVcK8mg9.js} +1 -1
- package/packages/server/dist/{server-cj8g5_Ga.js → server-DYip2rIp.js} +1 -1
- package/packages/server/dist/{server-http-B1iOYD9-.js → server-http-BN2naf7o.js} +1 -1
- package/packages/server/dist/{server-http-CoPnhJ2c.js → server-http-BgcMKnaH.js} +1 -1
- package/packages/server/dist/{server-stdio-DSADqshO.js → server-stdio-38nK5K09.js} +1 -1
- package/packages/server/dist/{server-stdio-DaepLjg4.js → server-stdio-C5N56hsL.js} +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_process";import{existsSync as i,mkdirSync as a,readFileSync as o,unlinkSync as s,writeFileSync as c}from"node:fs";import{homedir as l,platform as u,tmpdir as d}from"node:os";import{join as f}from"node:path";import{z as p}from"zod";const m=`0.26.0`,h=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function g(){return f(l(),`.aikit`,`browsers`)}function _(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??g()}function v(){try{let e=r(`${u()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,stdio:`pipe`,timeout:3e3}).trim().split(/\r?\n/)[0];if(!e)return null;if(u()===`win32`){if(i(`${e}.cmd`))return`${e}.cmd`;if(i(`${e}.bat`))return`${e}.bat`;if(i(`${e}.exe`))return`${e}.exe`}return i(e)?e:null}catch{return null}}function y(e){return f(e,`agent-browser`,te())}function te(){switch(u()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function b(e,t){try{c(f(e,h),t,`utf8`)}catch{}}function ne(e){try{return o(f(e,h),`utf8`).trim()}catch{return null}}function re(e){let t=ne(e);return t?ie(t,m)>=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!!(i(f(e,`chrome`))||i(f(l(),`.cache`,`agent-browser`,`chrome`)))}async function oe(t,n){let o=v();if(o)return n?.(`Using globally installed agent-browser`),o;let s=_(t);i(s)||a(s,{recursive:!0});let c=y(s);if(i(c)&&re(s))return n?.(`Using cached agent-browser at ${c}`),c;n?.(`Downloading agent-browser (first use)...`),await new Promise((t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),12e4),a=e(`npx -y agent-browser@latest install --install-dir "${s}"`,{timeout:12e4,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:s},signal:r.signal},(e,r,a)=>{if(clearTimeout(i),e){let t=ee(a)||e.message||`Unknown agent-browser install failure`;n(Error(`Failed to install agent-browser: ${t}`));return}t()});a.stdin&&a.stdin.destroy()});let l=c;try{let e=r(`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&i(e)&&(l=e,b(s,m))}catch{try{let e=r(`npx -y agent-browser --version`,{encoding:`utf8`,timeout:1e4,stdio:`pipe`}).trim();e&&b(s,e)}catch{}}return n?.(`agent-browser ready`),l}async function se(e){try{return n(e,[`--version`],{encoding:`utf8`,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function ce(e){if(v())return!0;let t=_(e);return ae(t)||i(y(t))}const le=[`ui`,`headless`];function ue(e){return le.includes(e)?e:`headless`}function de(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function fe(e){return{headless:e===`headless`,args:de(e)}}var x=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}},pe=class{tabs=new x;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 S={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:3e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var C=class{binaryPath=null;_currentMode=null;_isLaunched=!1;idleTimer=null;tabs=new x;config;constructor(e={}){this.config={...S,...e}}get currentMode(){return this._currentMode}async launch(e,t){let n=ue(e??this.config.defaultMode);if(!(this._isLaunched&&this._currentMode===n)){this._isLaunched&&this._currentMode!==n&&await this.close(),this._currentMode=n,this.binaryPath=await oe(this.config,t);try{let e=await this.exec(`--version`);t?.(`agent-browser ${e.stdout.trim()}`)}catch(e){throw Error(`agent-browser binary failed: ${e instanceof Error?e.message:String(e)}`)}this._isLaunched=!0,this.resetIdleTimer()}}async exec(e,...t){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let n=this.binaryPath;u()===`win32`&&!n.endsWith(`.cmd`)&&!n.endsWith(`.bat`)&&!n.endsWith(`.exe`)&&i(`${n}.cmd`)&&(n=`${n}.cmd`);let r=[e,...t];if(u()===`win32`&&(n.endsWith(`.cmd`)||n.endsWith(`.bat`))){let e=`"${n}" ${r.map(e=>/[^\w/:@.\-_{}()/\\]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e).join(` `)}`;return await this.execViaShell(e)}return await this.execViaExecFile(n,r)}execViaExecFile(e,n){return new Promise((r,i)=>{t(e,n,{timeout:this.config.evalTimeoutMs},(t,a,o)=>{if(t){let s=t;if(s.code===`ENOENT`){i(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(s.killed||s.signal){i(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${e} ${n.join(` `)}`));return}r({stdout:a??``,stderr:o??``,exitCode:typeof s.code==`number`?s.code:1});return}r({stdout:a??``,stderr:o??``,exitCode:0})}).stdin?.end()})}execViaShell(t){return new Promise((n,r)=>{e(t,{timeout:this.config.evalTimeoutMs},(e,i,a)=>{if(e){let o=e;if(o.code===`ENOENT`){r(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(o.killed||o.signal){r(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${t}`));return}n({stdout:i??``,stderr:a??``,exitCode:typeof o.code==`number`?o.code:1});return}n({stdout:i??``,stderr:a??``,exitCode:0})})})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=this._currentMode===`ui`?[`open`,e,`--headed`]:[`open`,e],i=await this.exec(...r);if(i.exitCode!==0)throw Error(`agent-browser failed to open URL (exit ${i.exitCode}): ${i.stderr||i.stdout||`Unknown error`}`);return this.tabs.register(`t0`,e,i.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`,a=f(t?.screenshotDir??d(),`aikit-screenshot-${Date.now()}.${i}`),c=[a];t?.fullPage&&c.push(`--full`),t?.screenshotDir&&c.push(`--screenshot-dir`,t.screenshotDir),t?.format===`jpeg`&&c.push(`--screenshot-format`,`jpeg`),t?.quality&&c.push(`--screenshot-quality`,String(t.quality)),t?.annotate&&c.push(`--annotate`),await this.exec(`screenshot`,...c);let l=o(a),u=l.toString(`base64`);try{s(a)}catch{}return this.resetIdleTimer(),{base64:u,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}getBinaryPath(){return this.binaryPath}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 w=null;function T(e){return w||=new C(e),w}async function me(){w&&=(await w.close(),null)}function E(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 D(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 he=[`ui`,`headless`];function ge(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`&&he.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 _e(e){let t=ge(e.browser)??{};return{...S,defaultMode:j(process.env.AIKIT_BROWSER_DEFAULT_MODE)??j(t.defaultMode)??S.defaultMode,browsersPath:O(process.env.AIKIT_BROWSER_PATH)??O(process.env.AIKIT_BROWSER_BROWSERS_PATH)??O(t.browsersPath)??S.browsersPath,userDataDirRoot:O(t.userDataDirRoot)??S.userDataDirRoot,idleShutdownMinutes:M(`AIKIT_BROWSER_IDLE_MINUTES`)??A(t.idleShutdownMinutes)??S.idleShutdownMinutes,allowInternalSchemes:k(t.allowInternalSchemes)??S.allowInternalSchemes,allowLoopback:k(t.allowLoopback)??S.allowLoopback,evalTimeoutMs:M(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??A(t.evalTimeoutMs)??S.evalTimeoutMs,evalMaxResultBytes:A(t.evalMaxResultBytes)??S.evalMaxResultBytes,redactPasswordFieldsInScreenshots:k(t.redactPasswordFieldsInScreenshots)??S.redactPasswordFieldsInScreenshots,engine:O(t.engine)??S.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 F(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`){let e=I(t);if(e.length>0)return e.join(`
|
|
2
|
-
`)}return JSON.stringify(t,null,2)}catch{return e}}function
|
|
1
|
+
import{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_process";import{copyFileSync as i,existsSync as a,mkdirSync as o,readFileSync as s,readdirSync as c,unlinkSync as l,writeFileSync as u}from"node:fs";import{homedir as d,platform as f,tmpdir as p}from"node:os";import{join as m}from"node:path";import{z as h}from"zod";const g=`0.26.0`,_=`.agent-browser-version`;function ee(e){return typeof e==`string`?e.trim():e instanceof Buffer?e.toString(`utf8`).trim():``}function v(){return m(d(),`.aikit`,`browsers`)}function y(e){return e.browsersPath??process.env.AIKIT_BROWSER_PATH??process.env.AIKIT_BROWSER_BROWSERS_PATH??v()}function b(){try{let e=r(`${f()===`win32`?`where`:`which`} agent-browser`,{encoding:`utf8`,stdio:`pipe`,timeout:3e3}).trim().split(/\r?\n/)[0];if(!e)return null;if(f()===`win32`){if(a(`${e}.cmd`))return`${e}.cmd`;if(a(`${e}.bat`))return`${e}.bat`;if(a(`${e}.exe`))return`${e}.exe`}return a(e)?e:null}catch{return null}}function x(e){return m(e,`agent-browser`,te())}function te(){switch(f()){case`win32`:return`agent-browser.exe`;default:return`agent-browser`}}function ne(e,t){try{u(m(e,_),t,`utf8`)}catch{}}function re(e){try{return s(m(e,_),`utf8`).trim()}catch{return null}}function ie(e){let t=re(e);return t?ae(t,g)>=0:!1}function ae(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<Math.max(n.length,r.length);e++){let t=n[e]||0,i=r[e]||0;if(t!==i)return t-i}return 0}function oe(e){return!!(a(m(e,`chrome`))||a(m(d(),`.cache`,`agent-browser`,`chrome`)))}async function se(t,n){let s=b();if(s)return n?.(`Using globally installed agent-browser`),s;let l=y(t);a(l)||o(l,{recursive:!0});let u=x(l);if(a(u)&&ie(l))return n?.(`Using cached agent-browser at ${u}`),u;n?.(`Downloading agent-browser (first use)...`),await new Promise((t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),12e4),a=e(`npx -y agent-browser@latest install --install-dir "${l}"`,{timeout:12e4,encoding:`utf8`,env:{...process.env,AGENT_BROWSER_CACHE_DIR:l},signal:r.signal},(e,r,a)=>{if(clearTimeout(i),e){let t=ee(a)||e.message||`Unknown agent-browser install failure`;n(Error(`Failed to install agent-browser: ${t}`));return}t()});a.stdin&&a.stdin.destroy()});let d=u;try{let e=r(f()===`win32`?`npx -y -p agent-browser node -e "process.stdout.write(__dirname)"`:`npx -y -p agent-browser which agent-browser 2>/dev/null || true`,{encoding:`utf8`,timeout:15e3,stdio:`pipe`}).trim(),t=f()===`win32`?`agent-browser-win32-x64.exe`:f()===`darwin`?process.arch===`arm64`?`agent-browser-darwin-arm64`:`agent-browser-darwin-x64`:`agent-browser-linux-${process.arch===`arm64`?`arm64`:`x64`}`,s=[];e&&!e.includes(`MODULE_NOT_FOUND`)&&(s.push(e),s.push(m(e,`..`)));try{let e=m(r(`npm config get cache`,{encoding:`utf8`,timeout:5e3,stdio:`pipe`}).trim(),`_npx`);if(a(e)){let n=c(e,{withFileTypes:!0});for(let r of n){if(!r.isDirectory())continue;let n=m(e,r.name,`node_modules`,`agent-browser`);if(a(m(n,`bin`,t))){s.push(n);break}}}}catch{}for(let e of s){let r=m(e,`bin`,t);if(a(r)){let t=m(l,`agent-browser`);a(t)||o(t,{recursive:!0});let s=x(l);i(r,s);let c=m(e,`bin`,`agent-browser.js`);a(c)&&i(c,m(t,`agent-browser.js`)),ne(l,g),d=s,n?.(`Cached agent-browser at ${s}`);break}}}catch{}return n?.(`agent-browser ready`),d}async function ce(e){try{return n(e,[`--version`],{encoding:`utf8`,stdio:`pipe`,timeout:5e3}).trim()}catch{return null}}function le(e){if(b())return!0;let t=y(e);return oe(t)||a(x(t))}const ue=[`ui`,`headless`];function de(e){return ue.includes(e)?e:`headless`}function fe(e){let t=[];return e===`headless`&&t.push(`--headless`),t}function pe(e){return{headless:e===`headless`,args:fe(e)}}var S=class{tabs=new Map;labelToId=new Map;register(e,t,n,r){return this.tabs.set(e,{tabId:e,url:t,title:n??t,label:r,createdAt:new Date}),r&&this.labelToId.set(r,e),e}resolve(e){return this.tabs.has(e)?e:this.labelToId.get(e)||e}getTab(e){let t=this.tabs.get(e);if(!t)throw Error(`Tab not found: ${e}`);return t}updateTabInfo(e,t,n){let r=this.tabs.get(e);r&&this.tabs.set(e,{...r,url:t,title:n})}setSnapshot(e,t){let n=this.tabs.get(e);n&&this.tabs.set(e,{...n,snapshot:t})}getSnapshot(e){return this.tabs.get(e)?.snapshot}async removeTab(e){let t=this.tabs.get(e);t&&(t.label&&this.labelToId.delete(t.label),this.tabs.delete(e))}listTabs(){return[...this.tabs.values()]}listPages(){return this.listTabs().map(e=>({pageId:e.tabId,url:e.url,title:e.title,label:e.label,createdAt:e.createdAt}))}async closeAll(){this.tabs.clear(),this.labelToId.clear()}clear(){this.tabs.clear(),this.labelToId.clear()}get size(){return this.tabs.size}},me=class{tabs=new S;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 C={defaultMode:`ui`,browsersPath:null,userDataDirRoot:null,idleShutdownMinutes:10,allowInternalSchemes:!1,allowLoopback:!1,evalTimeoutMs:3e4,evalMaxResultBytes:262144,redactPasswordFieldsInScreenshots:!0,engine:`chrome`};var w=class{binaryPath=null;_currentMode=null;_isLaunched=!1;idleTimer=null;tabs=new S;config;constructor(e={}){this.config={...C,...e}}get currentMode(){return this._currentMode}async launch(e,t){let n=de(e??this.config.defaultMode);if(!(this._isLaunched&&this._currentMode===n)){this._isLaunched&&this._currentMode!==n&&await this.close(),this._currentMode=n,this.binaryPath=await se(this.config,t);try{let e=await this.exec(`--version`);t?.(`agent-browser ${e.stdout.trim()}`)}catch(e){throw Error(`agent-browser binary failed: ${e instanceof Error?e.message:String(e)}`)}this._isLaunched=!0,this.resetIdleTimer()}}async exec(e,...t){if(!this.binaryPath)throw Error(`agent-browser not launched. Call launch() first, or use getEngine() singleton.`);let n=this.binaryPath;f()===`win32`&&!n.endsWith(`.cmd`)&&!n.endsWith(`.bat`)&&!n.endsWith(`.exe`)&&a(`${n}.cmd`)&&(n=`${n}.cmd`);let r=[e,...t];if(f()===`win32`&&(n.endsWith(`.cmd`)||n.endsWith(`.bat`))){let e=`"${n}" ${r.map(e=>/[^\w/:@.\-_{}()/\\]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e).join(` `)}`;return await this.execViaShell(e)}return await this.execViaExecFile(n,r)}execViaExecFile(e,n){return new Promise((r,i)=>{t(e,n,{timeout:this.config.evalTimeoutMs},(t,a,o)=>{if(t){let s=t;if(s.code===`ENOENT`){i(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(s.killed||s.signal){i(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${e} ${n.join(` `)}`));return}r({stdout:a??``,stderr:o??``,exitCode:typeof s.code==`number`?s.code:1});return}r({stdout:a??``,stderr:o??``,exitCode:0})}).stdin?.end()})}execViaShell(t){return new Promise((n,r)=>{e(t,{timeout:this.config.evalTimeoutMs},(e,i,a)=>{if(e){let o=e;if(o.code===`ENOENT`){r(Error(`agent-browser binary not found at ${this.binaryPath}`));return}if(o.killed||o.signal){r(Error(`agent-browser command timed out after ${this.config.evalTimeoutMs}ms: ${t}`));return}n({stdout:i??``,stderr:a??``,exitCode:typeof o.code==`number`?o.code:1});return}n({stdout:i??``,stderr:a??``,exitCode:0})})})}async tabExec(e,t,...n){return this.exec(`tab`,e,t,...n)}async open(e,t,n){await this.launch(t);let r=this._currentMode===`ui`?[`open`,e,`--headed`]:[`open`,e],i=await this.exec(...r);if(i.exitCode!==0)throw Error(`agent-browser failed to open URL (exit ${i.exitCode}): ${i.stderr||i.stdout||`Unknown error`}`);return this.tabs.register(`t0`,e,i.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`,a=m(t?.screenshotDir??p(),`aikit-screenshot-${Date.now()}.${i}`),o=[a];t?.fullPage&&o.push(`--full`),t?.screenshotDir&&o.push(`--screenshot-dir`,t.screenshotDir),t?.format===`jpeg`&&o.push(`--screenshot-format`,`jpeg`),t?.quality&&o.push(`--screenshot-quality`,String(t.quality)),t?.annotate&&o.push(`--annotate`),await this.exec(`screenshot`,...o);let c=s(a),u=c.toString(`base64`);try{l(a)}catch{}return this.resetIdleTimer(),{base64:u,mimeType:r,bytes:c.length}}async 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}getBinaryPath(){return this.binaryPath}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 w(e),T}async function he(){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 O(e,t){return Buffer.byteLength(e,`utf8`)<=t?{valid:!0,result:e,truncated:!1}:{valid:!0,result:`${Buffer.from(e).subarray(0,t).toString(`utf8`)}\n... [truncated]`,truncated:!0,reason:`Result exceeded ${t} bytes, truncated to ${t} bytes`}}const ge=[`ui`,`headless`];function _e(e){return typeof e==`object`&&e?e:null}function k(e){return typeof e==`string`&&e.length>0?e:void 0}function A(e){return typeof e==`boolean`?e:void 0}function j(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function M(e){return typeof e==`string`&&ge.includes(e)?e:void 0}function N(e){let t=process.env[e];if(!t)return;let n=Number(t);return Number.isFinite(n)?n:void 0}function ve(e){let t=_e(e.browser)??{};return{...C,defaultMode:M(process.env.AIKIT_BROWSER_DEFAULT_MODE)??M(t.defaultMode)??C.defaultMode,browsersPath:k(process.env.AIKIT_BROWSER_PATH)??k(process.env.AIKIT_BROWSER_BROWSERS_PATH)??k(t.browsersPath)??C.browsersPath,userDataDirRoot:k(t.userDataDirRoot)??C.userDataDirRoot,idleShutdownMinutes:N(`AIKIT_BROWSER_IDLE_MINUTES`)??j(t.idleShutdownMinutes)??C.idleShutdownMinutes,allowInternalSchemes:A(t.allowInternalSchemes)??C.allowInternalSchemes,allowLoopback:A(t.allowLoopback)??C.allowLoopback,evalTimeoutMs:N(`AIKIT_BROWSER_EVAL_TIMEOUT_MS`)??j(t.evalTimeoutMs)??C.evalTimeoutMs,evalMaxResultBytes:j(t.evalMaxResultBytes)??C.evalMaxResultBytes,redactPasswordFieldsInScreenshots:A(t.redactPasswordFieldsInScreenshots)??C.redactPasswordFieldsInScreenshots,engine:k(t.engine)??C.engine,proxy:k(t.proxy),viewport:k(t.viewport)}}function P(e,t){return{content:[{type:`text`,text:e}],structuredContent:t}}function F(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 I(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`){let e=L(t);if(e.length>0)return e.join(`
|
|
2
|
+
`)}return JSON.stringify(t,null,2)}catch{return e}}function L(e,t=0,n=[]){let r=` `.repeat(t),i=typeof e.role==`string`?e.role.toUpperCase():``,a=typeof e.ref==`string`?e.ref:``,o=typeof e.name==`string`?e.name:``,s=typeof e.value==`string`?`="${e.value}"`:``,c=Array.isArray(e.children)?e.children:[];if(i&&a){let e=ye(i),t=o||s||``;n.push(`${r}[${e}] [${a}] ${t}`.trimEnd())}else if(o||i){let e=i.toLowerCase();n.push(`${r}${e}: ${o}`.trimEnd())}for(let e of c)typeof e==`object`&&e&&L(e,t+1,n);return n}function ye(e){return{BUTTON:`BUTTON`,LINK:`LINK`,TEXT_FIELD:`TEXTFIELD`,TEXTBOX:`TEXTFIELD`,COMBOBOX:`SELECT`,CHECKBOX:`CHECKBOX`,RADIO:`RADIO`,SWITCH:`SWITCH`,SLIDER:`SLIDER`,TAB:`TAB`,MENU_ITEM:`MENUITEM`,LISTBOX:`LIST`,GRID:`GRID`,TABLE:`TABLE`,HEADING:`HEADING`,IMAGE:`IMAGE`,IMG:`IMAGE`,PROGRESSBAR:`PROGRESS`,DIALOG:`DIALOG`,TOOLTIP:`TOOLTIP`,ALERT:`ALERT`,MENU:`MENU`,NAVIGATION:`NAV`,SEARCH:`SEARCH`,MAIN:`MAIN`,COMPLEMENTARY:`COMPLEMENT`,CONTENTINFO:`INFO`,REGION:`REGION`}[e]??e.slice(0,8)}function be(e){return async({pageId:t,kind:n,ref:r,selector:i,element:a,text:o,key:s,value:c,fromRef:l,fromSelector:u,toRef:d,toSelector:f})=>{let p=E(e),m=p.resolvePageId(t);switch(n){case`click`:{let e=F({ref:r,selector:i,element:a},`browser_act(click)`);await p.tabExec(m,`click`,e);break}case`type`:{let e=F({ref:r,selector:i,element:a},`browser_act(type)`);await p.tabExec(m,`fill`,e,o??``);break}case`press`:{let e=F({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=F({ref:r,selector:i,element:a},`browser_act(hover)`);await p.tabExec(m,`hover`,e);break}case`drag`:{let e=F({ref:l??r,selector:u??i,element:a},`browser_act(drag) source`),t=F({ref:d,selector:f??c,element:a},`browser_act(drag) target`);await p.tabExec(m,`drag`,e,t);break}case`select`:{let e=F({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=F({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=F({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(),P(`ok`,{ok:!0})}}function xe(e){return async({pageId:t,subAction:n,level:r,bufferSize:i,expression:a})=>{let o=E(e),s=o.resolvePageId(t);switch(n){case`enable`:{let e=[`--enable`];return i&&e.push(`--buffer-size`,String(i)),r&&e.push(`--level`,r),await o.tabExec(s,`console`,...e),o.resetIdleTimer(),P(`Console capture enabled`,{enabled:!0})}case`get`:{let t=[`--json`];r&&t.push(`--level`,r);let n=await o.tabExec(s,`console`,...t);o.resetIdleTimer();let i=[];try{i=JSON.parse(n.stdout)}catch{i=[{raw:n.stdout}]}let c,l;if(a)try{c=(await o.tabExec(s,`evaluate`,`--timeout=${e.evalTimeoutMs}`,`--`,a)).stdout}catch(e){l=e instanceof Error?e.message:String(e)}return P(c===void 0?`Console has ${i.length} entries`:`Console has ${i.length} entries\nEvaluation: ${c}`,{entries:i,count:i.length,expression:a,evalResult:c,evalError:l})}case`clear`:return await o.tabExec(s,`console`,`clear`),o.resetIdleTimer(),P(`Console cleared`,{cleared:!0});default:return P(`Unknown console sub-action`,{error:`Unknown console sub-action`})}}}function Se(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(),P(`Dialog ${n?`accepted`:`dismissed`}`,{accepted:n})}}function Ce(e){return async({pageId:t})=>{let n=E(e),r=n.resolvePageId(t),i=await n.tabExec(r,`diff`,`snapshot`);return n.resetIdleTimer(),P(i.stdout,{pageId:r,diff:i.stdout})}}function we(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=O(s.stdout,e.evalMaxResultBytes);return P(c.result,{pageId:a,result:c.result,truncated:c.truncated})}}function Te(e){return async({pageId:t,url:n,method:r,headers:i,body:a,timeoutMs:o,includeHeaders:s})=>{let c=E(e),l=c.resolvePageId(t),u=o??e.evalTimeoutMs,d=Ee(n,r??`GET`,s??!0,i,a),f=await c.tabExec(l,`evaluate`,`--timeout=${u}`,`--`,d);return c.resetIdleTimer(),P(f.stdout,{pageId:l,response:f.stdout})}}function Ee(e,t,n,r,i){let a={method:t,headers:r??{}};i&&[`POST`,`PUT`,`PATCH`].includes(t.toUpperCase())&&(a.body=i);let o=JSON.stringify(a);return n?`fetch(${JSON.stringify(e)}, ${o}).then(async r => {
|
|
3
3
|
const text = await r.text();
|
|
4
4
|
const headers = {};
|
|
5
5
|
r.headers.forEach((v, k) => { headers[k] = v; });
|
|
@@ -7,5 +7,5 @@ import{exec as e,execFile as t,execFileSync as n,execSync as r}from"node:child_p
|
|
|
7
7
|
})`:`fetch(${JSON.stringify(e)}, ${o}).then(async r => {
|
|
8
8
|
const text = await r.text();
|
|
9
9
|
return JSON.stringify({ status: r.status, statusText: r.statusText, body: text.slice(0, 100000) });
|
|
10
|
-
})`}function
|
|
11
|
-
`)}`,{pages:e})}case`close`:return u?(await l.tabExec(u,`close`).catch(()=>{}),await l.tabs.removeTab(u),l.resetIdleTimer(),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 L=[`open`,`batch`,`read`,`act`,`navigate`,`network`,`console`,`fetch`,`eval`,`diff`,`screenshot`,`dialog`,`session`],R=[`ui`,`headless`],z=[`load`,`domcontentloaded`,`networkidle`],B=[`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`],V=[`back`,`forward`,`reload`,`waitFor`],H=[`enable`,`get`,`clear`,`export-har`],U=[`enable`,`get`,`clear`],W=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],G=[`list`,`close`,`cookies`,`set-cookie`,`delete-cookie`,`clear-cookies`,`get-storage`,`set-storage`,`clear-storage`],Me={action:p.enum(L).describe(`Browser action to perform`),pageId:p.string().optional().describe(`Tracked browser page identifier`),label:p.string().optional().describe(`Human-readable label for the page (used as alternative to pageId)`),url:p.string().url().optional().describe(`URL to open or navigate to`),mode:p.enum(R).optional().describe(`Browser launch mode (open only)`),forceNew:p.boolean().optional().describe(`Reserved for future tab reuse`),autoDialog:p.boolean().optional().describe(`Auto-accept alert/beforeunload dialogs (default: true). Set false to handle all dialogs manually.`),includeSnapshot:p.boolean().optional().describe(`Include ARIA snapshot in response (default: true for open/navigate). Set false to skip snapshot for speed.`),waitUntil:p.enum(z).optional().describe(`Navigation readiness event`),kind:p.enum(B).optional().describe(`Interaction kind (act only)`),ref:p.string().optional().describe(`Target ref alias`),selector:p.string().optional().describe(`CSS selector for targeting`),element:p.string().optional().describe(`Human-readable element label. Prefer selector for precision.`),text:p.string().optional().describe(`Text to type`),key:p.string().optional().describe(`Key to press`),value:p.string().optional().describe(`Option value or drag target`),fromRef:p.string().optional().describe(`Drag source ref`),fromSelector:p.string().optional().describe(`Drag source selector`),toRef:p.string().optional().describe(`Drag target ref`),toSelector:p.string().optional().describe(`Drag target selector`),type:p.enum(V).optional().describe(`Navigation type`),subAction:p.enum(H).optional().describe(`Network sub-action: enable, get, clear, or export-har`),code:p.string().optional().describe(`JavaScript expression or IIFE evaluated in page context.`),timeoutMs:p.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),filter:p.object({resourceTypes:p.array(p.string()).optional(),urlPattern:p.string().optional(),excludeUrls:p.array(p.string()).optional()}).optional().describe(`Network capture filter for resource types and URL patterns`),showSensitive:p.boolean().optional().describe(`Include sensitive headers instead of redacting them`),includeBody:p.boolean().optional().describe(`Include truncated request bodies in captured entries`),bufferSize:p.number().int().min(1).max(1e4).optional().describe(`Buffer capacity (1-10000, default varies by action)`),consoleSubAction:p.enum(U).optional().describe(`Console sub-action: enable, get, or clear`),expression:p.string().optional().describe(`JavaScript expression to evaluate in page context (console get only). Like browser_console expression in Hermes.`),level:p.string().optional().describe(`Filter console entries by level (log/info/warn/error/debug)`),fetchUrl:p.string().optional().describe(`URL for fetch action (http/https only). Uses page cookies/session.`),fetchMethod:p.enum(W).optional().describe(`HTTP method for fetch action (default: GET)`),fetchHeaders:p.record(p.string(),p.string()).optional().describe(`Custom headers for fetch action`),fetchBody:p.string().optional().describe(`Request body for fetch action (POST/PUT/PATCH)`),includeResponseHeaders:p.boolean().optional().describe(`Include response headers in fetch output (default: true)`),fullPage:p.boolean().optional().describe(`Capture full page`),annotate:p.boolean().optional().describe(`Overlay numbered [N] labels on interactive elements matching snapshot ref IDs (screenshot only).`),redactPasswords:p.boolean().optional().describe(`Mask password fields`),readMode:p.enum([`snapshot`,`dom`,`markdown`,`text`]).optional().describe(`Extraction mode for read action: snapshot (ARIA tree), dom (HTML), markdown (clean MD), text (plain text)`),clip:p.object({x:p.number(),y:p.number(),width:p.number(),height:p.number()}).optional().describe(`Capture a specific page region { x, y, width, height }`),format:p.enum([`png`,`jpeg`]).optional().describe(`Screenshot image format (default: png)`),quality:p.number().min(0).max(100).optional().describe(`JPEG quality 0-100 (only for jpeg format)`),cookies:p.array(p.object({name:p.string(),value:p.string(),url:p.string().optional(),domain:p.string().optional(),path:p.string().optional(),expires:p.number().optional(),httpOnly:p.boolean().optional(),secure:p.boolean().optional(),sameSite:p.enum([`Lax`,`None`,`Strict`]).optional()})).optional().describe(`Cookies to set (for session set-cookie action)`),name:p.string().optional().describe(`Cookie name for delete-cookie action`),storageType:p.enum([`localStorage`,`sessionStorage`]).optional().describe(`Storage type for get/set/clear-storage actions`),storageKey:p.string().optional().describe(`Storage key to get or set`),storageValue:p.string().optional().describe(`Value to set in storage`),accept:p.boolean().optional().describe(`Accept or dismiss dialog`),promptText:p.string().optional().describe(`Text for prompt dialog`),sessionAction:p.enum(G).optional().describe(`Session sub-action (session only)`),confirm:p.boolean().optional().describe(`Explicit confirmation for cookie export`),steps:p.array(p.record(p.string(),p.unknown())).optional().describe(`Array of action steps for batch execution. Each step is an object with action + action-specific params.`)};function Ne(e,t){return typeof e==`string`&&t.includes(e)}function K(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function Pe(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function q(e,t){let n=e[t];return typeof n==`string`?n:void 0}function J(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function Y(e,t){let n=e[t];return typeof n==`number`?n:void 0}function X(e,t){let n=e[t];return typeof n==`object`&&n?n:void 0}function Fe(e,t){let n=e.steps;if(!Array.isArray(n)||n.length===0)throw Error(`${t} requires non-empty steps`);return n.map((e,n)=>{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} step ${n+1} must be an object`);return e})}function Z(e,t,n,r){let i=e[t];if(!Ne(i,n))throw Error(`${r} requires ${t}`);return i}function Q(e,t,n,r){let i=e[t];if(i!==void 0){if(!Ne(i,n))throw Error(`${r} received invalid ${t}`);return i}}function Ie(e,t){let n=q(e,`pageId`);if(n)return T(t).resolvePageId(n)}function $(e,t,n){let r=q(e,`pageId`);if(!r)throw Error(`${n} requires pageId`);return T(t).resolvePageId(r)}async function Le(e,t,n){let r=Z(e,`action`,L,`browser`);switch(r){case`open`:return t.openHandler({url:K(e,`url`,`browser(open)`),mode:Q(e,`mode`,R,`browser(open)`),forceNew:J(e,`forceNew`),label:q(e,`label`),autoDialog:J(e,`autoDialog`),waitUntil:Q(e,`waitUntil`,z,`browser(open)`),includeSnapshot:J(e,`includeSnapshot`)});case`batch`:{let r=Fe(e,`browser(batch)`),i=[],a=0;for(let e=0;e<r.length;e+=1){let o=r[e],s=q(o,`action`)??`unknown`;try{let r=await Le(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:$(e,n,`browser(read)`),mode:Q(e,`readMode`,[`snapshot`,`dom`,`markdown`,`text`],`browser(read)`),selector:q(e,`selector`)});case`act`:return t.actHandler({pageId:$(e,n,`browser(act)`),kind:Z(e,`kind`,B,`browser(act)`),ref:q(e,`ref`),selector:q(e,`selector`),element:q(e,`element`),text:q(e,`text`),key:q(e,`key`),value:q(e,`value`),fromRef:q(e,`fromRef`),fromSelector:q(e,`fromSelector`),toRef:q(e,`toRef`),toSelector:q(e,`toSelector`)});case`navigate`:return t.navigateHandler({pageId:$(e,n,`browser(navigate)`),url:q(e,`url`),type:Q(e,`type`,V,`browser(navigate)`),selector:q(e,`selector`),timeoutMs:Y(e,`timeoutMs`),includeSnapshot:J(e,`includeSnapshot`)});case`network`:return t.networkHandler({pageId:$(e,n,`browser(network)`),subAction:Z(e,`subAction`,H,`browser(network)`),filter:X(e,`filter`),showSensitive:J(e,`showSensitive`),includeBody:J(e,`includeBody`),bufferSize:Y(e,`bufferSize`)});case`console`:return t.consoleHandler({pageId:$(e,n,`browser(console)`),subAction:Z(e,`consoleSubAction`,U,`browser(console)`),level:q(e,`level`),bufferSize:Y(e,`bufferSize`),expression:q(e,`expression`)});case`fetch`:return t.fetchHandler({pageId:$(e,n,`browser(fetch)`),url:K(e,`fetchUrl`,`browser(fetch)`),method:Q(e,`fetchMethod`,W,`browser(fetch)`),headers:X(e,`fetchHeaders`),body:q(e,`fetchBody`),timeoutMs:Y(e,`timeoutMs`),includeHeaders:J(e,`includeResponseHeaders`)});case`eval`:return t.evalHandler({pageId:$(e,n,`browser(eval)`),code:K(e,`code`,`browser(eval)`),timeoutMs:Y(e,`timeoutMs`)});case`diff`:return t.diffHandler({pageId:$(e,n,`browser(diff)`)});case`screenshot`:{let r=X(e,`clip`);return t.screenshotHandler({pageId:$(e,n,`browser(screenshot)`),ref:q(e,`ref`),selector:q(e,`selector`),fullPage:J(e,`fullPage`),annotate:J(e,`annotate`),redactPasswords:J(e,`redactPasswords`),clip:r,format:Q(e,`format`,[`png`,`jpeg`],`browser(screenshot)`),quality:Y(e,`quality`)})}case`dialog`:return t.dialogHandler({pageId:$(e,n,`browser(dialog)`),accept:Pe(e,`accept`,`browser(dialog)`),promptText:q(e,`promptText`)});case`session`:return t.sessionHandler({sessionAction:Z(e,`sessionAction`,G,`browser(session)`),pageId:q(e,`pageId`)&&Ie(e,n),confirm:J(e,`confirm`),cookies:X(e,`cookies`),name:q(e,`name`),storageType:Q(e,`storageType`,[`localStorage`,`sessionStorage`],`browser(session)`),storageKey:q(e,`storageKey`),storageValue:q(e,`storageValue`)});default:return N(`Unknown action: ${r}`,{error:`Unknown action: ${r}`})}}function Re(e,t){let n=_e(t),r={openHandler:Oe(n),readHandler:ke(n),actHandler:ye(n),navigateHandler:Ee(n),networkHandler:De(n),consoleHandler:be(n),fetchHandler:we(n),evalHandler:Ce(n),diffHandler:Se(n),screenshotHandler:Ae(n),dialogHandler:xe(n),sessionHandler:je(n)};e.tool(`browser`,`Unified browser automation tool using agent-browser (Chrome DevTools Protocol). Provides open, read, act, navigate, screenshot, eval, dialog, network, console, fetch, diff, session actions. New: includeSnapshot (open/navigate auto-returns ARIA tree), annotate (numbered labels on screenshots), expression (evaluate JS in console action).`,Me,async e=>{try{let t=await Le(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{C as BrowserEngine,S as DEFAULT_BROWSER_CONFIG,pe as SessionRegistry,x as TabRegistry,ue as autoSelectMode,me as closeEngine,oe as ensureAgentBrowserInstalled,se as getAgentBrowserVersion,de as getDaemonArgs,g as getDefaultBrowsersPath,T as getEngine,fe as getLaunchArgs,ce as isBrowserReady,E as isUrlAllowed,Re as registerBrowserTools,_ as resolveBrowsersPath,D as validateEvalResult};
|
|
10
|
+
})`}function De(e){return async({pageId:t,url:n,type:r,selector:i,timeoutMs:a,includeSnapshot:o})=>{let s=E(e),c=s.resolvePageId(t);if(n){let t=D(n,e);if(!t.allowed)return P(`Navigation blocked: ${t.reason}`,{blocked:!0,pageId:c,reason:t.reason});await s.tabExec(c,`goto`,n)}else if(!r)return P(`Navigation requires url or type`,{error:`Navigation requires url or type`,pageId:c});else if(r===`back`)await s.tabExec(c,`back`);else if(r===`forward`)await s.tabExec(c,`forward`);else if(r===`reload`)await s.tabExec(c,`reload`);else if(r===`waitFor`){if(!i)throw Error(`browser_navigate(waitFor) requires selector`);let e=a?[i,String(a)]:[i];await s.tabExec(c,`wait`,...e)}let l=await s.tabExec(c,`get`,`text`).catch(()=>({stdout:n??``})),u=await s.tabExec(c,`get`,`attr`,`title`).catch(()=>({stdout:``})),d=l.stdout.trim()||n||``,f=u.stdout.trim()||d;s.tabs.updateTabInfo(c,d,f),s.resetIdleTimer();let p;if(o!==!1)try{p=I(await s.readSnapshot(c))}catch{}return P(p?`${f||d}\n${d}\n\n${p}`:`${f||d}\n${d}`,{pageId:c,url:d,title:f,snapshot:p})}}function Oe(e){return async({pageId:t,subAction:n,filter:r,includeBody:i,bufferSize:a})=>{let o=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(),P(`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 P(`Captured ${t.length} network requests`,{entries:t,count:t.length})}case`clear`:return await o.tabExec(s,`network`,`clear`),o.resetIdleTimer(),P(`Network capture cleared`,{cleared:!0});case`export-har`:{let e=await o.tabExec(s,`network`,`har`);return o.resetIdleTimer(),P(e.stdout,{har:e.stdout})}default:return P(`Unknown network sub-action`,{error:`Unknown network sub-action`})}}}function ke(e){return async({url:t,mode:n,label:r,waitUntil:i,includeSnapshot:a,forceNew:o,autoDialog:s})=>{let c=D(t,e);if(!c.allowed)return P(`Navigation blocked: ${c.reason}`,{blocked:!0,reason:c.reason});let l=E(e);await l.launch(n);let u=await l.exec(`open`,t);l.tabs.register(`t0`,t,r??u.stdout.trim(),r),l.resetIdleTimer();let d=[];i===`networkidle`&&d.push(`--wait-until`,`networkidle`),i===`domcontentloaded`&&d.push(`--wait-until`,`domcontentloaded`),d.length>0&&await l.tabExec(`t0`,`wait`,...d).catch(()=>{});let f;if(a!==!1)try{f=I(await l.readSnapshot(`t0`))}catch{}return P(f?`Opened ${t}\n\n${f}`:`Opened ${t}\nTab: t0`,{pageId:`t0`,url:t,tabId:`t0`,label:r,snapshot:f})}}function Ae(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(),P(t.stdout,{pageId:a,mode:`snapshot`,content:t.stdout})}case`dom`:{let e=await i.tabExec(a,`get`,`html`);return i.resetIdleTimer(),P(e.stdout,{pageId:a,mode:`dom`,content:e.stdout})}case`markdown`:{let e=await i.tabExec(a,`snapshot`,`-c`);return i.resetIdleTimer(),P(e.stdout,{pageId:a,mode:`markdown`,content:e.stdout})}case`text`:{let e=await i.tabExec(a,`get`,`text`);return i.resetIdleTimer(),P(e.stdout,{pageId:a,mode:`text`,content:e.stdout})}default:return P(`Unknown read mode`,{error:`Unknown read mode`,pageId:a})}}}function je(e){return async({pageId:t,ref:n,selector:r,fullPage:i,annotate:a,clip:o,format:s,quality:c})=>{let l=E(e),u=l.resolvePageId(t),d=r??n;if(d){let e=await l.tabExec(u,`screenshot`,`--element`,d);return l.resetIdleTimer(),P(`Screenshot captured for element ${d}`,{element:d,pageId:u,screenshot:e.stdout})}let f=await l.screenshot(u,{fullPage:i,format:s,quality:c,annotate:a});return l.resetIdleTimer(),P(`Screenshot captured (${f.bytes} bytes)`,{pageId:u,base64:f.base64,mimeType:f.mimeType,bytes:f.bytes})}}function Me(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 P(`Open tabs: ${e.length}\n${e.map(e=>` ${e.pageId}: ${e.title||e.url}`).join(`
|
|
11
|
+
`)}`,{pages:e})}case`close`:return u?(await l.tabExec(u,`close`).catch(()=>{}),await l.tabs.removeTab(u),l.resetIdleTimer(),P(`Closed tab ${u}`,{closed:u})):P(`close requires pageId`,{error:`pageId required`});case`cookies`:{if(!r)return P(`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 P(`Exported ${t.length} cookies`,{cookies:t,count:t.length})}case`set-cookie`:{if(!i||i.length===0)return P(`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(),P(`Set ${i.length} cookies`,{count:i.length})}case`delete-cookie`:return a?(await l.tabExec(u??`t0`,`cookies`,`clear`,a),l.resetIdleTimer(),P(`Deleted cookie ${a}`,{deleted:a})):P(`delete-cookie requires name`,{error:`name required`});case`clear-cookies`:return await l.tabExec(u??`t0`,`cookies`,`clear`),l.resetIdleTimer(),P(`Cookies cleared`,{cleared:!0});case`get-storage`:{if(!o||!s)return P(`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(),P(e.stdout,{value:e.stdout})}case`set-storage`:return!o||!s||c===void 0?P(`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(),P(`Storage key ${s} set`,{key:s}));case`clear-storage`:return o?(await l.tabExec(u??`t0`,`storage`,o===`localStorage`?`local`:`session`,`clear`),l.resetIdleTimer(),P(`Storage cleared`,{cleared:!0})):P(`clear-storage requires storageType`,{error:`storageType required`});default:return P(`Unknown session action`,{error:`Unknown session action`})}}}const R=[`open`,`batch`,`read`,`act`,`navigate`,`network`,`console`,`fetch`,`eval`,`diff`,`screenshot`,`dialog`,`session`],z=[`ui`,`headless`],B=[`load`,`domcontentloaded`,`networkidle`],V=[`click`,`type`,`press`,`hover`,`drag`,`select`,`scroll`,`upload`],H=[`back`,`forward`,`reload`,`waitFor`],U=[`enable`,`get`,`clear`,`export-har`],W=[`enable`,`get`,`clear`],Ne=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],Pe=[`list`,`close`,`cookies`,`set-cookie`,`delete-cookie`,`clear-cookies`,`get-storage`,`set-storage`,`clear-storage`],Fe={action:h.enum(R).describe(`Browser action to perform`),pageId:h.string().optional().describe(`Tracked browser page identifier`),label:h.string().optional().describe(`Human-readable label for the page (used as alternative to pageId)`),url:h.string().url().optional().describe(`URL to open or navigate to`),mode:h.enum(z).optional().describe(`Browser launch mode (open only)`),forceNew:h.boolean().optional().describe(`Reserved for future tab reuse`),autoDialog:h.boolean().optional().describe(`Auto-accept alert/beforeunload dialogs (default: true). Set false to handle all dialogs manually.`),includeSnapshot:h.boolean().optional().describe(`Include ARIA snapshot in response (default: true for open/navigate). Set false to skip snapshot for speed.`),waitUntil:h.enum(B).optional().describe(`Navigation readiness event`),kind:h.enum(V).optional().describe(`Interaction kind (act only)`),ref:h.string().optional().describe(`Target ref alias`),selector:h.string().optional().describe(`CSS selector for targeting`),element:h.string().optional().describe(`Human-readable element label. Prefer selector for precision.`),text:h.string().optional().describe(`Text to type`),key:h.string().optional().describe(`Key to press`),value:h.string().optional().describe(`Option value or drag target`),fromRef:h.string().optional().describe(`Drag source ref`),fromSelector:h.string().optional().describe(`Drag source selector`),toRef:h.string().optional().describe(`Drag target ref`),toSelector:h.string().optional().describe(`Drag target selector`),type:h.enum(H).optional().describe(`Navigation type`),subAction:h.enum(U).optional().describe(`Network sub-action: enable, get, clear, or export-har`),code:h.string().optional().describe(`JavaScript expression or IIFE evaluated in page context.`),timeoutMs:h.number().min(1).max(6e4).optional().describe(`Timeout in milliseconds`),filter:h.object({resourceTypes:h.array(h.string()).optional(),urlPattern:h.string().optional(),excludeUrls:h.array(h.string()).optional()}).optional().describe(`Network capture filter for resource types and URL patterns`),showSensitive:h.boolean().optional().describe(`Include sensitive headers instead of redacting them`),includeBody:h.boolean().optional().describe(`Include truncated request bodies in captured entries`),bufferSize:h.number().int().min(1).max(1e4).optional().describe(`Buffer capacity (1-10000, default varies by action)`),consoleSubAction:h.enum(W).optional().describe(`Console sub-action: enable, get, or clear`),expression:h.string().optional().describe(`JavaScript expression to evaluate in page context (console get only). Like browser_console expression in Hermes.`),level:h.string().optional().describe(`Filter console entries by level (log/info/warn/error/debug)`),fetchUrl:h.string().optional().describe(`URL for fetch action (http/https only). Uses page cookies/session.`),fetchMethod:h.enum(Ne).optional().describe(`HTTP method for fetch action (default: GET)`),fetchHeaders:h.record(h.string(),h.string()).optional().describe(`Custom headers for fetch action`),fetchBody:h.string().optional().describe(`Request body for fetch action (POST/PUT/PATCH)`),includeResponseHeaders:h.boolean().optional().describe(`Include response headers in fetch output (default: true)`),fullPage:h.boolean().optional().describe(`Capture full page`),annotate:h.boolean().optional().describe(`Overlay numbered [N] labels on interactive elements matching snapshot ref IDs (screenshot only).`),redactPasswords:h.boolean().optional().describe(`Mask password fields`),readMode:h.enum([`snapshot`,`dom`,`markdown`,`text`]).optional().describe(`Extraction mode for read action: snapshot (ARIA tree), dom (HTML), markdown (clean MD), text (plain text)`),clip:h.object({x:h.number(),y:h.number(),width:h.number(),height:h.number()}).optional().describe(`Capture a specific page region { x, y, width, height }`),format:h.enum([`png`,`jpeg`]).optional().describe(`Screenshot image format (default: png)`),quality:h.number().min(0).max(100).optional().describe(`JPEG quality 0-100 (only for jpeg format)`),cookies:h.array(h.object({name:h.string(),value:h.string(),url:h.string().optional(),domain:h.string().optional(),path:h.string().optional(),expires:h.number().optional(),httpOnly:h.boolean().optional(),secure:h.boolean().optional(),sameSite:h.enum([`Lax`,`None`,`Strict`]).optional()})).optional().describe(`Cookies to set (for session set-cookie action)`),name:h.string().optional().describe(`Cookie name for delete-cookie action`),storageType:h.enum([`localStorage`,`sessionStorage`]).optional().describe(`Storage type for get/set/clear-storage actions`),storageKey:h.string().optional().describe(`Storage key to get or set`),storageValue:h.string().optional().describe(`Value to set in storage`),accept:h.boolean().optional().describe(`Accept or dismiss dialog`),promptText:h.string().optional().describe(`Text for prompt dialog`),sessionAction:h.enum(Pe).optional().describe(`Session sub-action (session only)`),confirm:h.boolean().optional().describe(`Explicit confirmation for cookie export`),steps:h.array(h.record(h.string(),h.unknown())).optional().describe(`Array of action steps for batch execution. Each step is an object with action + action-specific params.`)};function G(e,t){return typeof e==`string`&&t.includes(e)}function K(e,t,n){let r=e[t];if(typeof r!=`string`)throw Error(`${n} requires ${t}`);return r}function Ie(e,t,n){let r=e[t];if(typeof r!=`boolean`)throw Error(`${n} requires ${t}`);return r}function q(e,t){let n=e[t];return typeof n==`string`?n:void 0}function J(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function Y(e,t){let n=e[t];return typeof n==`number`?n:void 0}function X(e,t){let n=e[t];return typeof n==`object`&&n?n:void 0}function Le(e,t){let n=e.steps;if(!Array.isArray(n)||n.length===0)throw Error(`${t} requires non-empty steps`);return n.map((e,n)=>{if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} step ${n+1} must be an object`);return e})}function Z(e,t,n,r){let i=e[t];if(!G(i,n))throw Error(`${r} requires ${t}`);return i}function Q(e,t,n,r){let i=e[t];if(i!==void 0){if(!G(i,n))throw Error(`${r} received invalid ${t}`);return i}}function Re(e,t){let n=q(e,`pageId`);if(n)return E(t).resolvePageId(n)}function $(e,t,n){let r=q(e,`pageId`);if(!r)throw Error(`${n} requires pageId`);return E(t).resolvePageId(r)}async function ze(e,t,n){let r=Z(e,`action`,R,`browser`);switch(r){case`open`:return t.openHandler({url:K(e,`url`,`browser(open)`),mode:Q(e,`mode`,z,`browser(open)`),forceNew:J(e,`forceNew`),label:q(e,`label`),autoDialog:J(e,`autoDialog`),waitUntil:Q(e,`waitUntil`,B,`browser(open)`),includeSnapshot:J(e,`includeSnapshot`)});case`batch`:{let r=Le(e,`browser(batch)`),i=[],a=0;for(let e=0;e<r.length;e+=1){let o=r[e],s=q(o,`action`)??`unknown`;try{let r=await ze(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 P(`Batch completed: ${a}/${r.length} steps succeeded`,{total:r.length,succeeded:a,steps:i})}case`read`:return t.readHandler({pageId:$(e,n,`browser(read)`),mode:Q(e,`readMode`,[`snapshot`,`dom`,`markdown`,`text`],`browser(read)`),selector:q(e,`selector`)});case`act`:return t.actHandler({pageId:$(e,n,`browser(act)`),kind:Z(e,`kind`,V,`browser(act)`),ref:q(e,`ref`),selector:q(e,`selector`),element:q(e,`element`),text:q(e,`text`),key:q(e,`key`),value:q(e,`value`),fromRef:q(e,`fromRef`),fromSelector:q(e,`fromSelector`),toRef:q(e,`toRef`),toSelector:q(e,`toSelector`)});case`navigate`:return t.navigateHandler({pageId:$(e,n,`browser(navigate)`),url:q(e,`url`),type:Q(e,`type`,H,`browser(navigate)`),selector:q(e,`selector`),timeoutMs:Y(e,`timeoutMs`),includeSnapshot:J(e,`includeSnapshot`)});case`network`:return t.networkHandler({pageId:$(e,n,`browser(network)`),subAction:Z(e,`subAction`,U,`browser(network)`),filter:X(e,`filter`),showSensitive:J(e,`showSensitive`),includeBody:J(e,`includeBody`),bufferSize:Y(e,`bufferSize`)});case`console`:return t.consoleHandler({pageId:$(e,n,`browser(console)`),subAction:Z(e,`consoleSubAction`,W,`browser(console)`),level:q(e,`level`),bufferSize:Y(e,`bufferSize`),expression:q(e,`expression`)});case`fetch`:return t.fetchHandler({pageId:$(e,n,`browser(fetch)`),url:K(e,`fetchUrl`,`browser(fetch)`),method:Q(e,`fetchMethod`,Ne,`browser(fetch)`),headers:X(e,`fetchHeaders`),body:q(e,`fetchBody`),timeoutMs:Y(e,`timeoutMs`),includeHeaders:J(e,`includeResponseHeaders`)});case`eval`:return t.evalHandler({pageId:$(e,n,`browser(eval)`),code:K(e,`code`,`browser(eval)`),timeoutMs:Y(e,`timeoutMs`)});case`diff`:return t.diffHandler({pageId:$(e,n,`browser(diff)`)});case`screenshot`:{let r=X(e,`clip`);return t.screenshotHandler({pageId:$(e,n,`browser(screenshot)`),ref:q(e,`ref`),selector:q(e,`selector`),fullPage:J(e,`fullPage`),annotate:J(e,`annotate`),redactPasswords:J(e,`redactPasswords`),clip:r,format:Q(e,`format`,[`png`,`jpeg`],`browser(screenshot)`),quality:Y(e,`quality`)})}case`dialog`:return t.dialogHandler({pageId:$(e,n,`browser(dialog)`),accept:Ie(e,`accept`,`browser(dialog)`),promptText:q(e,`promptText`)});case`session`:return t.sessionHandler({sessionAction:Z(e,`sessionAction`,Pe,`browser(session)`),pageId:q(e,`pageId`)&&Re(e,n),confirm:J(e,`confirm`),cookies:X(e,`cookies`),name:q(e,`name`),storageType:Q(e,`storageType`,[`localStorage`,`sessionStorage`],`browser(session)`),storageKey:q(e,`storageKey`),storageValue:q(e,`storageValue`)});default:return P(`Unknown action: ${r}`,{error:`Unknown action: ${r}`})}}function Be(e,t){let n=ve(t),r={openHandler:ke(n),readHandler:Ae(n),actHandler:be(n),navigateHandler:De(n),networkHandler:Oe(n),consoleHandler:xe(n),fetchHandler:Te(n),evalHandler:we(n),diffHandler:Ce(n),screenshotHandler:je(n),dialogHandler:Se(n),sessionHandler:Me(n)};e.tool(`browser`,`Unified browser automation tool using agent-browser (Chrome DevTools Protocol). Provides open, read, act, navigate, screenshot, eval, dialog, network, console, fetch, diff, session actions. New: includeSnapshot (open/navigate auto-returns ARIA tree), annotate (numbered labels on screenshots), expression (evaluate JS in console action).`,Fe,async e=>{try{let t=await ze(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{w as BrowserEngine,C as DEFAULT_BROWSER_CONFIG,me as SessionRegistry,S as TabRegistry,de as autoSelectMode,he as closeEngine,se as ensureAgentBrowserInstalled,ce as getAgentBrowserVersion,fe as getDaemonArgs,v as getDefaultBrowsersPath,E as getEngine,pe as getLaunchArgs,le as isBrowserReady,D as isUrlAllowed,Be as registerBrowserTools,y as resolveBrowsersPath,O as validateEvalResult};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "aikit",
|
|
4
4
|
"display_name": "AI Kit",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.387",
|
|
6
6
|
"description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "AnVPX",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as p,M as ee,N as te,O as ne,P as re,R as ie,S as ae,T as oe,V as se,_ as ce,a as m,b as h,c as le,d as ue,f as g,g as _,h as v,i as de,j as fe,k as pe,l as
|
|
1
|
+
import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as p,M as ee,N as te,O as ne,P as re,R as ie,S as ae,T as oe,V as se,_ as ce,a as m,b as h,c as le,d as ue,f as g,g as _,h as v,i as de,j as fe,k as pe,l as y,m as b,n as me,o as x,p as he,r as ge,s as _e,t as ve,u as ye,v as be,w as xe,x as Se,y as Ce,z as we}from"./templates-DLra78_O.js";import{copyFileSync as Te,existsSync as S,mkdirSync as C,readFileSync as w,readdirSync as T,renameSync as Ee,rmSync as E,statSync as De,unlinkSync as Oe,writeFileSync as D}from"node:fs";import{basename as ke,dirname as O,join as k,posix as A,relative as Ae,resolve as j,win32 as M}from"node:path";import{fileURLToPath as je}from"node:url";import{arch as Me,homedir as N,platform as Ne}from"node:os";import{AIKIT_PATHS as P,AIKIT_RUNTIME_PATHS as Pe,DEFAULT_SERVER_NAME as F,EMBEDDING_DEFAULTS as Fe,INSTALL_ARGS as Ie,cleanupOldVersions as Le,createLogger as I,getGlobalDataDir as Re,getPartitionDir as ze,isUserInstalled as Be,migrateLegacyWorkspaceLayout as Ve,registerWorkspace as He,safeCwd as L,safeCwdOrHome as Ue,saveRegistry as We}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{IncrementalIndexer as qe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Je,createSqliteAdapter as Ye,createStore as Xe}from"../../store/dist/index.js";import{mkdir as Ze,readFile as Qe,rename as $e,rm as et,unlink as tt,writeFile as R}from"node:fs/promises";import{addToWorkset as nt,audit as rt,check as it,checkpointLatest as at,checkpointList as ot,checkpointLoad as st,checkpointSave as ct,codemod as lt,compact as ut,dataTransform as dt,delegate as ft,delegateListModels as pt,deleteWorkset as mt,diffParse as ht,evaluate as gt,fileSummary as _t,find as vt,findDeadSymbols as yt,findExamples as bt,getWorkset as xt,gitContext as St,graphQuery as Ct,guide as wt,health as Tt,laneCreate as Et,laneDiff as Dt,laneDiscard as Ot,laneList as kt,laneMerge as At,laneStatus as jt,listWorksets as Mt,parseOutput as Nt,processList as Pt,processLogs as Ft,processStart as It,processStatus as Lt,processStop as Rt,queueClear as zt,queueCreate as Bt,queueDelete as Vt,queueDone as Ht,queueFail as Ut,queueGet as Wt,queueList as Gt,queueNext as Kt,queuePush as qt,removeFromWorkset as Jt,rename as Yt,replayClear as Xt,replayList as Zt,replayTrim as Qt,saveWorkset as $t,scopeMap as en,stashClear as tn,stashDelete as nn,stashGet as rn,stashList as an,stashSet as on,symbol as sn,testRun as cn,trace as ln,watchList as un,watchStart as dn,watchStop as fn}from"../../tools/dist/index.js";import{execFileSync as pn,execSync as z,fork as mn,spawn as hn}from"node:child_process";import{extractSvg as gn,renderToResult as _n,sanitizeTitle as vn}from"../../server/dist/index.js";import{randomUUID as yn}from"node:crypto";import{platform as bn}from"node:process";import{parse as xn,stringify as Sn}from"yaml";function Cn(){let e=L(),t=process.env.AIKIT_CONFIG_PATH??(e&&S(j(e,`aikit.config.json`))?j(e,`aikit.config.json`):null),n=t?O(t):e??N();if(Ve(n),!t)return wn();let r=w(t,`utf-8`),i;try{i=JSON.parse(r)}catch{console.error(`Failed to parse ${t} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let a=n;return i.sources=i.sources.map(e=>({...e,path:j(a,e.path)})),i.store.path=j(a,i.store.path),i.curated=i.curated??{path:P.aiCurated},i.curated.path=j(a,i.curated.path),i.onboardDir||=P.aiContext,i.onboardDir=j(a,i.onboardDir),i.stateDir||=P.state,i.stateDir=j(a,i.stateDir),Tn(i,a),i}function wn(){let e=process.env.AIKIT_WORKSPACE_ROOT??L()??N();Ve(e);let t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`AI Kit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:Fe.model,dimensions:Fe.dimensions},store:{backend:`sqlite-vec`,path:j(e,P.data)},curated:{path:j(e,P.aiCurated)},onboardDir:j(e,P.aiContext),stateDir:j(e,P.state)};return Tn(t,e),t}function Tn(e,t){if(!Be())return;let n=He(t);e.store.path=j(ze(n.partition),Pe.data),e.stateDir=j(ze(n.partition),Pe.state),e.onboardDir=j(ze(n.partition),Pe.onboard),e.curated={path:j(ze(n.partition),Pe.curated)}}async function En(){let e=Cn(),t=new Ke({model:e.embedding.model,dimensions:e.embedding.dimensions,interOpNumThreads:e.embedding.interOpNumThreads,intraOpNumThreads:e.embedding.intraOpNumThreads});await t.initialize();let n=null;if(e.store.backend===`sqlite-vec`){let t=j(e.store.path,`aikit.db`),r=O(t);if(!S(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await Ye(t)}let r=await Xe({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new qe(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Je({adapter:n}):new Je({path:e.store.path});await t.initialize(),s=t,i.setGraphStore(s)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),s={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNodes:async()=>[],getNeighbors:async()=>({nodes:[],edges:[]}),traverse:async()=>({nodes:[],edges:[]}),findNodes:async()=>[],findEdges:async()=>[],deleteNode:async()=>{},deleteBySourcePath:async()=>0,clear:async()=>{},getStats:async()=>({nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}),validate:async()=>({valid:!0,orphanNodes:[],danglingEdges:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}}),setNodeCommunity:async()=>{},detectCommunities:async()=>({}),traceProcess:async()=>({id:``,entryNodeId:``,label:``,properties:{},steps:[]}),getProcesses:async()=>[],deleteProcess:async()=>{},depthGroupedTraversal:async()=>({}),getCohesionScore:async()=>0,getSymbol360:async()=>({node:{id:``,type:``,name:``,properties:{}},incoming:[],outgoing:[],community:null,processes:[]}),close:async()=>{}}}return await Ge().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const Dn=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;if(!t||!n)throw new g(`Usage: aikit analyze <type> <path>
|
|
2
2
|
Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`);let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=j(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(L()??N(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new g(`Unknown analyze type: ${t}\nTypes: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`)}console.log(d.output)}},{name:`onboard`,description:`Run all analyses for first-time codebase onboarding`,usage:`aikit onboard <path> [--generate] [--out-dir <dir>]`,run:async e=>{let{onboard:t}=await import(`../../tools/dist/index.js`),n=``,r=`memory`,i;for(let t=0;t<e.length;t++){let a=e[t].trim();a===`--generate`?r=`generate`:a===`--out-dir`&&t+1<e.length?i=e[++t].trim():a.startsWith(`--`)||(n=a)}n||=L()??N();let a=j(n),o=Cn();console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
|
|
3
|
-
`);let s=await t({path:a,mode:r,outDir:i??o.onboardDir});for(let e of s.steps){let t=e.status===`success`?`✓`:`✗`,n=e.status===`success`?`${e.durationMs}ms, ${e.output.length} chars`:e.error;console.log(` ${t} ${e.name} — ${n}`)}console.log(`\nTotal: ${s.totalDurationMs}ms`),s.outDir&&console.log(`Output written to: ${s.outDir}`)}}],On=[{name:`parse-output`,description:`Parse build or tool output from stdin`,usage:`aikit parse-output [--tool tsc|vitest|biome|git-status]`,run:async e=>{let t=_(e,`--tool`,``).trim()||void 0,n=await p();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),ee(Nt(n,t))}},{name:`git`,description:`Show git branch, status, recent commits, and optional diff stats`,usage:`aikit git [--cwd path] [--commit-count N] [--diff]`,run:async e=>{pe(await St({cwd:_(e,`--cwd`,``).trim()||void 0,commitCount:v(e,`--commit-count`,5),includeDiff:
|
|
4
|
-
`;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var W=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!S(t))return{};let n=await Qe(t,`utf-8`);try{return JSON.parse(Bn(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=O(n),i=k(r,`.aikit-tmp-${yn()}.json`);await Ze(r,{recursive:!0});try{await R(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await $e(i,n)}catch(e){try{await tt(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}};const Vn=`orchestrator`;var Hn=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule().resolve(N());return S(this.getPathModule().resolve(e,`.claude.json`))||S(this.getPathModule().resolve(e,`.claude`))}getConfigPath(){return this.getPathModule().resolve(N(),`.claude.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}async registerMcp(e,t,n){await super.registerMcp(e,t,n);let r=this.getPathModule(),i=r.resolve(N(),`.claude`),a=r.resolve(i,`settings.json`),o;if(!S(a))C(i,{recursive:!0}),o={agent:Vn};else try{o=JSON.parse(w(a,`utf-8`))}catch{o={}}o.agent=Vn;let s=r.resolve(i,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=me(`claude`,s);e.hooks&&Object.keys(e.hooks).length>0&&(o.hooks=e.hooks)}catch{}D(a,`${JSON.stringify(o,null,2)}\n`,`utf-8`)}getPathModule(){return process.platform===`win32`?M:A}},Un=class extends W{id=`claude-desktop`;name=`Claude Desktop`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getConfigPath()):!1}getConfigPath(){let e=this.getPathModule();if(bn===`win32`){let t=process.env.LOCALAPPDATA;if(t){let n=e.resolve(t,`Packages`);if(S(n))try{let t=T(n).find(t=>t.startsWith(`Claude_`)&&S(e.resolve(n,t,`LocalCache`,`Roaming`,`Claude`,`claude_desktop_config.json`)));if(t)return e.resolve(n,t,`LocalCache`,`Roaming`,`Claude`,`claude_desktop_config.json`)}catch{}}let n=process.env.APPDATA;return n?e.resolve(n,`Claude`,`claude_desktop_config.json`):e.resolve(N(),`AppData`,`Roaming`,`Claude`,`claude_desktop_config.json`)}return bn===`darwin`?e.resolve(N(),`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`):e.resolve(N(),`.config`,`Claude`,`claude_desktop_config.json`)}getScaffoldRoot(){return null}getScaffoldPaths(){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}getPathModule(){return bn===`win32`?M:A}},Wn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},G=class extends W{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return S(e)||t!==null&&S(t)}return S(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=N();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?M:A}},Gn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(j(N(),`.copilot`)):!1}getConfigPath(){return j(N(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return j(N(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=j(N(),`.copilot`);return{agents:j(e,`agents`),skills:j(e,`skills`),prompts:null,flows:j(e,`flows`),hooks:j(e,`hooks`),commands:null,instructions:j(N(),`.github`,`copilot-instructions.md`),manifest:j(e,`.aikit-scaffold.json`)}}},Kn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},qn=class extends G{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Jn=class e extends W{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(S(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!S(t))return!1;try{return T(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return j(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ze(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=j(r,`${e}-launcher.js`);await R(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=N();return process.platform===`win32`?j(process.env.LOCALAPPDATA??j(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`github-copilot`,`intellij`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=N();return process.platform===`win32`?j(process.env.APPDATA??j(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`JetBrains`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`JetBrains`)}},Yn=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Xn=class extends G{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Zn=class extends G{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Qn=class extends G{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},$n=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},er=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},tr=class extends W{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return S(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!S(e))return{};let t=w(e,`utf-8`);try{return xn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(S(t))try{r=xn(w(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ze(n,{recursive:!0}),D(t,Sn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
|
|
3
|
+
`);let s=await t({path:a,mode:r,outDir:i??o.onboardDir});for(let e of s.steps){let t=e.status===`success`?`✓`:`✗`,n=e.status===`success`?`${e.durationMs}ms, ${e.output.length} chars`:e.error;console.log(` ${t} ${e.name} — ${n}`)}console.log(`\nTotal: ${s.totalDurationMs}ms`),s.outDir&&console.log(`Output written to: ${s.outDir}`)}}],On=[{name:`parse-output`,description:`Parse build or tool output from stdin`,usage:`aikit parse-output [--tool tsc|vitest|biome|git-status]`,run:async e=>{let t=_(e,`--tool`,``).trim()||void 0,n=await p();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),ee(Nt(n,t))}},{name:`git`,description:`Show git branch, status, recent commits, and optional diff stats`,usage:`aikit git [--cwd path] [--commit-count N] [--diff]`,run:async e=>{pe(await St({cwd:_(e,`--cwd`,``).trim()||void 0,commitCount:v(e,`--commit-count`,5),includeDiff:b(e,`--diff`)}))}},{name:`diff`,description:`Parse unified diff text from stdin into structured file changes`,usage:`git diff | aikit diff`,run:async()=>{let e=await p();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),u(ht({diff:e}))}},{name:`summarize`,description:`Show a structural summary of a file`,usage:`aikit summarize <path>`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit summarize <path>`),process.exit(1)),ne(await _t({path:j(t)}))}},{name:`checkpoint`,description:`Save and restore lightweight session checkpoints`,usage:`aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1));let n=await he();switch(t){case`save`:{let t=e.shift()?.trim(),r=_(e,`--data`,``),i=_(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await p();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),xe(ct(n,t,ae(r||a),{notes:i}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let r=st(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}xe(r);return}case`list`:{let e=ot(n);if(e.length===0){console.log(`No checkpoints saved.`);return}console.log(`Checkpoints (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.id}`),console.log(` Label: ${t.label}`),console.log(` Created: ${t.createdAt}`);return}case`latest`:{let e=at(n);if(!e){console.log(`No checkpoints saved.`);return}xe(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],kn=k(N(),`.aikit`),B=k(kn,`daemon.json`),An=3210,V=I(`cli:daemon`);function jn(){if(!S(B))return null;try{return JSON.parse(w(B,`utf-8`))}catch{return null}}function Mn(e){S(kn)||C(kn,{recursive:!0});let t=`${B}.tmp`;D(t,JSON.stringify(e,null,2)),Ee(t,B)}function Nn(){S(B)&&E(B)}async function H(e){try{return process.kill(e,0),!0}catch{return!1}}async function Pn(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function Fn(e,t){let n=Date.now();for(V.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await Pn(e))return V.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function In(){let e=jn();if(!e)return V.info(`Daemon is not running`),null;if(!await H(e.pid))return Nn(),V.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};V.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(e.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return Nn(),{pid:e.pid,wasRunning:!0}}async function Ln(e){let t=ie();V.debug(`Spawning daemon process...`);let n=hn(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await Fn(e,3e4)||(V.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=Ce();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return Mn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const Rn=[{name:`daemon`,description:`Run AI Kit as a background HTTP daemon — survives IDE restarts, shares across windows (start|stop|status|restart)`,usage:`aikit daemon <start|stop|status|restart> [--port <port>]`,run:async e=>{let t=e[0];if(!t){console.error(`Usage: aikit daemon <start|stop|status|restart>`),console.error(``),console.error(`Commands:`),console.error(` start Start the AI Kit daemon`),console.error(` stop Stop the AI Kit daemon`),console.error(` status Show daemon status`),console.error(` restart Restart the AI Kit daemon`);return}switch(t){case`start`:{let t=jn();if(t){if(await H(t.pid)&&await Pn(t.port)){V.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}V.debug(`Cleaning up stale daemon state...`),Nn()}let n=e.indexOf(`--port`),r=await Ln(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):An);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await In();e?.wasRunning&&V.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=jn();if(!e){console.log(`Daemon: stopped`);return}if(!(await H(e.pid)&&await Pn(e.port))){Nn(),console.log(`Daemon: stopped (stale state cleaned up)`);return}console.log(`Daemon: running`),console.log(` PID: ${e.pid}`),console.log(` Port: ${e.port}`),console.log(` Version: ${e.version}`),console.log(` Started: ${e.startedAt}`);return}case`restart`:{let t=jn();if(t){if(await H(t.pid)){V.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(t.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}Nn(),V.info(`Daemon stopped (PID ${t.pid})`)}else V.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await Ln(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):An);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],zn=[{name:`diagram`,description:`Render a diagram from structured JSON input. Reads stdin, produces HTML + markdown + SVG.`,usage:`aikit diagram [--type <type>] [--output <dir>] [--title <title>] [--subtitle <subtitle>] [--palette warm|technical] [--format all|html|md|svg] < input.json`,run:async e=>{let t=U(e,`--type`),n=U(e,`--output`),r=U(e,`--title`),i=U(e,`--subtitle`),a=U(e,`--format`)??`all`,o=U(e,`--palette`),s=``,c=process.stdin;c.setEncoding(`utf-8`);for await(let e of c)s+=e;s.trim()||(console.error(`No input provided. Pipe diagram JSON to stdin.`),console.error(`Usage: aikit diagram [--type <type>] [--output <dir>] < input.json`),process.exit(1));let l;try{l=JSON.parse(s)}catch(e){console.error(`Invalid JSON: ${e.message}`),process.exit(1)}let u=l.meta??{};t&&l.diagram_type!==t&&(console.error(`Error: --type "${t}" does not match input diagram_type "${l.diagram_type}". Remove --type or use the correct type. Mutating the discriminator produces invalid output.`),process.exit(1)),o&&(o!==`warm`&&o!==`technical`&&(console.error(`Invalid palette "${o}". Expected "warm" or "technical".`),process.exit(1)),u.palette&&u.palette!==o&&console.warn(`Warning: --palette "${o}" overrides input meta.palette "${String(u.palette)}"`),l.meta={...u,palette:o});try{let e=_n(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=j(n);await Ze(t,{recursive:!0});let i=vn(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=k(t,`${i}.html`);await R(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=k(t,`${i}.md`);await R(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=gn(e.html);if(n){let e=k(t,`${i}.svg`);await R(e,n,`utf-8`),console.log(`Written: ${e}`)}}}else process.stdout.write(e.html)}catch(e){console.error(`Rendering failed: ${e.message}`),process.exit(1)}}}];function U(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1]}function Bn(e){let t=``,n=0,r=e.length;for(;n<r;)if(e[n]===`"`){for(t+=`"`,n++;n<r&&e[n]!==`"`;)e[n]===`\\`&&(t+=e[n++]),n<r&&(t+=e[n++]);n<r&&(t+=e[n++])}else if(e[n]===`/`&&n+1<r&&e[n+1]===`/`)for(n+=2;n<r&&e[n]!==`
|
|
4
|
+
`;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var W=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!S(t))return{};let n=await Qe(t,`utf-8`);try{return JSON.parse(Bn(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=O(n),i=k(r,`.aikit-tmp-${yn()}.json`);await Ze(r,{recursive:!0});try{await R(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await $e(i,n)}catch(e){try{await tt(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}};const Vn=`orchestrator`;var Hn=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule().resolve(N());return S(this.getPathModule().resolve(e,`.claude.json`))||S(this.getPathModule().resolve(e,`.claude`))}getConfigPath(){return this.getPathModule().resolve(N(),`.claude.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}async registerMcp(e,t,n){await super.registerMcp(e,t,n);let r=this.getPathModule(),i=r.resolve(N(),`.claude`),a=r.resolve(i,`settings.json`),o;if(!S(a))C(i,{recursive:!0}),o={agent:Vn};else try{o=JSON.parse(w(a,`utf-8`))}catch{o={}}o.agent=Vn;let s=r.resolve(i,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=y(`claude`,s);e.hooks&&Object.keys(e.hooks).length>0&&(o.hooks=e.hooks)}catch{}D(a,`${JSON.stringify(o,null,2)}\n`,`utf-8`)}getPathModule(){return process.platform===`win32`?M:A}},Un=class extends W{id=`claude-desktop`;name=`Claude Desktop`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getConfigPath()):!1}getConfigPath(){let e=this.getPathModule();if(bn===`win32`){let t=process.env.LOCALAPPDATA;if(t){let n=e.resolve(t,`Packages`);if(S(n))try{let t=T(n).find(t=>t.startsWith(`Claude_`)&&S(e.resolve(n,t,`LocalCache`,`Roaming`,`Claude`,`claude_desktop_config.json`)));if(t)return e.resolve(n,t,`LocalCache`,`Roaming`,`Claude`,`claude_desktop_config.json`)}catch{}}let n=process.env.APPDATA;return n?e.resolve(n,`Claude`,`claude_desktop_config.json`):e.resolve(N(),`AppData`,`Roaming`,`Claude`,`claude_desktop_config.json`)}return bn===`darwin`?e.resolve(N(),`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`):e.resolve(N(),`.config`,`Claude`,`claude_desktop_config.json`)}getScaffoldRoot(){return null}getScaffoldPaths(){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}getPathModule(){return bn===`win32`?M:A}},Wn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},G=class extends W{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return S(e)||t!==null&&S(t)}return S(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=N();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?M:A}},Gn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(j(N(),`.copilot`)):!1}getConfigPath(){return j(N(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return j(N(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=j(N(),`.copilot`);return{agents:j(e,`agents`),skills:j(e,`skills`),prompts:null,flows:j(e,`flows`),hooks:j(e,`hooks`),commands:null,instructions:j(N(),`.github`,`copilot-instructions.md`),manifest:j(e,`.aikit-scaffold.json`)}}},Kn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},qn=class extends G{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Jn=class e extends W{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(S(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!S(t))return!1;try{return T(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return j(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ze(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=j(r,`${e}-launcher.js`);await R(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=N();return process.platform===`win32`?j(process.env.LOCALAPPDATA??j(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`github-copilot`,`intellij`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=N();return process.platform===`win32`?j(process.env.APPDATA??j(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`JetBrains`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`JetBrains`)}},Yn=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Xn=class extends G{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Zn=class extends G{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Qn=class extends G{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},$n=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},er=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},tr=class extends W{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return S(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!S(e))return{};let t=w(e,`utf-8`);try{return xn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(S(t))try{r=xn(w(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ze(n,{recursive:!0}),D(t,Sn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
|
|
5
5
|
|
|
6
6
|
This project has an **AI Kit** MCP server (\`aikit\`) providing 64 tools for search, code analysis,
|
|
7
7
|
persistent memory, context compression, and guided development flows.
|
|
@@ -36,24 +36,24 @@ After install, verify with:
|
|
|
36
36
|
Options:
|
|
37
37
|
--version <version> Install a specific version instead of latest
|
|
38
38
|
--offline <path> Install from a local tarball (no network needed)
|
|
39
|
-
--help, -h Show this help`;function ur(e){if(!or.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function dr(){let e=await fetch(`https://registry.npmjs.org/${cr}/latest`,{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw Error(`Failed to fetch latest version from npm registry (HTTP ${e.status})`);let t=await e.json();if(!t.version)throw Error(`npm registry response missing "version" field`);return t.version}function fr(e){let t=k(e,`packages`,`server`,`dist`,`bin.js`);if(!S(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=k(e,`node_modules`);if(!S(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function pr(e){let t=k(e,`package.json`),n=JSON.parse(w(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function mr(e){S(q)||C(q,{recursive:!0});let t=k(q,`current-version.json.tmp`);D(t,`${JSON.stringify({version:e},null,2)}\n`),Ee(t,sr)}function hr(e){let t=T(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function gr(e,t){K.debug(`Extracting...`),z(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=k(e,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);return K.debug(`Installing production dependencies...`),z(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function _r(e,t){let n=k(J,`v${t}`);S(J)||C(J,{recursive:!0}),S(n)&&(K.debug(`Removing previous installation...`,{target:n}),E(n,{recursive:!0})),Ee(e,n),mr(t),Le(J,t),K.debug(`Installation complete`,{package:`${cr}@${t}`,target:n})}function vr(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[Ne()],r=t[Me()];return!n||!r?(K.warn(`Unknown platform, falling back to npm pack`,{platform:Ne(),arch:Me()}),``):`${n}-${r}`}function yr(e){let t=vr();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=k(k(q,`cache`,`tarballs`),n);return S(r)?r:null}function br(e,t){let n=k(J,`v${t}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Extracting prebuilt tarball...`),z(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=k(n,`aikit-v${t}-${vr()}`);if(!S(r)){let e=k(n,`package`);if(S(e)){K.debug(`Validating installation...`),fr(e),_r(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}K.debug(`Validating installation...`),fr(r),_r(r,t)}finally{S(n)&&E(n,{recursive:!0})}}function xr(e){ur(e);let t=yr(e);if(t){K.debug(`Found prebuilt tarball`,{path:t}),br(t,e);return}let n=k(J,`v${e}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Downloading...`,{package:`${cr}@${e}`}),z(`npm pack ${cr}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=hr(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=gr(n,t);K.debug(`Validating installation...`),fr(r),_r(r,e)}finally{S(n)&&E(n,{recursive:!0})}}function Sr(e){ur(e);let t=k(J,`v${e}`);try{fr(t),mr(e)}catch{xr(e)}}function Cr(e){if(!S(e))throw Error(`Tarball not found: ${e}`);let t=k(J,`_offline-detect-${Date.now()}`);C(t,{recursive:!0});let n;try{z(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=pr(k(t,`package`))}finally{S(t)&&E(t,{recursive:!0})}K.debug(`Installing from local tarball...`,{package:`${cr}@${n}`});let r=k(J,`v${n}-staging`);S(r)&&E(r,{recursive:!0}),C(r,{recursive:!0});try{Te(e,k(r,`offline-${n}.tgz`));let t=gr(r,`offline-${n}.tgz`);return K.debug(`Validating installation...`),fr(t),_r(t,n),n}finally{S(r)&&E(r,{recursive:!0})}}async function wr(e){try{let t=k(J,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!S(t)){K.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}let r=await ar({scope:`user`});if(r.length===0){K.info(`No supported IDEs detected for MCP registration`);return}for(let e of r)try{(await e.readConfig())?.[e.configKey]?.[`AI Kit`]&&(await e.unregisterMcp(b),K.info(`Migrated ${e.name}: old '${b}' → '${F}'`))}catch{}let i=0;for(let e of r)try{await e.registerMcp(F,n),i++}catch(t){K.warn(`Failed to register MCP for ${e.name}`,{error:t.message})}i>0&&K.info(`MCP server configured for ${i} IDE(s) — using '${F}'`)}catch(e){K.warn(`MCP registration failed`,{error:e.message})}}const Tr=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:lr,run:async e=>{let t=e.indexOf(`--version`),n=e.indexOf(`--offline`),r=t!==-1&&t+1<e.length,i=n!==-1&&n+1<e.length;if(e.includes(`--help`)||e.includes(`-h`)){console.log(lr);return}if(i){let t=e[n+1];await wr(Cr(t)),K.debug(`Install complete — restart your IDE to use the new version`);return}let a;r?a=e[t+1]:(K.debug(`Checking npm registry for latest version...`),a=await dr(),K.debug(`Latest version detected`,{version:a})),xr(a),await wr(a),K.debug(`Install complete — restart your IDE to use the new version`)}}];function Er(){let e=Dr();if(e)return e;let t={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(t.command=e)}catch{}}return t}function Dr(){let e=k(N(),`.aikit`,`current-version.json`);if(!S(e))return null;try{let t=JSON.parse(w(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!S(k(k(N(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}return n}catch{return null}}const Or=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function kr(e,t,n){let r=j(N(),`.copilot`,`instructions`,`copilot-instructions.md`);!S(r)||n.has(r)||(C(O(r),{recursive:!0}),D(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function Ar(e,t=!1){if(!Or.has(e.name))return;let n=j(O(e.getConfigPath()),`settings.json`),r={};if(S(n))try{let e=w(n,`utf-8`);r=JSON.parse(e)}catch{console.log(` ${e.name}: skipped settings.json (invalid JSON)`);return}let i=!1;for(let[e,n]of Object.entries(le))if(typeof n==`object`&&n){let t=typeof r[e]==`object`&&r[e]!==null?r[e]:{},a={...t,...n};JSON.stringify(a)!==JSON.stringify(t)&&(r[e]=a,i=!0)}else(t||!(e in r))&&(r[e]=n,i=!0);i&&(D(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function jr(r,o,s,c,l=!1){let u=new Map,d=new Set,f=_e(`aikit`,s),p=he(`aikit`,s),ee=ve(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(kr(f,ee,d),u.size===0){d.size>0?console.log(` Instruction files: ${[...d].join(`, `)}`):console.log(` No IDEs with global scaffold support detected.`);return}let te=await n(r,`copilot`),ne=await n(r,`opencode`),re=await n(r,`hermes`),ie=await n(r,`claude-code`),ae=e=>{let t=new Map;for(let n of e){let e=n.path.indexOf(`/`);if(e===-1)continue;let r=n.path.substring(0,e);if(r===`agents`||r===`prompts`){let i=t.get(r)??[];i.push({path:n.path.substring(e+1),content:n.content}),t.set(r,i)}else if(r===`.opencode`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}else if(r===`.claude`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}}return t},oe=ae(te),se=ae(ne),ce=ae(re),m=ae(ie),h=await n(r,`skills`),le=new Set;for(let e of h){let t=e.path.indexOf(`/`);t!==-1&&le.add(e.path.substring(0,t))}let g=await n(r,`flows`),_=new Set;for(let e of g){let t=e.path.indexOf(`/`);t!==-1&&_.add(e.path.substring(0,t))}let v=await n(r,`claude-code`),de=j(r,`scaffold`,`general`,`hooks`,`scripts`),fe=S(de)?de:j(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),pe=ue(),me=new Set,y=new Set,b=new Set,ge=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(me.has(d))return;me.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),b.add(O(r))},x=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(me.has(u))return;if(me.add(u),o===`flows`&&!y.has(n)){for(let e of _){let t=j(n,e,`skills`);S(t)&&(E(t,{recursive:!0,force:!0}),console.log(` ${O(r)}: migrated ${e} flow to steps/ layout`))}y.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),b.add(O(r))},be=(e,t,n)=>{!e||!t||x(e,t,`hooks`,[...ye(n,j(e,`scripts`).replace(/\\/g,`/`)),...pe.map(e=>({path:`scripts/${e}`,content:w(j(fe,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?se:e.family===`hermes`?ce:e.family===`claude`?m:oe;ge(t.agents,t.manifest,`agents`,n),ge(t.prompts,t.manifest,`prompts`,n),x(t.skills,t.manifest,`skills`,h),x(t.flows,t.manifest,`flows`,g),x(t.commands,t.manifest,`commands`,v),be(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of b)console.log(` ${e}: scaffold updated (${le.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(C(O(t),{recursive:!0}),D(t,e.buildInstructionContent(e.family===`claude`?p:f,ee),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function Mr(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e){if(Or.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(j(r,`kb.instructions.md`)),t.push(j(r,`aikit.instructions.md`))}else if(n.name===`Cursor`||n.name===`Cursor Nightly`)t.push(j(e,`rules`,`kb.mdc`));else if(n.name===`Windsurf`)t.push(j(e,`rules`,`kb.md`));else if(n.family===`claude`){let n=j(e,`agents`);if(S(n)){for(let e of T(n))if(e.endsWith(`.agent.md`)){let r=j(n,e);Oe(r),t.push(r)}}}}}for(let e of t)S(e)&&(Oe(e),console.log(` Removed legacy file: ${e}`))}async function Nr(e){let t=F,n=be(),r=JSON.parse(w(j(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=Re();C(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),Sr(r),We({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await ar({scope:`user`});if(a.length===0)console.log(`
|
|
40
|
-
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${a.length} IDE(s):`);let n=
|
|
41
|
-
Installing scaffold files:`),await
|
|
39
|
+
--help, -h Show this help`;function ur(e){if(!or.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function dr(){let e=await fetch(`https://registry.npmjs.org/${cr}/latest`,{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw Error(`Failed to fetch latest version from npm registry (HTTP ${e.status})`);let t=await e.json();if(!t.version)throw Error(`npm registry response missing "version" field`);return t.version}function fr(e){let t=k(e,`packages`,`server`,`dist`,`bin.js`);if(!S(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=k(e,`node_modules`);if(!S(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function pr(e){let t=k(e,`package.json`),n=JSON.parse(w(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function mr(e){S(q)||C(q,{recursive:!0});let t=k(q,`current-version.json.tmp`);D(t,`${JSON.stringify({version:e},null,2)}\n`),Ee(t,sr)}function hr(e){let t=T(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function gr(e,t){K.debug(`Extracting...`),z(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=k(e,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);return K.debug(`Installing production dependencies...`),z(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function _r(e,t){let n=k(J,`v${t}`);S(J)||C(J,{recursive:!0}),S(n)&&(K.debug(`Removing previous installation...`,{target:n}),E(n,{recursive:!0})),Ee(e,n),mr(t),Le(J,t),K.debug(`Installation complete`,{package:`${cr}@${t}`,target:n})}function vr(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[Ne()],r=t[Me()];return!n||!r?(K.warn(`Unknown platform, falling back to npm pack`,{platform:Ne(),arch:Me()}),``):`${n}-${r}`}function yr(e){let t=vr();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=k(k(q,`cache`,`tarballs`),n);return S(r)?r:null}function br(e,t){let n=k(J,`v${t}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Extracting prebuilt tarball...`),z(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=k(n,`aikit-v${t}-${vr()}`);if(!S(r)){let e=k(n,`package`);if(S(e)){K.debug(`Validating installation...`),fr(e),_r(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}K.debug(`Validating installation...`),fr(r),_r(r,t)}finally{S(n)&&E(n,{recursive:!0})}}function xr(e){ur(e);let t=yr(e);if(t){K.debug(`Found prebuilt tarball`,{path:t}),br(t,e);return}let n=k(J,`v${e}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Downloading...`,{package:`${cr}@${e}`}),z(`npm pack ${cr}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=hr(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=gr(n,t);K.debug(`Validating installation...`),fr(r),_r(r,e)}finally{S(n)&&E(n,{recursive:!0})}}function Sr(e){ur(e);let t=k(J,`v${e}`);try{fr(t),mr(e)}catch{xr(e)}}function Cr(e){if(!S(e))throw Error(`Tarball not found: ${e}`);let t=k(J,`_offline-detect-${Date.now()}`);C(t,{recursive:!0});let n;try{z(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=pr(k(t,`package`))}finally{S(t)&&E(t,{recursive:!0})}K.debug(`Installing from local tarball...`,{package:`${cr}@${n}`});let r=k(J,`v${n}-staging`);S(r)&&E(r,{recursive:!0}),C(r,{recursive:!0});try{Te(e,k(r,`offline-${n}.tgz`));let t=gr(r,`offline-${n}.tgz`);return K.debug(`Validating installation...`),fr(t),_r(t,n),n}finally{S(r)&&E(r,{recursive:!0})}}async function wr(e){try{let t=k(J,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!S(t)){K.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}let r=await ar({scope:`user`});if(r.length===0){K.info(`No supported IDEs detected for MCP registration`);return}for(let e of r)try{(await e.readConfig())?.[e.configKey]?.[`AI Kit`]&&(await e.unregisterMcp(x),K.info(`Migrated ${e.name}: old '${x}' → '${F}'`))}catch{}let i=0;for(let e of r)try{await e.registerMcp(F,n),i++}catch(t){K.warn(`Failed to register MCP for ${e.name}`,{error:t.message})}i>0&&K.info(`MCP server configured for ${i} IDE(s) — using '${F}'`)}catch(e){K.warn(`MCP registration failed`,{error:e.message})}}async function Tr(){let e=k(N(),`.aikit`,`browsers`);K.debug(`Pre-installing browser runtime...`);try{S(e)||C(e,{recursive:!0}),z(`npx -y agent-browser@latest install --install-dir "${e}"`,{cwd:e,stdio:`pipe`,timeout:3e5,env:{...process.env,AGENT_BROWSER_CACHE_DIR:e}}),K.debug(`Browser runtime installed`,{target:e})}catch(e){K.debug(`Browser runtime pre-install skipped (will lazy-load on first use)`,{error:e instanceof Error?e.message:String(e)})}}const Er=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:lr,run:async e=>{let t=e.indexOf(`--version`),n=e.indexOf(`--offline`),r=t!==-1&&t+1<e.length,i=n!==-1&&n+1<e.length,a=e.includes(`--help`)||e.includes(`-h`),o=e.includes(`--skip-browser`);if(a){console.log(lr);return}if(i){let t=e[n+1];await wr(Cr(t)),o||await Tr(),K.debug(`Install complete — restart your IDE to use the new version`);return}let s;r?s=e[t+1]:(K.debug(`Checking npm registry for latest version...`),s=await dr(),K.debug(`Latest version detected`,{version:s})),xr(s),await wr(s),o||await Tr(),K.debug(`Install complete — restart your IDE to use the new version`)}}];function Dr(){let e=Or();if(e)return e;let t={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(t.command=e)}catch{}}return t}function Or(){let e=k(N(),`.aikit`,`current-version.json`);if(!S(e))return null;try{let t=JSON.parse(w(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!S(k(k(N(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:m.command,args:m.args?[...m.args]:void 0,type:m.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}return n}catch{return null}}const kr=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function Ar(e,t,n){let r=j(N(),`.copilot`,`instructions`,`copilot-instructions.md`);!S(r)||n.has(r)||(C(O(r),{recursive:!0}),D(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function jr(e,t=!1){if(!kr.has(e.name))return;let n=j(O(e.getConfigPath()),`settings.json`),r={};if(S(n))try{let e=w(n,`utf-8`);r=JSON.parse(e)}catch{console.log(` ${e.name}: skipped settings.json (invalid JSON)`);return}let i=!1;for(let[e,n]of Object.entries(le))if(typeof n==`object`&&n){let t=typeof r[e]==`object`&&r[e]!==null?r[e]:{},a={...t,...n};JSON.stringify(a)!==JSON.stringify(t)&&(r[e]=a,i=!0)}else(t||!(e in r))&&(r[e]=n,i=!0);i&&(D(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function Mr(r,o,s,c,l=!1){let u=new Map,d=new Set,f=ge(`aikit`,s),p=me(`aikit`,s),ee=ve(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(Ar(f,ee,d),u.size===0){d.size>0?console.log(` Instruction files: ${[...d].join(`, `)}`):console.log(` No IDEs with global scaffold support detected.`);return}let te=await n(r,`copilot`),ne=await n(r,`opencode`),re=await n(r,`hermes`),ie=await n(r,`claude-code`),ae=e=>{let t=new Map;for(let n of e){let e=n.path.indexOf(`/`);if(e===-1)continue;let r=n.path.substring(0,e);if(r===`agents`||r===`prompts`){let i=t.get(r)??[];i.push({path:n.path.substring(e+1),content:n.content}),t.set(r,i)}else if(r===`.opencode`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}else if(r===`.claude`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}}return t},oe=ae(te),se=ae(ne),ce=ae(re),m=ae(ie),h=await n(r,`skills`),le=new Set;for(let e of h){let t=e.path.indexOf(`/`);t!==-1&&le.add(e.path.substring(0,t))}let g=await n(r,`flows`),_=new Set;for(let e of g){let t=e.path.indexOf(`/`);t!==-1&&_.add(e.path.substring(0,t))}let v=await n(r,`claude-code`),de=j(r,`scaffold`,`general`,`hooks`,`scripts`),fe=S(de)?de:j(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),pe=ue(),y=new Set,b=new Set,x=new Set,he=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(y.has(d))return;y.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),x.add(O(r))},_e=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(y.has(u))return;if(y.add(u),o===`flows`&&!b.has(n)){for(let e of _){let t=j(n,e,`skills`);S(t)&&(E(t,{recursive:!0,force:!0}),console.log(` ${O(r)}: migrated ${e} flow to steps/ layout`))}b.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),x.add(O(r))},be=(e,t,n)=>{!e||!t||_e(e,t,`hooks`,[...ye(n,j(e,`scripts`).replace(/\\/g,`/`)),...pe.map(e=>({path:`scripts/${e}`,content:w(j(fe,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?se:e.family===`hermes`?ce:e.family===`claude`?m:oe;he(t.agents,t.manifest,`agents`,n),he(t.prompts,t.manifest,`prompts`,n),_e(t.skills,t.manifest,`skills`,h),_e(t.flows,t.manifest,`flows`,g),_e(t.commands,t.manifest,`commands`,v),be(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of x)console.log(` ${e}: scaffold updated (${le.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(C(O(t),{recursive:!0}),D(t,e.buildInstructionContent(e.family===`claude`?p:f,ee),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function Nr(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e){if(kr.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(j(r,`kb.instructions.md`)),t.push(j(r,`aikit.instructions.md`))}else if(n.name===`Cursor`||n.name===`Cursor Nightly`)t.push(j(e,`rules`,`kb.mdc`));else if(n.name===`Windsurf`)t.push(j(e,`rules`,`kb.md`));else if(n.family===`claude`){let n=j(e,`agents`);if(S(n)){for(let e of T(n))if(e.endsWith(`.agent.md`)){let r=j(n,e);Oe(r),t.push(r)}}}}}for(let e of t)S(e)&&(Oe(e),console.log(` Removed legacy file: ${e}`))}async function Pr(e){let t=F,n=be(),r=JSON.parse(w(j(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=Re();C(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),Sr(r),We({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await ar({scope:`user`});if(a.length===0)console.log(`
|
|
40
|
+
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${a.length} IDE(s):`);let n=Or();if(!n)throw Error(`Managed runtime v${r} was installed but its MCP server entry could not be resolved.`);for(let e of a)try{await e.registerMcp(t,n),console.log(` ${e.name}: configured ${t}`)}catch(t){console.log(` ${e.name}: failed to configure (${t.message})`)}for(let t of a)jr(t,e.force)}console.log(`
|
|
41
|
+
Installing scaffold files:`),await Mr(n,a,t,r,e.force),Nr(a),console.log(`
|
|
42
42
|
User-level AI Kit installation complete!`),console.log(`
|
|
43
|
-
Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}const
|
|
43
|
+
Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}const Fr=[{directory:`.github/copilot/agents`,suffix:`.agent.md`},{directory:`.github/copilot/prompts`,suffix:`.prompt.md`},{directory:`.copilot/skills`,suffix:`/SKILL.md`},{directory:`.agents/skills`,suffix:`/SKILL.md`}],Ir=[`.copilot/skills`,`.agents/skills`],Lr=/^(?:mcp_)?aikit_[a-z0-9_]+$/;function Rr(e,t){return(Ae(e,t)||t).split(`\\`).join(`/`)}function zr(e){let t=new Set;for(let n of Fr){let r=k(e,n.directory);if(S(r))try{for(let e of T(r,{withFileTypes:!0})){if(n.suffix===`/SKILL.md`){if(e.isDirectory()){let n=k(r,e.name,`SKILL.md`);S(n)&&t.add(n)}continue}e.isFile()&&e.name.endsWith(n.suffix)&&t.add(k(r,e.name))}}catch{}}return[...t].sort()}function Br(e){let t=new Set;for(let n of Ir){let r=k(e,n);if(S(r))try{for(let e of T(r,{withFileTypes:!0}))e.isDirectory()&&t.add(e.name.toLowerCase())}catch{}}return t}function Vr(e){if(!e.startsWith(`---`))return null;let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return t?t[1]:null}function Hr(e){let t=e.trim();if(!t)return[];let n=t.startsWith(`[`)&&t.endsWith(`]`)?t.slice(1,-1):t,r=[],i=``,a=null;for(let e of n){if((e===`"`||e===`'`)&&a===null){a=e,i+=e;continue}if(e===a){a=null,i+=e;continue}if(e===`,`&&a===null){let e=Ur(i);e&&r.push(e),i=``;continue}i+=e}let o=Ur(i);return o&&r.push(o),r}function Ur(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function Wr(e){let t=e.trim();if(!t)return;if(t.startsWith(`[`)!==t.endsWith(`]`))return`inline array is missing a closing bracket`;if(!t.startsWith(`[`))return;let n=null;for(let e=1;e<t.length-1;e+=1){let r=t[e];if((r===`"`||r===`'`)&&n===null){n=r;continue}r===n&&(n=null)}if(n!==null)return`inline array has an unterminated quoted value`}function Gr(e){if(!e.startsWith(`---`))return;let t=Vr(e);if(t===null)return`frontmatter is missing a closing --- delimiter`;let n=!1;for(let e of t.split(/\r?\n/)){let t=e.trim();if(!t||t.startsWith(`#`))continue;if(n){if(/^\s{2,}[A-Za-z0-9_-]+:\s*.*$/.test(e))return Wr(e.replace(/^\s{2,}[A-Za-z0-9_-]+:\s*/,``));n=!1}let r=e.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);if(!r)return`unsupported frontmatter line: ${t}`;let[,i,a]=r;if(i===`metadata`&&a.trim()===``){n=!0;continue}let o=Wr(a);if(o)return o}}function Kr(e,t){try{let n=w(t,`utf8`),i=Gr(n);return{filePath:t,displayPath:Rr(e,t),content:n,parsed:i?null:r(n),yamlError:i}}catch{return null}}function qr(e){return zr(e).map(t=>Kr(e,t)).filter(e=>e!==null)}function Jr(e){if(!e.parsed)return[];let t=e.parsed.fields.applyTo;return t?Hr(t):[]}function Yr(e){let t=e.trim();if(!t)return`glob pattern is empty`;let n=[],r={"[":`]`,"{":`}`,"(":`)`},i=new Set(Object.values(r));for(let e=0;e<t.length;e+=1){let a=t[e];if(t[e-1]!==`\\`){if(a in r){n.push(r[a]);continue}if(i.has(a)&&n.pop()!==a)return`glob pattern has an unexpected '${a}'`}}if(n.length>0)return`glob pattern is missing '${n[n.length-1]}'`}function Xr(e){let t=new Set;for(let n of e.matchAll(/<skill>\s*([a-z][a-z0-9-]*)\s*<\/skill>/gi))t.add(n[1].toLowerCase());let n=e.split(/\r?\n/),r=!1;for(let e of n){if(/^#{1,6}\s+skills\b/i.test(e)){r=!0;continue}if(r&&/^#{1,6}\s+/.test(e)&&(r=!1),!r)continue;let n=e.match(/^\|\s*([a-z][a-z0-9-]*)\s*\|/i);if(n){let e=n[1].toLowerCase();e!==`skill`&&t.add(e)}for(let n of e.matchAll(/`([a-z][a-z0-9-]*)`/gi))t.add(n[1].toLowerCase())}return[...t]}const Zr={name:`yaml-parse`,run:e=>{try{return qr(e).filter(e=>e.yamlError).map(e=>({severity:`error`,file:e.displayPath,message:`invalid YAML frontmatter: ${e.yamlError}`,code:`yaml-parse-error`}))}catch{return[]}}},Qr={name:`skill-refs`,run:e=>{try{let t=Br(e);if(t.size===0)return[];let n=[];for(let r of qr(e))if(r.filePath.endsWith(`.agent.md`))for(let e of Xr(r.content))t.has(e)||n.push({severity:`warning`,file:r.displayPath,message:`referenced skill '${e}' was not found in .copilot/skills or .agents/skills`,code:`skill-ref-missing`});return n}catch{return[]}}},$r={name:`tool-names`,run:e=>{try{let t=[];for(let n of qr(e))if(n.parsed)for(let e of n.parsed.tools.map(Ur))e&&!Lr.test(e)&&t.push({severity:`warning`,file:n.displayPath,message:`tool '${e}' should use an aikit-prefixed name`,code:`tool-name-invalid`});return t}catch{return[]}}},ei={name:`glob-patterns`,run:e=>{try{let t=[];for(let n of qr(e))if(n.parsed)for(let e of Jr(n)){let r=Yr(e);r&&t.push({severity:`warning`,file:n.displayPath,message:`applyTo pattern '${e}' is invalid: ${r}`,code:`glob-pattern-invalid`})}return t}catch{return[]}}};async function Y(e){let t=console.log;console.log=()=>{};try{return await e()}finally{console.log=t}}async function ti(e){let t=e.reset??!1,n=e.silent??!1,r=[],i=0,a=0,o=await ar({scope:`user`}),s=Dr(),c=be(),l=Ce(),u=e=>{r.push(e),a+=1,n||console.log(`- ${e}`)};for(let e of o){let n=e.getConfigPath();if(i+=1,!S(n)){C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(F,s)),u(`Fixed: ${e.name} — MCP config was missing, recreated`);continue}try{let r=await e.readConfig();if(r[e.configKey]?.[`AI Kit`]){await Y(()=>e.unregisterMcp(x)),await Y(()=>e.registerMcp(F,s)),u(`Migrated: ${e.name} — old '${x}' → '${F}'`);continue}if(!r[e.configKey]?.[F]){C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(F,s)),u(`Fixed: ${e.name} — MCP entry was missing, added`);continue}t&&(C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(F,s)),u(`Reset: ${e.name} — MCP config restored to factory defaults`))}catch{Te(n,`${n}.bak`),C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(F,s)),u(`Fixed: ${e.name} — MCP config was corrupt, backed up and recreated`)}}await Y(async()=>{for(let e of o)jr(e,t)}),await Y(()=>Mr(c,o,F,l??`0.0.0`,t));let d=[Zr,Qr,$r,ei];for(let e of d)try{let t=L();if(!t)continue;let r=e.run(t);for(let e of r)(e.severity===`error`||e.severity===`warning`)&&(n||console.warn(`[doctor:${e.code}] ${e.file}: ${e.message}`))}catch{}if(n){if(r.length>0)for(let e of r)console.error(`[doctor] ${e}`)}else r.length===0&&console.log(`- No MCP config issues found.`);return{checked:i,fixed:a,issues:r}}const ni=[{name:`doctor`,description:`Check and repair AI Kit configuration files`,usage:`aikit doctor [--reset]`,run:async e=>{let t=e.includes(`--reset`);console.log(t?`Resetting AI Kit to factory defaults...
|
|
44
44
|
`:`Running AI Kit doctor...
|
|
45
|
-
`);let n=await
|
|
46
|
-
Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],ni=[{name:`proc`,description:`Manage in-memory child processes`,usage:`aikit proc <start|stop|status|list|logs> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim(),n=e.shift()?.trim();(!t||!n)&&(console.error(`Usage: aikit proc start <id> <command> [args...]`),process.exit(1)),fe(It(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=Rt(t);if(!n){console.log(`No managed process found: ${t}`);return}fe(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Lt(t);if(!n){console.log(`No managed process found: ${t}`);return}fe(n);return}case`list`:{let e=Pt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)fe(t),console.log(``);return}case`logs`:{let t=v(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=Ft(n,t);if(r.length===0){console.log(`No logs found for process: ${n}`);return}for(let e of r)console.log(e);return}default:console.error(`Unknown proc action: ${t}`),console.error(`Actions: start, stop, status, list, logs`),process.exit(1)}}},{name:`watch`,description:`Manage in-memory filesystem watchers`,usage:`aikit watch <start|stop|list> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch start <path>`),process.exit(1));let n=dn({path:j(t)});console.log(`Started watcher: ${n.id}`),console.log(` Path: ${n.path}`),console.log(` Status: ${n.status}`);return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch stop <id>`),process.exit(1));let n=fn(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=un();if(e.length===0){console.log(`No active watchers.`);return}for(let t of e)console.log(`${t.id}`),console.log(` Path: ${t.path}`),console.log(` Status: ${t.status}`),console.log(` Events: ${t.eventCount}`);return}default:console.error(`Unknown watch action: ${t}`),console.error(`Actions: start, stop, list`),process.exit(1)}}},{name:`delegate`,description:`Delegate a task to a local Ollama model`,usage:`aikit delegate [--model name] [--system prompt] [--temp 0.3] <prompt | --stdin>`,run:async e=>{if((e[0]===`models`?e.shift():void 0)===`models`){try{let e=await pt();if(e.length===0){console.log(`No Ollama models available. Pull one with: ollama pull gemma4:e2b`);return}for(let t of e)console.log(t)}catch{console.error(`Ollama is not running. Start it with: ollama serve`),process.exit(1)}return}let t=_(e,`--model`,``),n=_(e,`--system`,``),r=v(e,`--temp`,.3),i=_(e,`--context`,``),a=e.join(` `);a||=await p(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await Qe(j(i),`utf-8`));let s=await ft({prompt:a,model:t||void 0,system:n||void 0,context:o,temperature:r});s.error&&(console.error(`Error: ${s.error}`),process.exit(1)),console.log(s.response),console.error(`\n(${s.model}, ${s.durationMs}ms, ${s.tokenCount??`?`} tokens)`)}}],ri=[{name:`eval`,description:`Evaluate JavaScript or TypeScript in a constrained VM sandbox`,usage:`aikit eval [code] [--lang js|ts] [--timeout ms]`,run:async e=>{let t=_(e,`--lang`,`js`),n=v(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await p(),a=r||i;if(!a.trim())throw new g(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await gt({code:a,lang:t===`ts`?`ts`:`js`,timeout:n});if(!o.success){console.error(`Eval failed in ${o.durationMs}ms: ${o.error}`),process.exitCode=1;return}console.log(`Eval succeeded in ${o.durationMs}ms`),console.log(`─`.repeat(60)),console.log(o.output)}},{name:`proxy`,description:`Run stdio-to-HTTP proxy for IDE MCP integration`,usage:`aikit proxy [--port port] [--no-auto-start]`,run:async e=>{let t=v(e,`--port`,3210),n=!y(e,`--no-auto-start`),{runProxy:r}=await import(`../../server/dist/proxy.js`);await r({port:t,autoStart:n})}},{name:`test`,description:`Run Vitest for all tests or a specific subset`,usage:`aikit test [files...] [--grep pattern] [--cwd path] [--timeout ms]`,run:async e=>{let t=_(e,`--grep`,``).trim()||void 0,n=_(e,`--cwd`,``).trim()||void 0,r=v(e,`--timeout`,6e4),i=e.filter(Boolean),a=await cn({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});re(a),a.passed||(process.exitCode=1)}},{name:`rename`,description:`Rename a symbol across files using whole-word regex matching`,usage:`aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``,r=e.shift()?.trim()??``;if(!t||!n||!r)throw new g(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=s(_(e,`--extensions`,``)),a=s(_(e,`--exclude`,``)),o=await Yt({oldName:t,newName:n,rootPath:j(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:y(e,`--dry-run`)});console.log(JSON.stringify(o,null,2))}},{name:`codemod`,description:`Apply regex-based codemod rules from a JSON file across a path`,usage:`aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=_(e,`--rules`,``).trim();if(!t||!n)throw new g(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await Qe(j(n),`utf-8`),i;try{i=JSON.parse(r)}catch{throw Error(`Failed to parse rules file as JSON: ${n}`)}if(!Array.isArray(i))throw Error(`Codemod rules file must contain a JSON array.`);let a=s(_(e,`--extensions`,``)),o=s(_(e,`--exclude`,``)),c=await lt({rootPath:j(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:y(e,`--dry-run`)});console.log(JSON.stringify(c,null,2))}},{name:`transform`,description:`Apply jq-like transforms to JSON from stdin`,usage:`cat data.json | aikit transform <expression>`,run:async e=>{let t=e.join(` `).trim(),n=await p();if(!t||!n.trim())throw new g(`Usage: cat data.json | aikit transform <expression>`);let r=dt({input:n,expression:t});console.log(r.outputString)}}];async function ii(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:i}=e,a=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,o=Cn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=k(s,`flows`,`installed`),l=k(Re(),`flows`);C(l,{recursive:!0});let u=k(l,`registry.json`),d=o.sources[0].path,f=k(d,`.flows`);return{loader:new t,registry:new n(u),stateMachine:new r(f,{before:[],after:[{id:`_docs-sync`,description:`Synchronize project documentation — update docs/ folder based on changes made during the flow.`,position:`after`,skills:[`docs`]}]}),git:new i(c),getBuiltinFlows:a,cwd:d}}const ai=[e=>k(`skills`,e,`SKILL.md`),e=>k(`skills`,e,`README.md`),e=>k(e,`SKILL.md`),e=>k(e,`README.md`)];function oi(e,t){for(let n of t.steps){let t=k(e,n.instruction);if(S(t))continue;let r=!1;for(let i of ai){let a=k(e,i(n.id));if(S(a)){let e=O(t);S(e)||C(e,{recursive:!0}),Te(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${ai.map(e=>e(n.id)).join(`, `)}`)}}const si=[{name:`flow`,description:`Manage pluggable development flows`,usage:`flow <add|remove|list|info|use|update|status|start|reset> [args]`,run:async e=>{let t=e[0];if(!t){console.log(`Usage: aikit flow <add|remove|list|info|use|update|status|start|reset|runs>`),console.log(``),console.log(`Commands:`),console.log(` add <source> Install a flow from git URL or local path`),console.log(` remove <name> Remove an installed flow`),console.log(` list List all installed flows`),console.log(` info <name> Show details of a flow`),console.log(` use <name> Set active flow (start it)`),console.log(` update <name> Update a flow from its source`),console.log(` status Show current flow execution status`),console.log(` start [name] Start a flow (or resume)`),console.log(` reset Reset the active flow`),console.log(` runs List all flow runs`);return}let n=await ii();switch(t){case`add`:{let t=e[1];if(!t){console.error(`Usage: aikit flow add <source>`),console.error(` source: git URL (https://...) or local path`);return}let r=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),i=j(t),a=S(i);if(!r&&!a){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let o,s;if(r){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}o=e.data,s=`git`}else{let r=e[2]||ke(i);console.log(`Copying local flow from ${t}...`);let a=n.git.copyLocal(i,r);if(!a.success||!a.data){console.error(a.error??`Failed to copy local flow`);return}o=a.data,s=`local`}let c=await n.loader.load(o);if(!c.success||!c.data){console.error(c.error??`Failed to load flow`),n.git.remove(o);return}let{manifest:l,format:u}=c.data;if(oi(o,l),l.install.length>0){console.log(`Installing ${l.install.length} dependencies...`);let e=n.git.runInstallDeps(l.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(o);return}}let d=new Date().toISOString(),f=n.registry.register({name:l.name,version:l.version,source:t,sourceType:s,installPath:o,format:u,registeredAt:d,updatedAt:d,manifest:l});if(!f.success){console.error(f.error??`Failed to register flow`),n.git.remove(o);return}console.log(`✓ Flow "${l.name}" v${l.version} installed (${u} format)`),console.log(` Steps: ${l.steps.map(e=>e.id).join(` → `)}`);break}case`remove`:{let t=e[1];if(!t){console.error(`Usage: aikit flow remove <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}let i=n.git.remove(r.installPath);if(!i.success){console.error(i.error??`Failed to remove flow files`);return}let a=n.registry.unregister(t);if(!a.success){console.error(a.error??`Failed to unregister flow`);return}console.log(`✓ Flow "${t}" removed`);break}case`list`:{let e=n.registry.list();if(e.length===0){console.log("No flows installed. Use `aikit flow add <source>` to install one.");return}console.log(`Installed Flows:`),console.log(`─`.repeat(60));for(let t of e){let e=t.manifest.steps.map(e=>e.id).join(` → `);console.log(` ${t.name} v${t.version} (${t.sourceType}, ${t.format})`),console.log(` Steps: ${e}`)}let t=n.stateMachine.getStatus();t.success&&t.data&&(console.log(``),console.log(`Active: ${t.data.flow} (${t.data.status}, step: ${t.data.currentStep??`done`})`));break}case`info`:{let t=e[1];if(!t){console.error(`Usage: aikit flow info <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}console.log(`Flow: ${r.name}`),console.log(`Version: ${r.version}`),console.log(`Source: ${r.source} (${r.sourceType})`),console.log(`Format: ${r.format}`),console.log(`Path: ${r.installPath}`),console.log(`Registered: ${r.registeredAt}`),console.log(`Updated: ${r.updatedAt}`),console.log(``),console.log(`Steps:`);for(let e of r.manifest.steps){let t=e.requires.length?` (requires: ${e.requires.join(`, `)})`:``;console.log(` ${e.id}: ${e.name}${t}`),console.log(` Skill: ${e.skill}`),console.log(` Produces: ${e.produces.join(`, `)}`)}if(r.manifest.install.length>0){console.log(``),console.log(`Dependencies:`);for(let e of r.manifest.install)console.log(` ${e}`)}break}case`use`:case`start`:{let r=e[1],i=r?n.registry.get(r):null;if(t===`use`&&!r){console.error(`Usage: aikit flow use <name>`);return}if(t===`start`&&!r){let e=n.stateMachine.getStatus();if(e.success&&e.data&&e.data.status===`active`){console.log(`Resuming flow: ${e.data.flow}`),console.log(`Current step: ${e.data.currentStep}`),console.log(`Completed: ${e.data.completedSteps.join(`, `)||`none`}`);return}console.error("No active flow. Use `aikit flow start <name>` to begin one.");return}if(!i){console.error(`Flow "${r}" not found. Use \`aikit flow list\` to see installed flows.`);return}let a=e[2],o=n.stateMachine.start(i.name,i.manifest,a);if(!o.success||!o.data){console.error(o.error??`Failed to start flow`);return}let s=o.data;console.log(`✓ Flow "${i.name}" started`),console.log(` Topic: ${s.topic}`),console.log(` Run directory: ${s.runDir}`),console.log(` Current step: ${s.currentStep}`),console.log(` Steps: ${i.manifest.steps.map(e=>e.id).join(` → `)}`);break}case`update`:{let t=e[1];if(!t){console.error(`Usage: aikit flow update <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}if(r.sourceType!==`git`){console.error(`Flow "${t}" is ${r.sourceType}, not updatable via git`);return}console.log(`Updating ${t}...`);let i=n.git.update(r.installPath);if(!i.success){console.error(i.error??`Failed to update flow`);return}let a=await n.loader.load(r.installPath);if(a.success&&a.data){let e=new Date().toISOString(),t=n.registry.register({...r,version:a.data.manifest.version,format:a.data.format,manifest:a.data.manifest,updatedAt:e});if(!t.success){console.error(t.error??`Failed to refresh flow registry entry`);return}}console.log(`✓ Flow "${t}" updated`);break}case`status`:{let e=n.stateMachine.getStatus();if(!e.success||!e.data){console.log(`No active flow.`);return}let t=e.data;if(console.log(`Flow: ${t.flow}`),console.log(`Topic: ${t.topic}`),console.log(`Slug: ${t.slug}`),console.log(`Run Dir: ${t.runDir}`),console.log(`Status: ${t.status}`),console.log(`Current Step: ${t.currentStep??`(completed)`}`),console.log(`Completed: ${t.completedSteps.join(`, `)||`none`}`),t.skippedSteps.length>0&&console.log(`Skipped: ${t.skippedSteps.join(`, `)}`),console.log(`Started: ${t.startedAt}`),console.log(`Updated: ${t.updatedAt}`),Object.keys(t.artifacts).length>0){console.log(`Artifacts:`);for(let[e,n]of Object.entries(t.artifacts))console.log(` ${e}: ${n}`)}break}case`reset`:{let e=n.stateMachine.reset();if(!e.success){console.error(e.error??`Failed to reset flow state`);return}console.log(`✓ Flow abandoned`);break}case`runs`:{let t=e[1],r=e[2],i=n.stateMachine.listRuns({flow:t,status:r});if(i.length===0){console.log(`No flow runs found.`);return}console.log(`Flow Runs:`),console.log(`─`.repeat(80));for(let e of i){let t=e.currentStep?` → ${e.currentStep}`:``;console.log(` ${e.id} [${e.status}] ${e.flow}${t}`),console.log(` Topic: ${e.topic}`),console.log(` Started: ${e.startedAt} | Updated: ${e.updatedAt}`)}break}default:console.error(`Unknown flow command: ${t}`),console.log("Use `aikit flow` for help.")}}}],X=I(`cli:gc`),ci=k(N(),`.aikit`,`versions`),li=k(N(),`.aikit`,`current-version.json`);function ui(e){let t=e.match(/^v(\d+)\.(\d+)\.(\d+)$/);return t?{major:Number.parseInt(t[1],10),minor:Number.parseInt(t[2],10),patch:Number.parseInt(t[3],10)}:null}function di(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function fi(){try{return S(li)?JSON.parse(w(li,`utf-8`)).version??null:null}catch{return null}}const pi=[{name:`gc`,description:`Free disk space by removing old AI Kit versions (keeps current + last N)`,usage:`aikit gc [--keep N]`,run:async e=>{if(!S(ci)){X.info(`No version directories found.`);return}let t=v(e,`--keep`,2),n=fi(),r=T(ci,{withFileTypes:!0}),i=new Set(r.filter(e=>e.isDirectory()&&(e.name.includes(`-staging`)||e.name.startsWith(`_offline-detect-`)||e.name.startsWith(`_aikit-tarball-staging-`))).map(e=>e.name));for(let e of i)await et(k(ci,e),{recursive:!0,force:!0}),X.debug(`Removed ${e}`);let a=r.filter(e=>e.isDirectory()&&!i.has(e.name)).map(e=>({name:e.name,semver:ui(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>di(e.semver,t.semver));if(a.length===0){X.info(`No version directories found.`);return}let o=new Set;n&&o.add(`v${n}`);for(let e of a){if(o.size>=t+ +!!n)break;o.add(e.name)}let s=a.filter(e=>!o.has(e.name));if(s.length===0){X.info(`No versions to clean`);return}for(let e of s)await et(k(ci,e.name),{recursive:!0,force:!0}),X.debug(`Removed ${e.name}`);X.info(`Removed ${s.length} versions`)}}];let mi=null;async function Z(){return mi||=await En(),mi}function hi(){return mi}const gi=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
|
|
45
|
+
`);let n=await ti({reset:t,silent:!1});if(console.log(`\nDone: ${n.checked} checked, ${n.fixed} fixed.`),n.issues.length>0){console.log(`
|
|
46
|
+
Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],ri=[{name:`proc`,description:`Manage in-memory child processes`,usage:`aikit proc <start|stop|status|list|logs> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim(),n=e.shift()?.trim();(!t||!n)&&(console.error(`Usage: aikit proc start <id> <command> [args...]`),process.exit(1)),fe(It(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=Rt(t);if(!n){console.log(`No managed process found: ${t}`);return}fe(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Lt(t);if(!n){console.log(`No managed process found: ${t}`);return}fe(n);return}case`list`:{let e=Pt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)fe(t),console.log(``);return}case`logs`:{let t=v(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=Ft(n,t);if(r.length===0){console.log(`No logs found for process: ${n}`);return}for(let e of r)console.log(e);return}default:console.error(`Unknown proc action: ${t}`),console.error(`Actions: start, stop, status, list, logs`),process.exit(1)}}},{name:`watch`,description:`Manage in-memory filesystem watchers`,usage:`aikit watch <start|stop|list> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch start <path>`),process.exit(1));let n=dn({path:j(t)});console.log(`Started watcher: ${n.id}`),console.log(` Path: ${n.path}`),console.log(` Status: ${n.status}`);return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch stop <id>`),process.exit(1));let n=fn(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=un();if(e.length===0){console.log(`No active watchers.`);return}for(let t of e)console.log(`${t.id}`),console.log(` Path: ${t.path}`),console.log(` Status: ${t.status}`),console.log(` Events: ${t.eventCount}`);return}default:console.error(`Unknown watch action: ${t}`),console.error(`Actions: start, stop, list`),process.exit(1)}}},{name:`delegate`,description:`Delegate a task to a local Ollama model`,usage:`aikit delegate [--model name] [--system prompt] [--temp 0.3] <prompt | --stdin>`,run:async e=>{if((e[0]===`models`?e.shift():void 0)===`models`){try{let e=await pt();if(e.length===0){console.log(`No Ollama models available. Pull one with: ollama pull gemma4:e2b`);return}for(let t of e)console.log(t)}catch{console.error(`Ollama is not running. Start it with: ollama serve`),process.exit(1)}return}let t=_(e,`--model`,``),n=_(e,`--system`,``),r=v(e,`--temp`,.3),i=_(e,`--context`,``),a=e.join(` `);a||=await p(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await Qe(j(i),`utf-8`));let s=await ft({prompt:a,model:t||void 0,system:n||void 0,context:o,temperature:r});s.error&&(console.error(`Error: ${s.error}`),process.exit(1)),console.log(s.response),console.error(`\n(${s.model}, ${s.durationMs}ms, ${s.tokenCount??`?`} tokens)`)}}],ii=[{name:`eval`,description:`Evaluate JavaScript or TypeScript in a constrained VM sandbox`,usage:`aikit eval [code] [--lang js|ts] [--timeout ms]`,run:async e=>{let t=_(e,`--lang`,`js`),n=v(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await p(),a=r||i;if(!a.trim())throw new g(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await gt({code:a,lang:t===`ts`?`ts`:`js`,timeout:n});if(!o.success){console.error(`Eval failed in ${o.durationMs}ms: ${o.error}`),process.exitCode=1;return}console.log(`Eval succeeded in ${o.durationMs}ms`),console.log(`─`.repeat(60)),console.log(o.output)}},{name:`proxy`,description:`Run stdio-to-HTTP proxy for IDE MCP integration`,usage:`aikit proxy [--port port] [--no-auto-start]`,run:async e=>{let t=v(e,`--port`,3210),n=!b(e,`--no-auto-start`),{runProxy:r}=await import(`../../server/dist/proxy.js`);await r({port:t,autoStart:n})}},{name:`test`,description:`Run Vitest for all tests or a specific subset`,usage:`aikit test [files...] [--grep pattern] [--cwd path] [--timeout ms]`,run:async e=>{let t=_(e,`--grep`,``).trim()||void 0,n=_(e,`--cwd`,``).trim()||void 0,r=v(e,`--timeout`,6e4),i=e.filter(Boolean),a=await cn({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});re(a),a.passed||(process.exitCode=1)}},{name:`rename`,description:`Rename a symbol across files using whole-word regex matching`,usage:`aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``,r=e.shift()?.trim()??``;if(!t||!n||!r)throw new g(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=s(_(e,`--extensions`,``)),a=s(_(e,`--exclude`,``)),o=await Yt({oldName:t,newName:n,rootPath:j(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:b(e,`--dry-run`)});console.log(JSON.stringify(o,null,2))}},{name:`codemod`,description:`Apply regex-based codemod rules from a JSON file across a path`,usage:`aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=_(e,`--rules`,``).trim();if(!t||!n)throw new g(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await Qe(j(n),`utf-8`),i;try{i=JSON.parse(r)}catch{throw Error(`Failed to parse rules file as JSON: ${n}`)}if(!Array.isArray(i))throw Error(`Codemod rules file must contain a JSON array.`);let a=s(_(e,`--extensions`,``)),o=s(_(e,`--exclude`,``)),c=await lt({rootPath:j(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:b(e,`--dry-run`)});console.log(JSON.stringify(c,null,2))}},{name:`transform`,description:`Apply jq-like transforms to JSON from stdin`,usage:`cat data.json | aikit transform <expression>`,run:async e=>{let t=e.join(` `).trim(),n=await p();if(!t||!n.trim())throw new g(`Usage: cat data.json | aikit transform <expression>`);let r=dt({input:n,expression:t});console.log(r.outputString)}}];async function ai(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:i}=e,a=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,o=Cn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=k(s,`flows`,`installed`),l=k(Re(),`flows`);C(l,{recursive:!0});let u=k(l,`registry.json`),d=o.sources[0].path,f=k(d,`.flows`);return{loader:new t,registry:new n(u),stateMachine:new r(f,{before:[],after:[{id:`_docs-sync`,description:`Synchronize project documentation — update docs/ folder based on changes made during the flow.`,position:`after`,skills:[`docs`]}]}),git:new i(c),getBuiltinFlows:a,cwd:d}}const oi=[e=>k(`skills`,e,`SKILL.md`),e=>k(`skills`,e,`README.md`),e=>k(e,`SKILL.md`),e=>k(e,`README.md`)];function si(e,t){for(let n of t.steps){let t=k(e,n.instruction);if(S(t))continue;let r=!1;for(let i of oi){let a=k(e,i(n.id));if(S(a)){let e=O(t);S(e)||C(e,{recursive:!0}),Te(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${oi.map(e=>e(n.id)).join(`, `)}`)}}const ci=[{name:`flow`,description:`Manage pluggable development flows`,usage:`flow <add|remove|list|info|use|update|status|start|reset> [args]`,run:async e=>{let t=e[0];if(!t){console.log(`Usage: aikit flow <add|remove|list|info|use|update|status|start|reset|runs>`),console.log(``),console.log(`Commands:`),console.log(` add <source> Install a flow from git URL or local path`),console.log(` remove <name> Remove an installed flow`),console.log(` list List all installed flows`),console.log(` info <name> Show details of a flow`),console.log(` use <name> Set active flow (start it)`),console.log(` update <name> Update a flow from its source`),console.log(` status Show current flow execution status`),console.log(` start [name] Start a flow (or resume)`),console.log(` reset Reset the active flow`),console.log(` runs List all flow runs`);return}let n=await ai();switch(t){case`add`:{let t=e[1];if(!t){console.error(`Usage: aikit flow add <source>`),console.error(` source: git URL (https://...) or local path`);return}let r=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),i=j(t),a=S(i);if(!r&&!a){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let o,s;if(r){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}o=e.data,s=`git`}else{let r=e[2]||ke(i);console.log(`Copying local flow from ${t}...`);let a=n.git.copyLocal(i,r);if(!a.success||!a.data){console.error(a.error??`Failed to copy local flow`);return}o=a.data,s=`local`}let c=await n.loader.load(o);if(!c.success||!c.data){console.error(c.error??`Failed to load flow`),n.git.remove(o);return}let{manifest:l,format:u}=c.data;if(si(o,l),l.install.length>0){console.log(`Installing ${l.install.length} dependencies...`);let e=n.git.runInstallDeps(l.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(o);return}}let d=new Date().toISOString(),f=n.registry.register({name:l.name,version:l.version,source:t,sourceType:s,installPath:o,format:u,registeredAt:d,updatedAt:d,manifest:l});if(!f.success){console.error(f.error??`Failed to register flow`),n.git.remove(o);return}console.log(`✓ Flow "${l.name}" v${l.version} installed (${u} format)`),console.log(` Steps: ${l.steps.map(e=>e.id).join(` → `)}`);break}case`remove`:{let t=e[1];if(!t){console.error(`Usage: aikit flow remove <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}let i=n.git.remove(r.installPath);if(!i.success){console.error(i.error??`Failed to remove flow files`);return}let a=n.registry.unregister(t);if(!a.success){console.error(a.error??`Failed to unregister flow`);return}console.log(`✓ Flow "${t}" removed`);break}case`list`:{let e=n.registry.list();if(e.length===0){console.log("No flows installed. Use `aikit flow add <source>` to install one.");return}console.log(`Installed Flows:`),console.log(`─`.repeat(60));for(let t of e){let e=t.manifest.steps.map(e=>e.id).join(` → `);console.log(` ${t.name} v${t.version} (${t.sourceType}, ${t.format})`),console.log(` Steps: ${e}`)}let t=n.stateMachine.getStatus();t.success&&t.data&&(console.log(``),console.log(`Active: ${t.data.flow} (${t.data.status}, step: ${t.data.currentStep??`done`})`));break}case`info`:{let t=e[1];if(!t){console.error(`Usage: aikit flow info <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}console.log(`Flow: ${r.name}`),console.log(`Version: ${r.version}`),console.log(`Source: ${r.source} (${r.sourceType})`),console.log(`Format: ${r.format}`),console.log(`Path: ${r.installPath}`),console.log(`Registered: ${r.registeredAt}`),console.log(`Updated: ${r.updatedAt}`),console.log(``),console.log(`Steps:`);for(let e of r.manifest.steps){let t=e.requires.length?` (requires: ${e.requires.join(`, `)})`:``;console.log(` ${e.id}: ${e.name}${t}`),console.log(` Skill: ${e.skill}`),console.log(` Produces: ${e.produces.join(`, `)}`)}if(r.manifest.install.length>0){console.log(``),console.log(`Dependencies:`);for(let e of r.manifest.install)console.log(` ${e}`)}break}case`use`:case`start`:{let r=e[1],i=r?n.registry.get(r):null;if(t===`use`&&!r){console.error(`Usage: aikit flow use <name>`);return}if(t===`start`&&!r){let e=n.stateMachine.getStatus();if(e.success&&e.data&&e.data.status===`active`){console.log(`Resuming flow: ${e.data.flow}`),console.log(`Current step: ${e.data.currentStep}`),console.log(`Completed: ${e.data.completedSteps.join(`, `)||`none`}`);return}console.error("No active flow. Use `aikit flow start <name>` to begin one.");return}if(!i){console.error(`Flow "${r}" not found. Use \`aikit flow list\` to see installed flows.`);return}let a=e[2],o=n.stateMachine.start(i.name,i.manifest,a);if(!o.success||!o.data){console.error(o.error??`Failed to start flow`);return}let s=o.data;console.log(`✓ Flow "${i.name}" started`),console.log(` Topic: ${s.topic}`),console.log(` Run directory: ${s.runDir}`),console.log(` Current step: ${s.currentStep}`),console.log(` Steps: ${i.manifest.steps.map(e=>e.id).join(` → `)}`);break}case`update`:{let t=e[1];if(!t){console.error(`Usage: aikit flow update <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}if(r.sourceType!==`git`){console.error(`Flow "${t}" is ${r.sourceType}, not updatable via git`);return}console.log(`Updating ${t}...`);let i=n.git.update(r.installPath);if(!i.success){console.error(i.error??`Failed to update flow`);return}let a=await n.loader.load(r.installPath);if(a.success&&a.data){let e=new Date().toISOString(),t=n.registry.register({...r,version:a.data.manifest.version,format:a.data.format,manifest:a.data.manifest,updatedAt:e});if(!t.success){console.error(t.error??`Failed to refresh flow registry entry`);return}}console.log(`✓ Flow "${t}" updated`);break}case`status`:{let e=n.stateMachine.getStatus();if(!e.success||!e.data){console.log(`No active flow.`);return}let t=e.data;if(console.log(`Flow: ${t.flow}`),console.log(`Topic: ${t.topic}`),console.log(`Slug: ${t.slug}`),console.log(`Run Dir: ${t.runDir}`),console.log(`Status: ${t.status}`),console.log(`Current Step: ${t.currentStep??`(completed)`}`),console.log(`Completed: ${t.completedSteps.join(`, `)||`none`}`),t.skippedSteps.length>0&&console.log(`Skipped: ${t.skippedSteps.join(`, `)}`),console.log(`Started: ${t.startedAt}`),console.log(`Updated: ${t.updatedAt}`),Object.keys(t.artifacts).length>0){console.log(`Artifacts:`);for(let[e,n]of Object.entries(t.artifacts))console.log(` ${e}: ${n}`)}break}case`reset`:{let e=n.stateMachine.reset();if(!e.success){console.error(e.error??`Failed to reset flow state`);return}console.log(`✓ Flow abandoned`);break}case`runs`:{let t=e[1],r=e[2],i=n.stateMachine.listRuns({flow:t,status:r});if(i.length===0){console.log(`No flow runs found.`);return}console.log(`Flow Runs:`),console.log(`─`.repeat(80));for(let e of i){let t=e.currentStep?` → ${e.currentStep}`:``;console.log(` ${e.id} [${e.status}] ${e.flow}${t}`),console.log(` Topic: ${e.topic}`),console.log(` Started: ${e.startedAt} | Updated: ${e.updatedAt}`)}break}default:console.error(`Unknown flow command: ${t}`),console.log("Use `aikit flow` for help.")}}}],X=I(`cli:gc`),li=k(N(),`.aikit`,`versions`),ui=k(N(),`.aikit`,`current-version.json`);function di(e){let t=e.match(/^v(\d+)\.(\d+)\.(\d+)$/);return t?{major:Number.parseInt(t[1],10),minor:Number.parseInt(t[2],10),patch:Number.parseInt(t[3],10)}:null}function fi(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function pi(){try{return S(ui)?JSON.parse(w(ui,`utf-8`)).version??null:null}catch{return null}}const mi=[{name:`gc`,description:`Free disk space by removing old AI Kit versions (keeps current + last N)`,usage:`aikit gc [--keep N]`,run:async e=>{if(!S(li)){X.info(`No version directories found.`);return}let t=v(e,`--keep`,2),n=pi(),r=T(li,{withFileTypes:!0}),i=new Set(r.filter(e=>e.isDirectory()&&(e.name.includes(`-staging`)||e.name.startsWith(`_offline-detect-`)||e.name.startsWith(`_aikit-tarball-staging-`))).map(e=>e.name));for(let e of i)await et(k(li,e),{recursive:!0,force:!0}),X.debug(`Removed ${e}`);let a=r.filter(e=>e.isDirectory()&&!i.has(e.name)).map(e=>({name:e.name,semver:di(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>fi(e.semver,t.semver));if(a.length===0){X.info(`No version directories found.`);return}let o=new Set;n&&o.add(`v${n}`);for(let e of a){if(o.size>=t+ +!!n)break;o.add(e.name)}let s=a.filter(e=>!o.has(e.name));if(s.length===0){X.info(`No versions to clean`);return}for(let e of s)await et(k(li,e.name),{recursive:!0,force:!0}),X.debug(`Removed ${e.name}`);X.info(`Removed ${s.length} versions`)}}];let hi=null;async function Z(){return hi||=await En(),hi}function gi(){return hi}const _i=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
|
|
47
47
|
Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear
|
|
48
48
|
Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;if(!t)throw new g(`Usage: aikit graph <action>
|
|
49
49
|
Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=_(e,`--type`,``),i=_(e,`--name`,``),a=_(e,`--node-id`,``),o=_(e,`--edge-type`,``),s=_(e,`--direction`,`both`),c=v(e,`--depth`,2),l=v(e,`--limit`,50),u=_(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];if(!d)throw new g(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await Ct(n,{action:d,nodeType:r||void 0,namePattern:i||void 0,sourcePath:u||void 0,nodeId:a||void 0,edgeType:o||void 0,direction:s,maxDepth:c,limit:l});if(console.log(f.summary),f.nodes&&f.nodes.length>0){console.log(`
|
|
50
50
|
Nodes:`);for(let e of f.nodes){let t=Object.keys(e.properties).length>0?` ${JSON.stringify(e.properties)}`:``;console.log(` ${e.name} (${e.type}, id: ${e.id})${t}`)}}if(f.edges&&f.edges.length>0){console.log(`
|
|
51
|
-
Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],_i=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=_(e,`--category`,``).trim(),n=s(_(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await p(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),c=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${c.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=_(e,`--category`,``).trim()||void 0,n=_(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await p();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=v(e,`--max-chars`,3e3),n=_(e,`--path`,``).trim()||void 0,r=_(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await p();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ut(o,{path:n,query:i,maxChars:t,segmentation:r}):await ut(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function vi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function yi(){let e=await ar({scope:`user`});if(e.length===0)return 0;let t=Er(),n=0;for(let r of e)try{let e=await r.readConfig();if(e[r.configKey]?.[`AI Kit`]){await r.unregisterMcp(b),await r.registerMcp(F,t),n++;continue}let i=e[r.configKey]?.[F];if(!i||!vi(i))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(F,t),n++}catch{}return n}const bi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await yi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=I(`cli:rollback`),xi=k(N(),`.aikit`,`versions`),Si=k(N(),`.aikit`,`current-version.json`),Ci=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(xi,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(xi,`current-version.json.tmp`);await R(i,JSON.stringify({version:t},null,2),`utf-8`),await $e(i,Si),Q.debug(`Switched to v${t}`)}}],wi=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=h(e),n=v(e,`--limit`,5),r=_(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new g(`Usage: aikit search <query>`);let{embedder:s,store:c,graphStore:l}=await Z(),u=await s.embedQuery(a),d;if(r===`keyword`)d=await c.ftsSearch(a,{limit:n});else if(r===`semantic`)d=await c.search(u,{limit:n});else{let[e,t]=await Promise.all([c.search(u,{limit:n*2}),c.ftsSearch(a,{limit:n*2}).catch(()=>[])]);d=we(e,t).slice(0,n)}if(t){o({query:a,results:d,graphHops:i});return}if(d.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of d){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${d.length} result(s) found.`),i>0&&d.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(l,d.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=h(e),n=v(e,`--limit`,10),r=_(e,`--glob`,``).trim()||void 0,i=_(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new g(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:s,store:c}=await Z(),l=await vt(s,c,{query:a,glob:r,pattern:i,limit:n});if(t){o(l);return}if(l.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${l.strategies.join(`, `)}`),console.log(`Results: ${l.results.length} shown (${l.totalFound} total)`);for(let e of l.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=v(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await en(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${ce(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();te(await sn(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=_(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new g(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();d(await ln(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=v(e,`--limit`,5),n=_(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();l(await bt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=v(e,`--limit`,100),{embedder:n,store:r}=await Z();oe(await yt(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new g(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function Ti(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=ie(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new g(`Server failed to start within 30 seconds.`);let f=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${f}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}const Ei=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=h(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:s}=await import(`../../core/dist/index.js`),{existsSync:c}=await import(`node:fs`),l=Ue(),u=a(),d=c(j(l,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=j(l,n.data);else if(u){let e=r(l);f.mode=c(j(l,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=j(l,n.data);u&&!d&&(f.workspaces=s().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){o(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=s();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!c(j(l,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
|
|
52
|
-
`)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=_(e,`--transport`,`stdio`),n=_(e,`--port`,`3210`),r=
|
|
51
|
+
Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],vi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=_(e,`--category`,``).trim(),n=s(_(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await p(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),c=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${c.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=_(e,`--category`,``).trim()||void 0,n=_(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=_(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await p();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=v(e,`--max-chars`,3e3),n=_(e,`--path`,``).trim()||void 0,r=_(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await p();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ut(o,{path:n,query:i,maxChars:t,segmentation:r}):await ut(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function yi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function bi(){let e=await ar({scope:`user`});if(e.length===0)return 0;let t=Dr(),n=0;for(let r of e)try{let e=await r.readConfig();if(e[r.configKey]?.[`AI Kit`]){await r.unregisterMcp(x),await r.registerMcp(F,t),n++;continue}let i=e[r.configKey]?.[F];if(!i||!yi(i))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(F,t),n++}catch{}return n}const xi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await bi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=I(`cli:rollback`),Si=k(N(),`.aikit`,`versions`),Ci=k(N(),`.aikit`,`current-version.json`),wi=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(Si,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(Si,`current-version.json.tmp`);await R(i,JSON.stringify({version:t},null,2),`utf-8`),await $e(i,Ci),Q.debug(`Switched to v${t}`)}}],Ti=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=h(e),n=v(e,`--limit`,5),r=_(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new g(`Usage: aikit search <query>`);let{embedder:s,store:c,graphStore:l}=await Z(),u=await s.embedQuery(a),d;if(r===`keyword`)d=await c.ftsSearch(a,{limit:n});else if(r===`semantic`)d=await c.search(u,{limit:n});else{let[e,t]=await Promise.all([c.search(u,{limit:n*2}),c.ftsSearch(a,{limit:n*2}).catch(()=>[])]);d=we(e,t).slice(0,n)}if(t){o({query:a,results:d,graphHops:i});return}if(d.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of d){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${d.length} result(s) found.`),i>0&&d.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(l,d.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=h(e),n=v(e,`--limit`,10),r=_(e,`--glob`,``).trim()||void 0,i=_(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new g(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:s,store:c}=await Z(),l=await vt(s,c,{query:a,glob:r,pattern:i,limit:n});if(t){o(l);return}if(l.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${l.strategies.join(`, `)}`),console.log(`Results: ${l.results.length} shown (${l.totalFound} total)`);for(let e of l.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=v(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await en(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${ce(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new g(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();te(await sn(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=_(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new g(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();d(await ln(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=v(e,`--limit`,5),n=_(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();l(await bt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=v(e,`--limit`,100),{embedder:n,store:r}=await Z();oe(await yt(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new g(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function Ei(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=ie(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new g(`Server failed to start within 30 seconds.`);let f=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${f}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}const Di=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=h(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:s}=await import(`../../core/dist/index.js`),{existsSync:c}=await import(`node:fs`),l=Ue(),u=a(),d=c(j(l,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=j(l,n.data);else if(u){let e=r(l);f.mode=c(j(l,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=j(l,n.data);u&&!d&&(f.workspaces=s().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){o(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=s();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!c(j(l,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
|
|
52
|
+
`)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=_(e,`--transport`,`stdio`),n=_(e,`--port`,`3210`),r=b(e,`--daemon`);try{await ti({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=mn(ie(),[],{cwd:N(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:se(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n)throw new g(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-DMj2ctyd.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-DMj2ctyd.js`);await e({force:a})}else if(t)await Pr({force:a});else if(n){let{initProject:e}=await import(`./init-DMj2ctyd.js`);await e({force:a})}else await Pr({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=_(e,`--cwd`,``).trim()||void 0,n=_(e,`--files`,``),r=_(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await it({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});c(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=h(e),n=Tt(e.shift());if(t){o(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
|
|
53
53
|
`:`🧹 Pruning storage...
|
|
54
54
|
`);let c=await t({dryRun:i,maxAgeDays:s});console.log(`Results:`),console.log(` Forge-ground orphans: ${c.forgeGroundOrphans.count} dirs (${n(c.forgeGroundOrphans.bytesFreed)})`),console.log(` Legacy LanceDB: ${c.legacyLance.count} dirs (${n(c.legacyLance.bytesFreed)})`),console.log(` Empty ephemeral dirs: ${c.emptyEphemeral.count} dirs`),console.log(` Stale partitions: ${c.stalePartitions.count} dirs (${n(c.stalePartitions.bytesFreed)})`),console.log(` Browser profiles: ${c.browserProfiles.count} dirs (${n(c.browserProfiles.bytesFreed)})`),console.log(`\n Total freed: ${n(c.totalBytesFreed)}`),i||(r(),console.log(`
|
|
55
55
|
✅ Cleanup complete.`))}},{name:`audit`,description:`Run a unified project audit (structure, deps, patterns, health, dead symbols, check)`,usage:`aikit audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail efficient|normal|full]`,run:async e=>{let{store:t,embedder:n}=await Z(),r=_(e,`--detail`,`efficient`)||`efficient`,i=_(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await rt(t,n,{path:e.shift()||`.`,checks:a,detail:r});if(o.ok){if(console.log(o.summary),o.next&&o.next.length>0){console.log(`
|
|
56
56
|
Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit guide <goal> [--max N]
|
|
57
|
-
Example: aikit guide "audit this project"`);let i=wt(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Zt({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Qt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Xt(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await Ti({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await Ti({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=I(`cli:update`),Di=k(N(),`.aikit`),Oi=k(Di,`versions`),ki=k(Di,`current-version.json`);function Ai(){if(!S(ki))return null;try{let e=w(ki,`utf-8`);return JSON.parse(e)}catch{return null}}function ji(e){S(Di)||C(Di,{recursive:!0});let t=`${ki}.tmp`;D(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),Ee(t,ki)}function Mi(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Ni(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const Pi=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=Ai();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Ni()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Mi(t,e.version)){$.info(`Already latest version.`);return}$.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=k(Oi,`v${t}-staging`);S(i)&&E(i,{recursive:!0,force:!0}),C(i,{recursive:!0});try{let e=k(i,`aikit-${t}.tgz`);D(e,r),$.debug(`Extracting...`),z(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=k(i,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),z(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=k(n,`packages`,`server`,`dist`,`bin.js`);if(!S(a))throw Error(`Server entry not found at ${a}`);let o=k(Oi,`v${t}`);S(Oi)||C(Oi,{recursive:!0}),S(o)&&($.debug(`Removing previous installation at ${o}...`),E(o,{recursive:!0,force:!0})),Ee(n,o),ji(t),$.info(`Updated to ${t}`)}finally{S(i)&&E(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],Fi=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await Nr({force:!0});let e=L();if(e){if(S(j(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-DMj2ctyd.js`);await e({force:!0})}if(S(j(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=be(),r=Ce();await t(e,n,[...x],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[...de],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=k(N(),`.aikit`,`cache`,`wasm`);if(S(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Ii=I(`cli:versions`),Li=k(N(),`.aikit`,`versions`),Ri=k(N(),`.aikit`,`current-version.json`);function zi(){try{return S(Ri)?JSON.parse(w(Ri,`utf-8`)).version??null:null}catch{return null}}const Bi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!S(Li)){Ii.warn(`No versions installed.`);return}let e=zi(),t=T(Li,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=De(k(Li,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Ii.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Vi=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=s(_(e,`--files`,``)),r=_(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=$t(i,n,{description:r});console.log(`Saved workset: ${e.name}`),f(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=xt(i);if(!e){console.log(`No workset found: ${i}`);return}f(e);return}case`list`:{let e=Mt();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)f(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=mt(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=nt(i,n);console.log(`Updated workset: ${e.name}`),f(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Jt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),f(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await ge();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await p(),a=on(r,n,Se(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=rn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=an(r);if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=nn(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=tn(r);console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=kt();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=_(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=Et(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=jt(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Dt(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=At(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Ot(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Gt();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Bt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=qt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Kt(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Ht(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Ut(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Wt(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=zt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=Vt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Hi=[...wi,..._i,...Dn,...gi,...Tr,...Ei,...ri,...zn,...On,...Rn,...Vi,...ni,...Pi,...Fi,...si,...ti,...bi,...Bi,...Ci,...pi];Hi.push({name:`help`,description:`Show available commands`,run:async()=>{Wi()}});async function Ui(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Wi();return}if(n===`--version`||n===`-v`){let e=j(O(je(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(w(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Hi.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Hi.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Wi(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof g&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=hi();e&&await e.store.close()}}function Wi(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
|
|
57
|
+
Example: aikit guide "audit this project"`);let i=wt(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Zt({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Qt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Xt(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await Ei({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await Ei({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=I(`cli:update`),Oi=k(N(),`.aikit`),ki=k(Oi,`versions`),Ai=k(Oi,`current-version.json`);function ji(){if(!S(Ai))return null;try{let e=w(Ai,`utf-8`);return JSON.parse(e)}catch{return null}}function Mi(e){S(Oi)||C(Oi,{recursive:!0});let t=`${Ai}.tmp`;D(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),Ee(t,Ai)}function Ni(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Pi(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const Fi=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=ji();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Pi()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Ni(t,e.version)){$.info(`Already latest version.`);return}$.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=k(ki,`v${t}-staging`);S(i)&&E(i,{recursive:!0,force:!0}),C(i,{recursive:!0});try{let e=k(i,`aikit-${t}.tgz`);D(e,r),$.debug(`Extracting...`),z(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=k(i,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),z(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=k(n,`packages`,`server`,`dist`,`bin.js`);if(!S(a))throw Error(`Server entry not found at ${a}`);let o=k(ki,`v${t}`);S(ki)||C(ki,{recursive:!0}),S(o)&&($.debug(`Removing previous installation at ${o}...`),E(o,{recursive:!0,force:!0})),Ee(n,o),Mi(t),$.info(`Updated to ${t}`)}finally{S(i)&&E(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],Ii=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await Pr({force:!0});let e=L();if(e){if(S(j(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-DMj2ctyd.js`);await e({force:!0})}if(S(j(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=be(),r=Ce();await t(e,n,[..._e],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[...de],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=k(N(),`.aikit`,`cache`,`wasm`);if(S(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Li=I(`cli:versions`),Ri=k(N(),`.aikit`,`versions`),zi=k(N(),`.aikit`,`current-version.json`);function Bi(){try{return S(zi)?JSON.parse(w(zi,`utf-8`)).version??null:null}catch{return null}}const Vi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!S(Ri)){Li.warn(`No versions installed.`);return}let e=Bi(),t=T(Ri,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=De(k(Ri,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Li.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Hi=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=s(_(e,`--files`,``)),r=_(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=$t(i,n,{description:r});console.log(`Saved workset: ${e.name}`),f(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=xt(i);if(!e){console.log(`No workset found: ${i}`);return}f(e);return}case`list`:{let e=Mt();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)f(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=mt(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=nt(i,n);console.log(`Updated workset: ${e.name}`),f(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Jt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),f(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await he();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await p(),a=on(r,n,Se(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=rn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=an(r);if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=nn(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=tn(r);console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=kt();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=_(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=Et(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=jt(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Dt(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=At(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Ot(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Gt();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Bt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=qt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Kt(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Ht(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Ut(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Wt(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=zt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=Vt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Ui=[...Ti,...vi,...Dn,..._i,...Er,...Di,...ii,...zn,...On,...Rn,...Hi,...ri,...Fi,...Ii,...ci,...ni,...xi,...Vi,...wi,...mi];Ui.push({name:`help`,description:`Show available commands`,run:async()=>{Gi()}});async function Wi(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Gi();return}if(n===`--version`||n===`-v`){let e=j(O(je(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(w(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Ui.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Ui.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Gi(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof g&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=gi();e&&await e.store.close()}}function Gi(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
|
|
58
58
|
`),console.log(`Usage: aikit <command> [options]
|
|
59
|
-
`),console.log(`Commands:`);let e=Math.max(...
|
|
59
|
+
`),console.log(`Commands:`);let e=Math.max(...Ui.map(e=>e.name.length));for(let t of Ui)console.log(` ${t.name.padEnd(e+2)}${t.description}`);console.log(``),console.log(`Options:`),console.log(` --help, -h Show this help`),console.log(` --version, -v Show version`)}export{Wi as run};
|
|
@@ -5,4 +5,4 @@ import{fileURLToPath as e,pathToFileURL as t}from"node:url";import{parseArgs as
|
|
|
5
5
|
`).length,fileHash:this.hash(e.content),indexedAt:t,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});try{return await this.store.upsert(i,r),e.length}catch(t){z.error(`Failed to upsert curated batch`,{batchSize:e.length,...o(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return z.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...o(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;z.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...o(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),s=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(s,t,n)}}gitCommitKnowledge(e,t,n){try{if(!b(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;x(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!b(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;S([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>C(e)).join(`/`);return t.split(`/`).every(e=>y.test(e))?`${R}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
|
|
6
6
|
`).length,fileHash:this.hash(t),indexedAt:a,origin:`curated`,tags:n.tags,category:n.category,version:n.version};await this.store.upsert([o],[r])}async indexCuratedFileBestEffort(e,t,n,i){if(r.instance().isDegraded(`embedder`)){z.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:i,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){z.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:i,...o(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||l(t))throw Error(`Invalid path: ${t}. Must be relative within .ai/curated/ directory.`);let n=t.split(`/`)[0];return this.validateCategoryName(n),t}validateCategoryName(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid category name: "${e}". Must be lowercase kebab-case (e.g., "decisions", "api-contracts").`)}validateContentSize(e){if(Buffer.byteLength(e,`utf-8`)>L)throw Error(`Content exceeds maximum size of ${L/1024}KB`)}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)}normalizeTags(e){return[...new Set(e.map(e=>e.trim()).filter(Boolean))]}sameTags(e,t){if(e.length!==t.length)return!1;let n=new Set(e);return t.every(e=>n.has(e))}ensureCategoryPath(e,t){if(!e.startsWith(`${t}/`))throw Error(`Curated path "${e}" must stay within category "${t}"`)}async uniqueRelativePath(e,t){let n=`${e}/${t}.md`;if(!await this.adapter.exists(n))return n;for(let n=2;n<=100;n++){let r=`${e}/${t}-${n}.md`;if(!await this.adapter.exists(r))return r}throw Error(`Too many entries with slug "${t}" in category "${e}"`)}hash(e){return v(`sha256`).update(e).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
|
|
7
7
|
`)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
|
|
8
|
-
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
8
|
+
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-BN2naf7o.js`);await e(t,n.port)}else{let{startStdioMode:e}=await import(`./server-stdio-38nK5K09.js`);await e(t)}}K();export{T as a,k as i,I as n,E as o,F as r,O as s,B as t};
|
|
@@ -351,4 +351,4 @@ svg text{fill:var(--body);font-family:var(--sans);font-size:12px}
|
|
|
351
351
|
<\/script>
|
|
352
352
|
</body>
|
|
353
353
|
</html>`}const U=`<!-- DIAGRAM:SVG -->`;function W(e){let t=e.indexOf(U);if(t===-1)return null;let n=t+20,r=e.indexOf(U,n);if(r===-1)return null;let i=e.slice(n,r).trim();if(i.startsWith(`<svg`))return i;let a=e.slice(Math.max(0,t),r+20),o=a.match(/viewBox="([^"]+)"/),s=o?o[1]:`0 0 1200 800`,c=a.match(/width="(\d+)"/),l=c?c[1]:`1200`,u=a.match(/height="(\d+)"/);return[`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${s}" width="${l}" height="${u?u[1]:`800`}">`,` <defs>`,` <style>`,` text { font-family: system-ui, -apple-system, sans-serif; }`,` .title { font-size: 20px; font-weight: 600; fill: #fff; }`,` .subtitle { font-size: 14px; fill: #94a3b8; }`,` </style>`,` </defs>`,i,`</svg>`].join(`
|
|
354
|
-
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
354
|
+
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-BgcMKnaH.js`);await e(n,r.port)}else{let{startStdioMode:e}=await import(`./server-stdio-C5N56hsL.js`);await e(n)}}export{c as CuratedKnowledgeManager,s as applyWorkspaceRoots,a as bootstrapWorkspaceRoots,i as createSlidingWindowRateLimiter,ge as exportDiagram,W as extractSvg,n as getSessionIdHeader,Te as main,r as readPositiveIntEnv,t as readVersion,ye as renderHtml,be as renderMd,q as renderToResult,e as resolveCorsOrigin,Se as sanitizeTitle,o as selectWorkspaceRoot,xe as validate};
|
|
@@ -2905,7 +2905,7 @@ None.`:`### Stale Lessons\n${l.map(e=>`- **${e.title}** (\`${e.path}\`) — effe
|
|
|
2905
2905
|
navigator.sendBeacon('/callback', new Blob([body], { type: 'application/json' }));
|
|
2906
2906
|
});
|
|
2907
2907
|
})();
|
|
2908
|
-
<\/script>`}function Hm(e){try{if(process.platform===`win32`){gr(`
|
|
2908
|
+
<\/script>`}function Hm(e){try{if(process.platform===`win32`){gr(`powershell`,[`-NoProfile`,`-Command`,`Start-Process "${e}"`],{windowsHide:!0});return}if(process.platform===`darwin`){gr(`open`,[e]);return}gr(`xdg-open`,[e])}catch{}}async function Um(e){try{let t=process.env.AGENT_BROWSER_ARGS??``;t.includes(`--disable-automation`)||(process.env.AGENT_BROWSER_ARGS=t?`${t},--disable-automation`:`--disable-automation`);let n=qn();await n.launch(`ui`),n.resetIdleTimer(),await n.open(e);try{await n.exec(`set`,`viewport`,`1920`,`1080`),await n.exec(`eval`,`window.focus();`).catch(()=>{})}catch{}return!0}catch{return Hm(e),!1}}function Wm(e,t,n){let r=[e.title];return e.description&&r.push(e.description),r.push(``,`Opened in browser — ${t}`,n),r.join(`
|
|
2909
2909
|
`)}function Gm(e){return e.some(e=>e.id!==`__dismiss`)}function Km(e){return e.replace(`</head>`,`${Xh}\n</head>`).replace(`</body>`,`${Zh}\n</body>`)}function qm(e){if(!e.headersSent)try{e.writeHead(500,{"Content-Type":`text/plain`}),e.end(`Internal Server Error`)}catch{try{e.end()}catch{}}}function Jm(e,t){let n=e.headers.referer;return typeof n==`string`&&n.length>0?n:`http://127.0.0.1:${t.port}`}async function Ym(e,t){let n=qn(),r=`ss-${Date.now()}`;n.isLaunched()||await n.launch(`headless`);let{base64:i}=await n.screenshot(r,{fullPage:t?.fullPage!==!1,format:t?.format,quality:t?.quality,annotate:t?.annotate});return Buffer.from(i,`base64`)}async function Xm(e,t){if(!t){e.writeHead(503,{"Content-Type":`text/plain; charset=utf-8`}),e.end(`Screenshot target is not ready.`);return}try{let n=await Ym(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Screenshot capture failed:`,n),qm(e)}}async function Zm(e,t){if(!t){Rm(e,503,`CLIPBOARD_CAPTURE_TARGET_MISSING`,`Clipboard target is not ready.`);return}try{let n=await Ym(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Clipboard capture failed:`,n),Rm(e,500,`CLIPBOARD_CAPTURE_FAILED`,`Clipboard capture failed: ${n}`)}}async function Qm(e,t){let n=[];e.on(`data`,e=>n.push(e)),e.on(`end`,async()=>{let e=Buffer.concat(n);if(e.length===0){Rm(t,400,`EMPTY_BODY`,`No image data received.`);return}try{await $m(e),t.writeHead(200,{"Content-Type":`application/json`}),t.end(JSON.stringify({ok:!0}))}catch(e){let n=e instanceof Error?e.message:String(e);console.warn(`[present] System clipboard write failed:`,n),Rm(t,500,`SYSTEM_CLIPBOARD_WRITE_FAILED`,`System clipboard write failed: ${n}`)}}),e.on(`error`,e=>{console.warn(`[present] System clipboard write request error:`,e.message),Rm(t,500,`REQUEST_ERROR`,`Request stream error.`)})}async function $m(e){let t=F(Kn(),`aikit-clipboard-${Date.now()}-${qe(4).toString(`hex`)}.png`);Ne(t,e);try{if(process.platform===`win32`){let e=[`Add-Type -AssemblyName System.Drawing;`,`Add-Type -AssemblyName System.Windows.Forms;`,`$path = '${t.replace(/'/g,`''`)}';`,`$img = [System.Drawing.Image]::FromFile($path);`,`$img2 = [System.Drawing.Bitmap]::FromImage($img);`,`$img.Dispose();`,`[System.Windows.Forms.Clipboard]::SetImage($img2);`,`Start-Sleep -Milliseconds 500;`,`$img2.Dispose();`].join(` `);await new Promise((t,n)=>{hr(`powershell.exe -NoProfile -STA -Command "${e.replace(/"/g,`\\"`)}"`,{timeout:15e3},e=>{e?n(Error(`PowerShell clipboard write failed: ${e.message}`)):t()})})}else if(process.platform===`darwin`)await new Promise((e,n)=>{hr(`osascript -e 'set the clipboard to (read (POSIX file "${t}") as picture)'`,{timeout:15e3},t=>{t?n(Error(`macOS clipboard write failed: ${t.message}`)):e()})});else try{await new Promise((e,n)=>{hr(`wl-copy --type image/png < "${t}" 2>/dev/null`,{timeout:1e4},(t,r)=>{t?n(Error(`wl-copy failed: ${t.message}`)):e(r)})});return}catch{await new Promise((e,n)=>{hr(`xclip -selection clipboard -t image/png -i "${t}"`,{timeout:15e3},t=>{t?n(Error(`Linux clipboard write failed (tried wl-copy then xclip): ${t.message}. Install wl-clipboard (Wayland) or xclip (X11) for clipboard image support.`)):e()})})}}finally{try{Me(t)}catch{}}}function eh(e,t){return e.replace(/'\/callback'/g,`'/present/${t}/callback'`).replace(/"\/callback"/g,`"/present/${t}/callback"`)}function th(e,t){return e.replace(/src="\/viewer"/g,`src="/present/${t}/viewer"`)}async function nh(e,t){if(Oh(`<html><body style="font-family:system-ui;padding:2rem;color:#888;text-align:center"><p>Content opened in browser window.</p></body></html>`),e.data!=null&&t.inputSchema){let n=Tn({data:e.data,schema:t.inputSchema});if(!n.valid){let e=n.errors.map(e=>` ${e.path}: ${e.message}${e.expected?` (expected: ${e.expected}, got: ${e.received})`:``}`).join(`
|
|
2910
2910
|
`);return{content:[{type:`text`,text:`[ERROR:VALIDATION] Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}],structuredContent:{kind:`error`,error:{code:`VIEWER_DATA_INVALID`,message:`Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}},isError:!0}}}let n=Km(yp(t.resolveHtml(),e.data??null,t.injectId,t.transformData)),r=jm(),i=qe(16).toString(`hex`),a=r.createSession({surfaceId:`viewer`,transport:`viewer`,nonce:i});if(!a.ok)return{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:{kind:`error`,error:{code:`BROWSER_START_FAILED`,message:a.error.message}},isError:!0};let o=a.session.id,s=fm(`viewer`,e.actions??[],r,o,i),c=th(Cr({title:e.title,subtitle:e.description,html:[`<div class="present-viewer-container">`,` <iframe class="present-viewer-iframe" src="/viewer" sandbox="allow-scripts allow-same-origin"></iframe>`,` ${Qh(i)}`,`</div>`].join(`
|
|
2911
2911
|
`),css:[[`.present-viewer-container {`,` flex: 1;`,` min-height: calc(100vh - 12rem);`,` position: relative;`,` border-radius: 0.75rem;`,` overflow: hidden;`,` border: none;`,`}`,`.present-viewer-iframe {`,` border: none;`,` width: 100%;`,` height: 100%;`,` position: absolute;`,` inset: 0;`,` border-radius: inherit;`,`}`].join(`
|
|
@@ -2904,7 +2904,7 @@ None.`:`### Stale Lessons\n${l.map(e=>`- **${e.title}** (\`${e.path}\`) — effe
|
|
|
2904
2904
|
navigator.sendBeacon('/callback', new Blob([body], { type: 'application/json' }));
|
|
2905
2905
|
});
|
|
2906
2906
|
})();
|
|
2907
|
-
<\/script>`}function Hm(e){try{if(process.platform===`win32`){qn(`
|
|
2907
|
+
<\/script>`}function Hm(e){try{if(process.platform===`win32`){qn(`powershell`,[`-NoProfile`,`-Command`,`Start-Process "${e}"`],{windowsHide:!0});return}if(process.platform===`darwin`){qn(`open`,[e]);return}qn(`xdg-open`,[e])}catch{}}async function Um(e){try{let t=process.env.AGENT_BROWSER_ARGS??``;t.includes(`--disable-automation`)||(process.env.AGENT_BROWSER_ARGS=t?`${t},--disable-automation`:`--disable-automation`);let n=Zn();await n.launch(`ui`),n.resetIdleTimer(),await n.open(e);try{await n.exec(`set`,`viewport`,`1920`,`1080`),await n.exec(`eval`,`window.focus();`).catch(()=>{})}catch{}return!0}catch{return Hm(e),!1}}function Wm(e,t,n){let r=[e.title];return e.description&&r.push(e.description),r.push(``,`Opened in browser — ${t}`,n),r.join(`
|
|
2908
2908
|
`)}function Gm(e){return e.some(e=>e.id!==`__dismiss`)}function Km(e){return e.replace(`</head>`,`${Xh}\n</head>`).replace(`</body>`,`${Zh}\n</body>`)}function qm(e){if(!e.headersSent)try{e.writeHead(500,{"Content-Type":`text/plain`}),e.end(`Internal Server Error`)}catch{try{e.end()}catch{}}}function Jm(e,t){let n=e.headers.referer;return typeof n==`string`&&n.length>0?n:`http://127.0.0.1:${t.port}`}async function Ym(e,t){let n=Zn(),r=`ss-${Date.now()}`;n.isLaunched()||await n.launch(`headless`);let{base64:i}=await n.screenshot(r,{fullPage:t?.fullPage!==!1,format:t?.format,quality:t?.quality,annotate:t?.annotate});return Buffer.from(i,`base64`)}async function Xm(e,t){if(!t){e.writeHead(503,{"Content-Type":`text/plain; charset=utf-8`}),e.end(`Screenshot target is not ready.`);return}try{let n=await Ym(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Screenshot capture failed:`,n),qm(e)}}async function Zm(e,t){if(!t){Rm(e,503,`CLIPBOARD_CAPTURE_TARGET_MISSING`,`Clipboard target is not ready.`);return}try{let n=await Ym(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Clipboard capture failed:`,n),Rm(e,500,`CLIPBOARD_CAPTURE_FAILED`,`Clipboard capture failed: ${n}`)}}async function Qm(e,t){let n=[];e.on(`data`,e=>n.push(e)),e.on(`end`,async()=>{let e=Buffer.concat(n);if(e.length===0){Rm(t,400,`EMPTY_BODY`,`No image data received.`);return}try{await $m(e),t.writeHead(200,{"Content-Type":`application/json`}),t.end(JSON.stringify({ok:!0}))}catch(e){let n=e instanceof Error?e.message:String(e);console.warn(`[present] System clipboard write failed:`,n),Rm(t,500,`SYSTEM_CLIPBOARD_WRITE_FAILED`,`System clipboard write failed: ${n}`)}}),e.on(`error`,e=>{console.warn(`[present] System clipboard write request error:`,e.message),Rm(t,500,`REQUEST_ERROR`,`Request stream error.`)})}async function $m(e){let t=P(Xn(),`aikit-clipboard-${Date.now()}-${Je(4).toString(`hex`)}.png`);Pe(t,e);try{if(process.platform===`win32`){let e=[`Add-Type -AssemblyName System.Drawing;`,`Add-Type -AssemblyName System.Windows.Forms;`,`$path = '${t.replace(/'/g,`''`)}';`,`$img = [System.Drawing.Image]::FromFile($path);`,`$img2 = [System.Drawing.Bitmap]::FromImage($img);`,`$img.Dispose();`,`[System.Windows.Forms.Clipboard]::SetImage($img2);`,`Start-Sleep -Milliseconds 500;`,`$img2.Dispose();`].join(` `);await new Promise((t,n)=>{Kn(`powershell.exe -NoProfile -STA -Command "${e.replace(/"/g,`\\"`)}"`,{timeout:15e3},e=>{e?n(Error(`PowerShell clipboard write failed: ${e.message}`)):t()})})}else if(process.platform===`darwin`)await new Promise((e,n)=>{Kn(`osascript -e 'set the clipboard to (read (POSIX file "${t}") as picture)'`,{timeout:15e3},t=>{t?n(Error(`macOS clipboard write failed: ${t.message}`)):e()})});else try{await new Promise((e,n)=>{Kn(`wl-copy --type image/png < "${t}" 2>/dev/null`,{timeout:1e4},(t,r)=>{t?n(Error(`wl-copy failed: ${t.message}`)):e(r)})});return}catch{await new Promise((e,n)=>{Kn(`xclip -selection clipboard -t image/png -i "${t}"`,{timeout:15e3},t=>{t?n(Error(`Linux clipboard write failed (tried wl-copy then xclip): ${t.message}. Install wl-clipboard (Wayland) or xclip (X11) for clipboard image support.`)):e()})})}}finally{try{Ne(t)}catch{}}}function eh(e,t){return e.replace(/'\/callback'/g,`'/present/${t}/callback'`).replace(/"\/callback"/g,`"/present/${t}/callback"`)}function th(e,t){return e.replace(/src="\/viewer"/g,`src="/present/${t}/viewer"`)}async function nh(e,t){if(Oh(`<html><body style="font-family:system-ui;padding:2rem;color:#888;text-align:center"><p>Content opened in browser window.</p></body></html>`),e.data!=null&&t.inputSchema){let n=En({data:e.data,schema:t.inputSchema});if(!n.valid){let e=n.errors.map(e=>` ${e.path}: ${e.message}${e.expected?` (expected: ${e.expected}, got: ${e.received})`:``}`).join(`
|
|
2909
2909
|
`);return{content:[{type:`text`,text:`[ERROR:VALIDATION] Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}],structuredContent:{kind:`error`,error:{code:`VIEWER_DATA_INVALID`,message:`Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}},isError:!0}}}let n=Km(yp(t.resolveHtml(),e.data??null,t.injectId,t.transformData)),r=jm(),i=Je(16).toString(`hex`),a=r.createSession({surfaceId:`viewer`,transport:`viewer`,nonce:i});if(!a.ok)return{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:{kind:`error`,error:{code:`BROWSER_START_FAILED`,message:a.error.message}},isError:!0};let o=a.session.id,s=fm(`viewer`,e.actions??[],r,o,i),c=th(wr({title:e.title,subtitle:e.description,html:[`<div class="present-viewer-container">`,` <iframe class="present-viewer-iframe" src="/viewer" sandbox="allow-scripts allow-same-origin"></iframe>`,` ${Qh(i)}`,`</div>`].join(`
|
|
2910
2910
|
`),css:[[`.present-viewer-container {`,` flex: 1;`,` min-height: calc(100vh - 12rem);`,` position: relative;`,` border-radius: 0.75rem;`,` overflow: hidden;`,` border: none;`,`}`,`.present-viewer-iframe {`,` border: none;`,` width: 100%;`,` height: 100%;`,` position: absolute;`,` inset: 0;`,` border-radius: inherit;`,`}`].join(`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{c as e,f as t,p as n,s as r}from"./startup-maintenance-D7tKqECM.js";import{n as i,t as a}from"./bin.js";import{reconfigureForWorkspace as o}from"./config-CkXCQx7E.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-
|
|
2
|
+
import{c as e,f as t,p as n,s as r}from"./startup-maintenance-D7tKqECM.js";import{n as i,t as a}from"./bin.js";import{reconfigureForWorkspace as o}from"./config-CkXCQx7E.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-CasJ5Lv1.js";import{fileURLToPath as T}from"node:url";import{AIKIT_PATHS as re,DISPLAY_SERVER_NAME as E,EMBEDDING_DEFAULTS as D,MODEL_REGISTRY as O,addLogListener as k,computePartitionKey as A,createLogger as j,safeCwdOrHome as M,serializeError as N}from"../../core/dist/index.js";import{existsSync as P,mkdirSync as F,statSync as ie}from"node:fs";import{join as I,resolve as ae}from"node:path";import{FileCache as oe,checkpointList as L,checkpointSave as se,listWorksets as R,stashList as ce}from"../../tools/dist/index.js";import{homedir as z}from"node:os";import{McpServer as le}from"@modelcontextprotocol/sdk/server/mcp.js";import{WasmDiagnostics as B,initializeWasm as ue}from"../../chunker/dist/index.js";import{z as V}from"zod";import{EvolutionCollector as de,PolicyStore as fe}from"../../enterprise-bridge/dist/index.js";import{SqliteGraphStore as pe,allMigrations as me,createSqliteAdapter as H,createStateStore as he,createStore as ge,runMigrations as _e}from"../../store/dist/index.js";import{RootsListChangedNotificationSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{buildFormSchema as U,field as W,normalizeResponse as ye}from"../../elicitation/dist/index.js";import{completable as G}from"@modelcontextprotocol/sdk/server/completable.js";import{EmbedderProxy as be}from"../../embeddings/dist/index.js";import{FileHashCache as xe,IncrementalIndexer as Se}from"../../indexer/dist/index.js";import{AsyncLocalStorage as Ce}from"node:async_hooks";function we(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return ye(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,U({confirmed:W.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,U({selection:W.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,U({selections:W.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,U({text:W.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Te={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Ee(e){return k(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Te[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const K=3e4,q=new Map;function De(e,t,n){let r=q.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(q.set(e,{data:n,expires:Date.now()+t}),n))}function Oe(){q.clear()}function ke(e,t){return De(`curated-paths`,K,async()=>e.listPaths({limit:5e3})).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ae(e,t){return De(`file-paths`,K,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function je(e,t){return De(`symbol-names`,K,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Me(e,t){return t?ce(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Ne(e){return R().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Pe(e,t){return t?L(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Fe(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
|
|
3
3
|
`)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:V.string().optional().describe(`Path to analyze (default: workspace root)`)}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the full onboarding workflow for "${e??`.`}"`,``,`1. \`onboard({ path: "${e??`.`}" })\` — full codebase analysis`,`2. \`produce_knowledge({ path: "${e??`.`}" })\` — generate synthesis`,'3. `knowledge({ action: "remember", ... })` for key curated entries',"4. `status` to verify index health"].join(`
|
|
4
4
|
`)}}]})),e.registerPrompt(`sessionStart`,{title:`Start AI Kit Session`,description:`Initialize an AI Kit session — check status, list knowledge, and resume from last checkpoint`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session start protocol:`,``,"1. `status({})` — check AI Kit health and onboard state",'2. `knowledge({ action: "list" })` — see stored knowledge entries','3. `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — resume prior work'].join(`
|
|
5
5
|
`)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:V.string().describe(`Brief summary of decisions made, blockers encountered, and next steps`)}},async({summary:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session end protocol:`,``,'1. `knowledge({ action: "remember", title: "Session checkpoint: '+e.slice(0,60)+`...", content: "`+e.replace(/"/g,`\\"`)+'", category: "session" })` — persist findings',n===`smart`?`2. Smart indexing is active — index refreshes automatically`:"2. `reindex({})` — refresh search index if files changed",`3. Confirm session data saved`].join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,t}from"./curated-manager-D4MOFQ-t.js";import{c as n,f as r,p as i,s as a}from"./startup-maintenance-QrloHssd.js";import{reconfigureForWorkspace as o}from"./config-BS9mkd50.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-
|
|
1
|
+
import{n as e,t}from"./curated-manager-D4MOFQ-t.js";import{c as n,f as r,p as i,s as a}from"./startup-maintenance-QrloHssd.js";import{reconfigureForWorkspace as o}from"./config-BS9mkd50.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-DYDI84K2.js";import{fileURLToPath as T}from"node:url";import{AIKIT_PATHS as re,DISPLAY_SERVER_NAME as E,EMBEDDING_DEFAULTS as D,MODEL_REGISTRY as O,addLogListener as k,computePartitionKey as A,createLogger as j,safeCwdOrHome as M,serializeError as N}from"../../core/dist/index.js";import{existsSync as P,mkdirSync as F,statSync as ie}from"node:fs";import{join as I,resolve as ae}from"node:path";import{FileCache as oe,checkpointList as L,checkpointSave as se,listWorksets as R,stashList as ce}from"../../tools/dist/index.js";import{homedir as z}from"node:os";import{McpServer as le}from"@modelcontextprotocol/sdk/server/mcp.js";import{WasmDiagnostics as B,initializeWasm as ue}from"../../chunker/dist/index.js";import{z as V}from"zod";import{EvolutionCollector as de,PolicyStore as fe}from"../../enterprise-bridge/dist/index.js";import{SqliteGraphStore as pe,allMigrations as me,createSqliteAdapter as H,createStateStore as he,createStore as ge,runMigrations as _e}from"../../store/dist/index.js";import{RootsListChangedNotificationSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{buildFormSchema as U,field as W,normalizeResponse as ye}from"../../elicitation/dist/index.js";import{completable as G}from"@modelcontextprotocol/sdk/server/completable.js";import{EmbedderProxy as be}from"../../embeddings/dist/index.js";import{FileHashCache as xe,IncrementalIndexer as Se}from"../../indexer/dist/index.js";import{AsyncLocalStorage as Ce}from"node:async_hooks";function we(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return ye(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,U({confirmed:W.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,U({selection:W.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,U({selections:W.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,U({text:W.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Te={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Ee(e){return k(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Te[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const K=3e4,q=new Map;function De(e,t,n){let r=q.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(q.set(e,{data:n,expires:Date.now()+t}),n))}function Oe(){q.clear()}function ke(e,t){return De(`curated-paths`,K,async()=>e.listPaths({limit:5e3})).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ae(e,t){return De(`file-paths`,K,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function je(e,t){return De(`symbol-names`,K,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Me(e,t){return t?ce(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Ne(e){return R().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Pe(e,t){return t?L(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Fe(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
|
|
2
2
|
`)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:V.string().optional().describe(`Path to analyze (default: workspace root)`)}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the full onboarding workflow for "${e??`.`}"`,``,`1. \`onboard({ path: "${e??`.`}" })\` — full codebase analysis`,`2. \`produce_knowledge({ path: "${e??`.`}" })\` — generate synthesis`,'3. `knowledge({ action: "remember", ... })` for key curated entries',"4. `status` to verify index health"].join(`
|
|
3
3
|
`)}}]})),e.registerPrompt(`sessionStart`,{title:`Start AI Kit Session`,description:`Initialize an AI Kit session — check status, list knowledge, and resume from last checkpoint`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session start protocol:`,``,"1. `status({})` — check AI Kit health and onboard state",'2. `knowledge({ action: "list" })` — see stored knowledge entries','3. `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — resume prior work'].join(`
|
|
4
4
|
`)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:V.string().describe(`Brief summary of decisions made, blockers encountered, and next steps`)}},async({summary:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session end protocol:`,``,'1. `knowledge({ action: "remember", title: "Session checkpoint: '+e.slice(0,60)+`...", content: "`+e.replace(/"/g,`\\"`)+'", category: "session" })` — persist findings',n===`smart`?`2. Smart indexing is active — index refreshes automatically`:"2. `reindex({})` — refresh search index if files changed",`3. Confirm session data saved`].join(`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./startup-maintenance-D7tKqECM.js";import{a as n,i as r,o as i,s as a}from"./bin.js";import{t as o}from"./register-tools-UK5us8_p.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=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=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(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`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(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&&!f(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){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),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 g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=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=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-CkXCQx7E.js`),import(`./dashboard-static-CVRj5Cbv.js`),import(`./settings-static-VnUkp9iU.js`),import(`./routes-Ct7q5jrL.js`),import(`./auth-bEP-6uqy.js`)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=i(`AIKIT_HTTP_MAX_SESSIONS`,8),M=i(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=i(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=a({requestOrigin:r,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(i.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.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 I=w();E.use(C(I)),E.use(`/mcp`,(e,t,r)=>{let i=n(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));t.setHeader(`Retry-After`,String(a)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,t)=>{if(!z||!H||!U){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=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(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=n(e);if(!G){if(r){t.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,t,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{i()}},X=async(e,t)=>{let r=n(e);if(W&&(!G||r!==K)){await W.handleRequest(e,t,e.body);return}await Y(e,t)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:n,createMcpServer:r,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-27qvW6G0.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-D7tKqECM.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=n(T,d);q=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(()=>{})])},H=f.server,U=a,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-D7tKqECM.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return r(f.aikit,T)},createTransport:e=>new a(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(t){v.error(`Initial index failed; will retry on aikit_reindex`,e(s,t))}}):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,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){v.error(`Failed to start smart index scheduler`,e(s,t))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(t=>{v.error(`AI Kit initialization failed`,e(s,t)),z=!1,u=!0,H=null,U=null,q=null}),t(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(t){v.error(`Failed to load server modules`,e(s,t)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
2
|
+
import{n as e,t}from"./startup-maintenance-D7tKqECM.js";import{a as n,i as r,o as i,s as a}from"./bin.js";import{t as o}from"./register-tools-CasJ5Lv1.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=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=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(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`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(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&&!f(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){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),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 g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=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=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-CkXCQx7E.js`),import(`./dashboard-static-CVRj5Cbv.js`),import(`./settings-static-VnUkp9iU.js`),import(`./routes-Ct7q5jrL.js`),import(`./auth-bEP-6uqy.js`)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=i(`AIKIT_HTTP_MAX_SESSIONS`,8),M=i(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=i(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=a({requestOrigin:r,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(i.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.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 I=w();E.use(C(I)),E.use(`/mcp`,(e,t,r)=>{let i=n(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));t.setHeader(`Retry-After`,String(a)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,t)=>{if(!z||!H||!U){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=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(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=n(e);if(!G){if(r){t.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,t,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{i()}},X=async(e,t)=>{let r=n(e);if(W&&(!G||r!==K)){await W.handleRequest(e,t,e.body);return}await Y(e,t)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:n,createMcpServer:r,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-BVcK8mg9.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-D7tKqECM.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=n(T,d);q=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(()=>{})])},H=f.server,U=a,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-D7tKqECM.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return r(f.aikit,T)},createTransport:e=>new a(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(t){v.error(`Initial index failed; will retry on aikit_reindex`,e(s,t))}}):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,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){v.error(`Failed to start smart index scheduler`,e(s,t))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(t=>{v.error(`AI Kit initialization failed`,e(s,t)),z=!1,u=!0,H=null,U=null,q=null}),t(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(t){v.error(`Failed to load server modules`,e(s,t)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y 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-QrloHssd.js";import{t as o}from"./register-tools-W0FlaHc5.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=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=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(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`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(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&&!f(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){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),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 g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=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=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-BS9mkd50.js`),import(`./dashboard-static-q97RHnd3.js`),import(`./settings-static-HY0egyKG.js`),import(`./routes-DsSm9ea0.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=n(`AIKIT_HTTP_MAX_SESSIONS`,8),M=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(a.warn&&!F&&(F=!0,v.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 I=w();E.use(C(I)),E.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.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 L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,n)=>{if(!z||!H||!U){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=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(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=t(e);if(!G){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(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()}},X=async(e,n)=>{let r=t(e);if(W&&(!G||r!==K)){await W.handleRequest(e,n,e.body);return}await Y(e,n)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-cj8g5_Ga.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-QrloHssd.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=e(T,d);q=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(()=>{})])},H=f.server,U=r,z=!0,v.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`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-QrloHssd.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,T)},createTransport:e=>new r(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,i(s,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,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,i(s,e))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{v.error(`AI Kit initialization failed`,i(s,e)),z=!1,u=!0,H=null,U=null,q=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(e){v.error(`Failed to load server modules`,i(s,e)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y 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-QrloHssd.js";import{t as o}from"./register-tools-DYDI84K2.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=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=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(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`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(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&&!f(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){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),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 g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=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=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-BS9mkd50.js`),import(`./dashboard-static-q97RHnd3.js`),import(`./settings-static-HY0egyKG.js`),import(`./routes-DsSm9ea0.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=n(`AIKIT_HTTP_MAX_SESSIONS`,8),M=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(a.warn&&!F&&(F=!0,v.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 I=w();E.use(C(I)),E.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.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 L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,n)=>{if(!z||!H||!U){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=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(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=t(e);if(!G){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(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()}},X=async(e,n)=>{let r=t(e);if(W&&(!G||r!==K)){await W.handleRequest(e,n,e.body);return}await Y(e,n)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-DYip2rIp.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-QrloHssd.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=e(T,d);q=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(()=>{})])},H=f.server,U=r,z=!0,v.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`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-QrloHssd.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,T)},createTransport:e=>new r(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,i(s,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,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,i(s,e))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{v.error(`AI Kit initialization failed`,i(s,e)),z=!1,u=!0,H=null,U=null,q=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(e){v.error(`Failed to load server modules`,i(s,e)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./startup-maintenance-D7tKqECM.js";import{r as n}from"./bin.js";import{a as r,t as i}from"./register-tools-
|
|
2
|
+
import{n as e,t}from"./startup-maintenance-D7tKqECM.js";import{r as n}from"./bin.js";import{a as r,t as i}from"./register-tools-CasJ5Lv1.js";import{createLogger as a,serializeError as o,setDetailedErrorLoggingEnabled as s}from"../../core/dist/index.js";const c=a(`server`);var l=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 c.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 u(r){let[{loadConfig:a,reconfigureForWorkspace:u,resolveIndexMode:d},{createLazyServer:f},{checkForUpdates:p,autoUpgradeScaffold:m},{RootsListChangedNotificationSchema:h}]=await Promise.all([import(`./config-CkXCQx7E.js`),import(`./server-BVcK8mg9.js`),import(`./startup-maintenance-D7tKqECM.js`).then(e=>e.u),import(`@modelcontextprotocol/sdk/types.js`)]),g=a();s(g.logging?.errorDetails===!0),g.configError&&c.warn(`Config load failure`,{error:g.configError}),c.info(`Config loaded`,{sourceCount:g.sources.length,storePath:g.store.path}),m(),setInterval(p,1440*60*1e3).unref();let _=d(g),v=f(g,_),{server:y,startInit:b,ready:x,runInitialIndex:S}=v,{StdioServerTransport:C}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),w=new C;if(typeof w._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);w._readBuffer=new l,c.debug(`JSON repair installed on stdio transport`),await y.connect(w),c.debug(`MCP server started`,{transport:`stdio`}),await n({config:g,indexMode:_,log:c,rootsChangedNotificationSchema:h,reconfigureForWorkspace:u,runInitialIndex:S,server:y,startInit:b,version:r});let T=null,E=null,D=!1,O=async e=>{D||(D=!0,c.info(`Shutdown signal received`,{signal:e}),i(),T&&=(clearTimeout(T),null),E?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await w.close().catch(()=>void 0),await y.close().catch(()=>void 0),v.aikit&&await Promise.all([v.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),v.aikit.graphStore.close().catch(()=>{}),v.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),v.aikit.store.close().catch(()=>{})]),process.exit(0))},k=()=>{T&&clearTimeout(T),T=setTimeout(async()=>{c.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`),i();try{let e=v.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){c.warn(`Resource release failed during shutdown`,o(e))}},18e5),T.unref&&T.unref()};k(),process.stdin.on(`data`,()=>k()),process.stdin.on(`end`,()=>void O(`stdin-end`)),process.stdin.on(`close`,()=>void O(`stdin-close`)),process.stdin.on(`error`,()=>void O(`stdin-error`)),process.on(`SIGINT`,()=>void O(`SIGINT`)),process.on(`SIGTERM`,()=>void O(`SIGTERM`)),x.catch(t=>{c.error(`Initialization failed — server will continue with limited tools`,e(r,t))}),_===`smart`?x.then(async()=>{try{if(!v.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(v.aikit.indexer,g,v.aikit.store);E=t;let n=v.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),v.setSmartScheduler(t),c.debug(`Smart index scheduler started (stdio mode)`)}catch(t){c.error(`Failed to start smart index scheduler`,e(r,t))}}).catch(t=>c.error(`AI Kit init failed for smart scheduler`,e(r,t))):c.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:_}),t(x,()=>v.aikit?{curated:v.aikit.curated,stateStore:v.aikit.stateStore}:null,r)}export{u as startStdioMode};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./workspace-bootstrap-DTnTU8p2.js";import{n as t,t as n}from"./startup-maintenance-QrloHssd.js";import{a as r,t as i}from"./register-tools-
|
|
1
|
+
import{n as e}from"./workspace-bootstrap-DTnTU8p2.js";import{n as t,t as n}from"./startup-maintenance-QrloHssd.js";import{a as r,t as i}from"./register-tools-DYDI84K2.js";import{createLogger as a,serializeError as o,setDetailedErrorLoggingEnabled as s}from"../../core/dist/index.js";const c=a(`server`);var l=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 c.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 u(r){let[{loadConfig:a,reconfigureForWorkspace:u,resolveIndexMode:d},{createLazyServer:f},{checkForUpdates:p,autoUpgradeScaffold:m},{RootsListChangedNotificationSchema:h}]=await Promise.all([import(`./config-BS9mkd50.js`),import(`./server-DYip2rIp.js`),import(`./startup-maintenance-QrloHssd.js`).then(e=>e.u),import(`@modelcontextprotocol/sdk/types.js`)]),g=a();s(g.logging?.errorDetails===!0),g.configError&&c.warn(`Config load failure`,{error:g.configError}),c.info(`Config loaded`,{sourceCount:g.sources.length,storePath:g.store.path}),m(),setInterval(p,1440*60*1e3).unref();let _=d(g),v=f(g,_),{server:y,startInit:b,ready:x,runInitialIndex:S}=v,{StdioServerTransport:C}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),w=new C;if(typeof w._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);w._readBuffer=new l,c.debug(`JSON repair installed on stdio transport`),await y.connect(w),c.debug(`MCP server started`,{transport:`stdio`}),await e({config:g,indexMode:_,log:c,rootsChangedNotificationSchema:h,reconfigureForWorkspace:u,runInitialIndex:S,server:y,startInit:b,version:r});let T=null,E=null,D=!1,O=async e=>{D||(D=!0,c.info(`Shutdown signal received`,{signal:e}),i(),T&&=(clearTimeout(T),null),E?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await w.close().catch(()=>void 0),await y.close().catch(()=>void 0),v.aikit&&await Promise.all([v.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),v.aikit.graphStore.close().catch(()=>{}),v.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),v.aikit.store.close().catch(()=>{})]),process.exit(0))},k=()=>{T&&clearTimeout(T),T=setTimeout(async()=>{c.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`),i();try{let e=v.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){c.warn(`Resource release failed during shutdown`,o(e))}},18e5),T.unref&&T.unref()};k(),process.stdin.on(`data`,()=>k()),process.stdin.on(`end`,()=>void O(`stdin-end`)),process.stdin.on(`close`,()=>void O(`stdin-close`)),process.stdin.on(`error`,()=>void O(`stdin-error`)),process.on(`SIGINT`,()=>void O(`SIGINT`)),process.on(`SIGTERM`,()=>void O(`SIGTERM`)),x.catch(e=>{c.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),_===`smart`?x.then(async()=>{try{if(!v.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(v.aikit.indexer,g,v.aikit.store);E=t;let n=v.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),v.setSmartScheduler(t),c.debug(`Smart index scheduler started (stdio mode)`)}catch(e){c.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>c.error(`AI Kit init failed for smart scheduler`,t(r,e))):c.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:_}),n(x,()=>v.aikit?{curated:v.aikit.curated,stateStore:v.aikit.stateStore}:null,r)}export{u as startStdioMode};
|