@vpxa/aikit 0.1.111 → 0.1.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.111",
3
+ "version": "0.1.112",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- import{t as e}from"./curated-manager-CXSPygmJ.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-BL-I_FFY.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-OaSHcA6x.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-BnPh8aSm.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`);g=new e(s.aikit.indexer,l,s.aikit.store),g.start(),s.setSmartScheduler(g),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-BL-I_FFY.js`),import(`./server-BnPh8aSm.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(()=>{d.info(`Auto-shutdown: no activity for 30 minutes — exiting`),process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`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);t.start(),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
1
+ import{t as e}from"./curated-manager-CXSPygmJ.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-BL-I_FFY.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-OaSHcA6x.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-BzPxuGzZ.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`);g=new e(s.aikit.indexer,l,s.aikit.store),g.start(),s.setSmartScheduler(g),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-BL-I_FFY.js`),import(`./server-BzPxuGzZ.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(()=>{d.info(`Auto-shutdown: no activity for 30 minutes — exiting`),process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`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);t.start(),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
@@ -1246,7 +1246,7 @@ Use \`status({})\` to check smart indexing queue status.`}]};let l=xa(c).createT
1246
1246
 
1247
1247
  `)}`}]}}catch(e){return ou.error(`Replay failed`,j(e)),U(`INTERNAL`,`Replay failed: ${e instanceof Error?e.message:String(e)}`)}})}const cu=D(`tools`);function lu(e){let t=B(`restore`);e.registerTool(`restore`,{title:t.title,description:`List and restore file snapshots taken before destructive operations (codemod, rename, forget). Use action=list to see available restore points, action=restore with an id to undo.`,inputSchema:{action:I.enum([`list`,`restore`]).describe(`list: show restore points, restore: apply a restore point`),id:I.string().optional().describe(`Restore point ID (required for action=restore)`),limit:I.number().min(1).max(50).default(10).describe(`Max restore points to list`)},annotations:t.annotations},async({action:e,id:t,limit:n})=>{try{if(e===`list`){let e=Je().slice(0,n);return e.length===0?{content:[{type:`text`,text:`No restore points found.`}]}:{content:[{type:`text`,text:`## Restore Points\n\n${e.map(e=>`- **${e.id}** (${e.timestamp}) — ${e.operation}: ${e.description} (${e.files.length} files)`).join(`
1248
1248
  `)}`}]}}if(!t)throw Error(`id is required for restore action`);let r=await St(t);return{content:[{type:`text`,text:`Restored ${r.length} files:\n${r.map(e=>`- \`${e}\``).join(`
1249
- `)}`}]}}catch(e){return cu.error(`Restore failed`,j(e)),U(`INTERNAL`,`Restore failed: ${e instanceof Error?e.message:String(e)}`)}})}const uu=/<\/?curated-context>/gi;function du(e){return e.replace(uu,``)}function fu(e){return`<curated-context>\n${du(e)}\n</curated-context>`}const pu=D(`tools`);function mu(e){let t=[],n=p(process.cwd());n&&t.push(`[project: ${n}]`);let r=At(`__context_boost`);return r&&t.push(`[focus: ${r.value}]`),t.length===0?e:`${t.join(` `)} ${e}`}async function hu(e,t,n,r,i){if(!e||t>=e.config.fallbackThreshold&&n.length>0)return{results:n,triggered:!1,cacheHit:!1};let a=!1;try{let t=e.cache.get(r);return t?a=!0:(t=await e.client.search(r,i),t.length>0&&e.cache.set(r,t)),t.length>0?{results:mn(n,t,i).map(e=>({record:{id:`er:${e.sourcePath}`,content:e.content,sourcePath:e.source===`er`?`[ER] ${e.sourcePath}`:e.sourcePath,startLine:e.startLine??0,endLine:e.endLine??0,contentType:e.contentType??`documentation`,headingPath:e.headingPath,origin:e.source===`er`?`curated`:e.origin??`indexed`,category:e.category,tags:e.tags??[],chunkIndex:0,totalChunks:1,fileHash:``,indexedAt:new Date().toISOString(),version:1},score:e.score})),triggered:!0,cacheHit:a}:{results:n,triggered:!0,cacheHit:a}}catch(e){return pu.warn(`ER fallback failed`,j(e)),{results:n,triggered:!0,cacheHit:a}}}function gu(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score).map(({record:e,score:t})=>({record:e,score:t}))}function _u(e,t){let n=t.toLowerCase().split(/\s+/).filter(e=>e.length>=2);return n.length<2?e:e.map(e=>{let t=e.record.content.toLowerCase();if(t.length>5e3)return e;let r=n.map(e=>{let n=[],r=t.indexOf(e);for(;r!==-1&&n.length<10;)n.push(r),r=t.indexOf(e,r+1);return n});if(r.some(e=>e.length===0))return e;let i=t.length;for(let e of r[0]){let t=e,a=e+n[0].length;for(let i=1;i<r.length;i++){let o=r[i][0],s=Math.abs(o-e);for(let t=1;t<r[i].length;t++){let n=Math.abs(r[i][t]-e);n<s&&(s=n,o=r[i][t])}t=Math.min(t,o),a=Math.max(a,o+n[i].length)}i=Math.min(i,a-t)}let a=1+.25/(1+i/200);return{record:e.record,score:e.score*a}}).sort((e,t)=>t.score-e.score)}function vu(e,t,n=8){let r=new Set(t.toLowerCase().split(/\s+/).filter(e=>e.length>=2)),i=new Map,a=e.length;for(let t of e){let e=t.record.content.split(/[^a-zA-Z0-9_]+/).filter(e=>e.length>=3&&!yu.has(e.toLowerCase())),n=new Set;for(let t of e){let e=t.toLowerCase();/[_A-Z]/.test(t)&&i.set(`__id__${e}`,1),n.has(e)||(n.add(e),i.set(e,(i.get(e)??0)+1))}}let o=[];for(let[e,t]of i){if(e.startsWith(`__id__`)||r.has(e)||t>a*.8)continue;let n=Math.log(a/t),s=+!!i.has(`__id__${e}`),c=e.length>8?.5:0;o.push({term:e,score:n+s+c})}return o.sort((e,t)=>t.score-e.score).slice(0,n).map(e=>e.term)}const yu=new Set(`the.and.for.are.but.not.you.all.can.had.her.was.one.our.out.has.have.from.this.that.with.they.been.said.each.which.their.will.other.about.many.then.them.these.some.would.make.like.into.could.time.very.when.come.just.know.take.people.also.back.after.only.more.than.over.such.import.export.const.function.return.true.false.null.undefined.string.number.boolean.void.type.interface`.split(`.`));async function bu(e,t){try{let n=await e.getStats();if(!n.lastIndexedAt)return;let r=new Date(n.lastIndexedAt).getTime(),i=Date.now(),a=[...new Set(t.map(e=>e.record.sourcePath))].filter(e=>!e.startsWith(`[ER]`)).slice(0,5);if(a.length===0)return;let o=0;for(let e of a)try{(await Kt(e)).mtimeMs>r&&o++}catch{o++}if(o>0){let e=i-r,t=Math.floor(e/6e4),n=t<1?`<1 min`:`${t} min`;return`> ⚠️ **Index may be stale** — ${o} file(s) modified since last index (${n} ago). Use \`reindex\` to refresh.`}}catch{}}function xu(e,t,n,r,i,a,o){let s=B(`search`);e.registerTool(`search`,{title:s.title,description:`Search AI Kit for code, docs, and prior decisions. Default choice for discovery. Modes: hybrid (default), semantic, keyword. For multi-strategy precision queries use find; for a known file path use lookup.`,outputSchema:xi,inputSchema:{query:I.string().max(5e3).describe(`Natural language search query`),limit:I.number().min(1).max(20).default(5).describe(`Maximum results to return`),search_mode:I.enum([`hybrid`,`semantic`,`keyword`]).default(`hybrid`).describe(`Search strategy: hybrid (vector + FTS + RRF fusion, default), semantic (vector only), keyword (FTS only)`),content_type:I.enum(b).optional().describe(`Filter by content type`),source_type:I.enum(C).optional().describe(`Coarse filter: "source" (code only), "documentation" (md, curated), "test", "config". Overrides content_type if both set.`),origin:I.enum(S).optional().describe(`Filter by knowledge origin`),category:I.string().optional().describe(`Filter by category (e.g., decisions, patterns, conventions)`),tags:I.array(I.string()).optional().describe(`Filter by tags (returns results matching ANY of the specified tags)`),min_score:I.number().min(0).max(1).default(.25).describe(`Minimum similarity score`),graph_hops:I.number().min(0).max(3).default(1).describe(`Number of graph hops to augment results with connected entities (0 = disabled, 1 = direct connections, 2-3 = deeper traversal). Default 1 provides module/symbol context automatically.`),max_tokens:I.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),dedup:I.enum([`file`,`chunk`]).default(`chunk`).describe(`Deduplication mode: "chunk" (default, show all matching chunks) or "file" (collapse chunks from same file into single result with merged line ranges)`),workspaces:I.array(I.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all registered workspaces. Only works in user-level install mode.`)},annotations:s.annotations},async({query:e,limit:s,search_mode:c,content_type:l,source_type:u,origin:d,category:f,tags:p,min_score:m,graph_hops:h,max_tokens:g,dedup:_,workspaces:v})=>{try{let y={limit:s,minScore:m,contentType:l,sourceType:u,origin:d,category:f,tags:p},b,x=!1,S=!1,C=``,w=mu(e);if(c===`keyword`)b=await n.ftsSearch(e,y),b=b.slice(0,s);else if(c===`semantic`){let r=await t.embedQuery(w);b=await n.search(r,y);let a=await hu(i,b[0]?.score??0,b,e,s);b=a.results,x=a.triggered,S=a.cacheHit}else{let r=await t.embedQuery(w),[a,o]=await Promise.all([n.search(r,{...y,limit:s*2}),n.ftsSearch(e,{...y,limit:s*2}).catch(()=>[])]);b=gu(a,o).slice(0,s);let c=await hu(i,a[0]?.score??0,b,e,s);b=c.results,x=c.triggered,S=c.cacheHit}a&&a.recordSearch(e,x,S),b.length>1&&(b=_u(b,e));let T=``;if(v&&v.length>0){let n=ao(v,E(process.cwd()));if(n.length>0){let{stores:r,closeAll:i}=await oo(n);try{let i;i=c===`keyword`?await co(r,e,{...y,limit:s}):await so(r,await t.embedQuery(e),{...y,limit:s});for(let e of i)b.push({record:{...e.record,sourcePath:`[${e.workspace}] ${e.record.sourcePath}`},score:e.score});b=b.sort((e,t)=>t.score-e.score).slice(0,s),T=` + ${n.length} workspace(s)`}finally{await i()}}}if(_===`file`&&b.length>1){let e=new Map;for(let t of b){let n=t.record.sourcePath,r=e.get(n);r?(t.score>r.best.score&&(r.best=t),r.ranges.push({start:t.record.startLine,end:t.record.endLine})):e.set(n,{best:t,ranges:[{start:t.record.startLine,end:t.record.endLine}]})}b=[...e.values()].sort((e,t)=>t.best.score-e.best.score).map(({best:e,ranges:t})=>({record:{...e.record,content:t.length>1?`${e.record.content}\n\n_Matched ${t.length} sections: ${t.sort((e,t)=>e.start-t.start).map(e=>`L${e.start}-${e.end}`).join(`, `)}_`:e.record.content},score:e.score}))}if(b.length===0){if(o?.available)try{let r=(await o.createMessage({prompt:`The search query "${e}" returned 0 results in AI Kit code search. Suggest ONE alternative search query that might find relevant results. Reply with ONLY the alternative query, nothing else.`,systemPrompt:`You are a search query optimizer for AI Kit code search. Generate a single alternative query.`,maxTokens:100})).text.trim().split(`
1249
+ `)}`}]}}catch(e){return cu.error(`Restore failed`,j(e)),U(`INTERNAL`,`Restore failed: ${e instanceof Error?e.message:String(e)}`)}})}const uu=/<\/?curated-context>/gi;function du(e){return e.replace(uu,``)}function fu(e){return`<curated-context>\n${du(e)}\n</curated-context>`}const pu=D(`tools`);function mu(e){let t=[],n=p(process.cwd());n&&t.push(`[project: ${n}]`);let r=At(`__context_boost`);return r&&t.push(`[focus: ${r.value}]`),t.length===0?e:`${t.join(` `)} ${e}`}async function hu(e,t,n,r,i){if(!e||t>=e.config.fallbackThreshold&&n.length>0)return{results:n,triggered:!1,cacheHit:!1};let a=!1;try{let t=e.cache.get(r);return t?a=!0:(t=await e.client.search(r,i),t.length>0&&e.cache.set(r,t)),t.length>0?{results:mn(n,t,i).map(e=>({record:{id:`er:${e.sourcePath}`,content:e.content,sourcePath:e.source===`er`?`[ER] ${e.sourcePath}`:e.sourcePath,startLine:e.startLine??0,endLine:e.endLine??0,contentType:e.contentType??`documentation`,headingPath:e.headingPath,origin:e.source===`er`?`curated`:e.origin??`indexed`,category:e.category,tags:e.tags??[],chunkIndex:0,totalChunks:1,fileHash:``,indexedAt:new Date().toISOString(),version:1},score:e.score})),triggered:!0,cacheHit:a}:{results:n,triggered:!0,cacheHit:a}}catch(e){return pu.warn(`ER fallback failed`,j(e)),{results:n,triggered:!0,cacheHit:a}}}function gu(e,t,n=60){let r=new Map,i=e[0]?.score||1,a=t[0]?.score||1;for(let t=0;t<e.length;t++){let a=e[t],o=a.score/i;r.set(a.record.id,{record:a.record,score:1/(n+t+1)*o})}for(let e=0;e<t.length;e++){let i=t[e],o=i.score/a,s=r.get(i.record.id);s?s.score+=1/(n+e+1)*o:r.set(i.record.id,{record:i.record,score:1/(n+e+1)*o})}return[...r.values()].sort((e,t)=>t.score-e.score).map(({record:e,score:t})=>({record:e,score:t}))}function _u(e,t){let n=t.toLowerCase().split(/\s+/).filter(e=>e.length>=2);return n.length<2?e:e.map(e=>{let t=e.record.content.toLowerCase();if(t.length>5e3)return e;let r=n.map(e=>{let n=[],r=t.indexOf(e);for(;r!==-1&&n.length<10;)n.push(r),r=t.indexOf(e,r+1);return n});if(r.some(e=>e.length===0))return e;let i=t.length;for(let e of r[0]){let t=e,a=e+n[0].length;for(let i=1;i<r.length;i++){let o=r[i][0],s=Math.abs(o-e);for(let t=1;t<r[i].length;t++){let n=Math.abs(r[i][t]-e);n<s&&(s=n,o=r[i][t])}t=Math.min(t,o),a=Math.max(a,o+n[i].length)}i=Math.min(i,a-t)}let a=1+.25/(1+i/200);return{record:e.record,score:e.score*a}}).sort((e,t)=>t.score-e.score)}function vu(e){if(e.length<=1)return e;let t=new Set;return e.filter(e=>{let n=e.record.contentHash;return n?t.has(n)?!1:(t.add(n),!0):!0})}function yu(e,t,n=8){let r=new Set(t.toLowerCase().split(/\s+/).filter(e=>e.length>=2)),i=new Map,a=e.length;for(let t of e){let e=t.record.content.split(/[^a-zA-Z0-9_]+/).filter(e=>e.length>=3&&!bu.has(e.toLowerCase())),n=new Set;for(let t of e){let e=t.toLowerCase();/[_A-Z]/.test(t)&&i.set(`__id__${e}`,1),n.has(e)||(n.add(e),i.set(e,(i.get(e)??0)+1))}}let o=[];for(let[e,t]of i){if(e.startsWith(`__id__`)||r.has(e)||t>a*.8)continue;let n=Math.log(a/t),s=+!!i.has(`__id__${e}`),c=e.length>8?.5:0;o.push({term:e,score:n+s+c})}return o.sort((e,t)=>t.score-e.score).slice(0,n).map(e=>e.term)}const bu=new Set(`the.and.for.are.but.not.you.all.can.had.her.was.one.our.out.has.have.from.this.that.with.they.been.said.each.which.their.will.other.about.many.then.them.these.some.would.make.like.into.could.time.very.when.come.just.know.take.people.also.back.after.only.more.than.over.such.import.export.const.function.return.true.false.null.undefined.string.number.boolean.void.type.interface`.split(`.`));async function xu(e,t){try{let n=await e.getStats();if(!n.lastIndexedAt)return;let r=new Date(n.lastIndexedAt).getTime(),i=Date.now(),a=[...new Set(t.map(e=>e.record.sourcePath))].filter(e=>!e.startsWith(`[ER]`)).slice(0,5);if(a.length===0)return;let o=0;for(let e of a)try{(await Kt(e)).mtimeMs>r&&o++}catch{o++}if(o>0){let e=i-r,t=Math.floor(e/6e4),n=t<1?`<1 min`:`${t} min`;return`> ⚠️ **Index may be stale** — ${o} file(s) modified since last index (${n} ago). Use \`reindex\` to refresh.`}}catch{}}function Su(e,t,n,r,i,a,o){let s=B(`search`);e.registerTool(`search`,{title:s.title,description:`Search AI Kit for code, docs, and prior decisions. Default choice for discovery. Modes: hybrid (default), semantic, keyword. For multi-strategy precision queries use find; for a known file path use lookup.`,outputSchema:xi,inputSchema:{query:I.string().max(5e3).describe(`Natural language search query`),limit:I.number().min(1).max(20).default(5).describe(`Maximum results to return`),search_mode:I.enum([`hybrid`,`semantic`,`keyword`]).default(`hybrid`).describe(`Search strategy: hybrid (vector + FTS + RRF fusion, default), semantic (vector only), keyword (FTS only)`),content_type:I.enum(b).optional().describe(`Filter by content type`),source_type:I.enum(C).optional().describe(`Coarse filter: "source" (code only), "documentation" (md, curated), "test", "config". Overrides content_type if both set.`),origin:I.enum(S).optional().describe(`Filter by knowledge origin`),category:I.string().optional().describe(`Filter by category (e.g., decisions, patterns, conventions)`),tags:I.array(I.string()).optional().describe(`Filter by tags (returns results matching ANY of the specified tags)`),min_score:I.number().min(0).max(1).default(.25).describe(`Minimum similarity score`),graph_hops:I.number().min(0).max(3).default(1).describe(`Number of graph hops to augment results with connected entities (0 = disabled, 1 = direct connections, 2-3 = deeper traversal). Default 1 provides module/symbol context automatically.`),max_tokens:I.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),dedup:I.enum([`file`,`chunk`]).default(`chunk`).describe(`Deduplication mode: "chunk" (default, show all matching chunks) or "file" (collapse chunks from same file into single result with merged line ranges)`),workspaces:I.array(I.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all registered workspaces. Only works in user-level install mode.`)},annotations:s.annotations},async({query:e,limit:s,search_mode:c,content_type:l,source_type:u,origin:d,category:f,tags:p,min_score:m,graph_hops:h,max_tokens:g,dedup:_,workspaces:v})=>{try{let y={limit:s,minScore:m,contentType:l,sourceType:u,origin:d,category:f,tags:p},b,x=!1,S=!1,C=``,w=mu(e);if(c===`keyword`)b=await n.ftsSearch(e,y),b=b.slice(0,s);else if(c===`semantic`){let r=await t.embedQuery(w);b=await n.search(r,y);let a=await hu(i,b[0]?.score??0,b,e,s);b=a.results,x=a.triggered,S=a.cacheHit}else{let r=await t.embedQuery(w),a=n.coarseSearch,o=a?a.bind(n):n.search.bind(n),[c,l]=await Promise.all([o(r,{...y,limit:s*2}),n.ftsSearch(e,{...y,limit:s*2}).catch(()=>[])]);c.length===0&&l.length>0?(b=l.slice(0,s),C=` (FTS-only: vector index rebuilding)`):b=l.length===0&&c.length>0?c.slice(0,s):gu(c,l).slice(0,s);let u=await hu(i,c[0]?.score??0,b,e,s);b=u.results,x=u.triggered,S=u.cacheHit}a&&a.recordSearch(e,x,S),b.length>1&&(b=_u(b,e)),b=vu(b);let T=``;if(v&&v.length>0){let n=ao(v,E(process.cwd()));if(n.length>0){let{stores:r,closeAll:i}=await oo(n);try{let i;i=c===`keyword`?await co(r,e,{...y,limit:s}):await so(r,await t.embedQuery(e),{...y,limit:s});for(let e of i)b.push({record:{...e.record,sourcePath:`[${e.workspace}] ${e.record.sourcePath}`},score:e.score});b=b.sort((e,t)=>t.score-e.score).slice(0,s),T=` + ${n.length} workspace(s)`}finally{await i()}}}if(_===`file`&&b.length>1){let e=new Map;for(let t of b){let n=t.record.sourcePath,r=e.get(n);r?(t.score>r.best.score&&(r.best=t),r.ranges.push({start:t.record.startLine,end:t.record.endLine})):e.set(n,{best:t,ranges:[{start:t.record.startLine,end:t.record.endLine}]})}b=[...e.values()].sort((e,t)=>t.best.score-e.best.score).map(({best:e,ranges:t})=>({record:{...e.record,content:t.length>1?`${e.record.content}\n\n_Matched ${t.length} sections: ${t.sort((e,t)=>e.start-t.start).map(e=>`L${e.start}-${e.end}`).join(`, `)}_`:e.record.content},score:e.score}))}if(b.length>1){let e=b[0].score,t=Math.max(e*.4,.1);b=b.filter(e=>e.score>=t)}if(b.length===0){if(o?.available)try{let r=(await o.createMessage({prompt:`The search query "${e}" returned 0 results in AI Kit code search. Suggest ONE alternative search query that might find relevant results. Reply with ONLY the alternative query, nothing else.`,systemPrompt:`You are a search query optimizer for AI Kit code search. Generate a single alternative query.`,maxTokens:100})).text.trim().split(`
1250
1250
  `)[0].slice(0,500);if(r&&r!==e){let i=await t.embedQuery(r),a=await n.search(i,y);a.length>0&&(b=a,C=`> _Original query "${e}" returned 0 results. Auto-reformulated to "${r}"._\n\n`,pu.info(`Smart search fallback succeeded`,{originalQuery:e,altQuery:r,resultCount:a.length}))}}catch(e){pu.debug(`Smart search fallback failed`,{error:String(e)})}if(b.length===0)return{content:[{type:`text`,text:`No results found for the given query.`}],structuredContent:{results:[],totalResults:0,searchMode:c,query:e}}}let D,O;if(h>0&&!r&&(O="> **Note:** `graph_hops` was set but no graph store is available. Graph augmentation skipped."),h>0&&r)try{let e=await Ie(r,b.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:h,maxPerHit:5});D=new Map;for(let t of e)if(t.graphContext.nodes.length>0){let e=t.graphContext.nodes.slice(0,5).map(e=>` - **${e.name}** (${e.type})`).join(`
1251
1251
  `),n=t.graphContext.edges.slice(0,5).map(e=>` - ${e.fromId} —[${e.type}]→ ${e.toId}`).join(`
1252
1252
  `),r=[`- **Graph Context** (${h} hop${h>1?`s`:``}):`];e&&r.push(` Entities:\n${e}`),n&&r.push(` Relationships:\n${n}`),D.set(t.recordId,r.join(`
@@ -1255,23 +1255,23 @@ Use \`status({})\` to check smart indexing queue status.`}]};let l=xa(c).createT
1255
1255
 
1256
1256
  ---
1257
1257
 
1258
- `),A=(c===`hybrid`?`hybrid (vector + keyword RRF)`:c===`keyword`?`keyword (FTS)`:`semantic (vector)`)+T,M=vu(b,e),te=M.length>0?`\n_Distinctive terms: ${M.map(e=>`\`${e}\``).join(`, `)}_`:``,N=await bu(n,b),P=[];if(b.length===0)P.push("`reindex` — no results found, index may be stale"),P.push("`find` — try federated search with glob/regex");else{let e=b[0]?.record.sourcePath;e&&P.push(`\`lookup\` — see all chunks from \`${e}\``),P.push("`symbol` — resolve a specific symbol from the results"),P.push("`compact` — compress a result file for focused reading")}let ne=[O?`${O}\n\n`:``,N?`${N}\n\n`:``,ee,`\n\n---\n_Search mode: ${A} | ${b.length} results_${te}`,`\n_Next: ${P.join(` | `)}_`],re=C+ne.join(``);g&&(re=zt(re,g));let ae=new Set,oe=[];for(let e of b){if(e.record.origin!==`curated`||e.record.sourcePath.startsWith(`[`))continue;let t=Ts(e.record.sourcePath);if(!t)continue;let n=Cs(t,e.record.headingPath??t);n&&!ae.has(n.uri)&&(ae.add(n.uri),oe.push(n))}return{content:[{type:`text`,text:re},...oe],structuredContent:{results:b.map(e=>({sourcePath:e.record.sourcePath,contentType:e.record.contentType,score:e.score,...e.record.headingPath?{headingPath:e.record.headingPath}:{},...e.record.startLine?{startLine:e.record.startLine}:{},...e.record.endLine?{endLine:e.record.endLine}:{},...e.record.origin===`indexed`?{}:{origin:e.record.origin},...e.record.category?{category:e.record.category}:{},...e.record.tags?.length?{tags:e.record.tags}:{}})),totalResults:b.length,searchMode:c,query:e}}}catch(e){return pu.error(`Search failed`,j(e)),U(`INTERNAL`,`Search failed: ${e instanceof Error?e.message:String(e)}`)}})}const Su=D(`tools`);function Cu(e,t){let n=B(`session_digest`);e.registerTool(`session_digest`,{title:n.title,description:`Compress the current session's tool trajectory into a focused digest. Aggregates replay log, stash state, and checkpoints. Supports deterministic and LLM-assisted (sampling) modes with configurable token budget.`,inputSchema:{scope:I.enum([`tools`,`stash`,`all`]).default(`all`).describe(`What to include: tools (replay only), stash (stash + checkpoints only), or all`),since:I.string().optional().describe(`ISO timestamp — only include activity after this time`),last:I.number().min(1).max(500).optional().describe(`Max replay entries to consider (default: 50)`),focus:I.string().optional().describe(`Focus query — prioritize entries matching this topic`),mode:I.enum([`deterministic`,`sampling`]).default(`deterministic`).describe(`Summary mode: deterministic (fast, template-based) or sampling (LLM-assisted, richer)`),token_budget:I.number().min(100).max(8e3).default(2e3).describe(`Target token budget for the digest output`),persist:I.boolean().default(!0).describe(`Auto-save digest to stash for crash recovery`)},annotations:n.annotations},async({scope:e,since:n,last:r,focus:i,mode:a,token_budget:o,persist:s})=>{try{let c={scope:e,since:n,last:r,focus:i,mode:a,tokenBudget:o,persist:s};return{content:[{type:`text`,text:(a===`sampling`&&t?.available?await Dt(c,async(e,n,r)=>(await t.createMessage({prompt:e,systemPrompt:n,maxTokens:r})).text):Et(c)).digest}]}}catch(e){return Su.error(`Session digest failed`,j(e)),U(`INTERNAL`,`Session digest failed: ${e instanceof Error?e.message:String(e)}`)}})}const wu=D(`tools`);function Tu(e,t,n,r=15e3){let i,a=new Promise(e=>{i=setTimeout(()=>{wu.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),wu.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}const Eu=5*6e4;let Du=null,Ou=null;function ku(e,t,n,r){let i=Math.min(e/2e4,1),a=Math.min((t+n)/5e4,1),o=Math.min(r/200,1);return Math.round(i*40+a*35+o*25)}function Au(){let e=Date.now();if(Du&&e-Du.ts<Eu)return Du.value;try{let t=_(Cn(),`.copilot`,`.aikit-scaffold.json`);if(!a(t))return Du={value:null,ts:e},null;let n=JSON.parse(s(t,`utf-8`)).version??null;return Du={value:n,ts:e},n}catch{return Du={value:null,ts:e},null}}function ju(){let e=Date.now();if(Ou&&e-Ou.ts<Eu)return Ou.value;try{let t=_(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!a(t))return Ou={value:null,ts:e},null;let n=JSON.parse(s(t,`utf-8`)).version??null;return Ou={value:n,ts:e},n}catch{return Ou={value:null,ts:e},null}}function Mu(e){let t=B(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:fi,annotations:t.annotations},async()=>{let e=r(),t=Au(),a=ju(),o=t!=null&&t!==e,s=a!=null&&a!==e,c=[`## AI Kit Status`,``,`⏳ **AI Kit is initializing** — index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${sn.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${a??`not installed`}`];if(o||s){let r=i(),l=[];o&&l.push(`user scaffold v${t}`),s&&l.push(`workspace scaffold v${a}`);let u=l.join(`, `);r.state===`success`?c.push(``,`### ✅ Upgrade Applied`,`- Server v${e} — ${u} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):r.state===`pending`?c.push(``,`### ⏳ Upgrade In Progress`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade is running in the background…`):r.state===`failed`?(n(),c.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} ≠ ${u}`,`- Error: ${r.error??`unknown`}`)):(n(),c.push(``,`### ⬆ Upgrade Available`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade triggered — check again shortly.`))}let l={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!sn.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:a??null,upgradeAvailable:o||s,contextPressure:0};return{content:[{type:`text`,text:c.join(`
1259
- `)}],structuredContent:l}})}function Nu(e,t,o,s,c,l,u,f){let p=B(`status`);e.registerTool(`status`,{title:p.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:fi,annotations:p.annotations},async()=>{let e=[];try{let[p,m]=await Promise.all([Tu(t.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),Tu(t.listSourcePaths(),[],`store.listSourcePaths`)]),h=p.value;p.timedOut&&e.push(`⚠ Index stats timed out — values may be incomplete`);let g=m.value;m.timedOut&&e.push(`⚠ File listing timed out`);let v=null,b=0,x=[`## AI Kit Status`,``,`- **Total Records**: ${h.totalRecords}`,`- **Total Files**: ${h.totalFiles}`,`- **Last Indexed**: ${h.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(h.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...g.slice(0,50).map(e=>`- ${e}`),g.length>50?`\n... and ${g.length-50} more files`:``];if(o)try{let t=await Tu(o.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(t.timedOut)e.push(`⚠ Graph stats timed out`),x.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let e=t.value;v={nodes:e.nodeCount,edges:e.edgeCount},x.push(``,`### Knowledge Graph`,`- **Nodes**: ${e.nodeCount}`,`- **Edges**: ${e.edgeCount}`,...Object.entries(e.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await Tu(o.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||x.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&x.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{x.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let S=l?.onboardDir??_(process.cwd(),y.aiContext),C=a(S),w=c?.onboardComplete||C;if(x.push(``,`### Onboard Status`,w?`- ✅ Complete${c?.onboardTimestamp?` (last: ${c.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${S}\``),s)try{let t=await Tu(s.list(),[],`curated.list`);if(t.timedOut)e.push(`⚠ Curated knowledge listing timed out`),x.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let e=t.value;b=e.length,x.push(``,`### Curated Knowledge`,e.length>0?`- ${e.length} entries`:'- Empty — use `knowledge({ action: "remember", ... })` to persist decisions')}}catch{x.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let T=ku(h.totalRecords,v?.nodes??0,v?.edges??0,b);x.push(``),x.push(`## 📊 Context Pressure: ${T}/100`),T>=80?x.push(`⚠️ High pressure — consider pruning stale entries or compacting context.`):T>=50?x.push(`ℹ️ Moderate pressure — AI Kit memory is well-populated.`):x.push(`✅ Low pressure — plenty of headroom for more content.`);let E=0;if(h.lastIndexedAt){E=new Date(h.lastIndexedAt).getTime();let e=(Date.now()-E)/(1e3*60*60);x.push(``,`### Index Freshness`,e>24?u===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}let D=null,O=t;if(typeof O.getDiagnostics==`function`)try{D=O.getDiagnostics(),x.push(``,`### Storage`,`- **Backend**: ${l?.store?.backend??`unknown`}`,`- **Adapter**: ${D.adapterType}`,`- **Vector search**: ${D.vectorSearchEnabled?`✅ enabled`:`⚠ disabled (FTS-only fallback)`}`,D.dbPath?`- **DB**: ${D.dbPath}`:``,D.dbSizeBytes==null?``:`- **DB size**: ${(D.dbSizeBytes/1024/1024).toFixed(2)} MB`,`- **Embedding dim**: ${D.embeddingDim}`,`- **Vector dtype**: ${D.vectorDtype}`)}catch{}if(u===`smart`)if(x.push(``,`### Smart Indexing`),f){let e=f();e?x.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):x.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else x.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=_(process.cwd(),y.data,`stash`);if(a(e)){let t=d(e).mtimeMs;t>E&&(E=t)}}catch{}let e=[];if(s)try{let t=b>0?await s.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>E&&(E=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=E>0?Date.now()-E:0;if(t>=144e5){let n=Math.floor(t/36e5);if(x.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){x.push(`**Recent decisions/notes:**`);for(let t of e)x.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}x.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — find your last checkpoint',"- `restore({})` — resume from a saved checkpoint",'- `knowledge({ action: "list" })` — browse all stored knowledge')}}x.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${sn.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let k=Au(),ee=ju(),A=r(),j=k!=null&&k!==A,M=ee!=null&&ee!==A;if(j||M){let e=i(),t=[];j&&t.push(`user scaffold v${k}`),M&&t.push(`workspace scaffold v${ee}`);let r=t.join(`, `);e.state===`success`?x.push(``,`### ✅ Upgrade Applied`,`- Server v${A} — ${r} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?x.push(``,`### ⏳ Upgrade In Progress`,`- Server v${A} ≠ ${r}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(n(),x.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${A} ≠ ${r}`,`- Error: ${e.error??`unknown`}`)):(n(),x.push(``,`### ⬆ Upgrade Available`,`- Server v${A} ≠ ${r}`,`- Auto-upgrade triggered — check again shortly.`))}e.length>0&&x.push(``,`### ⚠ Warnings`,...e.map(e=>`- ${e}`));let te=Pr();if(te.length>0){let e=te.sort((e,t)=>t.callCount-e.callCount);x.push(``,`### Tool Usage This Session`,``),x.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),x.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);x.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let N=Dr();if(N.bufferSize>=10){let e=N.state===`healthy`?`🟢`:N.state===`degraded`?`🔴`:`🟡`;x.push(``,`### Auto-GC: ${e} ${N.state}`),x.push(`- p95 latency: ${N.p95}ms | buffer: ${N.bufferSize} samples`),N.gcCount>0&&x.push(`- GC cycles triggered: ${N.gcCount}`)}let P=x.join(`
1260
- `),ne={totalRecords:h.totalRecords,totalFiles:h.totalFiles,lastIndexedAt:h.lastIndexedAt??null,onboarded:w,onboardDir:S,contentTypes:h.contentTypeBreakdown,wasmAvailable:!!sn.get(),graphStats:v,curatedCount:b,serverVersion:A,scaffoldVersion:k??null,workspaceScaffoldVersion:ee??null,upgradeAvailable:j||M,storeBackend:l?.store?.backend,storeDiagnostics:D??null,contextPressure:T};return{content:[{type:`text`,text:P+(u===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships, or `reindex` to refresh the index._")}],structuredContent:ne}}catch(e){return wu.error(`Status failed`,j(e)),U(`INTERNAL`,`Status check failed: ${e instanceof Error?e.message:String(e)}`)}})}const Pu=D(`tools`);function Fu(e){let t=B(`web_search`);e.registerTool(`web_search`,{title:t.title,description:`PREFERRED web search — fans out to multiple keyless providers (DuckDuckGo + Bing-HTML + Mojeek) by default, returning a deduplicated, consensus-ranked union within a 10s deadline. Optional providers (SearXNG, Google, Brave, Bing API) join the fan-out automatically when their env vars are set. Pass one query or multiple for parallel searching.`,inputSchema:{queries:I.array(I.string().max(2e3)).min(1).max(5).describe('Search queries (1–5). Single: `["react hooks"]`. Multiple searched in parallel.'),limit:I.number().min(1).max(20).default(5).describe(`Max results per query`),site:I.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`),provider:I.enum([`multi`,`duckduckgo`,`bing-html`,`mojeek`,`searxng`,`google`,`brave`,`bing`]).optional().describe("Search provider. Defaults to env AIKIT_SEARCH_PROVIDER, then `multi` (fan-out). Single keyless: `duckduckgo`, `bing-html`, `mojeek`. Self-hosted: `searxng` (requires SEARXNG_URL). Keyed APIs: `google` (GOOGLE_API_KEY+GOOGLE_CSE_ID), `brave` (BRAVE_API_KEY), `bing` (BING_API_KEY). Missing keys auto-fall back to duckduckgo.")},annotations:t.annotations},async({queries:e,limit:t,site:n,provider:r})=>{let i=e,a=async e=>{let i=await Wt({query:e,limit:t,site:n,provider:r}),a=[`## Search: ${i.query} _(via ${i.provider})_`,``];if(i.results.length===0)a.push(`No results found.`);else for(let e of i.results)a.push(`### [${e.title}](${e.url})`,e.snippet,``);return a.join(`
1261
- `)};if(i.length===1)try{return{content:[{type:`text`,text:`${await a(i[0])}\n---\n_Next: Use \`web_fetch\` to read any of these pages in full._`}]}}catch(e){return Pu.error(`Web search failed`,j(e)),U(`INTERNAL`,`Web search failed: ${e instanceof Error?e.message:String(e)}`)}let o=await Promise.allSettled(i.map(e=>a(e))),s=[],c=0;for(let e=0;e<o.length;e++){let t=o[e];if(t.status===`fulfilled`)s.push(t.value);else{c++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);Pu.error(`Web search failed`,{query:i[e],error:n}),s.push(`## ❌ Search failed: ${i[e]}\n\n${n}`)}}let l=`_Searched ${o.length-c}/${o.length} queries successfully._`;s.push(``,`---`,l,"_Next: Use `web_fetch` to read any of these pages in full._");let u=s.join(`
1258
+ `),A=(c===`hybrid`?`hybrid (vector + keyword RRF)`:c===`keyword`?`keyword (FTS)`:`semantic (vector)`)+T,M=yu(b,e),te=M.length>0?`\n_Distinctive terms: ${M.map(e=>`\`${e}\``).join(`, `)}_`:``,N=await xu(n,b),P=[];if(b.length===0)P.push("`reindex` — no results found, index may be stale"),P.push("`find` — try federated search with glob/regex");else{let e=b[0]?.record.sourcePath;e&&P.push(`\`lookup\` — see all chunks from \`${e}\``),P.push("`symbol` — resolve a specific symbol from the results"),P.push("`compact` — compress a result file for focused reading")}let ne=[O?`${O}\n\n`:``,N?`${N}\n\n`:``,ee,`\n\n---\n_Search mode: ${A} | ${b.length} results_${te}`,`\n_Next: ${P.join(` | `)}_`],re=C+ne.join(``);g&&(re=zt(re,g));let ae=new Set,oe=[];for(let e of b){if(e.record.origin!==`curated`||e.record.sourcePath.startsWith(`[`))continue;let t=Ts(e.record.sourcePath);if(!t)continue;let n=Cs(t,e.record.headingPath??t);n&&!ae.has(n.uri)&&(ae.add(n.uri),oe.push(n))}return{content:[{type:`text`,text:re},...oe],structuredContent:{results:b.map(e=>({sourcePath:e.record.sourcePath,contentType:e.record.contentType,score:e.score,...e.record.headingPath?{headingPath:e.record.headingPath}:{},...e.record.startLine?{startLine:e.record.startLine}:{},...e.record.endLine?{endLine:e.record.endLine}:{},...e.record.origin===`indexed`?{}:{origin:e.record.origin},...e.record.category?{category:e.record.category}:{},...e.record.tags?.length?{tags:e.record.tags}:{}})),totalResults:b.length,searchMode:c,query:e}}}catch(e){return pu.error(`Search failed`,j(e)),U(`INTERNAL`,`Search failed: ${e instanceof Error?e.message:String(e)}`)}})}const Cu=D(`tools`);function wu(e,t){let n=B(`session_digest`);e.registerTool(`session_digest`,{title:n.title,description:`Compress the current session's tool trajectory into a focused digest. Aggregates replay log, stash state, and checkpoints. Supports deterministic and LLM-assisted (sampling) modes with configurable token budget.`,inputSchema:{scope:I.enum([`tools`,`stash`,`all`]).default(`all`).describe(`What to include: tools (replay only), stash (stash + checkpoints only), or all`),since:I.string().optional().describe(`ISO timestamp — only include activity after this time`),last:I.number().min(1).max(500).optional().describe(`Max replay entries to consider (default: 50)`),focus:I.string().optional().describe(`Focus query — prioritize entries matching this topic`),mode:I.enum([`deterministic`,`sampling`]).default(`deterministic`).describe(`Summary mode: deterministic (fast, template-based) or sampling (LLM-assisted, richer)`),token_budget:I.number().min(100).max(8e3).default(2e3).describe(`Target token budget for the digest output`),persist:I.boolean().default(!0).describe(`Auto-save digest to stash for crash recovery`)},annotations:n.annotations},async({scope:e,since:n,last:r,focus:i,mode:a,token_budget:o,persist:s})=>{try{let c={scope:e,since:n,last:r,focus:i,mode:a,tokenBudget:o,persist:s};return{content:[{type:`text`,text:(a===`sampling`&&t?.available?await Dt(c,async(e,n,r)=>(await t.createMessage({prompt:e,systemPrompt:n,maxTokens:r})).text):Et(c)).digest}]}}catch(e){return Cu.error(`Session digest failed`,j(e)),U(`INTERNAL`,`Session digest failed: ${e instanceof Error?e.message:String(e)}`)}})}const Tu=D(`tools`);function Eu(e,t,n,r=15e3){let i,a=new Promise(e=>{i=setTimeout(()=>{Tu.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),Tu.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}const Du=5*6e4;let Ou=null,ku=null;function Au(e,t,n,r){let i=Math.min(e/2e4,1),a=Math.min((t+n)/5e4,1),o=Math.min(r/200,1);return Math.round(i*40+a*35+o*25)}function ju(){let e=Date.now();if(Ou&&e-Ou.ts<Du)return Ou.value;try{let t=_(Cn(),`.copilot`,`.aikit-scaffold.json`);if(!a(t))return Ou={value:null,ts:e},null;let n=JSON.parse(s(t,`utf-8`)).version??null;return Ou={value:n,ts:e},n}catch{return Ou={value:null,ts:e},null}}function Mu(){let e=Date.now();if(ku&&e-ku.ts<Du)return ku.value;try{let t=_(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!a(t))return ku={value:null,ts:e},null;let n=JSON.parse(s(t,`utf-8`)).version??null;return ku={value:n,ts:e},n}catch{return ku={value:null,ts:e},null}}function Nu(e){let t=B(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:fi,annotations:t.annotations},async()=>{let e=r(),t=ju(),a=Mu(),o=t!=null&&t!==e,s=a!=null&&a!==e,c=[`## AI Kit Status`,``,`⏳ **AI Kit is initializing** — index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${sn.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${a??`not installed`}`];if(o||s){let r=i(),l=[];o&&l.push(`user scaffold v${t}`),s&&l.push(`workspace scaffold v${a}`);let u=l.join(`, `);r.state===`success`?c.push(``,`### ✅ Upgrade Applied`,`- Server v${e} — ${u} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):r.state===`pending`?c.push(``,`### ⏳ Upgrade In Progress`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade is running in the background…`):r.state===`failed`?(n(),c.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} ≠ ${u}`,`- Error: ${r.error??`unknown`}`)):(n(),c.push(``,`### ⬆ Upgrade Available`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade triggered — check again shortly.`))}let l={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!sn.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:a??null,upgradeAvailable:o||s,contextPressure:0};return{content:[{type:`text`,text:c.join(`
1259
+ `)}],structuredContent:l}})}function Pu(e,t,o,s,c,l,u,f){let p=B(`status`);e.registerTool(`status`,{title:p.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:fi,annotations:p.annotations},async()=>{let e=[];try{let[p,m]=await Promise.all([Eu(t.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),Eu(t.listSourcePaths(),[],`store.listSourcePaths`)]),h=p.value;p.timedOut&&e.push(`⚠ Index stats timed out — values may be incomplete`);let g=m.value;m.timedOut&&e.push(`⚠ File listing timed out`);let v=null,b=0,x=[`## AI Kit Status`,``,`- **Total Records**: ${h.totalRecords}`,`- **Total Files**: ${h.totalFiles}`,`- **Last Indexed**: ${h.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(h.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...g.slice(0,50).map(e=>`- ${e}`),g.length>50?`\n... and ${g.length-50} more files`:``];if(o)try{let t=await Eu(o.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(t.timedOut)e.push(`⚠ Graph stats timed out`),x.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let e=t.value;v={nodes:e.nodeCount,edges:e.edgeCount},x.push(``,`### Knowledge Graph`,`- **Nodes**: ${e.nodeCount}`,`- **Edges**: ${e.edgeCount}`,...Object.entries(e.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await Eu(o.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||x.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&x.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{x.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let S=l?.onboardDir??_(process.cwd(),y.aiContext),C=a(S),w=c?.onboardComplete||C;if(x.push(``,`### Onboard Status`,w?`- ✅ Complete${c?.onboardTimestamp?` (last: ${c.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${S}\``),s)try{let t=await Eu(s.list(),[],`curated.list`);if(t.timedOut)e.push(`⚠ Curated knowledge listing timed out`),x.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let e=t.value;b=e.length,x.push(``,`### Curated Knowledge`,e.length>0?`- ${e.length} entries`:'- Empty — use `knowledge({ action: "remember", ... })` to persist decisions')}}catch{x.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let T=Au(h.totalRecords,v?.nodes??0,v?.edges??0,b);x.push(``),x.push(`## 📊 Context Pressure: ${T}/100`),T>=80?x.push(`⚠️ High pressure — consider pruning stale entries or compacting context.`):T>=50?x.push(`ℹ️ Moderate pressure — AI Kit memory is well-populated.`):x.push(`✅ Low pressure — plenty of headroom for more content.`);let E=0;if(h.lastIndexedAt){E=new Date(h.lastIndexedAt).getTime();let e=(Date.now()-E)/(1e3*60*60);x.push(``,`### Index Freshness`,e>24?u===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}let D=null,O=t;if(typeof O.getDiagnostics==`function`)try{D=O.getDiagnostics(),x.push(``,`### Storage`,`- **Backend**: ${l?.store?.backend??`unknown`}`,`- **Adapter**: ${D.adapterType}`,`- **Vector search**: ${D.vectorSearchEnabled?`✅ enabled`:`⚠ disabled (FTS-only fallback)`}`,D.dbPath?`- **DB**: ${D.dbPath}`:``,D.dbSizeBytes==null?``:`- **DB size**: ${(D.dbSizeBytes/1024/1024).toFixed(2)} MB`,`- **Embedding dim**: ${D.embeddingDim}`,`- **Vector dtype**: ${D.vectorDtype}`)}catch{}if(u===`smart`)if(x.push(``,`### Smart Indexing`),f){let e=f();e?x.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):x.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else x.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=_(process.cwd(),y.data,`stash`);if(a(e)){let t=d(e).mtimeMs;t>E&&(E=t)}}catch{}let e=[];if(s)try{let t=b>0?await s.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>E&&(E=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=E>0?Date.now()-E:0;if(t>=144e5){let n=Math.floor(t/36e5);if(x.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){x.push(`**Recent decisions/notes:**`);for(let t of e)x.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}x.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — find your last checkpoint',"- `restore({})` — resume from a saved checkpoint",'- `knowledge({ action: "list" })` — browse all stored knowledge')}}x.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${sn.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let k=ju(),ee=Mu(),A=r(),j=k!=null&&k!==A,M=ee!=null&&ee!==A;if(j||M){let e=i(),t=[];j&&t.push(`user scaffold v${k}`),M&&t.push(`workspace scaffold v${ee}`);let r=t.join(`, `);e.state===`success`?x.push(``,`### ✅ Upgrade Applied`,`- Server v${A} — ${r} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?x.push(``,`### ⏳ Upgrade In Progress`,`- Server v${A} ≠ ${r}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(n(),x.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${A} ≠ ${r}`,`- Error: ${e.error??`unknown`}`)):(n(),x.push(``,`### ⬆ Upgrade Available`,`- Server v${A} ≠ ${r}`,`- Auto-upgrade triggered — check again shortly.`))}e.length>0&&x.push(``,`### ⚠ Warnings`,...e.map(e=>`- ${e}`));let te=Pr();if(te.length>0){let e=te.sort((e,t)=>t.callCount-e.callCount);x.push(``,`### Tool Usage This Session`,``),x.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),x.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);x.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let N=Dr();if(N.bufferSize>=10){let e=N.state===`healthy`?`🟢`:N.state===`degraded`?`🔴`:`🟡`;x.push(``,`### Auto-GC: ${e} ${N.state}`),x.push(`- p95 latency: ${N.p95}ms | buffer: ${N.bufferSize} samples`),N.gcCount>0&&x.push(`- GC cycles triggered: ${N.gcCount}`)}let P=x.join(`
1260
+ `),ne={totalRecords:h.totalRecords,totalFiles:h.totalFiles,lastIndexedAt:h.lastIndexedAt??null,onboarded:w,onboardDir:S,contentTypes:h.contentTypeBreakdown,wasmAvailable:!!sn.get(),graphStats:v,curatedCount:b,serverVersion:A,scaffoldVersion:k??null,workspaceScaffoldVersion:ee??null,upgradeAvailable:j||M,storeBackend:l?.store?.backend,storeDiagnostics:D??null,contextPressure:T};return{content:[{type:`text`,text:P+(u===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships, or `reindex` to refresh the index._")}],structuredContent:ne}}catch(e){return Tu.error(`Status failed`,j(e)),U(`INTERNAL`,`Status check failed: ${e instanceof Error?e.message:String(e)}`)}})}const Fu=D(`tools`);function Iu(e){let t=B(`web_search`);e.registerTool(`web_search`,{title:t.title,description:`PREFERRED web search — fans out to multiple keyless providers (DuckDuckGo + Bing-HTML + Mojeek) by default, returning a deduplicated, consensus-ranked union within a 10s deadline. Optional providers (SearXNG, Google, Brave, Bing API) join the fan-out automatically when their env vars are set. Pass one query or multiple for parallel searching.`,inputSchema:{queries:I.array(I.string().max(2e3)).min(1).max(5).describe('Search queries (1–5). Single: `["react hooks"]`. Multiple searched in parallel.'),limit:I.number().min(1).max(20).default(5).describe(`Max results per query`),site:I.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`),provider:I.enum([`multi`,`duckduckgo`,`bing-html`,`mojeek`,`searxng`,`google`,`brave`,`bing`]).optional().describe("Search provider. Defaults to env AIKIT_SEARCH_PROVIDER, then `multi` (fan-out). Single keyless: `duckduckgo`, `bing-html`, `mojeek`. Self-hosted: `searxng` (requires SEARXNG_URL). Keyed APIs: `google` (GOOGLE_API_KEY+GOOGLE_CSE_ID), `brave` (BRAVE_API_KEY), `bing` (BING_API_KEY). Missing keys auto-fall back to duckduckgo.")},annotations:t.annotations},async({queries:e,limit:t,site:n,provider:r})=>{let i=e,a=async e=>{let i=await Wt({query:e,limit:t,site:n,provider:r}),a=[`## Search: ${i.query} _(via ${i.provider})_`,``];if(i.results.length===0)a.push(`No results found.`);else for(let e of i.results)a.push(`### [${e.title}](${e.url})`,e.snippet,``);return a.join(`
1261
+ `)};if(i.length===1)try{return{content:[{type:`text`,text:`${await a(i[0])}\n---\n_Next: Use \`web_fetch\` to read any of these pages in full._`}]}}catch(e){return Fu.error(`Web search failed`,j(e)),U(`INTERNAL`,`Web search failed: ${e instanceof Error?e.message:String(e)}`)}let o=await Promise.allSettled(i.map(e=>a(e))),s=[],c=0;for(let e=0;e<o.length;e++){let t=o[e];if(t.status===`fulfilled`)s.push(t.value);else{c++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);Fu.error(`Web search failed`,{query:i[e],error:n}),s.push(`## ❌ Search failed: ${i[e]}\n\n${n}`)}}let l=`_Searched ${o.length-c}/${o.length} queries successfully._`;s.push(``,`---`,l,"_Next: Use `web_fetch` to read any of these pages in full._");let u=s.join(`
1262
1262
 
1263
- `);return c===o.length?U(`INTERNAL`,u):{content:[{type:`text`,text:u}]}})}function Iu(e){let t=B(`http`);e.registerTool(`http`,{title:t.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:I.string().url().describe(`Request URL (http/https only)`),method:I.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:I.record(I.string(),I.string()).optional().describe(`Request headers as key-value pairs`),body:I.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:I.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:t.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await Be({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated — total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
1264
- `)}]}}catch(e){return Pu.error(`HTTP request failed`,j(e)),U(`INTERNAL`,`HTTP request failed: ${e instanceof Error?e.message:String(e)}`)}})}function Lu(e){let t=B(`regex_test`);e.registerTool(`regex_test`,{title:t.title,description:`Test a regex pattern against sample strings. Supports match, replace, and split modes.`,inputSchema:{pattern:I.string().max(500).describe(`Regex pattern (without delimiters)`),flags:I.string().max(10).regex(/^[gimsuy]*$/).default(``).describe(`Regex flags (g, i, m, s, etc.)`),test_strings:I.array(I.string().max(1e4)).max(50).describe(`Strings to test the pattern against`),mode:I.enum([`match`,`replace`,`split`]).default(`match`).describe(`Test mode`),replacement:I.string().optional().describe(`Replacement string (for replace mode)`)},annotations:t.annotations},async({pattern:e,flags:t,test_strings:n,mode:r,replacement:i})=>{let a=mt({pattern:e,flags:t,testStrings:n,mode:r,replacement:i});if(!a.valid)return U(`VALIDATION`,`Invalid regex: ${a.error}`);let o=[`## Regex: \`/${a.pattern}/${a.flags}\``,``,`Mode: ${r}`,``];for(let e of a.results){if(o.push(`**Input:** \`${e.input}\``),o.push(`**Matched:** ${e.matched}`),e.matches)for(let t of e.matches){let e=t.groups.length>0?` groups: [${t.groups.join(`, `)}]`:``;o.push(` - "${t.full}" at index ${t.index}${e}`)}e.replaced!==void 0&&o.push(`**Result:** \`${e.replaced}\``),e.split&&o.push(`**Split:** ${JSON.stringify(e.split)}`),o.push(``)}return{content:[{type:`text`,text:o.join(`
1265
- `)}]}})}function Ru(e){let t=B(`encode`);e.registerTool(`encode`,{title:t.title,description:`Encode, decode, or hash text. Supports base64, URL encoding, SHA-256, MD5, JWT decode, hex.`,inputSchema:{operation:I.enum([`base64_encode`,`base64_decode`,`url_encode`,`url_decode`,`sha256`,`md5`,`jwt_decode`,`hex_encode`,`hex_decode`]).describe(`Operation to perform`),input:I.string().max(1e6).describe(`Input text`)},annotations:t.annotations},async({operation:e,input:t})=>{try{let n=we({operation:e,input:t});return{content:[{type:`text`,text:`## ${e}\n\n**Input:** \`${t.length>100?`${t.slice(0,100)}...`:t}\`\n**Output:**\n\`\`\`\n${n.output}\n\`\`\``}]}}catch(e){return Pu.error(`Encode failed`,j(e)),U(`INTERNAL`,`Encode failed: ${e instanceof Error?e.message:String(e)}`)}})}function zu(e){let t=B(`measure`);e.registerTool(`measure`,{title:t.title,description:`Measure code complexity, line counts, and function counts for a file or directory. Returns per-file metrics sorted by complexity.`,outputSchema:mi,inputSchema:{path:I.string().describe(`File or directory path to measure`),extensions:I.array(I.string()).optional().describe(`File extensions to include (default: .ts,.tsx,.js,.jsx)`)},annotations:t.annotations},async({path:e,extensions:t})=>{try{let n=await Xe({path:e,extensions:t}),r=[`## Code Metrics`,``,`**Files:** ${n.summary.totalFiles}`,`**Total lines:** ${n.summary.totalLines} (${n.summary.totalCodeLines} code)`,`**Functions:** ${n.summary.totalFunctions}`,`**Avg complexity:** ${n.summary.avgComplexity}`,`**Max complexity:** ${n.summary.maxComplexity.value} (${n.summary.maxComplexity.file})`,``,`### Top files by complexity`,``,`| File | Lines | Code | Complexity | Cognitive | Functions | Imports |`,`|------|-------|------|------------|-----------|-----------|---------|`];for(let e of n.files.slice(0,20)){let t=e.cognitiveComplexity===void 0?`—`:String(e.cognitiveComplexity);r.push(`| ${e.path} | ${e.lines.total} | ${e.lines.code} | ${e.complexity} | ${t} | ${e.functions} | ${e.imports} |`)}n.files.length>20&&r.push(``,`_...and ${n.files.length-20} more files_`);let i={summary:{totalFiles:n.summary.totalFiles,totalLines:n.summary.totalLines,totalCodeLines:n.summary.totalCodeLines,totalFunctions:n.summary.totalFunctions,avgComplexity:n.summary.avgComplexity,maxComplexity:{value:n.summary.maxComplexity.value,file:n.summary.maxComplexity.file}},files:n.files.map(e=>({path:e.path,lines:e.lines.total,code:e.lines.code,complexity:e.complexity,functions:e.functions}))};return{content:[{type:`text`,text:r.join(`
1266
- `)}],structuredContent:i}}catch(e){return Pu.error(`Measure failed`,j(e)),U(`INTERNAL`,`Measure failed: ${e instanceof Error?e.message:String(e)}`)}})}function Bu(e){let t=B(`changelog`);e.registerTool(`changelog`,{title:t.title,description:`Generate a changelog from git history between two refs. Groups by conventional commit type.`,inputSchema:{from:I.string().max(200).describe(`Start ref (tag, SHA, HEAD~N)`),to:I.string().max(200).default(`HEAD`).describe(`End ref (default: HEAD)`),format:I.enum([`grouped`,`chronological`,`per-scope`]).default(`grouped`).describe(`Output format`),include_breaking:I.boolean().default(!0).describe(`Highlight breaking changes`),cwd:I.string().optional().describe(`Repository root or working directory`)},annotations:t.annotations},async({from:e,to:t,format:n,include_breaking:r,cwd:i})=>{try{let a=ae({from:e,to:t,format:n,includeBreaking:r,cwd:i}),o=`${a.stats.total} commits (${Object.entries(a.stats.types).map(([e,t])=>`${t} ${e}`).join(`, `)})`;return{content:[{type:`text`,text:`${a.markdown}\n---\n_${o}_`}]}}catch(e){return Pu.error(`Changelog failed`,j(e)),U(`INTERNAL`,`Changelog failed: ${e instanceof Error?e.message:String(e)}`)}})}function Vu(e){let t=B(`schema_validate`);e.registerTool(`schema_validate`,{title:t.title,description:`Validate JSON data against a JSON Schema. Supports type, required, properties, items, enum, pattern, min/max.`,inputSchema:{data:I.string().max(5e5).describe(`JSON data to validate (as string)`),schema:I.string().max(5e5).describe(`JSON Schema to validate against (as string)`)},annotations:t.annotations},async({data:e,schema:t})=>{try{let n=wt({data:JSON.parse(e),schema:JSON.parse(t)});if(n.valid)return{content:[{type:`text`,text:`## Validation: PASSED
1263
+ `);return c===o.length?U(`INTERNAL`,u):{content:[{type:`text`,text:u}]}})}function Lu(e){let t=B(`http`);e.registerTool(`http`,{title:t.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:I.string().url().describe(`Request URL (http/https only)`),method:I.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:I.record(I.string(),I.string()).optional().describe(`Request headers as key-value pairs`),body:I.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:I.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:t.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await Be({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated — total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
1264
+ `)}]}}catch(e){return Fu.error(`HTTP request failed`,j(e)),U(`INTERNAL`,`HTTP request failed: ${e instanceof Error?e.message:String(e)}`)}})}function Ru(e){let t=B(`regex_test`);e.registerTool(`regex_test`,{title:t.title,description:`Test a regex pattern against sample strings. Supports match, replace, and split modes.`,inputSchema:{pattern:I.string().max(500).describe(`Regex pattern (without delimiters)`),flags:I.string().max(10).regex(/^[gimsuy]*$/).default(``).describe(`Regex flags (g, i, m, s, etc.)`),test_strings:I.array(I.string().max(1e4)).max(50).describe(`Strings to test the pattern against`),mode:I.enum([`match`,`replace`,`split`]).default(`match`).describe(`Test mode`),replacement:I.string().optional().describe(`Replacement string (for replace mode)`)},annotations:t.annotations},async({pattern:e,flags:t,test_strings:n,mode:r,replacement:i})=>{let a=mt({pattern:e,flags:t,testStrings:n,mode:r,replacement:i});if(!a.valid)return U(`VALIDATION`,`Invalid regex: ${a.error}`);let o=[`## Regex: \`/${a.pattern}/${a.flags}\``,``,`Mode: ${r}`,``];for(let e of a.results){if(o.push(`**Input:** \`${e.input}\``),o.push(`**Matched:** ${e.matched}`),e.matches)for(let t of e.matches){let e=t.groups.length>0?` groups: [${t.groups.join(`, `)}]`:``;o.push(` - "${t.full}" at index ${t.index}${e}`)}e.replaced!==void 0&&o.push(`**Result:** \`${e.replaced}\``),e.split&&o.push(`**Split:** ${JSON.stringify(e.split)}`),o.push(``)}return{content:[{type:`text`,text:o.join(`
1265
+ `)}]}})}function zu(e){let t=B(`encode`);e.registerTool(`encode`,{title:t.title,description:`Encode, decode, or hash text. Supports base64, URL encoding, SHA-256, MD5, JWT decode, hex.`,inputSchema:{operation:I.enum([`base64_encode`,`base64_decode`,`url_encode`,`url_decode`,`sha256`,`md5`,`jwt_decode`,`hex_encode`,`hex_decode`]).describe(`Operation to perform`),input:I.string().max(1e6).describe(`Input text`)},annotations:t.annotations},async({operation:e,input:t})=>{try{let n=we({operation:e,input:t});return{content:[{type:`text`,text:`## ${e}\n\n**Input:** \`${t.length>100?`${t.slice(0,100)}...`:t}\`\n**Output:**\n\`\`\`\n${n.output}\n\`\`\``}]}}catch(e){return Fu.error(`Encode failed`,j(e)),U(`INTERNAL`,`Encode failed: ${e instanceof Error?e.message:String(e)}`)}})}function Bu(e){let t=B(`measure`);e.registerTool(`measure`,{title:t.title,description:`Measure code complexity, line counts, and function counts for a file or directory. Returns per-file metrics sorted by complexity.`,outputSchema:mi,inputSchema:{path:I.string().describe(`File or directory path to measure`),extensions:I.array(I.string()).optional().describe(`File extensions to include (default: .ts,.tsx,.js,.jsx)`)},annotations:t.annotations},async({path:e,extensions:t})=>{try{let n=await Xe({path:e,extensions:t}),r=[`## Code Metrics`,``,`**Files:** ${n.summary.totalFiles}`,`**Total lines:** ${n.summary.totalLines} (${n.summary.totalCodeLines} code)`,`**Functions:** ${n.summary.totalFunctions}`,`**Avg complexity:** ${n.summary.avgComplexity}`,`**Max complexity:** ${n.summary.maxComplexity.value} (${n.summary.maxComplexity.file})`,``,`### Top files by complexity`,``,`| File | Lines | Code | Complexity | Cognitive | Functions | Imports |`,`|------|-------|------|------------|-----------|-----------|---------|`];for(let e of n.files.slice(0,20)){let t=e.cognitiveComplexity===void 0?`—`:String(e.cognitiveComplexity);r.push(`| ${e.path} | ${e.lines.total} | ${e.lines.code} | ${e.complexity} | ${t} | ${e.functions} | ${e.imports} |`)}n.files.length>20&&r.push(``,`_...and ${n.files.length-20} more files_`);let i={summary:{totalFiles:n.summary.totalFiles,totalLines:n.summary.totalLines,totalCodeLines:n.summary.totalCodeLines,totalFunctions:n.summary.totalFunctions,avgComplexity:n.summary.avgComplexity,maxComplexity:{value:n.summary.maxComplexity.value,file:n.summary.maxComplexity.file}},files:n.files.map(e=>({path:e.path,lines:e.lines.total,code:e.lines.code,complexity:e.complexity,functions:e.functions}))};return{content:[{type:`text`,text:r.join(`
1266
+ `)}],structuredContent:i}}catch(e){return Fu.error(`Measure failed`,j(e)),U(`INTERNAL`,`Measure failed: ${e instanceof Error?e.message:String(e)}`)}})}function Vu(e){let t=B(`changelog`);e.registerTool(`changelog`,{title:t.title,description:`Generate a changelog from git history between two refs. Groups by conventional commit type.`,inputSchema:{from:I.string().max(200).describe(`Start ref (tag, SHA, HEAD~N)`),to:I.string().max(200).default(`HEAD`).describe(`End ref (default: HEAD)`),format:I.enum([`grouped`,`chronological`,`per-scope`]).default(`grouped`).describe(`Output format`),include_breaking:I.boolean().default(!0).describe(`Highlight breaking changes`),cwd:I.string().optional().describe(`Repository root or working directory`)},annotations:t.annotations},async({from:e,to:t,format:n,include_breaking:r,cwd:i})=>{try{let a=ae({from:e,to:t,format:n,includeBreaking:r,cwd:i}),o=`${a.stats.total} commits (${Object.entries(a.stats.types).map(([e,t])=>`${t} ${e}`).join(`, `)})`;return{content:[{type:`text`,text:`${a.markdown}\n---\n_${o}_`}]}}catch(e){return Fu.error(`Changelog failed`,j(e)),U(`INTERNAL`,`Changelog failed: ${e instanceof Error?e.message:String(e)}`)}})}function Hu(e){let t=B(`schema_validate`);e.registerTool(`schema_validate`,{title:t.title,description:`Validate JSON data against a JSON Schema. Supports type, required, properties, items, enum, pattern, min/max.`,inputSchema:{data:I.string().max(5e5).describe(`JSON data to validate (as string)`),schema:I.string().max(5e5).describe(`JSON Schema to validate against (as string)`)},annotations:t.annotations},async({data:e,schema:t})=>{try{let n=wt({data:JSON.parse(e),schema:JSON.parse(t)});if(n.valid)return{content:[{type:`text`,text:`## Validation: PASSED
1267
1267
 
1268
1268
  Data matches the schema.`}]};let r=[`## Validation: FAILED`,``,`**${n.errors.length} error(s):**`,``];for(let e of n.errors){let t=e.expected?` (expected: ${e.expected}, got: ${e.received})`:``;r.push(`- \`${e.path}\`: ${e.message}${t}`)}return{content:[{type:`text`,text:r.join(`
1269
- `)}]}}catch(e){return Pu.error(`Schema validation failed`,j(e)),U(`INTERNAL`,`Schema validation failed: ${e instanceof Error?e.message:String(e)}`)}})}function Hu(e){let t=B(`env`);e.registerTool(`env`,{title:t.title,description:`Get system and runtime environment info. Sensitive env vars are redacted by default.`,outputSchema:hi,inputSchema:{include_env:I.boolean().default(!1).describe(`Include environment variables`),filter_env:I.string().optional().describe(`Filter env vars by name substring`),show_sensitive:I.boolean().default(!1).describe(`Show sensitive values (keys, tokens, etc.) — redacted by default`)},annotations:t.annotations},async({include_env:e,filter_env:t,show_sensitive:n})=>{let r=Te({includeEnv:e,filterEnv:t,showSensitive:n}),i=[`## Environment`,``,`**Platform:** ${r.system.platform} ${r.system.arch}`,`**OS:** ${r.system.type} ${r.system.release}`,`**Host:** ${r.system.hostname}`,`**CPUs:** ${r.system.cpus}`,`**Memory:** ${r.system.memoryFreeGb}GB free / ${r.system.memoryTotalGb}GB total`,``,`**Node:** ${r.runtime.node}`,`**V8:** ${r.runtime.v8}`,`**CWD:** ${r.cwd}`];if(r.env){i.push(``,`### Environment Variables`,``);for(let[e,t]of Object.entries(r.env))i.push(`- \`${e}\`: ${t}`)}let a={platform:r.system.platform,arch:r.system.arch,nodeVersion:r.runtime.node,cwd:r.cwd,cpus:r.system.cpus,memoryFreeGb:r.system.memoryFreeGb,memoryTotalGb:r.system.memoryTotalGb};return{content:[{type:`text`,text:i.join(`
1270
- `)}],structuredContent:a}})}function Uu(e){let t=B(`time`);e.registerTool(`time`,{title:t.title,description:`Parse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.`,outputSchema:gi,inputSchema:{operation:I.enum([`now`,`parse`,`convert`,`diff`,`add`]).describe(`now: current time | parse: parse a date string | convert: timezone conversion | diff: duration between two dates | add: add duration to date`),input:I.string().optional().describe(`Date input (ISO, unix timestamp, or parseable string). For diff: two comma-separated dates`),timezone:I.string().optional().describe(`Target timezone (e.g., "America/New_York", "Asia/Tokyo")`),duration:I.string().optional().describe(`Duration to add (e.g., "2h30m", "1d", "30s") — for add operation`)},annotations:t.annotations},async({operation:e,input:t,timezone:n,duration:r})=>{try{let i=Lt({operation:e,input:t,timezone:n,duration:r}),a=[`**${i.output}**`,``,`ISO: ${i.iso}`,`Unix: ${i.unix}`];i.details&&a.push(``,"```json",JSON.stringify(i.details),"```");let o={iso:i.iso,unix:i.unix,timezone:n??Intl.DateTimeFormat().resolvedOptions().timeZone,formatted:i.output};return{content:[{type:`text`,text:a.join(`
1271
- `)}],structuredContent:o}}catch(e){return Pu.error(`Time failed`,j(e)),U(`INTERNAL`,`Time failed: ${e instanceof Error?e.message:String(e)}`)}})}function Wu(e,t,n,r,i,a,o,s,c){let l=new br,u=new sr;u.register(ir),u.register(er),u.register(tr),u.register(Zn),u.register(qn),u.register(Jn),u.register(or);let d=new fr(u,t.curated);l.use(ur(d),{order:5,name:`auto-knowledge`}),l.use(Ir(),{order:10,name:`replay`}),l.use(Kr(),{order:50,name:`structured-content-guard`}),l.use(hr(mr(n.tokenBudget)),{order:90,name:`compression`}),Zr(e,l,n.toolPrefix??``);let f=c??di(n,[...R,...Br],z,Hr(n)),p=e=>f.has(e),m=[...f].filter(e=>Vr.has(e)?zr.includes(e)?!!t.bridge:e===`er_update_policy`?!!t.policyStore:e===`er_evolve_review`?!!t.evolutionCollector:!1:!0);p(`search`)&&xu(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,a);let h={store:t.store,graphStore:t.graphStore,embedder:t.embedder};p(`lookup`)&&$s(e,t.store,h);let g={onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp};p(`status`)&&Nu(e,t.store,t.graphStore,t.curated,g,n,o,s),p(`config`)&&ro(e,n),p(`reindex`)&&au(e,t.indexer,n,t.curated,t.store,i,o),p(`knowledge`)&&Zs(e,t.curated,t.policyStore,t.evolutionCollector,i),p(`analyze`)&&_a(e,t.store,t.embedder,h),p(`blast_radius`)&&va(e,t.store,t.embedder,t.graphStore,h),p(`produce_knowledge`)&&iu(e,n),p(`onboard`)&&mc(e,t.store,t.embedder,n,g,h),p(`graph`)&&gs(e,t.graphStore),p(`audit`)&&Ca(e,t.store,t.embedder,n.tokenBudget);let _=n.sources[0]?.path??process.cwd();p(`compact`)&&fo(e,t.embedder,t.fileCache,_,n.allRoots,h),p(`scope_map`)&&po(e,t.embedder,t.store,h),p(`find`)&&mo(e,t.embedder,t.store,_,h),p(`parse_output`)&&Oo(e),p(`workset`)&&gc(e),p(`check`)&&To(e,h,n.tokenBudget),p(`symbol`)&&ho(e,t.embedder,t.store,t.graphStore),p(`eval`)&&Eo(e),p(`test_run`)&&Do(e,h),p(`stash`)&&_c(e),p(`git_context`)&&tc(e),p(`diff_parse`)&&nc(e),p(`rename`)&&rc(e),p(`codemod`)&&ic(e),p(`restore`)&&lu(e),p(`file_summary`)&&go(e,t.fileCache,_,n.allRoots,h),p(`checkpoint`)&&vc(e),p(`data_transform`)&&ac(e),p(`trace`)&&_o(e,t.embedder,t.store,t.graphStore),p(`process`)&&vs(e),p(`watch`)&&ys(e),p(`dead_symbols`)&&vo(e,t.embedder,t.store,_,n.allRoots,h),p(`delegate`)&&ko(e,a),p(`health`)&&bs(e),p(`lane`)&&yc(e),p(`queue`)&&bc(e),p(`web_fetch`)&&xs(e),p(`guide`)&&Ss(e,o),cc.some(e=>p(e))&&lc(e,n,m),p(`evidence_map`)&&cs(e),p(`digest`)&&ls(e,t.embedder),p(`forge_classify`)&&us(e),p(`stratum_card`)&&ds(e,t.embedder,t.fileCache),p(`forge_ground`)&&fs(e,t.embedder,t.store),p(`present`)&&eu(e,r),p(`web_search`)&&Fu(e),p(`http`)&&Iu(e),p(`regex_test`)&&Lu(e),p(`encode`)&&Ru(e),p(`measure`)&&zu(e),p(`changelog`)&&Bu(e),p(`schema_validate`)&&Vu(e),p(`env`)&&Hu(e),p(`time`)&&Uu(e),p(`flow`)&&os(e,n),t.bridge&&zr.some(e=>p(e))&&(Da(e,t.bridge,t.evolutionCollector),Oa(e,t.bridge),ka(e,t.bridge)),t.policyStore&&p(`er_update_policy`)&&Ec(e,t.policyStore),t.evolutionCollector&&p(`er_evolve_review`)&&Co(e,t.evolutionCollector),Rr(e,t.store,t.curated),p(`replay`)&&su(e),p(`session_digest`)&&Cu(e,a)}function Gu(e,t,n){let r=e=>!n||n.has(e);r(`check`)&&To(e,void 0,t.tokenBudget),r(`eval`)&&Eo(e),r(`test_run`)&&Do(e),r(`parse_output`)&&Oo(e),r(`delegate`)&&ko(e),r(`git_context`)&&tc(e),r(`diff_parse`)&&nc(e),r(`rename`)&&rc(e),r(`codemod`)&&ic(e),r(`data_transform`)&&ac(e),r(`workset`)&&gc(e),r(`stash`)&&_c(e),r(`checkpoint`)&&vc(e),r(`restore`)&&lu(e),r(`lane`)&&yc(e),r(`queue`)&&bc(e),r(`session_digest`)&&Cu(e),r(`health`)&&bs(e),r(`process`)&&vs(e),r(`watch`)&&ys(e),r(`web_fetch`)&&xs(e),r(`guide`)&&Ss(e),cc.some(e=>r(e))&&lc(e,t,[...n??new Set(R)]),r(`evidence_map`)&&cs(e),r(`forge_classify`)&&us(e),r(`present`)&&eu(e),r(`produce_knowledge`)&&iu(e),r(`replay`)&&su(e),r(`status`)&&Mu(e),r(`flow`)&&os(e,t),r(`web_search`)&&Fu(e),r(`http`)&&Iu(e),r(`regex_test`)&&Lu(e),r(`encode`)&&Ru(e),r(`measure`)&&zu(e),r(`changelog`)&&Bu(e),r(`schema_validate`)&&Vu(e),r(`env`)&&Hu(e),r(`time`)&&Uu(e)}const Ku=D(`resource-notifier`);var qu=class{constructor(e){this.mcpServer=e}async notifyStatusChanged(){await this.sendUpdate(`aikit://status`)}async notifyFileTreeChanged(){await this.sendUpdate(`aikit://file-tree`)}async notifyCuratedIndexChanged(){await this.sendUpdate(`aikit://curated`)}async notifyCuratedEntryChanged(e){await this.sendUpdate(`aikit://curated/${e}`)}async notifyResourceListChanged(){try{await this.mcpServer.server.sendResourceListChanged()}catch(e){Ku.debug(`sendResourceListChanged failed`,{error:String(e)})}}async notifyAfterReindex(){await Promise.allSettled([this.notifyStatusChanged(),this.notifyFileTreeChanged()])}async notifyAfterCuratedWrite(e){let t=[this.notifyStatusChanged(),this.notifyCuratedIndexChanged()];e&&t.push(this.notifyCuratedEntryChanged(e)),await Promise.allSettled(t)}async sendUpdate(e){try{await this.mcpServer.server.sendResourceUpdated({uri:e})}catch(t){Ku.debug(`sendResourceUpdated failed`,{uri:e,error:String(t)})}}};const Z=D(`server`);async function Ju(n){Z.info(`Initializing AI Kit components`);let r=n.store.backend,i=n.store.path,o=null;if(r===`sqlite-vec`){let e=g(i,`aikit.db`);o=await yn(e),Z.info(`SQLite adapter ready`,{type:o.type,vectorCapable:o.vectorCapable,dbPath:e}),o.vectorCapable||Z.warn(`┌──────────────────────────────────────────────────────────────────┐
1269
+ `)}]}}catch(e){return Fu.error(`Schema validation failed`,j(e)),U(`INTERNAL`,`Schema validation failed: ${e instanceof Error?e.message:String(e)}`)}})}function Uu(e){let t=B(`env`);e.registerTool(`env`,{title:t.title,description:`Get system and runtime environment info. Sensitive env vars are redacted by default.`,outputSchema:hi,inputSchema:{include_env:I.boolean().default(!1).describe(`Include environment variables`),filter_env:I.string().optional().describe(`Filter env vars by name substring`),show_sensitive:I.boolean().default(!1).describe(`Show sensitive values (keys, tokens, etc.) — redacted by default`)},annotations:t.annotations},async({include_env:e,filter_env:t,show_sensitive:n})=>{let r=Te({includeEnv:e,filterEnv:t,showSensitive:n}),i=[`## Environment`,``,`**Platform:** ${r.system.platform} ${r.system.arch}`,`**OS:** ${r.system.type} ${r.system.release}`,`**Host:** ${r.system.hostname}`,`**CPUs:** ${r.system.cpus}`,`**Memory:** ${r.system.memoryFreeGb}GB free / ${r.system.memoryTotalGb}GB total`,``,`**Node:** ${r.runtime.node}`,`**V8:** ${r.runtime.v8}`,`**CWD:** ${r.cwd}`];if(r.env){i.push(``,`### Environment Variables`,``);for(let[e,t]of Object.entries(r.env))i.push(`- \`${e}\`: ${t}`)}let a={platform:r.system.platform,arch:r.system.arch,nodeVersion:r.runtime.node,cwd:r.cwd,cpus:r.system.cpus,memoryFreeGb:r.system.memoryFreeGb,memoryTotalGb:r.system.memoryTotalGb};return{content:[{type:`text`,text:i.join(`
1270
+ `)}],structuredContent:a}})}function Wu(e){let t=B(`time`);e.registerTool(`time`,{title:t.title,description:`Parse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.`,outputSchema:gi,inputSchema:{operation:I.enum([`now`,`parse`,`convert`,`diff`,`add`]).describe(`now: current time | parse: parse a date string | convert: timezone conversion | diff: duration between two dates | add: add duration to date`),input:I.string().optional().describe(`Date input (ISO, unix timestamp, or parseable string). For diff: two comma-separated dates`),timezone:I.string().optional().describe(`Target timezone (e.g., "America/New_York", "Asia/Tokyo")`),duration:I.string().optional().describe(`Duration to add (e.g., "2h30m", "1d", "30s") — for add operation`)},annotations:t.annotations},async({operation:e,input:t,timezone:n,duration:r})=>{try{let i=Lt({operation:e,input:t,timezone:n,duration:r}),a=[`**${i.output}**`,``,`ISO: ${i.iso}`,`Unix: ${i.unix}`];i.details&&a.push(``,"```json",JSON.stringify(i.details),"```");let o={iso:i.iso,unix:i.unix,timezone:n??Intl.DateTimeFormat().resolvedOptions().timeZone,formatted:i.output};return{content:[{type:`text`,text:a.join(`
1271
+ `)}],structuredContent:o}}catch(e){return Fu.error(`Time failed`,j(e)),U(`INTERNAL`,`Time failed: ${e instanceof Error?e.message:String(e)}`)}})}function Gu(e,t,n,r,i,a,o,s,c){let l=new br,u=new sr;u.register(ir),u.register(er),u.register(tr),u.register(Zn),u.register(qn),u.register(Jn),u.register(or);let d=new fr(u,t.curated);l.use(ur(d),{order:5,name:`auto-knowledge`}),l.use(Ir(),{order:10,name:`replay`}),l.use(Kr(),{order:50,name:`structured-content-guard`}),l.use(hr(mr(n.tokenBudget)),{order:90,name:`compression`}),Zr(e,l,n.toolPrefix??``);let f=c??di(n,[...R,...Br],z,Hr(n)),p=e=>f.has(e),m=[...f].filter(e=>Vr.has(e)?zr.includes(e)?!!t.bridge:e===`er_update_policy`?!!t.policyStore:e===`er_evolve_review`?!!t.evolutionCollector:!1:!0);p(`search`)&&Su(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,a);let h={store:t.store,graphStore:t.graphStore,embedder:t.embedder};p(`lookup`)&&$s(e,t.store,h);let g={onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp};p(`status`)&&Pu(e,t.store,t.graphStore,t.curated,g,n,o,s),p(`config`)&&ro(e,n),p(`reindex`)&&au(e,t.indexer,n,t.curated,t.store,i,o),p(`knowledge`)&&Zs(e,t.curated,t.policyStore,t.evolutionCollector,i),p(`analyze`)&&_a(e,t.store,t.embedder,h),p(`blast_radius`)&&va(e,t.store,t.embedder,t.graphStore,h),p(`produce_knowledge`)&&iu(e,n),p(`onboard`)&&mc(e,t.store,t.embedder,n,g,h),p(`graph`)&&gs(e,t.graphStore),p(`audit`)&&Ca(e,t.store,t.embedder,n.tokenBudget);let _=n.sources[0]?.path??process.cwd();p(`compact`)&&fo(e,t.embedder,t.fileCache,_,n.allRoots,h),p(`scope_map`)&&po(e,t.embedder,t.store,h),p(`find`)&&mo(e,t.embedder,t.store,_,h),p(`parse_output`)&&Oo(e),p(`workset`)&&gc(e),p(`check`)&&To(e,h,n.tokenBudget),p(`symbol`)&&ho(e,t.embedder,t.store,t.graphStore),p(`eval`)&&Eo(e),p(`test_run`)&&Do(e,h),p(`stash`)&&_c(e),p(`git_context`)&&tc(e),p(`diff_parse`)&&nc(e),p(`rename`)&&rc(e),p(`codemod`)&&ic(e),p(`restore`)&&lu(e),p(`file_summary`)&&go(e,t.fileCache,_,n.allRoots,h),p(`checkpoint`)&&vc(e),p(`data_transform`)&&ac(e),p(`trace`)&&_o(e,t.embedder,t.store,t.graphStore),p(`process`)&&vs(e),p(`watch`)&&ys(e),p(`dead_symbols`)&&vo(e,t.embedder,t.store,_,n.allRoots,h),p(`delegate`)&&ko(e,a),p(`health`)&&bs(e),p(`lane`)&&yc(e),p(`queue`)&&bc(e),p(`web_fetch`)&&xs(e),p(`guide`)&&Ss(e,o),cc.some(e=>p(e))&&lc(e,n,m),p(`evidence_map`)&&cs(e),p(`digest`)&&ls(e,t.embedder),p(`forge_classify`)&&us(e),p(`stratum_card`)&&ds(e,t.embedder,t.fileCache),p(`forge_ground`)&&fs(e,t.embedder,t.store),p(`present`)&&eu(e,r),p(`web_search`)&&Iu(e),p(`http`)&&Lu(e),p(`regex_test`)&&Ru(e),p(`encode`)&&zu(e),p(`measure`)&&Bu(e),p(`changelog`)&&Vu(e),p(`schema_validate`)&&Hu(e),p(`env`)&&Uu(e),p(`time`)&&Wu(e),p(`flow`)&&os(e,n),t.bridge&&zr.some(e=>p(e))&&(Da(e,t.bridge,t.evolutionCollector),Oa(e,t.bridge),ka(e,t.bridge)),t.policyStore&&p(`er_update_policy`)&&Ec(e,t.policyStore),t.evolutionCollector&&p(`er_evolve_review`)&&Co(e,t.evolutionCollector),Rr(e,t.store,t.curated),p(`replay`)&&su(e),p(`session_digest`)&&wu(e,a)}function Ku(e,t,n){let r=e=>!n||n.has(e);r(`check`)&&To(e,void 0,t.tokenBudget),r(`eval`)&&Eo(e),r(`test_run`)&&Do(e),r(`parse_output`)&&Oo(e),r(`delegate`)&&ko(e),r(`git_context`)&&tc(e),r(`diff_parse`)&&nc(e),r(`rename`)&&rc(e),r(`codemod`)&&ic(e),r(`data_transform`)&&ac(e),r(`workset`)&&gc(e),r(`stash`)&&_c(e),r(`checkpoint`)&&vc(e),r(`restore`)&&lu(e),r(`lane`)&&yc(e),r(`queue`)&&bc(e),r(`session_digest`)&&wu(e),r(`health`)&&bs(e),r(`process`)&&vs(e),r(`watch`)&&ys(e),r(`web_fetch`)&&xs(e),r(`guide`)&&Ss(e),cc.some(e=>r(e))&&lc(e,t,[...n??new Set(R)]),r(`evidence_map`)&&cs(e),r(`forge_classify`)&&us(e),r(`present`)&&eu(e),r(`produce_knowledge`)&&iu(e),r(`replay`)&&su(e),r(`status`)&&Nu(e),r(`flow`)&&os(e,t),r(`web_search`)&&Iu(e),r(`http`)&&Lu(e),r(`regex_test`)&&Ru(e),r(`encode`)&&zu(e),r(`measure`)&&Bu(e),r(`changelog`)&&Vu(e),r(`schema_validate`)&&Hu(e),r(`env`)&&Uu(e),r(`time`)&&Wu(e)}const qu=D(`resource-notifier`);var Ju=class{constructor(e){this.mcpServer=e}async notifyStatusChanged(){await this.sendUpdate(`aikit://status`)}async notifyFileTreeChanged(){await this.sendUpdate(`aikit://file-tree`)}async notifyCuratedIndexChanged(){await this.sendUpdate(`aikit://curated`)}async notifyCuratedEntryChanged(e){await this.sendUpdate(`aikit://curated/${e}`)}async notifyResourceListChanged(){try{await this.mcpServer.server.sendResourceListChanged()}catch(e){qu.debug(`sendResourceListChanged failed`,{error:String(e)})}}async notifyAfterReindex(){await Promise.allSettled([this.notifyStatusChanged(),this.notifyFileTreeChanged()])}async notifyAfterCuratedWrite(e){let t=[this.notifyStatusChanged(),this.notifyCuratedIndexChanged()];e&&t.push(this.notifyCuratedEntryChanged(e)),await Promise.allSettled(t)}async sendUpdate(e){try{await this.mcpServer.server.sendResourceUpdated({uri:e})}catch(t){qu.debug(`sendResourceUpdated failed`,{uri:e,error:String(t)})}}};const Z=D(`server`);async function Yu(n){Z.info(`Initializing AI Kit components`);let r=n.store.backend,i=n.store.path,o=null;if(r===`sqlite-vec`){let e=g(i,`aikit.db`);o=await yn(e),Z.info(`SQLite adapter ready`,{type:o.type,vectorCapable:o.vectorCapable,dbPath:e}),o.vectorCapable||Z.warn(`┌──────────────────────────────────────────────────────────────────┐
1272
1272
  │ ⚠ SQLite vector extension unavailable — DEGRADED MODE │
1273
1273
  │ Vector search is disabled. Hybrid search returns FTS only. │
1274
1274
  │ To enable: install/rebuild better-sqlite3 (native module). │
1275
- └──────────────────────────────────────────────────────────────────┘`);let t=g(i,`lance`);a(t)&&Z.info(`Old LanceDB data found at ${t} — ignored. Safe to delete after verifying sqlite-vec works.`)}let[s,c,l,u]=await Promise.all([(async()=>{let e=new Dn({model:n.embedding.model,dimensions:n.embedding.dimensions});return await e.initialize(),Z.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await bn({backend:r,path:i,adapter:o??void 0,embeddingDim:n.embedding.dimensions});return await e.initialize(),Z.info(`Store initialized`,{backend:r}),e})(),(async()=>{let e=o?new vn({adapter:o}):new vn({path:i});return await e.initialize(),Z.info(`Graph store initialized`,{shared:!!o}),e})(),(async()=>{let e=await cn();return e?Z.info(`WASM tree-sitter enabled for AST analysis`):Z.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),f=new kn(s,c),p=new On(n.store.path);p.load(),f.setHashCache(p);let m=n.curated.path,h=new e(m);await h.initialize();let v=new t(m,c,s,h);f.setGraphStore(l);let b=Ea(n.er),x=b?new fn(n.curated.path):void 0;x&&Z.info(`Policy store initialized`,{ruleCount:x.getRules().length});let S=b?new dn:void 0,C=_(n.sources[0]?.path??process.cwd(),y.aiContext),w=a(C),T=n.onboardDir?a(n.onboardDir):!1,E=w||T,D,O=w?C:n.onboardDir;if(E&&O)try{D=d(O).mtime.toISOString()}catch{}return Z.info(`Onboard state detected`,{onboardComplete:E,onboardTimestamp:D,aiKbExists:w,onboardDirExists:T}),{embedder:s,store:c,indexer:f,curated:v,graphStore:l,fileCache:new N,bridge:b,policyStore:x,evolutionCollector:S,onboardComplete:E,onboardTimestamp:D}}function Yu(e,t,n){if(e.serverInstructions)return e.serverInstructions;let r=new Set;for(let e of t){let t=n[e];if(t?.category)for(let e of t.category)r.add(e)}let i=[`This server provides ${t.size} tools across ${r.size} categories: ${[...r].sort().join(`, `)}.`];return e.readOnly&&i.push(`Server is in read-only mode. Mutating operations are disabled.`),e.features?.length&&i.push(`Active feature groups: ${e.features.join(`, `)}.`),i.join(` `)}const Xu=D(`background-task`);var Zu=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Xu.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Xu.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Xu.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const Qu=D(`idle-timer`);var $u=class{timer=null;cleanupFns=[];idleMs;disposed=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(this._busy){Qu.info(`Skipping idle cleanup — background work in progress`);return}Qu.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&Qu.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const ed=D(`memory-monitor`);var td=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??4294967296,this.criticalBytes=e?.criticalBytes??8589934592,this.intervalMs=e?.intervalMs??6e4}onPressure(e){this.pressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),ed.info(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?ed.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?ed.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&ed.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const nd=D(`tool-timeout`),rd=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var id=class extends Error{constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function ad(e){return rd.has(e)?6e5:12e4}function od(e,t,n){return new Promise((r,i)=>{let a=!1,o=setTimeout(()=>{if(!a){a=!0;let e=new id(n,t);nd.warn(e.message),i(e)}},t);o.unref&&o.unref(),e().then(e=>{a||(a=!0,clearTimeout(o),r(e))},e=>{a||(a=!0,clearTimeout(o),i(e))})})}const Q=D(`server`);function sd(e){let t=e.toLowerCase();return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`failed to initialize embedding`,`checksum`,`corrupt`,`malformed`,`could not load`,`onnx`,`database disk image is malformed`,`file is not a database`,`lance`].some(e=>t.includes(e))}async function cd(e,t){let n=t.toLowerCase(),r;try{({rm:r}=await import(`node:fs/promises`))}catch{return}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model??x.model,n=g(Cn(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(n,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:n})}catch{}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=g(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=g(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}}}function ld(e,t){let n=di(e,R,z,Hr(e)),i=Yu(e,n,z),a=new qt({name:e.serverName??`aikit`,version:r()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:i}),o=`initializing`,s=``,c=!1,l=null,u=null,d=null;function f(e){if(!e||typeof e!=`object`)return[];let t=e,n=[];for(let e of[`path`,`file`,`source_path`,`sourcePath`,`filePath`]){let r=t[e];typeof r==`string`&&r&&n.push(r)}for(let e of[`changed_files`,`paths`,`files`]){let r=t[e];if(Array.isArray(r))for(let e of r){if(typeof e==`string`){n.push(e);continue}e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path)}}if(Array.isArray(t.sources))for(let e of t.sources)e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path);return n}let p=()=>o===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**${Gr.size} tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,`To fix embedding errors, try deleting the cached model:`,` rm -rf ~/.cache/huggingface/transformers-js/mixedbread-ai/`,`Then restart the server to re-download a fresh copy.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
1275
+ └──────────────────────────────────────────────────────────────────┘`);let t=g(i,`lance`);a(t)&&Z.info(`Old LanceDB data found at ${t} — ignored. Safe to delete after verifying sqlite-vec works.`)}let[s,c,l,u]=await Promise.all([(async()=>{let e=new Dn({model:n.embedding.model,dimensions:n.embedding.dimensions});return await e.initialize(),Z.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await bn({backend:r,path:i,adapter:o??void 0,embeddingDim:n.embedding.dimensions});return await e.initialize(),Z.info(`Store initialized`,{backend:r}),e})(),(async()=>{let e=o?new vn({adapter:o}):new vn({path:i});return await e.initialize(),Z.info(`Graph store initialized`,{shared:!!o}),e})(),(async()=>{let e=await cn();return e?Z.info(`WASM tree-sitter enabled for AST analysis`):Z.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),f=new kn(s,c),p=new On(n.store.path);p.load(),f.setHashCache(p);let m=n.curated.path,h=new e(m);await h.initialize();let v=new t(m,c,s,h);f.setGraphStore(l);let b=Ea(n.er),x=b?new fn(n.curated.path):void 0;x&&Z.info(`Policy store initialized`,{ruleCount:x.getRules().length});let S=b?new dn:void 0,C=_(n.sources[0]?.path??process.cwd(),y.aiContext),w=a(C),T=n.onboardDir?a(n.onboardDir):!1,E=w||T,D,O=w?C:n.onboardDir;if(E&&O)try{D=d(O).mtime.toISOString()}catch{}return Z.info(`Onboard state detected`,{onboardComplete:E,onboardTimestamp:D,aiKbExists:w,onboardDirExists:T}),{embedder:s,store:c,indexer:f,curated:v,graphStore:l,fileCache:new N,bridge:b,policyStore:x,evolutionCollector:S,onboardComplete:E,onboardTimestamp:D}}function Xu(e,t,n){if(e.serverInstructions)return e.serverInstructions;let r=new Set;for(let e of t){let t=n[e];if(t?.category)for(let e of t.category)r.add(e)}let i=[`This server provides ${t.size} tools across ${r.size} categories: ${[...r].sort().join(`, `)}.`];return e.readOnly&&i.push(`Server is in read-only mode. Mutating operations are disabled.`),e.features?.length&&i.push(`Active feature groups: ${e.features.join(`, `)}.`),i.join(` `)}const Zu=D(`background-task`);var Qu=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Zu.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Zu.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Zu.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const $u=D(`idle-timer`);var ed=class{timer=null;cleanupFns=[];idleMs;disposed=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(this._busy){$u.info(`Skipping idle cleanup — background work in progress`);return}$u.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&$u.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const td=D(`memory-monitor`);var nd=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??4294967296,this.criticalBytes=e?.criticalBytes??8589934592,this.intervalMs=e?.intervalMs??6e4}onPressure(e){this.pressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),td.info(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?td.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?td.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&td.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const rd=D(`tool-timeout`),id=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var ad=class extends Error{constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function od(e){return id.has(e)?6e5:12e4}function sd(e,t,n){return new Promise((r,i)=>{let a=!1,o=setTimeout(()=>{if(!a){a=!0;let e=new ad(n,t);rd.warn(e.message),i(e)}},t);o.unref&&o.unref(),e().then(e=>{a||(a=!0,clearTimeout(o),r(e))},e=>{a||(a=!0,clearTimeout(o),i(e))})})}const Q=D(`server`);function cd(e){let t=e.toLowerCase();return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`failed to initialize embedding`,`checksum`,`corrupt`,`malformed`,`could not load`,`onnx`,`database disk image is malformed`,`file is not a database`,`lance`].some(e=>t.includes(e))}async function ld(e,t){let n=t.toLowerCase(),r;try{({rm:r}=await import(`node:fs/promises`))}catch{return}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model??x.model,n=g(Cn(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(n,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:n})}catch{}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=g(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=g(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}}}function ud(e,t){let n=di(e,R,z,Hr(e)),i=Xu(e,n,z),a=new qt({name:e.serverName??`aikit`,version:r()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:i}),o=`initializing`,s=``,c=!1,l=null,u=null,d=null;function f(e){if(!e||typeof e!=`object`)return[];let t=e,n=[];for(let e of[`path`,`file`,`source_path`,`sourcePath`,`filePath`]){let r=t[e];typeof r==`string`&&r&&n.push(r)}for(let e of[`changed_files`,`paths`,`files`]){let r=t[e];if(Array.isArray(r))for(let e of r){if(typeof e==`string`){n.push(e);continue}e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path)}}if(Array.isArray(t.sources))for(let e of t.sources)e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path);return n}let p=()=>o===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**${Gr.size} tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,`To fix embedding errors, try deleting the cached model:`,` rm -rf ~/.cache/huggingface/transformers-js/mixedbread-ai/`,`Then restart the server to re-download a fresh copy.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
1276
1276
  `):[`AI Kit is still initializing (loading embeddings model & store).`,``,`**${Gr.size} tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,`This tool requires the AI Kit index. Please retry in a few seconds,`,`or use one of the available tools above in the meantime.`].join(`
1277
- `);Mn(a),Zr(a,new br,e.toolPrefix??``);let m=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let h=[];for(let e of R){if(!n.has(e))continue;let t=B(e),r=a.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:p()}]}));Gr.has(e)?r.remove():h.push(r)}Gu(a,e,n),a.sendToolListChanged=m;let g=a.registerResource(`aikit-status`,`aikit://status`,{description:`AI Kit status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://status`,text:`AI Kit is initializing...`,mimeType:`text/plain`}]})),_=a.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:F(I.string(),()=>[])}},async()=>({messages:[]})),v,y,b=new Promise((e,t)=>{v=e,y=t}),x,S=new Promise(e=>{x=e}),C=()=>x?.(),w=(async()=>{await S;let n;try{n=await Ju(e)}catch(t){let r=t instanceof Error?t.message:String(t);if(sd(r)){Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await cd(e,r);try{n=await Ju(e),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){o=`failed`,s=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:s,originalError:r}),y?.(e instanceof Error?e:Error(s));return}}else{o=`failed`,s=r,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:s}),y?.(t instanceof Error?t:Error(s));return}}let r=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let i=a.sendPromptListChanged.bind(a);a.sendPromptListChanged=()=>{};let p=a.sendResourceListChanged.bind(a);a.sendResourceListChanged=()=>{};for(let e of h)e.remove();g.remove(),_.remove();let m=a._registeredTools??{};for(let e of Gr)m[e]?.remove();let b=new qu(a),x=Po(a);Wu(a,n,e,An(a),b,x,t,t===`smart`?(()=>{let e=d;return e?.getState?e.getState():null}):null),Un(a,{curated:n.curated,store:n.store,graphStore:n.graphStore},t),a.sendToolListChanged=r,a.sendPromptListChanged=i,a.sendResourceListChanged=p,Promise.resolve(a.sendToolListChanged()).catch(()=>{}),Promise.resolve(a.sendPromptListChanged()).catch(()=>{}),Promise.resolve(a.sendResourceListChanged()).catch(()=>{});let C=a._registeredTools??{};for(let[e,t]of Object.entries(C)){if(Ur.has(e))continue;let r=t.handler;t.handler=async(...t)=>{if(!n.indexer.isIndexing)return r(...t);let i=c?`re-indexing`:`running initial index`,a=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ AI Kit is ${i}. The tool "${e}" timed out waiting for index data (${Wr/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),Wr));return Promise.race([r(...t),a])}}for(let[e,t]of Object.entries(C)){let n=t.handler,r=ad(e);t.handler=async(...t)=>{try{return await od(()=>n(...t),r,e)}catch(t){if(t instanceof id)return{content:[{type:`text`,text:`⏳ Tool "${e}" timed out after ${r/1e3}s. This may indicate a long-running operation. Please retry or break the task into smaller steps.`}]};throw t}}}let w=Object.keys(C).length;w<R.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:R.length,registeredToolCount:w}),Q.info(`MCP server configured`,{toolCount:R.length,resourceCount:4});let T=new td;T.onPressure((e,t)=>{e===`warning`&&In(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),In())}),T.start();let D=new $u;u=D,D.onIdle(async()=>{if(E.isRunning||n.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),D.touch();return}Q.info(`Idle cleanup: closing store and graph connections`);try{await Promise.all([n.store.close().catch(()=>{}),n.graphStore.close().catch(()=>{})])}catch{}}),D.touch();for(let e of Object.values(C)){let t=e.handler;e.handler=async(...e)=>{if(D.touch(),d){let t=f(e[0]);t.length>0&&d.prioritize(...t)}return t(...e)}}l=n,v?.(n)})(),T=async()=>{let t;try{t=await b}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}u?.setBusy(!0);try{let n=e.sources.map(e=>e.path).join(`, `);Q.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});c=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,j(e))}try{let e=await t.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Q.error(`Curated re-index failed`,j(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,j(e))}finally{u?.setBusy(!1)}},E=new Zu,D=()=>E.schedule({name:`initial-index`,fn:T}),O=process.ppid,k=setInterval(()=>{try{process.kill(O,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:O}),clearInterval(k),b.then(async e=>{await Promise.all([e.embedder.shutdown().catch(()=>{}),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return k.unref(),{server:a,startInit:C,ready:w,runInitialIndex:D,get aikit(){return l},scheduler:E,setSmartScheduler(e){d=e}}}const $=D(`server`);function ud(e,t){let n=di(t,[...R,...Br],z,Hr(t)),i=Yu(t,n,z),a=new qt({name:t.serverName??`aikit`,version:r()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:i});return Mn(a),Wu(a,e,t,An(a),new qu(a),Po(a),void 0,null,n),Un(a,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),a}async function dd(e){let t=await Ju(e),n=ud(t,e);$.info(`MCP server configured`,{toolCount:R.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,j(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,j(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,j(e))}},i=async()=>{$.info(`Shutting down`),await Promise.all([t.embedder.shutdown().catch(()=>{}),t.graphStore.close().catch(()=>{}),t.store.close().catch(()=>{})]),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{R as ALL_TOOL_NAMES,ld as createLazyServer,ud as createMcpServer,dd as createServer,Ju as initializeAikit,Wu as registerMcpTools};
1277
+ `);Mn(a),Zr(a,new br,e.toolPrefix??``);let m=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let h=[];for(let e of R){if(!n.has(e))continue;let t=B(e),r=a.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:p()}]}));Gr.has(e)?r.remove():h.push(r)}Ku(a,e,n),a.sendToolListChanged=m;let g=a.registerResource(`aikit-status`,`aikit://status`,{description:`AI Kit status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://status`,text:`AI Kit is initializing...`,mimeType:`text/plain`}]})),_=a.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:F(I.string(),()=>[])}},async()=>({messages:[]})),v,y,b=new Promise((e,t)=>{v=e,y=t}),x,S=new Promise(e=>{x=e}),C=()=>x?.(),w=(async()=>{await S;let n;try{n=await Yu(e)}catch(t){let r=t instanceof Error?t.message:String(t);if(cd(r)){Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await ld(e,r);try{n=await Yu(e),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){o=`failed`,s=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:s,originalError:r}),y?.(e instanceof Error?e:Error(s));return}}else{o=`failed`,s=r,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:s}),y?.(t instanceof Error?t:Error(s));return}}let r=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let i=a.sendPromptListChanged.bind(a);a.sendPromptListChanged=()=>{};let p=a.sendResourceListChanged.bind(a);a.sendResourceListChanged=()=>{};for(let e of h)e.remove();g.remove(),_.remove();let m=a._registeredTools??{};for(let e of Gr)m[e]?.remove();let b=new Ju(a),x=Po(a);Gu(a,n,e,An(a),b,x,t,t===`smart`?(()=>{let e=d;return e?.getState?e.getState():null}):null),Un(a,{curated:n.curated,store:n.store,graphStore:n.graphStore},t),a.sendToolListChanged=r,a.sendPromptListChanged=i,a.sendResourceListChanged=p,Promise.resolve(a.sendToolListChanged()).catch(()=>{}),Promise.resolve(a.sendPromptListChanged()).catch(()=>{}),Promise.resolve(a.sendResourceListChanged()).catch(()=>{});let C=a._registeredTools??{};for(let[e,t]of Object.entries(C)){if(Ur.has(e))continue;let r=t.handler;t.handler=async(...t)=>{if(!n.indexer.isIndexing)return r(...t);let i=c?`re-indexing`:`running initial index`,a=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ AI Kit is ${i}. The tool "${e}" timed out waiting for index data (${Wr/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),Wr));return Promise.race([r(...t),a])}}for(let[e,t]of Object.entries(C)){let n=t.handler,r=od(e);t.handler=async(...t)=>{try{return await sd(()=>n(...t),r,e)}catch(t){if(t instanceof ad)return{content:[{type:`text`,text:`⏳ Tool "${e}" timed out after ${r/1e3}s. This may indicate a long-running operation. Please retry or break the task into smaller steps.`}]};throw t}}}let w=Object.keys(C).length;w<R.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:R.length,registeredToolCount:w}),Q.info(`MCP server configured`,{toolCount:R.length,resourceCount:4});let T=new nd;T.onPressure((e,t)=>{e===`warning`&&In(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),In())}),T.start();let D=new ed;u=D,D.onIdle(async()=>{if(E.isRunning||n.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),D.touch();return}Q.info(`Idle cleanup: closing store and graph connections`);try{await Promise.all([n.store.close().catch(()=>{}),n.graphStore.close().catch(()=>{})])}catch{}}),D.touch();for(let e of Object.values(C)){let t=e.handler;e.handler=async(...e)=>{if(D.touch(),d){let t=f(e[0]);t.length>0&&d.prioritize(...t)}return t(...e)}}l=n,v?.(n)})(),T=async()=>{let t;try{t=await b}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}u?.setBusy(!0);try{let n=e.sources.map(e=>e.path).join(`, `);Q.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});c=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,j(e))}try{let e=await t.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Q.error(`Curated re-index failed`,j(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,j(e))}finally{u?.setBusy(!1)}},E=new Qu,D=()=>E.schedule({name:`initial-index`,fn:T}),O=process.ppid,k=setInterval(()=>{try{process.kill(O,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:O}),clearInterval(k),b.then(async e=>{await Promise.all([e.embedder.shutdown().catch(()=>{}),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return k.unref(),{server:a,startInit:C,ready:w,runInitialIndex:D,get aikit(){return l},scheduler:E,setSmartScheduler(e){d=e}}}const $=D(`server`);function dd(e,t){let n=di(t,[...R,...Br],z,Hr(t)),i=Xu(t,n,z),a=new qt({name:t.serverName??`aikit`,version:r()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:i});return Mn(a),Gu(a,e,t,An(a),new Ju(a),Po(a),void 0,null,n),Un(a,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),a}async function fd(e){let t=await Yu(e),n=dd(t,e);$.info(`MCP server configured`,{toolCount:R.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,j(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,j(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,j(e))}},i=async()=>{$.info(`Shutting down`),await Promise.all([t.embedder.shutdown().catch(()=>{}),t.graphStore.close().catch(()=>{}),t.store.close().catch(()=>{})]),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{R as ALL_TOOL_NAMES,ud as createLazyServer,dd as createMcpServer,fd as createServer,Yu as initializeAikit,Gu as registerMcpTools};
@@ -187,6 +187,8 @@ interface IKnowledgeStore {
187
187
  upsertWithoutVector?(record: KnowledgeRecord, sourceRecordId: string): Promise<void>;
188
188
  /** Search by vector similarity */
189
189
  search(queryVector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
190
+ /** Coarse vector search using reduced-dimension embeddings (multi-resolution matryoshka) */
191
+ coarseSearch?(queryVector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
190
192
  /** Get a specific record by ID */
191
193
  getById(id: string): Promise<KnowledgeRecord | null>;
192
194
  /** Delete records by source path (used during re-indexing) */
@@ -388,6 +390,8 @@ declare class SqliteVecStore implements IKnowledgeStore {
388
390
  private readonly externalAdapter;
389
391
  private readonly dbPath;
390
392
  private readonly embeddingDim;
393
+ /** Coarse embedding dimension for multi-resolution search (matryoshka). */
394
+ private readonly coarseDim;
391
395
  private vectorEnabled;
392
396
  private warnedVectorDisabled;
393
397
  private _draining;
@@ -423,6 +427,7 @@ declare class SqliteVecStore implements IKnowledgeStore {
423
427
  private upsertKnowledgeRow;
424
428
  private _upsertImpl;
425
429
  search(queryVector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
430
+ coarseSearch(queryVector: Float32Array, options?: SearchOptions): Promise<SearchResult[]>;
426
431
  ftsSearch(query: string, options?: SearchOptions): Promise<SearchResult[]>;
427
432
  getById(id: string): Promise<KnowledgeRecord | null>;
428
433
  deleteBySourcePath(sourcePath: string): Promise<number>;
@@ -1,4 +1,4 @@
1
- import{t as e}from"./lance-store-BRoi-4qY.js";import{i as t,r as n,t as r}from"./sqlite-vec-store-Bnn0_imk.js";import{AIKIT_PATHS as i}from"../../core/dist/index.js";import{existsSync as a,mkdirSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";var l=class{adapter=null;reopenPromise=null;dbPath;externalAdapter;constructor(e={}){if(e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=e.path??i.data;this.dbPath=c(t,`graph.db`),this.externalAdapter=!1}}async initialize(){if(this.externalAdapter){let e=this.getAdapter();this.createTables(e),this.migrateSchema(e),e.flush();return}let e=s(this.dbPath);a(e)||o(e,{recursive:!0}),this.adapter=await t(this.dbPath),this.configureAdapter(this.adapter),this.createTables(this.adapter),this.migrateSchema(this.adapter),this.adapter.flush()}configureAdapter(e){e.pragma(`journal_mode = WAL`),e.pragma(`foreign_keys = ON`)}createTables(e){e.exec(`
1
+ import{t as e}from"./lance-store-BRoi-4qY.js";import{i as t,r as n,t as r}from"./sqlite-vec-store-DQE-A0rY.js";import{AIKIT_PATHS as i}from"../../core/dist/index.js";import{existsSync as a,mkdirSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";var l=class{adapter=null;reopenPromise=null;dbPath;externalAdapter;constructor(e={}){if(e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=e.path??i.data;this.dbPath=c(t,`graph.db`),this.externalAdapter=!1}}async initialize(){if(this.externalAdapter){let e=this.getAdapter();this.createTables(e),this.migrateSchema(e),e.flush();return}let e=s(this.dbPath);a(e)||o(e,{recursive:!0}),this.adapter=await t(this.dbPath),this.configureAdapter(this.adapter),this.createTables(this.adapter),this.migrateSchema(this.adapter),this.adapter.flush()}configureAdapter(e){e.pragma(`journal_mode = WAL`),e.pragma(`foreign_keys = ON`)}createTables(e){e.exec(`
2
2
  CREATE TABLE IF NOT EXISTS nodes (
3
3
  id TEXT PRIMARY KEY,
4
4
  type TEXT NOT NULL,
@@ -87,4 +87,4 @@ import{t as e}from"./lance-store-BRoi-4qY.js";import{i as t,r as n,t as r}from".
87
87
  VALUES (?, ?, ?, '{}', ?)`,[a,e,t,o]);for(let e=0;e<n.length;e++)this.run(`INSERT INTO process_steps (process_id, node_id, step_order) VALUES (?, ?, ?)`,[a,n[e],e]);s.exec(`COMMIT`),s.flush()}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){await this.ensureOpen();let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
88
88
  FROM processes p
89
89
  JOIN process_steps ps ON p.id = ps.process_id
90
- WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:u(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}async close(){this.adapter&&=(this.externalAdapter||this.adapter.close(),null)}};function u(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function d(e){return{id:e.id,type:e.type,name:e.name,properties:u(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function f(e){return{id:e.id,fromId:e.from_id,toId:e.to_id,type:e.type,weight:e.weight??1,confidence:e.confidence??1,properties:u(e.properties)}}function p(e){return{id:e.edge_id,fromId:e.from_id,toId:e.to_id,type:e.edge_type,weight:e.weight??1,confidence:e.edge_confidence??1,properties:u(e.edge_props??`{}`)}}function m(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:u(e.node_props??`{}`),sourceRecordId:e.node_src_rec??void 0,sourcePath:e.node_src_path??void 0,createdAt:e.node_created,community:e.node_community??void 0}}async function h(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-BRoi-4qY.js`).then(e=>e.n);return new t({path:e.path})}case`sqlite-vec`:{let{SqliteVecStore:t}=await import(`./sqlite-vec-store-Bnn0_imk.js`).then(e=>e.n);return new t({path:e.path,adapter:e.adapter,embeddingDim:e.embeddingDim})}default:{let t=e.backend;throw Error(`Unknown store backend: "${t}". Supported: lancedb, sqlite-vec`)}}}export{e as LanceStore,l as SqliteGraphStore,r as SqliteVecStore,n as createSqlJsAdapter,t as createSqliteAdapter,h as createStore};
90
+ WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:u(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}async close(){this.adapter&&=(this.externalAdapter||this.adapter.close(),null)}};function u(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function d(e){return{id:e.id,type:e.type,name:e.name,properties:u(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function f(e){return{id:e.id,fromId:e.from_id,toId:e.to_id,type:e.type,weight:e.weight??1,confidence:e.confidence??1,properties:u(e.properties)}}function p(e){return{id:e.edge_id,fromId:e.from_id,toId:e.to_id,type:e.edge_type,weight:e.weight??1,confidence:e.edge_confidence??1,properties:u(e.edge_props??`{}`)}}function m(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:u(e.node_props??`{}`),sourceRecordId:e.node_src_rec??void 0,sourcePath:e.node_src_path??void 0,createdAt:e.node_created,community:e.node_community??void 0}}async function h(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-BRoi-4qY.js`).then(e=>e.n);return new t({path:e.path})}case`sqlite-vec`:{let{SqliteVecStore:t}=await import(`./sqlite-vec-store-DQE-A0rY.js`).then(e=>e.n);return new t({path:e.path,adapter:e.adapter,embeddingDim:e.embeddingDim})}default:{let t=e.backend;throw Error(`Unknown store backend: "${t}". Supported: lancedb, sqlite-vec`)}}}export{e as LanceStore,l as SqliteGraphStore,r as SqliteVecStore,n as createSqlJsAdapter,t as createSqliteAdapter,h as createStore};
@@ -0,0 +1,88 @@
1
+ import{n as e,t}from"./rolldown-runtime-BynbHzcv.js";import{createRequire as n}from"node:module";import{EMBEDDING_DEFAULTS as r,SEARCH_DEFAULTS as i,STORE_DEFAULTS as a,createLogger as o,serializeError as s,sourceTypeContentTypes as c}from"../../core/dist/index.js";import{existsSync as l,mkdirSync as u,readFileSync as d,renameSync as f,unlinkSync as p,writeFileSync as m}from"node:fs";import{dirname as h}from"node:path";const g=o(`sqlite-adapter`),_=n(import.meta.url);var v=class{type=`better-sqlite3`;vectorCapable=!1;db=null;stmtCache=new Map;async open(e){let t;try{t=_(`better-sqlite3`)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new t(e),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{_(`sqlite-vec`).load(this.db),this.vectorCapable=!0,g.info(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,g.warn(`sqlite-vec extension failed to load; vector search disabled`,s(e))}}exec(e){this.getDb().exec(e)}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}run(e,t=[]){let n=this.prepareCached(e);t.length>0?n.run(...t):n.run()}flush(){}close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function y(e){return _.resolve(`sql.js/dist/${e}`)}var b=class{type=`sql.js`;vectorCapable=!1;db=null;dbPath=``;dirty=!1;inTransaction=!1;async open(e){this.dbPath=e;let t=(await import(`sql.js`)).default,n=await t({locateFile:e=>y(e)});if(l(e)){let t=d(e);this.db=new n.Database(t)}else this.db=new n.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.dirty=!0}pragma(e){this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=!this.inTransaction&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));i&&n.run(`SAVEPOINT fk_check`);try{if(t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(i){if(n.exec(`PRAGMA foreign_key_check`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(i)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export(),t=`${this.dbPath}.tmp`;m(t,Buffer.from(e)),f(t,this.dbPath),this.dirty=!1}close(){if(this.db){let e=this.db,t;try{this.flush()}catch(e){t=e;try{p(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};let x=!1;async function S(e){let t=new v;try{return await t.open(e),t}catch(e){x||(x=!0,g.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,s(e)))}let n=new b;try{return await n.open(e),n}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function C(e){let t=new b;return await t.open(e),t}var w=t({SqliteVecStore:()=>A});function T(e){let t=0;for(let n=0;n<e.length;n++){let r=e[n]<0?-e[n]:e[n];r>t&&(t=r)}let n=new Int8Array(e.length);if(t===0)return Buffer.from(n.buffer,n.byteOffset,n.byteLength);let r=127/t;for(let t=0;t<e.length;t++){let i=Math.round(e[t]*r);n[t]=i<-127?-127:i>127?127:i}return Buffer.from(n.buffer,n.byteOffset,n.byteLength)}const E=/^[\w.\-/ ]+$/,D=o(`sqlite-vec-store`);function O(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function k(e,t){if(!E.test(e))throw Error(`Invalid ${t} filter value: contains disallowed characters`);return e}var A=class{adapter=null;externalAdapter;dbPath;embeddingDim;coarseDim;vectorEnabled=!1;warnedVectorDisabled=!1;_draining=!1;_priorityQueue=[];_normalQueue=[];constructor(e={}){this.embeddingDim=e.embeddingDim??r.dimensions,this.coarseDim=Math.min(128,this.embeddingDim),e.adapter?(this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``):(this.dbPath=e.path??`${a.path}/aikit.db`,this.externalAdapter=!1)}async initialize(){if(!this.adapter){let e=h(this.dbPath);l(e)||u(e,{recursive:!0}),this.adapter=await S(this.dbPath)}this.vectorEnabled=this.adapter.vectorCapable,this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled?this.ensureVecTable():this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,D.warn(`SqliteVecStore: vector search disabled (sqlite-vec extension not loaded). Hybrid search will return FTS-only results.`))}getDiagnostics(){let t=this.adapter,n=t?t.constructor.name:`unknown`,r=null,i=this.externalAdapter?``:this.dbPath;if(i)try{let{statSync:t}=e(`node:fs`);r=t(i).size}catch{r=null}return{adapterType:n,vectorSearchEnabled:this.vectorEnabled,degradedMode:!this.vectorEnabled,dbPath:i,dbSizeBytes:r,embeddingDim:this.embeddingDim,vectorDtype:`int8`}}createKnowledgeTable(){let e=this.getAdapter();e.exec(`
2
+ CREATE TABLE IF NOT EXISTS knowledge (
3
+ id TEXT PRIMARY KEY,
4
+ content TEXT NOT NULL,
5
+ sourcePath TEXT NOT NULL,
6
+ contentType TEXT NOT NULL,
7
+ headingPath TEXT NOT NULL DEFAULT '',
8
+ chunkIndex INTEGER NOT NULL DEFAULT 0,
9
+ totalChunks INTEGER NOT NULL DEFAULT 1,
10
+ startLine INTEGER NOT NULL DEFAULT 0,
11
+ endLine INTEGER NOT NULL DEFAULT 0,
12
+ fileHash TEXT NOT NULL DEFAULT '',
13
+ content_hash TEXT NOT NULL DEFAULT '',
14
+ indexedAt TEXT NOT NULL,
15
+ origin TEXT NOT NULL DEFAULT 'indexed',
16
+ tags TEXT NOT NULL DEFAULT '[]',
17
+ category TEXT NOT NULL DEFAULT '',
18
+ version INTEGER NOT NULL DEFAULT 1
19
+ )
20
+ `),e.queryAll(`PRAGMA table_info(knowledge)`).some(e=>e.name===`content_hash`)||e.exec(`ALTER TABLE knowledge ADD COLUMN content_hash TEXT NOT NULL DEFAULT ''`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_sourcePath ON knowledge(sourcePath)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_contentType ON knowledge(contentType)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_content_hash ON knowledge(content_hash)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_origin ON knowledge(origin)`)}createFtsTable(){this.getAdapter().exec(`
21
+ CREATE VIRTUAL TABLE IF NOT EXISTS knowledge_fts USING fts5(
22
+ id UNINDEXED,
23
+ content,
24
+ tokenize = 'unicode61 remove_diacritics 2'
25
+ )
26
+ `)}ensureVecTable(){let e=this.getAdapter(),t=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type='table' AND name='vec_knowledge'`);if(t.length>0){let n=t[0].sql??``,r=n.match(/(?:float|int8)\[(\d+)\]/i),i=r?Number(r[1]):null,a=/int8\[/i.test(n);(i!==null&&i!==this.embeddingDim||!a)&&(D.warn(`Vec table schema mismatch — dropping for recreation`,{existingDim:i,newDim:this.embeddingDim,wasInt8:a}),e.exec(`DROP TABLE vec_knowledge`))}e.exec(`
27
+ CREATE VIRTUAL TABLE IF NOT EXISTS vec_knowledge USING vec0(
28
+ embedding int8[${this.embeddingDim}] distance_metric=cosine,
29
+ +knowledge_id TEXT
30
+ )
31
+ `),this.coarseDim<this.embeddingDim&&e.exec(`
32
+ CREATE VIRTUAL TABLE IF NOT EXISTS vec_knowledge_coarse USING vec0(
33
+ embedding int8[${this.coarseDim}] distance_metric=cosine,
34
+ +knowledge_id TEXT
35
+ )
36
+ `)}enqueueWrite(e,t=!1){return new Promise((n,r)=>{let i=async()=>{try{n(await e())}catch(e){r(e)}};t?this._priorityQueue.push(i):this._normalQueue.push(i),this._drain()})}async _drain(){if(!this._draining){this._draining=!0;try{for(;this._priorityQueue.length>0||this._normalQueue.length>0;){let e=this._priorityQueue.shift()??this._normalQueue.shift();e&&await e()}}finally{this._draining=!1}}}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async upsertInteractive(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t),!0)}}async upsertWithoutVector(e,t){return this.enqueueWrite(async()=>{let n=this.getAdapter(),r=e;n.exec(`BEGIN`);try{if(this.upsertKnowledgeRow(r),n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[r.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[r.id,r.content]),this.vectorEnabled){let e=n.queryAll(`SELECT embedding FROM vec_knowledge WHERE knowledge_id = ?`,[t]);if(e.length>0){if(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]),this.coarseDim<this.embeddingDim){let e=n.queryAll(`SELECT embedding FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[t]);e.length>0&&(n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]))}}else D.warn(`upsertWithoutVector: source vector not found, record will lack vector`,{recordId:r.id,sourceRecordId:t})}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()})}upsertKnowledgeRow(e){this.getAdapter().run(`INSERT INTO knowledge (id, content, sourcePath, contentType, headingPath, chunkIndex,
37
+ totalChunks, startLine, endLine, fileHash, content_hash, indexedAt, origin, tags, category, version)
38
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
39
+ ON CONFLICT(id) DO UPDATE SET
40
+ content = excluded.content,
41
+ sourcePath = excluded.sourcePath,
42
+ contentType = excluded.contentType,
43
+ headingPath = excluded.headingPath,
44
+ chunkIndex = excluded.chunkIndex,
45
+ totalChunks = excluded.totalChunks,
46
+ startLine = excluded.startLine,
47
+ endLine = excluded.endLine,
48
+ fileHash = excluded.fileHash,
49
+ content_hash = excluded.content_hash,
50
+ indexedAt = excluded.indexedAt,
51
+ origin = excluded.origin,
52
+ tags = excluded.tags,
53
+ category = excluded.category,
54
+ version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(e.tags??[]),e.category??``,e.version])}async _upsertImpl(e,t){let n=this.getAdapter();n.exec(`BEGIN`);try{for(let r=0;r<e.length;r++){let i=e[r];if(this.upsertKnowledgeRow(i),n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[i.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[i.id,i.content]),this.vectorEnabled&&(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[T(t[r]),i.id]),this.coarseDim<this.embeddingDim)){let e=t[r].subarray(0,this.coarseDim);n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[T(e),i.id])}}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()}async search(e,t){if(!this.vectorEnabled)return this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,D.warn(`search() called but vector backend is disabled — returning []`)),[];let n=this.getAdapter(),r=t?.limit??i.maxResults,a=t?.minScore??i.minScore,o=r*4,c=`
55
+ SELECT k.*, v.distance AS _distance
56
+ FROM (
57
+ SELECT knowledge_id, distance
58
+ FROM vec_knowledge
59
+ WHERE embedding MATCH vec_int8(?)
60
+ ORDER BY distance
61
+ LIMIT ?
62
+ ) v
63
+ JOIN knowledge k ON k.id = v.knowledge_id
64
+ ${this.buildFilterSqlSuffix(t)}
65
+ ORDER BY v.distance ASC
66
+ LIMIT ?
67
+ `,l;try{l=n.queryAll(c,[T(e),o,r])}catch(e){return D.warn(`vector search failed`,s(e)),[]}return l.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=a).slice(0,r)}async coarseSearch(e,t){if(!this.vectorEnabled||this.coarseDim>=this.embeddingDim)return this.search(e,t);let n=this.getAdapter(),r=t?.limit??i.maxResults,a=t?.minScore??i.minScore,o=r*4,c=e.subarray(0,this.coarseDim),l=`
68
+ SELECT k.*, v.distance AS _distance
69
+ FROM (
70
+ SELECT knowledge_id, distance
71
+ FROM vec_knowledge_coarse
72
+ WHERE embedding MATCH vec_int8(?)
73
+ ORDER BY distance
74
+ LIMIT ?
75
+ ) v
76
+ JOIN knowledge k ON k.id = v.knowledge_id
77
+ ${this.buildFilterSqlSuffix(t)}
78
+ ORDER BY v.distance ASC
79
+ LIMIT ?
80
+ `,u;try{u=n.queryAll(l,[T(c),o,r])}catch(n){return D.warn(`coarse vector search failed, falling back to full search`,s(n)),this.search(e,t)}return u.length===0?this.search(e,t):u.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=a).slice(0,r)}async ftsSearch(e,t){if(!e||e.trim().length===0)return[];let n=this.getAdapter(),r=t?.limit??i.maxResults,a=`
81
+ SELECT k.*, bm25(knowledge_fts) AS _bm25
82
+ FROM knowledge_fts
83
+ JOIN knowledge k ON k.id = knowledge_fts.id
84
+ WHERE knowledge_fts MATCH ?
85
+ ${this.buildFilterSqlSuffix(t,!0)}
86
+ ORDER BY _bm25 ASC
87
+ LIMIT ?
88
+ `,o;try{let t=j(e);o=n.queryAll(a,[t,r])}catch(e){return D.warn(`fts search failed`,s(e)),[]}return o.map(e=>({record:this.fromRow(e),score:M(e._bm25)}))}async getById(e){let t=this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE id = ? LIMIT 1`,[e]);return t.length===0?null:this.fromRow(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){let t=this.getAdapter(),n=t.queryAll(`SELECT id FROM knowledge WHERE sourcePath = ?`,[e]);if(n.length===0)return 0;t.exec(`BEGIN`);try{for(let{id:e}of n)this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]);t.run(`DELETE FROM knowledge WHERE sourcePath = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),n.length}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async deleteByIdInteractive(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e),!0)}async _deleteByIdImpl(e){let t=this.getAdapter();if(t.queryAll(`SELECT id FROM knowledge WHERE id = ? LIMIT 1`,[e]).length===0)return!1;t.exec(`BEGIN`);try{this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]),t.run(`DELETE FROM knowledge WHERE id = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),!0}async getBySourcePath(e){return this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE sourcePath = ? ORDER BY chunkIndex ASC`,[e]).map(e=>this.fromRow(e))}async getStats(){let e=this.getAdapter(),t=e.queryAll(`SELECT COUNT(*) AS n FROM knowledge`)[0]?.n??0;if(t===0)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`sqlite-vec`,embeddingModel:r.model};let n=e.queryAll(`SELECT COUNT(DISTINCT sourcePath) AS n FROM knowledge`),i=e.queryAll(`SELECT contentType, COUNT(*) AS n FROM knowledge GROUP BY contentType`),a=e.queryAll(`SELECT MAX(indexedAt) AS ts FROM knowledge`),o={};for(let e of i)o[e.contentType]=e.n;return{totalRecords:t,totalFiles:n[0]?.n??0,contentTypeBreakdown:o,lastIndexedAt:a[0]?.ts??null,storeBackend:`sqlite-vec`,embeddingModel:r.model}}async listSourcePaths(){return this.getAdapter().queryAll(`SELECT DISTINCT sourcePath FROM knowledge ORDER BY sourcePath`).map(e=>e.sourcePath)}async createFtsIndex(){this.createFtsTable()}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){let e=this.getAdapter();e.exec(`DROP TABLE IF EXISTS knowledge_fts`),this.vectorEnabled&&(this.coarseDim<this.embeddingDim&&e.exec(`DROP TABLE IF EXISTS vec_knowledge_coarse`),e.exec(`DROP TABLE IF EXISTS vec_knowledge`)),e.exec(`DROP TABLE IF EXISTS knowledge`),e.flush(),this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled&&this.ensureVecTable()}async close(){for(;this._priorityQueue.length>0||this._normalQueue.length>0||this._draining;)await new Promise(e=>setTimeout(e,5));this.adapter&&!this.externalAdapter&&this.adapter.close(),this.adapter=null}getAdapter(){if(!this.adapter)throw Error(`SqliteVecStore: not initialized — call initialize() first`);return this.adapter}buildFilterSqlSuffix(e,t=!1){if(!e)return``;let n=[];if(e.contentType&&n.push(`k.contentType = '${k(e.contentType,`contentType`)}'`),e.sourceType){let t=c(e.sourceType);if(t.length>0){let e=t.map(e=>`'${k(e,`sourceType`)}'`).join(`, `);n.push(`k.contentType IN (${e})`)}}if(e.origin&&n.push(`k.origin = '${k(e.origin,`origin`)}'`),e.category&&n.push(`k.category = '${k(e.category,`category`)}'`),e.tags&&e.tags.length>0){let t=e.tags.map(e=>`k.tags LIKE '%' || '${k(e,`tag`)}' || '%'`);n.push(`(${t.join(` OR `)})`)}if(n.length===0)return``;let r=n.join(` AND `);return t?`AND ${r}`:`WHERE ${r}`}fromRow(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,contentHash:e.content_hash||void 0,indexedAt:e.indexedAt,origin:e.origin,tags:O(e.tags),category:e.category||void 0,version:e.version}}};function j(e){let t=e.replace(/["'()*:^-]/g,` `).trim();return t?t.split(/\s+/).filter(e=>e.length>0).map(e=>`"${e}"`).join(` OR `):`""`}function M(e){return e==null||Number.isNaN(e)?0:1-Math.exp(-Math.abs(e)/5)}export{S as i,w as n,C as r,A as t};
@@ -1,70 +0,0 @@
1
- import{n as e,t}from"./rolldown-runtime-BynbHzcv.js";import{createRequire as n}from"node:module";import{EMBEDDING_DEFAULTS as r,SEARCH_DEFAULTS as i,STORE_DEFAULTS as a,createLogger as o,serializeError as s,sourceTypeContentTypes as c}from"../../core/dist/index.js";import{existsSync as l,mkdirSync as u,readFileSync as d,renameSync as f,unlinkSync as p,writeFileSync as m}from"node:fs";import{dirname as h}from"node:path";const g=o(`sqlite-adapter`),_=n(import.meta.url);var v=class{type=`better-sqlite3`;vectorCapable=!1;db=null;stmtCache=new Map;async open(e){let t;try{t=_(`better-sqlite3`)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new t(e),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{_(`sqlite-vec`).load(this.db),this.vectorCapable=!0,g.info(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,g.warn(`sqlite-vec extension failed to load; vector search disabled`,s(e))}}exec(e){this.getDb().exec(e)}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}run(e,t=[]){let n=this.prepareCached(e);t.length>0?n.run(...t):n.run()}flush(){}close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function y(e){return _.resolve(`sql.js/dist/${e}`)}var b=class{type=`sql.js`;vectorCapable=!1;db=null;dbPath=``;dirty=!1;inTransaction=!1;async open(e){this.dbPath=e;let t=(await import(`sql.js`)).default,n=await t({locateFile:e=>y(e)});if(l(e)){let t=d(e);this.db=new n.Database(t)}else this.db=new n.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.dirty=!0}pragma(e){this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=!this.inTransaction&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));i&&n.run(`SAVEPOINT fk_check`);try{if(t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(i){if(n.exec(`PRAGMA foreign_key_check`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(i)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export(),t=`${this.dbPath}.tmp`;m(t,Buffer.from(e)),f(t,this.dbPath),this.dirty=!1}close(){if(this.db){let e=this.db,t;try{this.flush()}catch(e){t=e;try{p(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};let x=!1;async function S(e){let t=new v;try{return await t.open(e),t}catch(e){x||(x=!0,g.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,s(e)))}let n=new b;try{return await n.open(e),n}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function C(e){let t=new b;return await t.open(e),t}var w=t({SqliteVecStore:()=>A});function T(e){let t=0;for(let n=0;n<e.length;n++){let r=e[n]<0?-e[n]:e[n];r>t&&(t=r)}let n=new Int8Array(e.length);if(t===0)return Buffer.from(n.buffer,n.byteOffset,n.byteLength);let r=127/t;for(let t=0;t<e.length;t++){let i=Math.round(e[t]*r);n[t]=i<-127?-127:i>127?127:i}return Buffer.from(n.buffer,n.byteOffset,n.byteLength)}const E=/^[\w.\-/ ]+$/,D=o(`sqlite-vec-store`);function O(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function k(e,t){if(!E.test(e))throw Error(`Invalid ${t} filter value: contains disallowed characters`);return e}var A=class{adapter=null;externalAdapter;dbPath;embeddingDim;vectorEnabled=!1;warnedVectorDisabled=!1;_draining=!1;_priorityQueue=[];_normalQueue=[];constructor(e={}){this.embeddingDim=e.embeddingDim??r.dimensions,e.adapter?(this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``):(this.dbPath=e.path??`${a.path}/aikit.db`,this.externalAdapter=!1)}async initialize(){if(!this.adapter){let e=h(this.dbPath);l(e)||u(e,{recursive:!0}),this.adapter=await S(this.dbPath)}this.vectorEnabled=this.adapter.vectorCapable,this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled?this.ensureVecTable():this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,D.warn(`SqliteVecStore: vector search disabled (sqlite-vec extension not loaded). Hybrid search will return FTS-only results.`))}getDiagnostics(){let t=this.adapter,n=t?t.constructor.name:`unknown`,r=null,i=this.externalAdapter?``:this.dbPath;if(i)try{let{statSync:t}=e(`node:fs`);r=t(i).size}catch{r=null}return{adapterType:n,vectorSearchEnabled:this.vectorEnabled,degradedMode:!this.vectorEnabled,dbPath:i,dbSizeBytes:r,embeddingDim:this.embeddingDim,vectorDtype:`int8`}}createKnowledgeTable(){let e=this.getAdapter();e.exec(`
2
- CREATE TABLE IF NOT EXISTS knowledge (
3
- id TEXT PRIMARY KEY,
4
- content TEXT NOT NULL,
5
- sourcePath TEXT NOT NULL,
6
- contentType TEXT NOT NULL,
7
- headingPath TEXT NOT NULL DEFAULT '',
8
- chunkIndex INTEGER NOT NULL DEFAULT 0,
9
- totalChunks INTEGER NOT NULL DEFAULT 1,
10
- startLine INTEGER NOT NULL DEFAULT 0,
11
- endLine INTEGER NOT NULL DEFAULT 0,
12
- fileHash TEXT NOT NULL DEFAULT '',
13
- content_hash TEXT NOT NULL DEFAULT '',
14
- indexedAt TEXT NOT NULL,
15
- origin TEXT NOT NULL DEFAULT 'indexed',
16
- tags TEXT NOT NULL DEFAULT '[]',
17
- category TEXT NOT NULL DEFAULT '',
18
- version INTEGER NOT NULL DEFAULT 1
19
- )
20
- `),e.queryAll(`PRAGMA table_info(knowledge)`).some(e=>e.name===`content_hash`)||e.exec(`ALTER TABLE knowledge ADD COLUMN content_hash TEXT NOT NULL DEFAULT ''`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_sourcePath ON knowledge(sourcePath)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_contentType ON knowledge(contentType)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_content_hash ON knowledge(content_hash)`),e.exec(`CREATE INDEX IF NOT EXISTS idx_knowledge_origin ON knowledge(origin)`)}createFtsTable(){this.getAdapter().exec(`
21
- CREATE VIRTUAL TABLE IF NOT EXISTS knowledge_fts USING fts5(
22
- id UNINDEXED,
23
- content,
24
- tokenize = 'unicode61 remove_diacritics 2'
25
- )
26
- `)}ensureVecTable(){let e=this.getAdapter(),t=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type='table' AND name='vec_knowledge'`);if(t.length>0){let n=t[0].sql??``,r=n.match(/(?:float|int8)\[(\d+)\]/i),i=r?Number(r[1]):null,a=/int8\[/i.test(n);(i!==null&&i!==this.embeddingDim||!a)&&(D.warn(`Vec table schema mismatch — dropping for recreation`,{existingDim:i,newDim:this.embeddingDim,wasInt8:a}),e.exec(`DROP TABLE vec_knowledge`))}e.exec(`
27
- CREATE VIRTUAL TABLE IF NOT EXISTS vec_knowledge USING vec0(
28
- embedding int8[${this.embeddingDim}] distance_metric=cosine,
29
- +knowledge_id TEXT
30
- )
31
- `)}enqueueWrite(e,t=!1){return new Promise((n,r)=>{let i=async()=>{try{n(await e())}catch(e){r(e)}};t?this._priorityQueue.push(i):this._normalQueue.push(i),this._drain()})}async _drain(){if(!this._draining){this._draining=!0;try{for(;this._priorityQueue.length>0||this._normalQueue.length>0;){let e=this._priorityQueue.shift()??this._normalQueue.shift();e&&await e()}}finally{this._draining=!1}}}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async upsertInteractive(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t),!0)}}async upsertWithoutVector(e,t){return this.enqueueWrite(async()=>{let n=this.getAdapter(),r=e;n.exec(`BEGIN`);try{if(this.upsertKnowledgeRow(r),n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[r.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[r.id,r.content]),this.vectorEnabled){let e=n.queryAll(`SELECT embedding FROM vec_knowledge WHERE knowledge_id = ?`,[t]);e.length>0?(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id])):D.warn(`upsertWithoutVector: source vector not found, record will lack vector`,{recordId:r.id,sourceRecordId:t})}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()})}upsertKnowledgeRow(e){this.getAdapter().run(`INSERT INTO knowledge (id, content, sourcePath, contentType, headingPath, chunkIndex,
32
- totalChunks, startLine, endLine, fileHash, content_hash, indexedAt, origin, tags, category, version)
33
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
34
- ON CONFLICT(id) DO UPDATE SET
35
- content = excluded.content,
36
- sourcePath = excluded.sourcePath,
37
- contentType = excluded.contentType,
38
- headingPath = excluded.headingPath,
39
- chunkIndex = excluded.chunkIndex,
40
- totalChunks = excluded.totalChunks,
41
- startLine = excluded.startLine,
42
- endLine = excluded.endLine,
43
- fileHash = excluded.fileHash,
44
- content_hash = excluded.content_hash,
45
- indexedAt = excluded.indexedAt,
46
- origin = excluded.origin,
47
- tags = excluded.tags,
48
- category = excluded.category,
49
- version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(e.tags??[]),e.category??``,e.version])}async _upsertImpl(e,t){let n=this.getAdapter();n.exec(`BEGIN`);try{for(let r=0;r<e.length;r++){let i=e[r];this.upsertKnowledgeRow(i),n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[i.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[i.id,i.content]),this.vectorEnabled&&(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[T(t[r]),i.id]))}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()}async search(e,t){if(!this.vectorEnabled)return this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,D.warn(`search() called but vector backend is disabled — returning []`)),[];let n=this.getAdapter(),r=t?.limit??i.maxResults,a=t?.minScore??i.minScore,o=r*4,c=`
50
- SELECT k.*, v.distance AS _distance
51
- FROM (
52
- SELECT knowledge_id, distance
53
- FROM vec_knowledge
54
- WHERE embedding MATCH vec_int8(?)
55
- ORDER BY distance
56
- LIMIT ?
57
- ) v
58
- JOIN knowledge k ON k.id = v.knowledge_id
59
- ${this.buildFilterSqlSuffix(t)}
60
- ORDER BY v.distance ASC
61
- LIMIT ?
62
- `,l;try{l=n.queryAll(c,[T(e),o,r])}catch(e){return D.warn(`vector search failed`,s(e)),[]}return l.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=a).slice(0,r)}async ftsSearch(e,t){if(!e||e.trim().length===0)return[];let n=this.getAdapter(),r=t?.limit??i.maxResults,a=`
63
- SELECT k.*, bm25(knowledge_fts) AS _bm25
64
- FROM knowledge_fts
65
- JOIN knowledge k ON k.id = knowledge_fts.id
66
- WHERE knowledge_fts MATCH ?
67
- ${this.buildFilterSqlSuffix(t,!0)}
68
- ORDER BY _bm25 ASC
69
- LIMIT ?
70
- `,o;try{let t=j(e);o=n.queryAll(a,[t,r])}catch(e){return D.warn(`fts search failed`,s(e)),[]}return o.map(e=>({record:this.fromRow(e),score:M(e._bm25)}))}async getById(e){let t=this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE id = ? LIMIT 1`,[e]);return t.length===0?null:this.fromRow(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){let t=this.getAdapter(),n=t.queryAll(`SELECT id FROM knowledge WHERE sourcePath = ?`,[e]);if(n.length===0)return 0;t.exec(`BEGIN`);try{for(let{id:e}of n)this.vectorEnabled&&t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]);t.run(`DELETE FROM knowledge WHERE sourcePath = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),n.length}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async deleteByIdInteractive(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e),!0)}async _deleteByIdImpl(e){let t=this.getAdapter();if(t.queryAll(`SELECT id FROM knowledge WHERE id = ? LIMIT 1`,[e]).length===0)return!1;t.exec(`BEGIN`);try{this.vectorEnabled&&t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]),t.run(`DELETE FROM knowledge WHERE id = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),!0}async getBySourcePath(e){return this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE sourcePath = ? ORDER BY chunkIndex ASC`,[e]).map(e=>this.fromRow(e))}async getStats(){let e=this.getAdapter(),t=e.queryAll(`SELECT COUNT(*) AS n FROM knowledge`)[0]?.n??0;if(t===0)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`sqlite-vec`,embeddingModel:r.model};let n=e.queryAll(`SELECT COUNT(DISTINCT sourcePath) AS n FROM knowledge`),i=e.queryAll(`SELECT contentType, COUNT(*) AS n FROM knowledge GROUP BY contentType`),a=e.queryAll(`SELECT MAX(indexedAt) AS ts FROM knowledge`),o={};for(let e of i)o[e.contentType]=e.n;return{totalRecords:t,totalFiles:n[0]?.n??0,contentTypeBreakdown:o,lastIndexedAt:a[0]?.ts??null,storeBackend:`sqlite-vec`,embeddingModel:r.model}}async listSourcePaths(){return this.getAdapter().queryAll(`SELECT DISTINCT sourcePath FROM knowledge ORDER BY sourcePath`).map(e=>e.sourcePath)}async createFtsIndex(){this.createFtsTable()}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){let e=this.getAdapter();e.exec(`DROP TABLE IF EXISTS knowledge_fts`),this.vectorEnabled&&e.exec(`DROP TABLE IF EXISTS vec_knowledge`),e.exec(`DROP TABLE IF EXISTS knowledge`),e.flush(),this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled&&this.ensureVecTable()}async close(){for(;this._priorityQueue.length>0||this._normalQueue.length>0||this._draining;)await new Promise(e=>setTimeout(e,5));this.adapter&&!this.externalAdapter&&this.adapter.close(),this.adapter=null}getAdapter(){if(!this.adapter)throw Error(`SqliteVecStore: not initialized — call initialize() first`);return this.adapter}buildFilterSqlSuffix(e,t=!1){if(!e)return``;let n=[];if(e.contentType&&n.push(`k.contentType = '${k(e.contentType,`contentType`)}'`),e.sourceType){let t=c(e.sourceType);if(t.length>0){let e=t.map(e=>`'${k(e,`sourceType`)}'`).join(`, `);n.push(`k.contentType IN (${e})`)}}if(e.origin&&n.push(`k.origin = '${k(e.origin,`origin`)}'`),e.category&&n.push(`k.category = '${k(e.category,`category`)}'`),e.tags&&e.tags.length>0){let t=e.tags.map(e=>`k.tags LIKE '%' || '${k(e,`tag`)}' || '%'`);n.push(`(${t.join(` OR `)})`)}if(n.length===0)return``;let r=n.join(` AND `);return t?`AND ${r}`:`WHERE ${r}`}fromRow(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,contentHash:e.content_hash||void 0,indexedAt:e.indexedAt,origin:e.origin,tags:O(e.tags),category:e.category||void 0,version:e.version}}};function j(e){let t=e.replace(/["'()*:^-]/g,` `).trim();return t?t.split(/\s+/).filter(e=>e.length>0).map(e=>`"${e}"`).join(` OR `):`""`}function M(e){return e==null||Number.isNaN(e)?0:1-Math.exp(-Math.abs(e)/5)}export{S as i,w as n,C as r,A as t};