@vpxa/aikit 0.1.280 → 0.1.281
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/server/dist/bin.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{server-Bi0xdSS7.js → server-ChL1FsjF.js} +1 -1
- package/packages/server/dist/{server-BFwmsrI5.js → server-CuHLSa6U.js} +1 -1
- package/packages/tools/dist/index.js +1 -1
package/package.json
CHANGED
|
@@ -5,4 +5,4 @@ import{createHash as e,randomUUID as t}from"node:crypto";import{readFileSync 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){O.error(`Failed to upsert curated batch`,{batchSize:e.length,...f(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return O.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...f(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;O.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...f(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),o=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(o,t,n)}}gitCommitKnowledge(e,t,n){try{if(!h(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;g(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!h(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;_([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>v(e)).join(`/`);return t.split(`/`).every(e=>m.test(e))?`${D}/${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,r){if(u.instance().isDegraded(`embedder`)){O.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:r,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){O.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:r,...f(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||i(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`)>E)throw Error(`Content exceeds maximum size of ${E/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(t){return e(`sha256`).update(t).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 A=`__pending__:`;function j(e){return e.startsWith(A)}function M(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function N(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var P=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=M(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){N(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){N(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`&&!j(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!j(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&&!j(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){N(e,503,-32003,`Session capacity reached`);return}let n=this.now(),r=await this.options.createServer(),i={id:`${A}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function F(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var I=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=F(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};function L(){try{let e=o(r(s(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const R=d(`server`);function z(e,t){return t?{version:e,...f(t)}:{version:e}}const B=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function V({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?B.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function H({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function U(e){return e.startsWith(`file://`)?s(e):e}function W(e){let t=o(e);return process.platform===`win32`?t.toLowerCase():t}function G(e){let t=new Map;for(let n of e){let e=U(n.uri);t.set(W(e),e)}return[...t.values()].sort((e,t)=>W(e).localeCompare(W(t)))}function K({config:e,roots:t}){let n=G(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=W(r),t=n.find(t=>W(t)===e);if(t)return t}return n[0]}function q({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=G(r);if(i.length===0)return!1;let a=K({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path,s=o&&W(o)===W(a)?`configured-source`:`stable-sorted-root`;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:s}),n(e,a),e.allRoots=i,!0}async function J({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:l=()=>process.cwd()}){let u=L(),d=!1,p=!1,m,h=o.server,g=e=>{let t=f(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},_=()=>{d||(d=!0,s())},v=()=>{p||t!==`auto`||(p=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,z(u,e))}})())},y=t=>t.length===0||(m&&=(clearTimeout(m),void 0),!q({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),v(),!0);try{if(y((await h.listRoots()).roots))return;n.debug(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(g(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{version:u,cwd:l(),...f(e)}),_(),v();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{version:u,cwd:l(),...f(e)})}h.setNotificationHandler(r,async()=>{try{y((await h.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,z(u,e))}}),m=setTimeout(()=>{let t=l();n.debug(`Timed out waiting for MCP roots/list_changed; falling back to cwd workspace`,{cwd:t}),q({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:t}]})&&(_(),v())},c)}function Y(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function X(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===c(e).href}catch{return!1}}function Z(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function Q(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function $(){return X()?l({allowPositionals:!0,options:{transport:{type:`string`,default:Y()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:Y(),port:process.env.AIKIT_PORT??`3210`}}async function ee(){let e=L(),n=$();process.on(`unhandledRejection`,t=>{R.error(`Unhandled rejection`,z(e,t))}),process.on(`uncaughtException`,t=>{R.error(`Uncaught exception — exiting`,z(e,t)),process.exit(1)});let r=(t,n)=>{t.then(async()=>{try{let{markPromoteRun:e,markPruneRun:t,prune:r,shouldRunStartupPrune:i,shouldRunWeeklyPromote:a}=await import(`../../tools/dist/index.js`),o=n();if(!o)return;if(i()){let e=await r({});t(),e.totalBytesFreed>0&&R.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:n,pruneLessons:i}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),a=await i(o.curated,o.stateStore,{dryRun:!1});a.pruned.length>0&&R.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let s=await n(o.curated,o.stateStore,{dryRun:!1});(s.groupsCreated>0||s.lessonsGrouped>0)&&R.info(`Startup lesson grouping complete`,{groupsCreated:s.groupsCreated,lessonsGrouped:s.lessonsGrouped})}if(a()){let{DEFAULT_PROMOTE_CONFIG:t,collectWorkspaceLessons:n,getGlobalCuratedDir:r,promoteLessons:i,scanForDuplicates:a}=await import(`./promotion-CJFYv4Ye.js`).then(e=>e.o),s=o.curated,c=new k(r(),s.store,s.embedder),l=await n(),u={...t,dryRun:!1},d=await i(a(l,u),c,u);e(),d.promoted.length>0&&R.info(`Weekly lesson promotion complete`,{promoted:d.promoted.length,candidates:d.candidates.length})}}catch(t){R.warn(`Startup maintenance failed (non-critical)`,z(e,t))}}).catch(()=>{})};if(R.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let[{default:i},{loadConfig:a,resolveIndexMode:o},{registerDashboardRoutes:s,resolveDashboardDir:c},{registerSettingsRoutes:l,resolveSettingsDir:u},{createSettingsRouter:d},{authMiddleware:m,getOrCreateToken:h}]=await Promise.all([import(`express`),import(`./config-DZ-6Zy94.js`),import(`./dashboard-static-CRfR1yKU.js`),import(`./settings-static-B3lnYvcb.js`),import(`./routes-KC-D2U8n.js`),import(`./auth-lzZKfxlV.js`)]),g=a();p(g.logging?.errorDetails===!0),R.info(`Config loaded`,{sourceCount:g.sources.length,storePath:g.store.path});let _=i();_.use(i.json({limit:`1mb`}));let v=Number(n.port),y=`http://localhost:${v}`,b=process.env.AIKIT_CORS_ORIGIN??y,x=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,S=Q(`AIKIT_HTTP_MAX_SESSIONS`,8),C=Q(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),w=Q(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),T=H({limit:100,windowMs:6e4}),E=!1;_.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=V({requestOrigin:r,configuredOrigin:b,allowAnyOrigin:x,fallbackOrigin:y});if(i.warn&&!E&&(E=!0,R.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 D=h();console.error(`[aikit] Auth token: ~/.aikit/token`),_.use(m(D)),_.use(`/mcp`,(e,t,n)=>{let r=Z(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(T.allow(r)){n();return}let i=Math.max(1,Math.ceil(T.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),s(_,c(),R);let O=new Date().toISOString();_.use(`/settings/api`,d({log:R,mcpInfo:()=>({transport:`http`,port:v,pid:process.pid,startedAt:O})})),l(_,u(),R),_.get(`/health`,(e,t)=>{t.json({status:`ok`})});let k=!1,A=null,j=null,M=null,N=null,F=null,L=null,B=null,U=Promise.resolve(),W=async(e,n)=>{if(!k||!M||!N){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=U,i;U=new Promise(e=>{i=e}),await r;try{let r=Z(e);if(!L){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new N({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{B=e,j?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&j?.onSessionEnd(e),B=null}});e.onclose=()=>{L===e&&(L=null),B===e.sessionId&&(B=null)},L=e,await M.connect(e)}let i=L;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(B=i.sessionId,j?.onSessionStart(i.sessionId,{transport:`http`}),j?.onSessionActivity(i.sessionId)):r&&j?.onSessionActivity(r))}catch(e){if(R.error(`MCP handler error`,f(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()}},G=async(e,t)=>{let n=Z(e);if(F&&(!L||n!==B)){await F.handleRequest(e,t,e.body);return}await W(e,t)};_.post(`/mcp`,G),_.get(`/mcp`,G),_.delete(`/mcp`,G);let K=_.listen(v,`127.0.0.1`,()=>{R.info(`MCP server listening`,{url:`http://127.0.0.1:${v}/mcp`,port:v}),setTimeout(async()=>{try{let[{createLazyServer:t,createMcpServer:n,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:s,autoUpgradeScaffold:c}]=await Promise.all([import(`./server-BFwmsrI5.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CgfflkJX.js`)]);s(),c();let l=o(g),u=t(g,l);M=u.server,N=a,k=!0,R.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),u.startInit(),u.ready.then(()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);j=new I(u.aikit.stateStore,{staleTimeoutMinutes:C,gcIntervalMinutes:w,onBeforeSessionDelete:e=>{if(B===e&&L){let e=L;L=null,B=null,e.close().catch(()=>void 0)}F?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!u.aikit?.curated||!u.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),t=await e(u.aikit.curated,u.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&R.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),F=new P({createServer:()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);return n(u.aikit,g)},createTransport:e=>new a(e),maxSessions:S,sessionTimeoutMinutes:C,onSessionStart:e=>j?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>j?.onSessionActivity(e),onSessionEnd:e=>j?.onSessionEnd(e)}),j.startGC(),B&&(j.onSessionStart(B,{transport:`http`}),j.onSessionActivity(B)),R.info(`HTTP session runtime ready`,{maxSessions:S,sessionTimeoutMinutes:C,gcIntervalMinutes:w})}).catch(e=>R.error(`Failed to start session manager`,f(e))),l===`auto`?u.ready.then(async()=>{try{let e=g.sources.map(e=>e.path).join(`, `);R.info(`Running initial index`,{sourcePaths:e}),await u.runInitialIndex(),R.info(`Initial index complete`)}catch(t){R.error(`Initial index failed; will retry on aikit_reindex`,z(e,t))}}).catch(t=>R.error(`AI Kit init or indexing failed`,z(e,t))):l===`smart`?u.ready.then(async()=>{try{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(u.aikit.indexer,g,u.aikit.store),n=u.aikit.store;A=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),u.setSmartScheduler(t),R.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){R.error(`Failed to start smart index scheduler`,z(e,t))}}).catch(t=>R.error(`AI Kit initialization failed`,z(e,t))):(u.ready.catch(t=>R.error(`AI Kit initialization failed`,z(e,t))),R.info(`Initial full indexing skipped in HTTP mode`,{indexMode:l})),r(u.ready,()=>u.aikit?{curated:u.aikit.curated,stateStore:u.aikit.stateStore}:null)}catch(t){R.error(`Failed to load server modules`,z(e,t))}},100)}),q=async e=>{R.info(`Shutdown signal received`,{signal:e}),A?.stop(),j?.stop(),await F?.closeAll().catch(()=>void 0),B&&j?.onSessionEnd(B),L&&(await L.close().catch(()=>void 0),L=null,B=null),K.close(),M&&await M.close(),process.exit(0)};process.on(`SIGINT`,()=>q(`SIGINT`)),process.on(`SIGTERM`,()=>q(`SIGTERM`))}else{let[{loadConfig:t,reconfigureForWorkspace:n,resolveIndexMode:i},{createLazyServer:a},{checkForUpdates:o,autoUpgradeScaffold:s},{RootsListChangedNotificationSchema:c}]=await Promise.all([import(`./config-DZ-6Zy94.js`),import(`./server-BFwmsrI5.js`),import(`./version-check-CgfflkJX.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=t();p(l.logging?.errorDetails===!0),R.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),o(),s();let u=i(l),d=a(l,u),{server:f,startInit:m,ready:h,runInitialIndex:g}=d,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await f.connect(v),R.debug(`MCP server started`,{transport:`stdio`}),await J({config:l,indexMode:u,log:R,rootsChangedNotificationSchema:c,reconfigureForWorkspace:n,runInitialIndex:g,server:f,startInit:m});let y=null,b=()=>{y&&clearTimeout(y),y=setTimeout(async()=>{R.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=d.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch{}},18e5),y.unref&&y.unref()};b(),process.stdin.on(`data`,()=>b()),h.catch(t=>{R.error(`Initialization failed — server will continue with limited tools`,z(e,t))}),u===`smart`?h.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,l,d.aikit.store),n=d.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),R.debug(`Smart index scheduler started (stdio mode)`)}catch(t){R.error(`Failed to start smart index scheduler`,z(e,t))}}).catch(t=>R.error(`AI Kit init failed for smart scheduler`,z(e,t))):R.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u}),r(h,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}}ee();export{T as n,k as t};
|
|
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 A=`__pending__:`;function j(e){return e.startsWith(A)}function M(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function N(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var P=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=M(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){N(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){N(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`&&!j(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!j(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&&!j(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){N(e,503,-32003,`Session capacity reached`);return}let n=this.now(),r=await this.options.createServer(),i={id:`${A}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function F(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var I=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=F(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};function L(){try{let e=o(r(s(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const R=d(`server`);function z(e,t){return t?{version:e,...f(t)}:{version:e}}const B=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function V({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?B.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function H({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function U(e){return e.startsWith(`file://`)?s(e):e}function W(e){let t=o(e);return process.platform===`win32`?t.toLowerCase():t}function G(e){let t=new Map;for(let n of e){let e=U(n.uri);t.set(W(e),e)}return[...t.values()].sort((e,t)=>W(e).localeCompare(W(t)))}function K({config:e,roots:t}){let n=G(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=W(r),t=n.find(t=>W(t)===e);if(t)return t}return n[0]}function q({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=G(r);if(i.length===0)return!1;let a=K({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path,s=o&&W(o)===W(a)?`configured-source`:`stable-sorted-root`;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:s}),n(e,a),e.allRoots=i,!0}async function J({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:l=()=>process.cwd()}){let u=L(),d=!1,p=!1,m,h=o.server,g=e=>{let t=f(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},_=()=>{d||(d=!0,s())},v=()=>{p||t!==`auto`||(p=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,z(u,e))}})())},y=t=>t.length===0||(m&&=(clearTimeout(m),void 0),!q({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),v(),!0);try{if(y((await h.listRoots()).roots))return;n.debug(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(g(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{version:u,cwd:l(),...f(e)}),_(),v();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{version:u,cwd:l(),...f(e)})}h.setNotificationHandler(r,async()=>{try{y((await h.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,z(u,e))}}),m=setTimeout(()=>{let t=l();n.debug(`Timed out waiting for MCP roots/list_changed; falling back to cwd workspace`,{cwd:t}),q({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:t}]})&&(_(),v())},c)}function Y(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function X(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===c(e).href}catch{return!1}}function Z(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function Q(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function $(){return X()?l({allowPositionals:!0,options:{transport:{type:`string`,default:Y()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:Y(),port:process.env.AIKIT_PORT??`3210`}}async function ee(){let e=L(),n=$();process.on(`unhandledRejection`,t=>{R.error(`Unhandled rejection`,z(e,t))}),process.on(`uncaughtException`,t=>{R.error(`Uncaught exception — exiting`,z(e,t)),process.exit(1)});let r=(t,n)=>{t.then(async()=>{try{let{markPromoteRun:e,markPruneRun:t,prune:r,shouldRunStartupPrune:i,shouldRunWeeklyPromote:a}=await import(`../../tools/dist/index.js`),o=n();if(!o)return;if(i()){let e=await r({});t(),e.totalBytesFreed>0&&R.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:n,pruneLessons:i}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),a=await i(o.curated,o.stateStore,{dryRun:!1});a.pruned.length>0&&R.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let s=await n(o.curated,o.stateStore,{dryRun:!1});(s.groupsCreated>0||s.lessonsGrouped>0)&&R.info(`Startup lesson grouping complete`,{groupsCreated:s.groupsCreated,lessonsGrouped:s.lessonsGrouped})}if(a()){let{DEFAULT_PROMOTE_CONFIG:t,collectWorkspaceLessons:n,getGlobalCuratedDir:r,promoteLessons:i,scanForDuplicates:a}=await import(`./promotion-CJFYv4Ye.js`).then(e=>e.o),s=o.curated,c=new k(r(),s.store,s.embedder),l=await n(),u={...t,dryRun:!1},d=await i(a(l,u),c,u);e(),d.promoted.length>0&&R.info(`Weekly lesson promotion complete`,{promoted:d.promoted.length,candidates:d.candidates.length})}}catch(t){R.warn(`Startup maintenance failed (non-critical)`,z(e,t))}}).catch(()=>{})};if(R.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let[{default:i},{loadConfig:a,resolveIndexMode:o},{registerDashboardRoutes:s,resolveDashboardDir:c},{registerSettingsRoutes:l,resolveSettingsDir:u},{createSettingsRouter:d},{authMiddleware:m,getOrCreateToken:h}]=await Promise.all([import(`express`),import(`./config-DZ-6Zy94.js`),import(`./dashboard-static-CRfR1yKU.js`),import(`./settings-static-B3lnYvcb.js`),import(`./routes-KC-D2U8n.js`),import(`./auth-lzZKfxlV.js`)]),g=a();p(g.logging?.errorDetails===!0),R.info(`Config loaded`,{sourceCount:g.sources.length,storePath:g.store.path});let _=i();_.use(i.json({limit:`1mb`}));let v=Number(n.port),y=`http://localhost:${v}`,b=process.env.AIKIT_CORS_ORIGIN??y,x=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,S=Q(`AIKIT_HTTP_MAX_SESSIONS`,8),C=Q(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),w=Q(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),T=H({limit:100,windowMs:6e4}),E=!1;_.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=V({requestOrigin:r,configuredOrigin:b,allowAnyOrigin:x,fallbackOrigin:y});if(i.warn&&!E&&(E=!0,R.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 D=h();console.error(`[aikit] Auth token: ~/.aikit/token`),_.use(m(D)),_.use(`/mcp`,(e,t,n)=>{let r=Z(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(T.allow(r)){n();return}let i=Math.max(1,Math.ceil(T.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),s(_,c(),R);let O=new Date().toISOString();_.use(`/settings/api`,d({log:R,mcpInfo:()=>({transport:`http`,port:v,pid:process.pid,startedAt:O})})),l(_,u(),R),_.get(`/health`,(e,t)=>{t.json({status:`ok`})});let k=!1,A=null,j=null,M=null,N=null,F=null,L=null,B=null,U=Promise.resolve(),W=async(e,n)=>{if(!k||!M||!N){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=U,i;U=new Promise(e=>{i=e}),await r;try{let r=Z(e);if(!L){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new N({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{B=e,j?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&j?.onSessionEnd(e),B=null}});e.onclose=()=>{L===e&&(L=null),B===e.sessionId&&(B=null)},L=e,await M.connect(e)}let i=L;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(B=i.sessionId,j?.onSessionStart(i.sessionId,{transport:`http`}),j?.onSessionActivity(i.sessionId)):r&&j?.onSessionActivity(r))}catch(e){if(R.error(`MCP handler error`,f(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()}},G=async(e,t)=>{let n=Z(e);if(F&&(!L||n!==B)){await F.handleRequest(e,t,e.body);return}await W(e,t)};_.post(`/mcp`,G),_.get(`/mcp`,G),_.delete(`/mcp`,G);let K=_.listen(v,`127.0.0.1`,()=>{R.info(`MCP server listening`,{url:`http://127.0.0.1:${v}/mcp`,port:v}),setTimeout(async()=>{try{let[{createLazyServer:t,createMcpServer:n,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:s,autoUpgradeScaffold:c}]=await Promise.all([import(`./server-CuHLSa6U.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-CgfflkJX.js`)]);s(),c();let l=o(g),u=t(g,l);M=u.server,N=a,k=!0,R.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),u.startInit(),u.ready.then(()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);j=new I(u.aikit.stateStore,{staleTimeoutMinutes:C,gcIntervalMinutes:w,onBeforeSessionDelete:e=>{if(B===e&&L){let e=L;L=null,B=null,e.close().catch(()=>void 0)}F?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!u.aikit?.curated||!u.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),t=await e(u.aikit.curated,u.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&R.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),F=new P({createServer:()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);return n(u.aikit,g)},createTransport:e=>new a(e),maxSessions:S,sessionTimeoutMinutes:C,onSessionStart:e=>j?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>j?.onSessionActivity(e),onSessionEnd:e=>j?.onSessionEnd(e)}),j.startGC(),B&&(j.onSessionStart(B,{transport:`http`}),j.onSessionActivity(B)),R.info(`HTTP session runtime ready`,{maxSessions:S,sessionTimeoutMinutes:C,gcIntervalMinutes:w})}).catch(e=>R.error(`Failed to start session manager`,f(e))),l===`auto`?u.ready.then(async()=>{try{let e=g.sources.map(e=>e.path).join(`, `);R.info(`Running initial index`,{sourcePaths:e}),await u.runInitialIndex(),R.info(`Initial index complete`)}catch(t){R.error(`Initial index failed; will retry on aikit_reindex`,z(e,t))}}).catch(t=>R.error(`AI Kit init or indexing failed`,z(e,t))):l===`smart`?u.ready.then(async()=>{try{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(u.aikit.indexer,g,u.aikit.store),n=u.aikit.store;A=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),u.setSmartScheduler(t),R.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){R.error(`Failed to start smart index scheduler`,z(e,t))}}).catch(t=>R.error(`AI Kit initialization failed`,z(e,t))):(u.ready.catch(t=>R.error(`AI Kit initialization failed`,z(e,t))),R.info(`Initial full indexing skipped in HTTP mode`,{indexMode:l})),r(u.ready,()=>u.aikit?{curated:u.aikit.curated,stateStore:u.aikit.stateStore}:null)}catch(t){R.error(`Failed to load server modules`,z(e,t))}},100)}),q=async e=>{R.info(`Shutdown signal received`,{signal:e}),A?.stop(),j?.stop(),await F?.closeAll().catch(()=>void 0),B&&j?.onSessionEnd(B),L&&(await L.close().catch(()=>void 0),L=null,B=null),K.close(),M&&await M.close(),process.exit(0)};process.on(`SIGINT`,()=>q(`SIGINT`)),process.on(`SIGTERM`,()=>q(`SIGTERM`))}else{let[{loadConfig:t,reconfigureForWorkspace:n,resolveIndexMode:i},{createLazyServer:a},{checkForUpdates:o,autoUpgradeScaffold:s},{RootsListChangedNotificationSchema:c}]=await Promise.all([import(`./config-DZ-6Zy94.js`),import(`./server-CuHLSa6U.js`),import(`./version-check-CgfflkJX.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=t();p(l.logging?.errorDetails===!0),R.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),o(),s();let u=i(l),d=a(l,u),{server:f,startInit:m,ready:h,runInitialIndex:g}=d,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await f.connect(v),R.debug(`MCP server started`,{transport:`stdio`}),await J({config:l,indexMode:u,log:R,rootsChangedNotificationSchema:c,reconfigureForWorkspace:n,runInitialIndex:g,server:f,startInit:m});let y=null,b=()=>{y&&clearTimeout(y),y=setTimeout(async()=>{R.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=d.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch{}},18e5),y.unref&&y.unref()};b(),process.stdin.on(`data`,()=>b()),h.catch(t=>{R.error(`Initialization failed — server will continue with limited tools`,z(e,t))}),u===`smart`?h.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,l,d.aikit.store),n=d.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),R.debug(`Smart index scheduler started (stdio mode)`)}catch(t){R.error(`Failed to start smart index scheduler`,z(e,t))}}).catch(t=>R.error(`AI Kit init failed for smart scheduler`,z(e,t))):R.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u}),r(h,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}}ee();export{T as n,k as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./curated-manager-C5uOPept.js";import{randomUUID as t}from"node:crypto";import{readFileSync as n}from"node:fs";import{dirname as r,resolve as i}from"node:path";import{fileURLToPath as a,pathToFileURL as o}from"node:url";import{parseArgs as s}from"node:util";import{createLogger as c,serializeError as l,setDetailedErrorLoggingEnabled as u}from"../../core/dist/index.js";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 n=this.now(),r=await this.options.createServer(),i={id:`${d}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}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)}};function v(){try{let e=i(r(a(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const y=c(`server`);function b(e,t){return t?{version:e,...l(t)}:{version:e}}const x=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function S({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?x.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function C({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function w(e){return e.startsWith(`file://`)?a(e):e}function T(e){let t=i(e);return process.platform===`win32`?t.toLowerCase():t}function E(e){let t=new Map;for(let n of e){let e=w(n.uri);t.set(T(e),e)}return[...t.values()].sort((e,t)=>T(e).localeCompare(T(t)))}function D({config:e,roots:t}){let n=E(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=T(r),t=n.find(t=>T(t)===e);if(t)return t}return n[0]}function O({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=E(r);if(i.length===0)return!1;let a=D({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path,s=o&&T(o)===T(a)?`configured-source`:`stable-sorted-root`;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:s}),n(e,a),e.allRoots=i,!0}async function k({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:u=()=>process.cwd()}){let d=v(),f=!1,p=!1,m,h=o.server,g=e=>{let t=l(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},_=()=>{f||(f=!0,s())},y=()=>{p||t!==`auto`||(p=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,b(d,e))}})())},x=t=>t.length===0||(m&&=(clearTimeout(m),void 0),!O({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),y(),!0);try{if(x((await h.listRoots()).roots))return;n.debug(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(g(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{version:d,cwd:u(),...l(e)}),_(),y();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{version:d,cwd:u(),...l(e)})}h.setNotificationHandler(r,async()=>{try{x((await h.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,b(d,e))}}),m=setTimeout(()=>{let t=u();n.debug(`Timed out waiting for MCP roots/list_changed; falling back to cwd workspace`,{cwd:t}),O({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:t}]})&&(_(),y())},c)}function A(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function j(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===o(e).href}catch{return!1}}function M(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function N(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function P(){return j()?s({allowPositionals:!0,options:{transport:{type:`string`,default:A()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:A(),port:process.env.AIKIT_PORT??`3210`}}async function F(){let n=v(),r=P();process.on(`unhandledRejection`,e=>{y.error(`Unhandled rejection`,b(n,e))}),process.on(`uncaughtException`,e=>{y.error(`Uncaught exception — exiting`,b(n,e)),process.exit(1)});let i=(t,r)=>{t.then(async()=>{try{let{markPromoteRun:t,markPruneRun:n,prune:i,shouldRunStartupPrune:a,shouldRunWeeklyPromote:o}=await import(`../../tools/dist/index.js`),s=r();if(!s)return;if(a()){let e=await i({});n(),e.totalBytesFreed>0&&y.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:t,pruneLessons:r}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),a=await r(s.curated,s.stateStore,{dryRun:!1});a.pruned.length>0&&y.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let o=await t(s.curated,s.stateStore,{dryRun:!1});(o.groupsCreated>0||o.lessonsGrouped>0)&&y.info(`Startup lesson grouping complete`,{groupsCreated:o.groupsCreated,lessonsGrouped:o.lessonsGrouped})}if(o()){let{DEFAULT_PROMOTE_CONFIG:n,collectWorkspaceLessons:r,getGlobalCuratedDir:i,promoteLessons:a,scanForDuplicates:o}=await import(`./promotion-D9anNXv8.js`).then(e=>e.o),c=s.curated,l=new e(i(),c.store,c.embedder),u=await r(),d={...n,dryRun:!1},f=await a(o(u,d),l,d);t(),f.promoted.length>0&&y.info(`Weekly lesson promotion complete`,{promoted:f.promoted.length,candidates:f.candidates.length})}}catch(e){y.warn(`Startup maintenance failed (non-critical)`,b(n,e))}}).catch(()=>{})};if(y.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let[{default:e},{loadConfig:a,resolveIndexMode:o},{registerDashboardRoutes:s,resolveDashboardDir:c},{registerSettingsRoutes:d,resolveSettingsDir:f},{createSettingsRouter:p},{authMiddleware:m,getOrCreateToken:g}]=await Promise.all([import(`express`),import(`./config-DxWyWSb9.js`),import(`./dashboard-static-FmfoS46e.js`),import(`./settings-static-BtvyIrza.js`),import(`./routes-1wkXLxXe.js`),import(`./auth-Bz5dmZgR.js`).then(e=>e.t)]),v=a();u(v.logging?.errorDetails===!0),y.info(`Config loaded`,{sourceCount:v.sources.length,storePath:v.store.path});let x=e();x.use(e.json({limit:`1mb`}));let w=Number(r.port),T=`http://localhost:${w}`,E=process.env.AIKIT_CORS_ORIGIN??T,D=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,O=N(`AIKIT_HTTP_MAX_SESSIONS`,8),k=N(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),A=N(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),j=C({limit:100,windowMs:6e4}),P=!1;x.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=S({requestOrigin:r,configuredOrigin:E,allowAnyOrigin:D,fallbackOrigin:T});if(i.warn&&!P&&(P=!0,y.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 F=g();console.error(`[aikit] Auth token: ~/.aikit/token`),x.use(m(F)),x.use(`/mcp`,(e,t,n)=>{let r=M(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(j.allow(r)){n();return}let i=Math.max(1,Math.ceil(j.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),s(x,c(),y);let I=new Date().toISOString();x.use(`/settings/api`,p({log:y,mcpInfo:()=>({transport:`http`,port:w,pid:process.pid,startedAt:I})})),d(x,f(),y),x.get(`/health`,(e,t)=>{t.json({status:`ok`})});let L=!1,R=null,z=null,B=null,V=null,H=null,U=null,W=null,G=Promise.resolve(),K=async(e,n)=>{if(!L||!B||!V){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=G,i;G=new Promise(e=>{i=e}),await r;try{let r=M(e);if(!U){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new V({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{W=e,z?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&z?.onSessionEnd(e),W=null}});e.onclose=()=>{U===e&&(U=null),W===e.sessionId&&(W=null)},U=e,await B.connect(e)}let i=U;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(W=i.sessionId,z?.onSessionStart(i.sessionId,{transport:`http`}),z?.onSessionActivity(i.sessionId)):r&&z?.onSessionActivity(r))}catch(e){if(y.error(`MCP handler error`,l(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()}},q=async(e,t)=>{let n=M(e);if(H&&(!U||n!==W)){await H.handleRequest(e,t,e.body);return}await K(e,t)};x.post(`/mcp`,q),x.get(`/mcp`,q),x.delete(`/mcp`,q);let J=x.listen(w,`127.0.0.1`,()=>{y.info(`MCP server listening`,{url:`http://127.0.0.1:${w}/mcp`,port:w}),setTimeout(async()=>{try{let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:r},{StreamableHTTPServerTransport:a},{checkForUpdates:s,autoUpgradeScaffold:c}]=await Promise.all([import(`./server-Bi0xdSS7.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-ruLtfyDd.js`)]);s(),c();let u=o(v),d=e(v,u);B=d.server,V=a,L=!0,y.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:r.length,resourceCount:2}),d.startInit(),d.ready.then(()=>{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);z=new _(d.aikit.stateStore,{staleTimeoutMinutes:k,gcIntervalMinutes:A,onBeforeSessionDelete:e=>{if(W===e&&U){let e=U;U=null,W=null,e.close().catch(()=>void 0)}H?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!d.aikit?.curated||!d.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(d.aikit.curated,d.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&y.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),H=new h({createServer:()=>{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);return t(d.aikit,v)},createTransport:e=>new a(e),maxSessions:O,sessionTimeoutMinutes:k,onSessionStart:e=>z?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>z?.onSessionActivity(e),onSessionEnd:e=>z?.onSessionEnd(e)}),z.startGC(),W&&(z.onSessionStart(W,{transport:`http`}),z.onSessionActivity(W)),y.info(`HTTP session runtime ready`,{maxSessions:O,sessionTimeoutMinutes:k,gcIntervalMinutes:A})}).catch(e=>y.error(`Failed to start session manager`,l(e))),u===`auto`?d.ready.then(async()=>{try{let e=v.sources.map(e=>e.path).join(`, `);y.info(`Running initial index`,{sourcePaths:e}),await d.runInitialIndex(),y.info(`Initial index complete`)}catch(e){y.error(`Initial index failed; will retry on aikit_reindex`,b(n,e))}}).catch(e=>y.error(`AI Kit init or indexing failed`,b(n,e))):u===`smart`?d.ready.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,v,d.aikit.store),n=d.aikit.store;R=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),y.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){y.error(`Failed to start smart index scheduler`,b(n,e))}}).catch(e=>y.error(`AI Kit initialization failed`,b(n,e))):(d.ready.catch(e=>y.error(`AI Kit initialization failed`,b(n,e))),y.info(`Initial full indexing skipped in HTTP mode`,{indexMode:u})),i(d.ready,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}catch(e){y.error(`Failed to load server modules`,b(n,e))}},100)}),Y=async e=>{y.info(`Shutdown signal received`,{signal:e}),R?.stop(),z?.stop(),await H?.closeAll().catch(()=>void 0),W&&z?.onSessionEnd(W),U&&(await U.close().catch(()=>void 0),U=null,W=null),J.close(),B&&await B.close(),process.exit(0)};process.on(`SIGINT`,()=>Y(`SIGINT`)),process.on(`SIGTERM`,()=>Y(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:r},{createLazyServer:a},{checkForUpdates:o,autoUpgradeScaffold:s},{RootsListChangedNotificationSchema:c}]=await Promise.all([import(`./config-DxWyWSb9.js`),import(`./server-Bi0xdSS7.js`),import(`./version-check-ruLtfyDd.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();u(l.logging?.errorDetails===!0),y.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),o(),s();let d=r(l),f=a(l,d),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),y.debug(`MCP server started`,{transport:`stdio`}),await k({config:l,indexMode:d,log:y,rootsChangedNotificationSchema:c,reconfigureForWorkspace:t,runInitialIndex:g,server:p,startInit:m});let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{y.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=f.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch{}},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{y.error(`Initialization failed — server will continue with limited tools`,b(n,e))}),d===`smart`?h.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,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),y.debug(`Smart index scheduler started (stdio mode)`)}catch(e){y.error(`Failed to start smart index scheduler`,b(n,e))}}).catch(e=>y.error(`AI Kit init failed for smart scheduler`,b(n,e))):y.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:d}),i(h,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null)}}export{e as CuratedKnowledgeManager,O as applyWorkspaceRoots,k as bootstrapWorkspaceRoots,C as createSlidingWindowRateLimiter,F as main,S as resolveCorsOrigin,D as selectWorkspaceRoot};
|
|
1
|
+
import{t as e}from"./curated-manager-C5uOPept.js";import{randomUUID as t}from"node:crypto";import{readFileSync as n}from"node:fs";import{dirname as r,resolve as i}from"node:path";import{fileURLToPath as a,pathToFileURL as o}from"node:url";import{parseArgs as s}from"node:util";import{createLogger as c,serializeError as l,setDetailedErrorLoggingEnabled as u}from"../../core/dist/index.js";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 n=this.now(),r=await this.options.createServer(),i={id:`${d}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}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)}};function v(){try{let e=i(r(a(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const y=c(`server`);function b(e,t){return t?{version:e,...l(t)}:{version:e}}const x=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function S({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?x.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function C({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function w(e){return e.startsWith(`file://`)?a(e):e}function T(e){let t=i(e);return process.platform===`win32`?t.toLowerCase():t}function E(e){let t=new Map;for(let n of e){let e=w(n.uri);t.set(T(e),e)}return[...t.values()].sort((e,t)=>T(e).localeCompare(T(t)))}function D({config:e,roots:t}){let n=E(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=T(r),t=n.find(t=>T(t)===e);if(t)return t}return n[0]}function O({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=E(r);if(i.length===0)return!1;let a=D({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path,s=o&&T(o)===T(a)?`configured-source`:`stable-sorted-root`;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:s}),n(e,a),e.allRoots=i,!0}async function k({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:u=()=>process.cwd()}){let d=v(),f=!1,p=!1,m,h=o.server,g=e=>{let t=l(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},_=()=>{f||(f=!0,s())},y=()=>{p||t!==`auto`||(p=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,b(d,e))}})())},x=t=>t.length===0||(m&&=(clearTimeout(m),void 0),!O({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),y(),!0);try{if(x((await h.listRoots()).roots))return;n.debug(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(g(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{version:d,cwd:u(),...l(e)}),_(),y();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{version:d,cwd:u(),...l(e)})}h.setNotificationHandler(r,async()=>{try{x((await h.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,b(d,e))}}),m=setTimeout(()=>{let t=u();n.debug(`Timed out waiting for MCP roots/list_changed; falling back to cwd workspace`,{cwd:t}),O({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:t}]})&&(_(),y())},c)}function A(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function j(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===o(e).href}catch{return!1}}function M(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function N(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function P(){return j()?s({allowPositionals:!0,options:{transport:{type:`string`,default:A()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:A(),port:process.env.AIKIT_PORT??`3210`}}async function F(){let n=v(),r=P();process.on(`unhandledRejection`,e=>{y.error(`Unhandled rejection`,b(n,e))}),process.on(`uncaughtException`,e=>{y.error(`Uncaught exception — exiting`,b(n,e)),process.exit(1)});let i=(t,r)=>{t.then(async()=>{try{let{markPromoteRun:t,markPruneRun:n,prune:i,shouldRunStartupPrune:a,shouldRunWeeklyPromote:o}=await import(`../../tools/dist/index.js`),s=r();if(!s)return;if(a()){let e=await i({});n(),e.totalBytesFreed>0&&y.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:t,pruneLessons:r}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),a=await r(s.curated,s.stateStore,{dryRun:!1});a.pruned.length>0&&y.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let o=await t(s.curated,s.stateStore,{dryRun:!1});(o.groupsCreated>0||o.lessonsGrouped>0)&&y.info(`Startup lesson grouping complete`,{groupsCreated:o.groupsCreated,lessonsGrouped:o.lessonsGrouped})}if(o()){let{DEFAULT_PROMOTE_CONFIG:n,collectWorkspaceLessons:r,getGlobalCuratedDir:i,promoteLessons:a,scanForDuplicates:o}=await import(`./promotion-D9anNXv8.js`).then(e=>e.o),c=s.curated,l=new e(i(),c.store,c.embedder),u=await r(),d={...n,dryRun:!1},f=await a(o(u,d),l,d);t(),f.promoted.length>0&&y.info(`Weekly lesson promotion complete`,{promoted:f.promoted.length,candidates:f.candidates.length})}}catch(e){y.warn(`Startup maintenance failed (non-critical)`,b(n,e))}}).catch(()=>{})};if(y.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let[{default:e},{loadConfig:a,resolveIndexMode:o},{registerDashboardRoutes:s,resolveDashboardDir:c},{registerSettingsRoutes:d,resolveSettingsDir:f},{createSettingsRouter:p},{authMiddleware:m,getOrCreateToken:g}]=await Promise.all([import(`express`),import(`./config-DxWyWSb9.js`),import(`./dashboard-static-FmfoS46e.js`),import(`./settings-static-BtvyIrza.js`),import(`./routes-1wkXLxXe.js`),import(`./auth-Bz5dmZgR.js`).then(e=>e.t)]),v=a();u(v.logging?.errorDetails===!0),y.info(`Config loaded`,{sourceCount:v.sources.length,storePath:v.store.path});let x=e();x.use(e.json({limit:`1mb`}));let w=Number(r.port),T=`http://localhost:${w}`,E=process.env.AIKIT_CORS_ORIGIN??T,D=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,O=N(`AIKIT_HTTP_MAX_SESSIONS`,8),k=N(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),A=N(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),j=C({limit:100,windowMs:6e4}),P=!1;x.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=S({requestOrigin:r,configuredOrigin:E,allowAnyOrigin:D,fallbackOrigin:T});if(i.warn&&!P&&(P=!0,y.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 F=g();console.error(`[aikit] Auth token: ~/.aikit/token`),x.use(m(F)),x.use(`/mcp`,(e,t,n)=>{let r=M(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(j.allow(r)){n();return}let i=Math.max(1,Math.ceil(j.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),s(x,c(),y);let I=new Date().toISOString();x.use(`/settings/api`,p({log:y,mcpInfo:()=>({transport:`http`,port:w,pid:process.pid,startedAt:I})})),d(x,f(),y),x.get(`/health`,(e,t)=>{t.json({status:`ok`})});let L=!1,R=null,z=null,B=null,V=null,H=null,U=null,W=null,G=Promise.resolve(),K=async(e,n)=>{if(!L||!B||!V){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=G,i;G=new Promise(e=>{i=e}),await r;try{let r=M(e);if(!U){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new V({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{W=e,z?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&z?.onSessionEnd(e),W=null}});e.onclose=()=>{U===e&&(U=null),W===e.sessionId&&(W=null)},U=e,await B.connect(e)}let i=U;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(W=i.sessionId,z?.onSessionStart(i.sessionId,{transport:`http`}),z?.onSessionActivity(i.sessionId)):r&&z?.onSessionActivity(r))}catch(e){if(y.error(`MCP handler error`,l(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()}},q=async(e,t)=>{let n=M(e);if(H&&(!U||n!==W)){await H.handleRequest(e,t,e.body);return}await K(e,t)};x.post(`/mcp`,q),x.get(`/mcp`,q),x.delete(`/mcp`,q);let J=x.listen(w,`127.0.0.1`,()=>{y.info(`MCP server listening`,{url:`http://127.0.0.1:${w}/mcp`,port:w}),setTimeout(async()=>{try{let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:r},{StreamableHTTPServerTransport:a},{checkForUpdates:s,autoUpgradeScaffold:c}]=await Promise.all([import(`./server-ChL1FsjF.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-ruLtfyDd.js`)]);s(),c();let u=o(v),d=e(v,u);B=d.server,V=a,L=!0,y.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:r.length,resourceCount:2}),d.startInit(),d.ready.then(()=>{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);z=new _(d.aikit.stateStore,{staleTimeoutMinutes:k,gcIntervalMinutes:A,onBeforeSessionDelete:e=>{if(W===e&&U){let e=U;U=null,W=null,e.close().catch(()=>void 0)}H?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!d.aikit?.curated||!d.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(d.aikit.curated,d.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&y.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),H=new h({createServer:()=>{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);return t(d.aikit,v)},createTransport:e=>new a(e),maxSessions:O,sessionTimeoutMinutes:k,onSessionStart:e=>z?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>z?.onSessionActivity(e),onSessionEnd:e=>z?.onSessionEnd(e)}),z.startGC(),W&&(z.onSessionStart(W,{transport:`http`}),z.onSessionActivity(W)),y.info(`HTTP session runtime ready`,{maxSessions:O,sessionTimeoutMinutes:k,gcIntervalMinutes:A})}).catch(e=>y.error(`Failed to start session manager`,l(e))),u===`auto`?d.ready.then(async()=>{try{let e=v.sources.map(e=>e.path).join(`, `);y.info(`Running initial index`,{sourcePaths:e}),await d.runInitialIndex(),y.info(`Initial index complete`)}catch(e){y.error(`Initial index failed; will retry on aikit_reindex`,b(n,e))}}).catch(e=>y.error(`AI Kit init or indexing failed`,b(n,e))):u===`smart`?d.ready.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,v,d.aikit.store),n=d.aikit.store;R=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),y.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){y.error(`Failed to start smart index scheduler`,b(n,e))}}).catch(e=>y.error(`AI Kit initialization failed`,b(n,e))):(d.ready.catch(e=>y.error(`AI Kit initialization failed`,b(n,e))),y.info(`Initial full indexing skipped in HTTP mode`,{indexMode:u})),i(d.ready,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}catch(e){y.error(`Failed to load server modules`,b(n,e))}},100)}),Y=async e=>{y.info(`Shutdown signal received`,{signal:e}),R?.stop(),z?.stop(),await H?.closeAll().catch(()=>void 0),W&&z?.onSessionEnd(W),U&&(await U.close().catch(()=>void 0),U=null,W=null),J.close(),B&&await B.close(),process.exit(0)};process.on(`SIGINT`,()=>Y(`SIGINT`)),process.on(`SIGTERM`,()=>Y(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:r},{createLazyServer:a},{checkForUpdates:o,autoUpgradeScaffold:s},{RootsListChangedNotificationSchema:c}]=await Promise.all([import(`./config-DxWyWSb9.js`),import(`./server-ChL1FsjF.js`),import(`./version-check-ruLtfyDd.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();u(l.logging?.errorDetails===!0),y.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),o(),s();let d=r(l),f=a(l,d),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),y.debug(`MCP server started`,{transport:`stdio`}),await k({config:l,indexMode:d,log:y,rootsChangedNotificationSchema:c,reconfigureForWorkspace:t,runInitialIndex:g,server:p,startInit:m});let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{y.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=f.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch{}},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{y.error(`Initialization failed — server will continue with limited tools`,b(n,e))}),d===`smart`?h.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,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),y.debug(`Smart index scheduler started (stdio mode)`)}catch(e){y.error(`Failed to start smart index scheduler`,b(n,e))}}).catch(e=>y.error(`AI Kit init failed for smart scheduler`,b(n,e))):y.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:d}),i(h,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null)}}export{e as CuratedKnowledgeManager,O as applyWorkspaceRoots,k as bootstrapWorkspaceRoots,C as createSlidingWindowRateLimiter,F as main,S as resolveCorsOrigin,D as selectWorkspaceRoot};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,t}from"./curated-manager-C5uOPept.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-B4ITAs7F.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-CWEne3av.js";import{n as S,r as C}from"./resolve-sibling-1oDoO-Re.js";import{n as w,r as T}from"./evolution-BX_zTSdj.js";import{a as E,i as D,n as O,r as k,s as ee,t as te}from"./promotion-D9anNXv8.js";import{autoUpgradeScaffold as ne,getCurrentVersion as re,getUpgradeState as ie}from"./version-check-ruLtfyDd.js";import{createRequire as ae}from"node:module";import{createHash as A,randomBytes as oe,randomUUID as se,timingSafeEqual as ce}from"node:crypto";import{existsSync as j,mkdirSync as M,readFileSync as N,readdirSync as le,renameSync as ue,rmSync as de,statSync as fe,unlinkSync as pe,writeFileSync as me}from"node:fs";import{basename as he,dirname as ge,isAbsolute as _e,join as P,relative as ve,resolve as F,sep as ye}from"node:path";import{fileURLToPath as be}from"node:url";import{promisify as xe}from"node:util";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as I,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as L}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,storeReversibleContext as yn,stratumCard as bn,summarizeCheckResult as xn,symbol as Sn,testRun as Cn,timeUtils as wn,trace as Tn,truncateToTokenBudget as R,watchList as En,watchStart as Dn,watchStop as On,webFetch as kn,webSearch as An}from"../../tools/dist/index.js";import{mkdir as jn,readFile as Mn,readdir as Nn,rm as Pn,stat as Fn,unlink as In,writeFile as Ln}from"node:fs/promises";import{execFile as Rn,execSync as zn}from"node:child_process";import{homedir as Bn,tmpdir as Vn}from"node:os";import{McpServer as Hn,ResourceTemplate as Un}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Wn,field as Gn,normalizeResponse as Kn}from"../../elicitation/dist/index.js";import{completable as qn}from"@modelcontextprotocol/sdk/server/completable.js";import{z}from"zod";import{getEngine as Jn,registerBrowserTools as Yn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Xn,DependencyAnalyzer as Zn,DiagramGenerator as Qn,EntryPointAnalyzer as $n,KnowledgeProducer as er,PatternAnalyzer as tr,StructureAnalyzer as nr,SymbolAnalyzer as rr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as ir,WasmRuntime as ar,initializeWasm as or}from"../../chunker/dist/index.js";import{ERCache as sr,ERClient as cr,EvolutionCollector as lr,PolicyStore as ur,PushAdapter as dr,mergeResults as fr}from"../../enterprise-bridge/dist/index.js";import"../../tool-routing/dist/index.
|
|
1
|
+
import{n as e,t}from"./curated-manager-C5uOPept.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-B4ITAs7F.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-CWEne3av.js";import{n as S,r as C}from"./resolve-sibling-1oDoO-Re.js";import{n as w,r as T}from"./evolution-BX_zTSdj.js";import{a as E,i as D,n as O,r as k,s as ee,t as te}from"./promotion-D9anNXv8.js";import{autoUpgradeScaffold as ne,getCurrentVersion as re,getUpgradeState as ie}from"./version-check-ruLtfyDd.js";import{createRequire as ae}from"node:module";import{createHash as A,randomBytes as oe,randomUUID as se,timingSafeEqual as ce}from"node:crypto";import{existsSync as j,mkdirSync as M,readFileSync as N,readdirSync as le,renameSync as ue,rmSync as de,statSync as fe,unlinkSync as pe,writeFileSync as me}from"node:fs";import{basename as he,dirname as ge,isAbsolute as _e,join as P,relative as ve,resolve as F,sep as ye}from"node:path";import{fileURLToPath as be}from"node:url";import{promisify as xe}from"node:util";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as I,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as L}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,storeReversibleContext as yn,stratumCard as bn,summarizeCheckResult as xn,symbol as Sn,testRun as Cn,timeUtils as wn,trace as Tn,truncateToTokenBudget as R,watchList as En,watchStart as Dn,watchStop as On,webFetch as kn,webSearch as An}from"../../tools/dist/index.js";import{mkdir as jn,readFile as Mn,readdir as Nn,rm as Pn,stat as Fn,unlink as In,writeFile as Ln}from"node:fs/promises";import{execFile as Rn,execSync as zn}from"node:child_process";import{homedir as Bn,tmpdir as Vn}from"node:os";import{McpServer as Hn,ResourceTemplate as Un}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Wn,field as Gn,normalizeResponse as Kn}from"../../elicitation/dist/index.js";import{completable as qn}from"@modelcontextprotocol/sdk/server/completable.js";import{z}from"zod";import{getEngine as Jn,registerBrowserTools as Yn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Xn,DependencyAnalyzer as Zn,DiagramGenerator as Qn,EntryPointAnalyzer as $n,KnowledgeProducer as er,PatternAnalyzer as tr,StructureAnalyzer as nr,SymbolAnalyzer as rr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as ir,WasmRuntime as ar,initializeWasm as or}from"../../chunker/dist/index.js";import{ERCache as sr,ERClient as cr,EvolutionCollector as lr,PolicyStore as ur,PushAdapter as dr,mergeResults as fr}from"../../enterprise-bridge/dist/index.js";import"../../tool-routing/dist/index.mjs";import{RESOURCE_MIME_TYPE as pr,getUiCapability as mr,registerAppResource as hr,registerAppTool as gr}from"@modelcontextprotocol/ext-apps/server";import{SqliteGraphStore as _r,allMigrations as vr,createSqliteAdapter as yr,createStateStore as br,createStore as xr,runMigrations as Sr}from"../../store/dist/index.js";import{TemplateRegistry as Cr,buildShell as wr,dashboardTemplateDefinition as Tr,defaultRegistry as Er,flameGraphTemplateDefinition as Dr,isError as Or,isResult as kr,kanbanTemplateDefinition as Ar,listSortTemplateDefinition as jr,renderSurface as Mr}from"../../blocks-core/dist/index.mjs";import{createServer as Nr}from"node:http";import{EmbedderProxy as Pr}from"../../embeddings/dist/index.js";import{FileHashCache as Fr,IncrementalIndexer as Ir}from"../../indexer/dist/index.js";function Lr(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 Kn(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,Wn({confirmed:Gn.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,Wn({selection:Gn.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,Wn({selections:Gn.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,Wn({text:Gn.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Rr={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function zr(e){return Ae(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Rr[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const Br=3e4,Vr=new Map;function Hr(e,t,n){let r=Vr.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(Vr.set(e,{data:n,expires:Date.now()+t}),n))}function Ur(){Vr.clear()}function Wr(e,t){return Hr(`curated-paths`,Br,async()=>(await e.list()).map(e=>e.path)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Gr(e,t){return Hr(`file-paths`,Br,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Kr(e,t){return Hr(`symbol-names`,Br,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 qr(e,t){return t?_n(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Jr(e){return Nt().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Yr(e,t){return t?qe(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Xr(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:z.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:z.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: "conventions" })` — 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,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./bin.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-C3tsarCT.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-DO_ZROFl.js";import{n as S,r as C}from"./resolve-sibling-ByoHo7Tp.js";import{n as w,r as T}from"./evolution-DWaEE6XW.js";import{a as E,i as D,n as O,r as k,s as ee,t as te}from"./promotion-CJFYv4Ye.js";import{autoUpgradeScaffold as ne,getCurrentVersion as re,getUpgradeState as ie}from"./version-check-CgfflkJX.js";import{createRequire as ae}from"node:module";import{createHash as A,randomBytes as oe,randomUUID as se,timingSafeEqual as ce}from"node:crypto";import{existsSync as j,mkdirSync as M,readFileSync as N,readdirSync as le,renameSync as ue,rmSync as de,statSync as fe,unlinkSync as pe,writeFileSync as me}from"node:fs";import{basename as he,dirname as ge,isAbsolute as _e,join as P,relative as ve,resolve as F,sep as ye}from"node:path";import{fileURLToPath as be}from"node:url";import{promisify as xe}from"node:util";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as I,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as L}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,storeReversibleContext as yn,stratumCard as bn,summarizeCheckResult as xn,symbol as Sn,testRun as Cn,timeUtils as wn,trace as Tn,truncateToTokenBudget as R,watchList as En,watchStart as Dn,watchStop as On,webFetch as kn,webSearch as An}from"../../tools/dist/index.js";import{mkdir as jn,readFile as Mn,readdir as Nn,rm as Pn,stat as Fn,unlink as In,writeFile as Ln}from"node:fs/promises";import{homedir as Rn,tmpdir as zn}from"node:os";import{McpServer as Bn,ResourceTemplate as Vn}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Hn,field as Un,normalizeResponse as Wn}from"../../elicitation/dist/index.js";import{completable as Gn}from"@modelcontextprotocol/sdk/server/completable.js";import{z}from"zod";import{getEngine as Kn,registerBrowserTools as qn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Jn,DependencyAnalyzer as Yn,DiagramGenerator as Xn,EntryPointAnalyzer as Zn,KnowledgeProducer as Qn,PatternAnalyzer as $n,StructureAnalyzer as er,SymbolAnalyzer as tr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as nr,WasmRuntime as rr,initializeWasm as ir}from"../../chunker/dist/index.js";import{ERCache as ar,ERClient as or,EvolutionCollector as sr,PolicyStore as cr,PushAdapter as lr,mergeResults as ur}from"../../enterprise-bridge/dist/index.js";import"../../tool-routing/dist/index.
|
|
2
|
+
import{n as e,t}from"./bin.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-C3tsarCT.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-DO_ZROFl.js";import{n as S,r as C}from"./resolve-sibling-ByoHo7Tp.js";import{n as w,r as T}from"./evolution-DWaEE6XW.js";import{a as E,i as D,n as O,r as k,s as ee,t as te}from"./promotion-CJFYv4Ye.js";import{autoUpgradeScaffold as ne,getCurrentVersion as re,getUpgradeState as ie}from"./version-check-CgfflkJX.js";import{createRequire as ae}from"node:module";import{createHash as A,randomBytes as oe,randomUUID as se,timingSafeEqual as ce}from"node:crypto";import{existsSync as j,mkdirSync as M,readFileSync as N,readdirSync as le,renameSync as ue,rmSync as de,statSync as fe,unlinkSync as pe,writeFileSync as me}from"node:fs";import{basename as he,dirname as ge,isAbsolute as _e,join as P,relative as ve,resolve as F,sep as ye}from"node:path";import{fileURLToPath as be}from"node:url";import{promisify as xe}from"node:util";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as I,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as L}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,storeReversibleContext as yn,stratumCard as bn,summarizeCheckResult as xn,symbol as Sn,testRun as Cn,timeUtils as wn,trace as Tn,truncateToTokenBudget as R,watchList as En,watchStart as Dn,watchStop as On,webFetch as kn,webSearch as An}from"../../tools/dist/index.js";import{mkdir as jn,readFile as Mn,readdir as Nn,rm as Pn,stat as Fn,unlink as In,writeFile as Ln}from"node:fs/promises";import{homedir as Rn,tmpdir as zn}from"node:os";import{McpServer as Bn,ResourceTemplate as Vn}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Hn,field as Un,normalizeResponse as Wn}from"../../elicitation/dist/index.js";import{completable as Gn}from"@modelcontextprotocol/sdk/server/completable.js";import{z}from"zod";import{getEngine as Kn,registerBrowserTools as qn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Jn,DependencyAnalyzer as Yn,DiagramGenerator as Xn,EntryPointAnalyzer as Zn,KnowledgeProducer as Qn,PatternAnalyzer as $n,StructureAnalyzer as er,SymbolAnalyzer as tr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as nr,WasmRuntime as rr,initializeWasm as ir}from"../../chunker/dist/index.js";import{ERCache as ar,ERClient as or,EvolutionCollector as sr,PolicyStore as cr,PushAdapter as lr,mergeResults as ur}from"../../enterprise-bridge/dist/index.js";import"../../tool-routing/dist/index.mjs";import{RESOURCE_MIME_TYPE as dr,getUiCapability as fr,registerAppResource as pr,registerAppTool as mr}from"@modelcontextprotocol/ext-apps/server";import{SqliteGraphStore as hr,allMigrations as gr,createSqliteAdapter as _r,createStateStore as vr,createStore as yr,runMigrations as br}from"../../store/dist/index.js";import{execFile as xr,execSync as Sr}from"node:child_process";import{TemplateRegistry as Cr,buildShell as wr,dashboardTemplateDefinition as Tr,defaultRegistry as Er,flameGraphTemplateDefinition as Dr,isError as Or,isResult as kr,kanbanTemplateDefinition as Ar,listSortTemplateDefinition as jr,renderSurface as Mr}from"../../blocks-core/dist/index.mjs";import{createServer as Nr}from"node:http";import{EmbedderProxy as Pr}from"../../embeddings/dist/index.js";import{FileHashCache as Fr,IncrementalIndexer as Ir}from"../../indexer/dist/index.js";function Lr(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 Wn(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,Hn({confirmed:Un.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,Hn({selection:Un.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,Hn({selections:Un.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,Hn({text:Un.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Rr={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function zr(e){return Ae(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Rr[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const Br=3e4,Vr=new Map;function Hr(e,t,n){let r=Vr.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(Vr.set(e,{data:n,expires:Date.now()+t}),n))}function Ur(){Vr.clear()}function Wr(e,t){return Hr(`curated-paths`,Br,async()=>(await e.list()).map(e=>e.path)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Gr(e,t){return Hr(`file-paths`,Br,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Kr(e,t){return Hr(`symbol-names`,Br,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 qr(e,t){return t?_n(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Jr(e){return Nt().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Yr(e,t){return t?qe(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Xr(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:z.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:z.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: "conventions" })` — 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{mkdir as e,readFile as t,readdir as n,rm as r,stat as i,writeFile as a}from"node:fs/promises";import{basename as o,dirname as s,extname as c,isAbsolute as l,join as u,relative as d,resolve as f,sep as p}from"node:path";import{DependencyAnalyzer as m,DiagramGenerator as h,EntryPointAnalyzer as g,PatternAnalyzer as _,StructureAnalyzer as v,SymbolAnalyzer as y,extractRegexCallGraph as b,extractTsCallGraph as x}from"../../analyzers/dist/index.js";import{exec as S,execFile as C,execFileSync as w,spawn as ee}from"node:child_process";import{promisify as T}from"node:util";import{SUPPORTED_EXTENSIONS as E,WasmRuntime as D,extractCalls as O,extractImports as k,extractSymbols as A,resolveScopes as te}from"../../chunker/dist/index.js";import{appendFileSync as j,copyFileSync as ne,cpSync as re,existsSync as M,mkdirSync as N,readFileSync as P,readdirSync as F,renameSync as I,rmSync as ie,statSync as L,unlinkSync as ae,watch as oe,writeFileSync as R}from"node:fs";import{arch as se,cpus as ce,freemem as le,homedir as ue,hostname as de,platform as fe,release as pe,totalmem as me,type as he}from"node:os";import{AIKIT_PATHS as ge,AIKIT_RUNTIME_PATHS as _e,computePartitionKey as ve,createLogger as ye,getGlobalDataDir as be,getWorkspacePartitionDir as xe,loadRegistry as Se,migrateLegacyWorkspaceLayout as Ce,resolveLogDir as we,resolveStateDir as z,saveRegistry as Te}from"../../core/dist/index.js";import{createHash as B,randomUUID as Ee}from"node:crypto";import{LRUCache as De}from"lru-cache";import{encode as Oe}from"gpt-tokenizer/model/gpt-4o";import{createTwoFilesPatch as ke}from"diff";import{DEFAULT_ROUTES as Ae}from"../../tool-routing/dist/index.
|
|
1
|
+
import{mkdir as e,readFile as t,readdir as n,rm as r,stat as i,writeFile as a}from"node:fs/promises";import{basename as o,dirname as s,extname as c,isAbsolute as l,join as u,relative as d,resolve as f,sep as p}from"node:path";import{DependencyAnalyzer as m,DiagramGenerator as h,EntryPointAnalyzer as g,PatternAnalyzer as _,StructureAnalyzer as v,SymbolAnalyzer as y,extractRegexCallGraph as b,extractTsCallGraph as x}from"../../analyzers/dist/index.js";import{exec as S,execFile as C,execFileSync as w,spawn as ee}from"node:child_process";import{promisify as T}from"node:util";import{SUPPORTED_EXTENSIONS as E,WasmRuntime as D,extractCalls as O,extractImports as k,extractSymbols as A,resolveScopes as te}from"../../chunker/dist/index.js";import{appendFileSync as j,copyFileSync as ne,cpSync as re,existsSync as M,mkdirSync as N,readFileSync as P,readdirSync as F,renameSync as I,rmSync as ie,statSync as L,unlinkSync as ae,watch as oe,writeFileSync as R}from"node:fs";import{arch as se,cpus as ce,freemem as le,homedir as ue,hostname as de,platform as fe,release as pe,totalmem as me,type as he}from"node:os";import{AIKIT_PATHS as ge,AIKIT_RUNTIME_PATHS as _e,computePartitionKey as ve,createLogger as ye,getGlobalDataDir as be,getWorkspacePartitionDir as xe,loadRegistry as Se,migrateLegacyWorkspaceLayout as Ce,resolveLogDir as we,resolveStateDir as z,saveRegistry as Te}from"../../core/dist/index.js";import{createHash as B,randomUUID as Ee}from"node:crypto";import{LRUCache as De}from"lru-cache";import{encode as Oe}from"gpt-tokenizer/model/gpt-4o";import{createTwoFilesPatch as ke}from"diff";import{DEFAULT_ROUTES as Ae}from"../../tool-routing/dist/index.mjs";import{request as je}from"node:http";import Me from"node:vm";import{lookup as Ne}from"node:dns/promises";import{isIP as Pe}from"node:net";import Fe from"turndown";function Ie(e){let t=[];for(let n of e.matchAll(/^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm))t.push({file:n[1],line:Number.parseInt(n[2],10),column:Number.parseInt(n[3],10),severity:n[4],code:n[5],message:n[6]});if(t.length===0)for(let n of e.matchAll(/^(.+?):(\d+):(\d+)\s+-\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm))t.push({file:n[1],line:Number.parseInt(n[2],10),column:Number.parseInt(n[3],10),severity:n[4],code:n[5],message:n[6]});return t}function Le(e){return e.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g,``)}function Re(e){let t=Le(e),n=[];for(let e of t.matchAll(/^\s*([✓✕×-])\s+(.+?)(?:\s+(\d+)ms)?$/gm)){let t=e[1],r=t===`✓`?`pass`:t===`-`?`skip`:`fail`;n.push({name:e[2].trim(),status:r,duration:e[3]?Number.parseInt(e[3],10):void 0})}for(let e of t.matchAll(/^\s*([✓✕×])\s+(\S+\.test\.\w+)\s+\((\d+)\s+tests?\)\s*(\d+ms)?$/gm)){let t=e[1]===`✓`?`pass`:`fail`;n.push({name:e[2],file:e[2],status:t,duration:e[4]?Number.parseInt(e[4],10):void 0})}let r=/Tests\s+(?:(\d+)\s+passed)?(?:\s*\|\s*)?(?:(\d+)\s+failed)?(?:\s*\|\s*)?(?:(\d+)\s+skipped)?\s*\((\d+)\)/.exec(t),i=r?Number.parseInt(r[1]??`0`,10):n.filter(e=>e.status===`pass`).length,a=r?Number.parseInt(r[2]??`0`,10):n.filter(e=>e.status===`fail`).length,o=r?Number.parseInt(r[3]??`0`,10):n.filter(e=>e.status===`skip`).length,s=/Duration\s+(\d+(?:\.\d+)?)(?:ms|s)/.exec(t),c=s?s[0].includes(`s`)&&!s[0].includes(`ms`)?Number.parseFloat(s[1])*1e3:Number.parseFloat(s[1]):void 0,l=/Test Files\s+(\d+)\s+passed/.exec(t);return{tests:n,passed:i,failed:a,skipped:o,duration:c,suites:l?Number.parseInt(l[1],10):void 0}}function ze(e){let t=[];for(let n of e.matchAll(/^(.+?):(\d+):(\d+)\s+([\w/]+)\s+━+$/gm)){let r=n[1],i=Number.parseInt(n[2],10),a=Number.parseInt(n[3],10),o=n[4],s=e.slice((n.index??0)+n[0].length,(n.index??0)+n[0].length+500),c=/^\s*[×!i]\s+(.+)$/m.exec(s),l=c?c[1].trim():o,u=o.includes(`lint`)?`warning`:`error`;t.push({file:r,line:i,column:a,severity:u,code:o,message:l})}return t}function Be(e){let t=[],n=[],r=[],i;for(let a of e.split(`
|
|
2
2
|
`)){if(!a)continue;if(a.startsWith(`## `)){i=a.slice(3).split(`...`)[0];continue}let e=a[0],o=a[1],s=a.slice(3).trim();e===`?`&&o===`?`?r.push(s):(e!==` `&&e!==`?`&&t.push({status:Ve(e),file:s}),o!==` `&&o!==`?`&&n.push({status:Ve(o),file:s}))}return{staged:t,unstaged:n,untracked:r,branch:i}}function Ve(e){return{M:`modified`,A:`added`,D:`deleted`,R:`renamed`,C:`copied`,U:`unmerged`}[e]??e}function He(e,t){let n=t??Ue(e);switch(n){case`tsc`:return{tool:`tsc`,errors:Ie(e)};case`vitest`:return{tool:`vitest`,summary:Re(e)};case`biome`:return{tool:`biome`,errors:ze(e)};case`git-status`:return{tool:`git-status`,status:Be(e)};default:throw Error(`Unknown tool: ${n}. Supported: tsc, vitest, biome, git-status`)}}function Ue(e){return e.includes(`error TS`)||/\(\d+,\d+\):\s+error/.test(e)?`tsc`:e.includes(`vitest`)||e.includes(`Test Files`)||e.includes(`✓`)?`vitest`:e.includes(`biome`)||/\w+\/\w+\s+━+/.test(e)?`biome`:/^##\s/.test(e)||/^[MADRCU?! ]{2}\s/.test(e)?`git-status`:`unknown`}const We=T(S);let Ge=0;function Ke(e){let t=e;return[t.stdout?.toString()??``,t.stderr?.toString()??``].filter(Boolean).join(`
|
|
3
3
|
`).trim()||t.message||`Command failed`}async function qe(e={}){if(Ge>=2)throw Error(`Too many concurrent check runs (max 2). Try again later.`);Ge++;try{return await Je(e)}finally{Ge--}}async function Je(e){let n=e.cwd??process.cwd(),r={errors:[],passed:!0,raw:``},i={errors:[],passed:!0,raw:``};if(!e.skipTypes)try{let r=u(n,`package.json`),i=!1;try{i=!!JSON.parse(await t(r,`utf-8`)).scripts?.typecheck}catch{}if(i&&!e.files?.length)await We(`npx turbo run typecheck`,{cwd:n,timeout:12e4});else{let t=[`--noEmit`];e.files?.length&&t.push(...e.files),await We(`npx tsc ${t.join(` `)}`,{cwd:n,timeout:12e4})}}catch(e){r.raw=Ke(e),r.errors=Ie(r.raw),r.passed=r.errors.length===0}if(!e.skipLint)try{let t=[`check`];e.files?.length&&t.push(...e.files),await We(`npx biome ${t.join(` `)}`,{cwd:n,timeout:12e4})}catch(e){i.raw=Ke(e),i.errors=ze(i.raw),i.passed=i.errors.length===0}let a=e.detail??`normal`,o={tsc:r,biome:i,passed:r.passed&&i.passed};return a===`full`?o:{tsc:{errors:r.errors,passed:r.passed},biome:{errors:i.errors,passed:i.passed},passed:o.passed}}function Ye(e){let t=e.tsc.errors.filter(e=>e.severity===`error`),n=e.tsc.errors.filter(e=>e.severity===`warning`),r=e.biome.errors.filter(e=>e.severity===`error`),i=e.biome.errors.filter(e=>e.severity===`warning`);return{passed:e.passed,tsc:{passed:e.tsc.passed,errorCount:t.length,warningCount:n.length,topErrors:t.slice(0,3).map(e=>`${e.file}:${e.line} — ${e.message}`)},biome:{passed:e.biome.passed,errorCount:r.length,warningCount:i.length,topErrors:r.slice(0,3).map(e=>`${e.file}:${e.line} — ${e.message}`)}}}function Xe(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const Ze=new Set([`.md`,`.mdx`]);async function Qe(e,n,r={}){let{rootPath:i,limit:a=100}=r,o=await e.embed(`export function class const type interface enum`),s=await n.search(o,{limit:a*3}),l=/^export\s+(?:async\s+)?(?:function|class|const|let|interface|type|enum)\s+(\w+)/gm,u=[],d=new Map;for(let e of s){if(!$e(e.record.sourcePath,i))continue;let t=d.get(e.record.sourcePath)??[];t.push(e),d.set(e.record.sourcePath,t)}let f=new Set;if(D.get())for(let[e]of d){let n=c(e);if(E.has(n))try{let r=await A(await t(e,`utf-8`),n,e);for(let t of r)t.exported&&u.push({name:t.name,path:e,line:t.line,kind:t.kind});f.add(e)}catch{}}for(let[e,t]of d)if(!f.has(e))for(let e of t){let t=e.record.content;l.lastIndex=0;for(let n of t.matchAll(l)){let r=n.index??0,i=t.slice(0,r).split(`
|
|
4
4
|
`).length-1,a=t.slice(r).match(/export\s+(?:async\s+)?(\w+)/);u.push({name:n[1],path:e.record.sourcePath,line:e.record.startLine+i,kind:a?.[1]??`unknown`})}}let p=new Map;for(let e of u){let t=`${e.path}:${e.name}`;p.has(t)||p.set(t,e)}let m=[];for(let e of p.values()){let t=Xe(e.name),r=RegExp(`import\\s+.*\\b${t}\\b.*from`,`m`),i=RegExp(`export\\s+\\{[^}]*\\b${t}\\b`,`m`),a=await n.ftsSearch(`import ${e.name}`,{limit:10}),o=a.some(t=>t.record.sourcePath!==e.path&&r.test(t.record.content)),s=a.some(t=>t.record.sourcePath!==e.path&&i.test(t.record.content));!o&&!s&&m.push(e)}let h=(e,t)=>e.path===t.path?e.line-t.line:e.path.localeCompare(t.path),g=[],_=[];for(let e of m){let t=c(e.path).toLowerCase();Ze.has(t)?_.push(e):g.push(e)}return g.sort(h),_.sort(h),{deadInSource:g,deadInDocs:_,totalExports:p.size,totalDeadSource:g.length,totalDeadDocs:_.length}}function $e(e,t){if(!t)return!0;let n=et(t).replace(/\/+$/,``),r=et(e);return r===n||r.startsWith(`${n}/`)}function et(e){return e.replace(/\\/g,`/`).replace(/^\.\//,``)}function tt(e){let t=f(e??process.cwd()),n=[],r=u(t,`package.json`);if(M(r)){n.push({name:`package.json`,status:`pass`,message:`Found`});try{let e=JSON.parse(P(r,`utf-8`));e.name?n.push({name:`package.name`,status:`pass`,message:e.name}):n.push({name:`package.name`,status:`warn`,message:`Missing package name`});let t=e.scripts??{};for(let e of[`build`,`test`,`lint`])t[e]?n.push({name:`script:${e}`,status:`pass`,message:t[e]}):n.push({name:`script:${e}`,status:`warn`,message:`No "${e}" script defined`});e.type===`module`?n.push({name:`esm`,status:`pass`,message:`ESM ("type": "module")`}):e.type===`commonjs`?n.push({name:`esm`,status:`pass`,message:`CJS ("type": "commonjs")`}):n.push({name:`esm`,status:`warn`,message:`No "type" field — defaults to CJS`}),e.engines?.node?n.push({name:`engines.node`,status:`pass`,message:e.engines.node}):n.push({name:`engines.node`,status:`warn`,message:`No Node.js engine constraint`})}catch{n.push({name:`package.json`,status:`fail`,message:`Failed to parse package.json`})}}else n.push({name:`package.json`,status:`fail`,message:`Missing — not a Node.js project`});let i=u(t,`tsconfig.json`);M(i)?n.push({name:`tsconfig.json`,status:`pass`,message:`Found`}):n.push({name:`tsconfig.json`,status:`warn`,message:`Missing`});let a=u(t,`.gitignore`);if(M(a)){let e=P(a,`utf-8`),t=e.includes(`node_modules`),r=e.includes(`dist`);t&&r?n.push({name:`.gitignore`,status:`pass`,message:`Includes node_modules and dist`}):n.push({name:`.gitignore`,status:`warn`,message:`Missing: ${t?``:`node_modules `}${r?``:`dist`}`.trim()})}else n.push({name:`.gitignore`,status:`warn`,message:`Missing`});let o=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`].find(e=>M(u(t,e)));o?n.push({name:`lockfile`,status:`pass`,message:o}):n.push({name:`lockfile`,status:`warn`,message:`No lock file found`});let s=u(t,`README.md`);if(M(s)){let e=P(s,`utf-8`).length;n.push({name:`README.md`,status:e>100?`pass`:`warn`,message:e>100?`Found (${e} chars)`:`Found but very short`})}else n.push({name:`README.md`,status:`warn`,message:`Missing`});if(M(u(t,`LICENSE`))||M(u(t,`LICENSE.md`))?n.push({name:`LICENSE`,status:`pass`,message:`Found`}):n.push({name:`LICENSE`,status:`warn`,message:`Missing`}),M(i))try{let e=P(i,`utf-8`).replace(/\/\/.*$/gm,``).replace(/\/\*[\s\S]*?\*\//g,``);JSON.parse(e).compilerOptions?.strict===!0?n.push({name:`typescript.strict`,status:`pass`,message:`strict: true`}):n.push({name:`typescript.strict`,status:`warn`,message:`strict mode not enabled in tsconfig.json`})}catch{}if(M(r))try{let e=JSON.parse(P(r,`utf-8`));e.exports?n.push({name:`package.exports`,status:`pass`,message:`Has exports field`}):e.workspaces||M(u(t,`pnpm-workspace.yaml`))||n.push({name:`package.exports`,status:`warn`,message:`Missing — consider adding exports field for explicit public API`});let i=nt(t,e);i.length>0&&rt(t,i,n)}catch{}let c=u(t,`dist`),l=u(t,`src`);if(M(c)&&M(l))try{let e=L(c).mtimeMs;it(l)>e?n.push({name:`build.freshness`,status:`warn`,message:`Source files are newer than dist/ — rebuild may be needed`}):n.push({name:`build.freshness`,status:`pass`,message:`Build output is fresh`})}catch{}if(M(l)){let e=st(l);if(e.length===0)n.push({name:`circular_deps`,status:`pass`,message:`No circular imports detected`});else{let t=e.slice(0,3).map(e=>e.join(` → `));n.push({name:`circular_deps`,status:`warn`,message:`${e.length} circular import(s): ${t.join(`; `)}${e.length>3?` (+${e.length-3} more)`:``}`})}}let d=n.length,p=n.filter(e=>e.status===`pass`).length,m=n.filter(e=>e.status===`fail`).length;return{path:t,checks:n,score:d>0?Math.round(p/d*100):0,summary:m>0?`${m} critical issue(s), ${d-p-m} warning(s)`:d-p>0?`${d-p} warning(s)`:`All checks passed`}}function nt(e,t){let n=[];Array.isArray(t.workspaces)?n.push(...t.workspaces):t.workspaces&&typeof t.workspaces==`object`&&Array.isArray(t.workspaces.packages)&&n.push(...t.workspaces.packages);let r=u(e,`pnpm-workspace.yaml`);if(M(r)){let e=P(r,`utf-8`);for(let t of e.split(`
|