@vpxa/aikit 0.1.235 → 0.1.236

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.235",
3
+ "version": "0.1.236",
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,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import{t as e}from"./rolldown-runtime-yuFVEuWy.js";import{createHash as t,randomUUID as n}from"node:crypto";import{readFileSync as r}from"node:fs";import{dirname as i,isAbsolute as a,join as o,resolve as s}from"node:path";import{fileURLToPath as c,pathToFileURL as l}from"node:url";import{parseArgs as u}from"node:util";import{HealthBus as d,createLogger as f,serializeError as p}from"../../core/dist/index.js";import{GIT_REF_SLUG_PATTERN as m,gitAvailable as h,gitCommitToRef as g,gitExec as _,slugForRef as v}from"../../tools/dist/index.js";import{mkdir as y,readFile as b,readdir as x,stat as S,unlink as C,writeFile as w}from"node:fs/promises";const T=`__pending__:`;function E(e){return e.startsWith(T)}function D(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function O(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var k=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=D(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){O(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){O(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!E(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!E(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!E(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){O(e,503,-32003,`Session capacity reached`);return}let t=this.now(),r=await this.options.createServer(),i={id:`${T}${n()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>n(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function A(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var j=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=A(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}},M=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await y(this.baseDir,{recursive:!0})}async read(e){let t=o(this.baseDir,e);try{return await b(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,n){let r=o(this.baseDir,e);await y(i(r),{recursive:!0}),await w(r,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`})}async delete(e){let t=o(this.baseDir,e);try{return await C(t),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async list(e){let t=[],n=e?[e]:await this.listDirectories();for(let e of n){let n=o(this.baseDir,e),r;try{r=await x(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,i=o(this.baseDir,r);try{let e=await S(i);t.push({path:r,size:e.size})}catch{}}}return t}async exists(e){let t=o(this.baseDir,e);try{return await S(t),!0}catch{return!1}}async listDirectories(){try{return(await x(this.baseDir,{withFileTypes:!0})).filter(e=>e.isDirectory()&&/^[a-z][a-z0-9-]*$/.test(e.name)).map(e=>e.name)}catch{return[]}}async close(){}},N=e({CuratedKnowledgeManager:()=>L});const P=50*1024,F=`refs/aikit/knowledge`,I=f(`server`);var L=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new M(e)){this.curatedDir=e,this.store=t,this.embedder=n,this.adapter=r}async remember(e,t,n,r=[]){this.validateCategoryName(n),this.validateContentSize(t);let i=this.slugify(e),a=await this.uniqueRelativePath(n,i),o=new Date().toISOString(),s={title:e,category:n,tags:r,created:o,updated:o,version:1,origin:`curated`,changelog:[{version:1,date:o,reason:`Initial creation`}]},c=this.serializeFile(t,s);try{await this.adapter.write(a,c,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${a}" — retry the operation`):e}return this.gitCommitKnowledge(a,c,`remember: ${e}\n\nCategory: ${n}\nTags: ${r.join(`, `)}`),await this.indexCuratedFileBestEffort(a,t,s,`remember`),{path:a}}async update(e,t,n){e=this.guardPath(e),this.validateContentSize(t);let r=await this.adapter.read(e);if(r==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:i}=this.parseFile(r),a=(i.version??1)+1,o=new Date().toISOString();i.version=a,i.updated=o,i.changelog=[...i.changelog??[],{version:a,date:o,reason:n}];let s=this.serializeFile(t,i);return await this.adapter.write(e,s),this.gitCommitKnowledge(e,s,`update(v${a}): ${i.title}\n\nReason: ${n}\nVersion: ${a}`),await this.indexCuratedFileBestEffort(e,t,i,`update`),{path:e,version:a}}async forget(e,t){if(e=this.guardPath(e),!await this.adapter.delete(e))throw Error(`Curated entry not found: ${e}`);let n=`.ai/curated/${e}`;return await this.store.deleteBySourcePath(n).catch(e=>{I.warn(`File deleted but vector cleanup failed`,{sourcePath:n,...p(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!h(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=_([`log`,`--format=%H|%aI|%s`,n,`-n`,String(t)],this.curatedDir);return r?r.split(`
3
3
  `).filter(Boolean).map(e=>{let[t,n,...r]=e.split(`|`);return{sha:t,date:n,message:r.join(`|`)}}):[]}async diff(e,t,n){if(e=this.guardPath(e),!h(this.curatedDir))return``;if(!n){let r=await this.history(e,2);if(r.length===0)return``;n=r[0].sha,r.length>1&&!t&&(t=r[1].sha)}return t&&n?_([`diff`,`${t}:entry.md`,`${n}:entry.md`],this.curatedDir)??``:n?_([`show`,`${n}:entry.md`],this.curatedDir)??``:``}async recover(e){if(e=this.guardPath(e),await this.adapter.exists(e))throw Error(`Entry already exists on filesystem: ${e}. Use update() instead.`);if(!h(this.curatedDir))return null;let t=this.knowledgeRefForPath(e);if(!t)return null;let n=_([`show`,`${t}:entry.md`],this.curatedDir);if(!n)return null;await this.adapter.write(e,n);let{frontmatter:r,content:i}=this.parseFile(n);return await this.indexCuratedFile(e,i,r),{path:e,version:r.version??1}}async listOrphaned(){if(!h(this.curatedDir))return[];let e=_([`for-each-ref`,`--format=%(refname)|%(subject)`,`${F}/`],this.curatedDir);if(!e)return[];let t=[];for(let n of e.split(`
4
- `).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${F}/`,``)}.md`;await this.adapter.exists(a)||t.push({ref:e,path:a,lastMessage:i})}return t}async read(e){e=this.guardPath(e);let t=await this.adapter.read(e);if(t==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:n,content:r}=this.parseFile(t),i=e.split(`/`)[0];return{path:e,title:n.title??e,category:i,tags:n.tags??[],version:n.version??1,created:n.created??``,updated:n.updated??``,contentPreview:r.slice(0,200),content:r}}async list(e){let t=[],n=e?.category?[e.category]:await this.discoverCategories();for(let r of n){let n=await this.adapter.list(r);for(let i of n){let n=await this.adapter.read(i.path);if(n==null)continue;let{frontmatter:a,content:o}=this.parseFile(n);e?.tag&&!(a.tags??[]).includes(e.tag)||t.push({path:i.path,title:a.title??i.path,category:r,tags:a.tags??[],version:a.version??1,created:a.created??``,updated:a.updated??``,contentPreview:o.slice(0,200)})}}return t}async reindexAll(){let e=await this.discoverCategories(),t=[],n=[];for(let r of e){let e=await this.adapter.list(r);for(let r of e){let e=r.path;try{let r=await this.adapter.read(e);if(r==null){t.push(`${e}: read failed`);continue}let{frontmatter:i,content:a}=this.parseFile(r);n.push({relativePath:e,content:a,frontmatter:i})}catch(n){I.error(`Failed to read curated file`,{relativePath:e,...p(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=await this.embedder.embedBatch(n.map(e=>e.content)),i=new Date().toISOString(),a=n.map(e=>{let t=`.ai/curated/${e.relativePath}`;return{id:this.hashId(t,0),content:e.content,sourcePath:t,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
5
- `).length,fileHash:this.hash(e.content),indexedAt:i,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});return await this.store.upsert(a,r),{indexed:n.length,errors:t}}gitCommitKnowledge(e,t,n){try{if(!h(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;g(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!h(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;_([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>v(e)).join(`/`);return t.split(`/`).every(e=>m.test(e))?`${F}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
4
+ `).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${F}/`,``)}.md`;await this.adapter.exists(a)||t.push({ref:e,path:a,lastMessage:i})}return t}async read(e){e=this.guardPath(e);let t=await this.adapter.read(e);if(t==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:n,content:r}=this.parseFile(t),i=e.split(`/`)[0];return{path:e,title:n.title??e,category:i,tags:n.tags??[],version:n.version??1,created:n.created??``,updated:n.updated??``,contentPreview:r.slice(0,200),content:r}}async list(e){let t=[],n=e?.category?[e.category]:await this.discoverCategories();for(let r of n){let n=await this.adapter.list(r);for(let i of n){let n=await this.adapter.read(i.path);if(n==null)continue;let{frontmatter:a,content:o}=this.parseFile(n);e?.tag&&!(a.tags??[]).includes(e.tag)||t.push({path:i.path,title:a.title??i.path,category:r,tags:a.tags??[],version:a.version??1,created:a.created??``,updated:a.updated??``,contentPreview:o.slice(0,200)})}}return t}async reindexAll(){let e=await this.discoverCategories(),t=[],n=[];for(let r of e){let e=await this.adapter.list(r);for(let r of e){let e=r.path;try{let r=await this.adapter.read(e);if(r==null){t.push(`${e}: read failed`);continue}let{frontmatter:i,content:a}=this.parseFile(r);n.push({relativePath:e,content:a,frontmatter:i})}catch(n){I.error(`Failed to read curated file`,{relativePath:e,...p(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=new Date().toISOString(),i=0;for(let e=0;e<n.length;e+=32){let a=n.slice(e,e+32);i+=await this.embedAndUpsertBatch(a,r,t)}return{indexed:i,errors:t}}async embedAndUpsertBatch(e,t,n){try{let r=await this.embedder.embedBatch(e.map(e=>e.content)),i=e.map(e=>{let n=`.ai/curated/${e.relativePath}`;return{id:this.hashId(n,0),content:e.content,sourcePath:n,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
5
+ `).length,fileHash:this.hash(e.content),indexedAt:t,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});try{return await this.store.upsert(i,r),e.length}catch(t){I.error(`Failed to upsert curated batch`,{batchSize:e.length,...p(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return I.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...p(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;I.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...p(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),o=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(o,t,n)}}gitCommitKnowledge(e,t,n){try{if(!h(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;g(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!h(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;_([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>v(e)).join(`/`);return t.split(`/`).every(e=>m.test(e))?`${F}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
6
6
  `).length,fileHash:this.hash(t),indexedAt:a,origin:`curated`,tags:n.tags,category:n.category,version:n.version};await this.store.upsert([o],[r])}async indexCuratedFileBestEffort(e,t,n,r){if(d.instance().isDegraded(`embedder`)){I.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:r,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){I.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:r,...p(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||a(t))throw Error(`Invalid path: ${t}. Must be relative within .ai/curated/ directory.`);let n=t.split(`/`)[0];return this.validateCategoryName(n),t}validateCategoryName(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid category name: "${e}". Must be lowercase kebab-case (e.g., "decisions", "api-contracts").`)}validateContentSize(e){if(Buffer.byteLength(e,`utf-8`)>P)throw Error(`Content exceeds maximum size of ${P/1024}KB`)}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)}async uniqueRelativePath(e,t){let n=`${e}/${t}.md`;if(!await this.adapter.exists(n))return n;for(let n=2;n<=100;n++){let r=`${e}/${t}-${n}.md`;if(!await this.adapter.exists(r))return r}throw Error(`Too many entries with slug "${t}" in category "${e}"`)}hash(e){return t(`sha256`).update(e).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
7
7
  `)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
8
8
  `),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};function R(){try{let e=s(i(c(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(r(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const z=f(`server`),B=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function V({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?B.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function H({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function U({config:e,log:t,reconfigureForWorkspace:n,roots:r}){if(r.length===0)return!1;let i=r[0].uri,a=i.startsWith(`file://`)?c(i):i;return t.info(`MCP roots resolved`,{rootUri:i,rootPath:a,rootCount:r.length}),n(e,a),e.allRoots=r.map(e=>{let t=e.uri;return t.startsWith(`file://`)?c(t):t}),!0}async function W({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:l=()=>process.cwd()}){let u=!1,d=!1,f,m=o.server,h=e=>{let t=p(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},g=()=>{u||(u=!0,s())},_=()=>{d||t!==`auto`||(d=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,p(e))}})())},v=t=>t.length===0||(f&&=(clearTimeout(f),void 0),g(),!U({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),!0);try{if(v((await m.listRoots()).roots))return;n.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(h(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:l(),...p(e)}),g(),_();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{cwd:l(),...p(e)}),g()}m.setNotificationHandler(r,async()=>{try{v((await m.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,p(e))}}),f=setTimeout(()=>{n.warn(`Timed out waiting for MCP roots/list_changed; starting in limited mode`,{cwd:l()}),g()},c)}function G(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function K(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function q(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function J(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function Y(){return K()?u({allowPositionals:!0,options:{transport:{type:`string`,default:G()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:G(),port:process.env.AIKIT_PORT??`3210`}}async function X(){let e=R(),t=Y();process.on(`unhandledRejection`,e=>{z.error(`Unhandled rejection`,p(e))}),process.on(`uncaughtException`,e=>{z.error(`Uncaught exception — exiting`,p(e)),process.exit(1)});let r=(e,t)=>{e.then(async()=>{try{let{markPromoteRun:e,markPruneRun:n,prune:r,shouldRunStartupPrune:i,shouldRunWeeklyPromote:a}=await import(`../../tools/dist/index.js`),o=t();if(!o)return;if(i()){let e=await r({});n(),e.totalBytesFreed>0&&z.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:t,pruneLessons:i}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),a=await i(o.curated,o.stateStore,{dryRun:!1});a.pruned.length>0&&z.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let s=await t(o.curated,o.stateStore,{dryRun:!1});(s.groupsCreated>0||s.lessonsGrouped>0)&&z.info(`Startup lesson grouping complete`,{groupsCreated:s.groupsCreated,lessonsGrouped:s.lessonsGrouped})}if(a()){let{DEFAULT_PROMOTE_CONFIG:t,collectWorkspaceLessons:n,getGlobalCuratedDir:r,promoteLessons:i,scanForDuplicates:a}=await import(`./promotion-CJFYv4Ye.js`).then(e=>e.o),{CuratedKnowledgeManager:s}=await Promise.resolve().then(()=>N),c=o.curated,l=new s(r(),c.store,c.embedder),u=await n(),d={...t,dryRun:!1},f=await i(a(u,d),l,d);e(),f.promoted.length>0&&z.info(`Weekly lesson promotion complete`,{promoted:f.promoted.length,candidates:f.candidates.length})}}catch(e){z.warn(`Startup maintenance failed (non-critical)`,p(e))}}).catch(()=>{})};if(z.info(`Starting MCP AI Kit server`,{version:e}),t.transport===`http`){let[{default:e},{loadConfig:i,resolveIndexMode:a},{registerDashboardRoutes:o,resolveDashboardDir:s},{registerSettingsRoutes:c,resolveSettingsDir:l},{createSettingsRouter:u},{authMiddleware:d,getOrCreateToken:f}]=await Promise.all([import(`express`),import(`./config-DzZLgNQT.js`),import(`./dashboard-static-CRfR1yKU.js`),import(`./settings-static-B3lnYvcb.js`),import(`./routes-Afg7J7xK.js`),import(`./auth-lzZKfxlV.js`)]),m=i();z.info(`Config loaded`,{sourceCount:m.sources.length,storePath:m.store.path});let h=e();h.use(e.json({limit:`1mb`}));let g=Number(t.port),_=`http://localhost:${g}`,v=process.env.AIKIT_CORS_ORIGIN??_,y=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,b=J(`AIKIT_HTTP_MAX_SESSIONS`,8),x=J(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),S=J(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),C=H({limit:100,windowMs:6e4}),w=!1;h.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=V({requestOrigin:r,configuredOrigin:v,allowAnyOrigin:y,fallbackOrigin:_});if(i.warn&&!w&&(w=!0,z.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let T=f();console.error(`[aikit] Auth token: ~/.aikit/token`),h.use(d(T)),h.use(`/mcp`,(e,t,n)=>{let r=q(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(C.allow(r)){n();return}let i=Math.max(1,Math.ceil(C.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),o(h,s(),z);let E=new Date().toISOString();h.use(`/settings/api`,u({log:z,mcpInfo:()=>({transport:`http`,port:g,pid:process.pid,startedAt:E})})),c(h,l(),z),h.get(`/health`,(e,t)=>{t.json({status:`ok`})});let D=!1,O=null,A=null,M=null,N=null,P=null,F=null,I=null,L=Promise.resolve(),R=async(e,t)=>{if(!D||!M||!N){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=L,i;L=new Promise(e=>{i=e}),await r;try{let r=q(e);if(!F){if(r){t.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new N({sessionIdGenerator:()=>n(),onsessioninitialized:async e=>{I=e,A?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&A?.onSessionEnd(e),I=null}});e.onclose=()=>{F===e&&(F=null),I===e.sessionId&&(I=null)},F=e,await M.connect(e)}let i=F;await i.handleRequest(e,t,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(I=i.sessionId,A?.onSessionStart(i.sessionId,{transport:`http`}),A?.onSessionActivity(i.sessionId)):r&&A?.onSessionActivity(r))}catch(e){if(z.error(`MCP handler error`,p(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{i()}},B=async(e,t)=>{let n=q(e);if(P&&(!F||n!==I)){await P.handleRequest(e,t,e.body);return}await R(e,t)};h.post(`/mcp`,B),h.get(`/mcp`,B),h.delete(`/mcp`,B);let U=h.listen(g,`127.0.0.1`,()=>{z.info(`MCP server listening`,{url:`http://127.0.0.1:${g}/mcp`,port:g}),setTimeout(async()=>{try{let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:i},{checkForUpdates:o,autoUpgradeScaffold:s}]=await Promise.all([import(`./server-DUwue6o8.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-gazMo-D4.js`)]);o(),s();let c=a(m),l=e(m,c);M=l.server,N=i,D=!0,z.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),l.startInit(),l.ready.then(()=>{if(!l.aikit)throw Error(`AI Kit components are not available after initialization`);A=new j(l.aikit.stateStore,{staleTimeoutMinutes:x,gcIntervalMinutes:S,onBeforeSessionDelete:e=>{if(I===e&&F){let e=F;F=null,I=null,e.close().catch(()=>void 0)}P?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!l.aikit?.curated||!l.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-DWaEE6XW.js`).then(e=>e.t),t=await e(l.aikit.curated,l.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&z.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),P=new k({createServer:()=>{if(!l.aikit)throw Error(`AI Kit components are not available after initialization`);return t(l.aikit,m)},createTransport:e=>new i(e),maxSessions:b,sessionTimeoutMinutes:x,onSessionStart:e=>A?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>A?.onSessionActivity(e),onSessionEnd:e=>A?.onSessionEnd(e)}),A.startGC(),I&&(A.onSessionStart(I,{transport:`http`}),A.onSessionActivity(I)),z.info(`HTTP session runtime ready`,{maxSessions:b,sessionTimeoutMinutes:x,gcIntervalMinutes:S})}).catch(e=>z.error(`Failed to start session manager`,p(e))),c===`auto`?l.ready.then(async()=>{try{let e=m.sources.map(e=>e.path).join(`, `);z.info(`Running initial index`,{sourcePaths:e}),await l.runInitialIndex(),z.info(`Initial index complete`)}catch(e){z.error(`Initial index failed; will retry on aikit_reindex`,p(e))}}).catch(e=>z.error(`AI Kit init or indexing failed`,p(e))):c===`smart`?l.ready.then(async()=>{try{if(!l.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(l.aikit.indexer,m,l.aikit.store),n=l.aikit.store;O=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),l.setSmartScheduler(t),z.info(`Smart index scheduler started (HTTP mode)`)}catch(e){z.error(`Failed to start smart index scheduler`,p(e))}}).catch(e=>z.error(`AI Kit initialization failed`,p(e))):(l.ready.catch(e=>z.error(`AI Kit initialization failed`,p(e))),z.info(`Initial full indexing skipped in HTTP mode`,{indexMode:c})),r(l.ready,()=>l.aikit?{curated:l.aikit.curated,stateStore:l.aikit.stateStore}:null)}catch(e){z.error(`Failed to load server modules`,p(e))}},100)}),W=async e=>{z.info(`Shutdown signal received`,{signal:e}),O?.stop(),A?.stop(),await P?.closeAll().catch(()=>void 0),I&&A?.onSessionEnd(I),F&&(await F.close().catch(()=>void 0),F=null,I=null),U.close(),M&&await M.close(),process.exit(0)};process.on(`SIGINT`,()=>W(`SIGINT`)),process.on(`SIGTERM`,()=>W(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:i},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-DzZLgNQT.js`),import(`./server-DUwue6o8.js`),import(`./version-check-gazMo-D4.js`),import(`@modelcontextprotocol/sdk/types.js`)]),c=e();z.info(`Config loaded`,{sourceCount:c.sources.length,storePath:c.store.path}),a(),o();let l=n(c),u=i(c,l),{server:d,startInit:f,ready:m,runInitialIndex:h}=u,{StdioServerTransport:g}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),_=new g;await d.connect(_),z.info(`MCP server started`,{transport:`stdio`}),await W({config:c,indexMode:l,log:z,rootsChangedNotificationSchema:s,reconfigureForWorkspace:t,runInitialIndex:h,server:d,startInit:f});let v=null,y=()=>{v&&clearTimeout(v),v=setTimeout(async()=>{z.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=u.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),v.unref&&v.unref()};y(),process.stdin.on(`data`,()=>y()),m.catch(e=>{z.error(`Initialization failed — server will continue with limited tools`,p(e))}),l===`smart`?m.then(async()=>{try{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(u.aikit.indexer,c,u.aikit.store),n=u.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),u.setSmartScheduler(t),z.info(`Smart index scheduler started (stdio mode)`)}catch(e){z.error(`Failed to start smart index scheduler`,p(e))}}).catch(e=>z.error(`AI Kit init failed for smart scheduler`,p(e))):z.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:l}),r(m,()=>u.aikit?{curated:u.aikit.curated,stateStore:u.aikit.stateStore}:null)}}X();export{M as n,L as t};
@@ -1,7 +1,7 @@
1
1
  import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{createHash as t}from"node:crypto";import{dirname as n,isAbsolute as r,join as i}from"node:path";import{HealthBus as a,createLogger as o,serializeError as s}from"../../core/dist/index.js";import{GIT_REF_SLUG_PATTERN as c,gitAvailable as l,gitCommitToRef as u,gitExec as d,slugForRef as f}from"../../tools/dist/index.js";import{mkdir as p,readFile as m,readdir as h,stat as g,unlink as _,writeFile as v}from"node:fs/promises";var y=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await p(this.baseDir,{recursive:!0})}async read(e){let t=i(this.baseDir,e);try{return await m(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,r){let a=i(this.baseDir,e);await p(n(a),{recursive:!0}),await v(a,t,{encoding:`utf-8`,flag:r?.exclusive?`wx`:`w`})}async delete(e){let t=i(this.baseDir,e);try{return await _(t),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async list(e){let t=[],n=e?[e]:await this.listDirectories();for(let e of n){let n=i(this.baseDir,e),r;try{r=await h(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,a=i(this.baseDir,r);try{let e=await g(a);t.push({path:r,size:e.size})}catch{}}}return t}async exists(e){let t=i(this.baseDir,e);try{return await g(t),!0}catch{return!1}}async listDirectories(){try{return(await h(this.baseDir,{withFileTypes:!0})).filter(e=>e.isDirectory()&&/^[a-z][a-z0-9-]*$/.test(e.name)).map(e=>e.name)}catch{return[]}}async close(){}},b=e({CuratedKnowledgeManager:()=>w});const x=50*1024,S=`refs/aikit/knowledge`,C=o(`server`);var w=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new y(e)){this.curatedDir=e,this.store=t,this.embedder=n,this.adapter=r}async remember(e,t,n,r=[]){this.validateCategoryName(n),this.validateContentSize(t);let i=this.slugify(e),a=await this.uniqueRelativePath(n,i),o=new Date().toISOString(),s={title:e,category:n,tags:r,created:o,updated:o,version:1,origin:`curated`,changelog:[{version:1,date:o,reason:`Initial creation`}]},c=this.serializeFile(t,s);try{await this.adapter.write(a,c,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${a}" — retry the operation`):e}return this.gitCommitKnowledge(a,c,`remember: ${e}\n\nCategory: ${n}\nTags: ${r.join(`, `)}`),await this.indexCuratedFileBestEffort(a,t,s,`remember`),{path:a}}async update(e,t,n){e=this.guardPath(e),this.validateContentSize(t);let r=await this.adapter.read(e);if(r==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:i}=this.parseFile(r),a=(i.version??1)+1,o=new Date().toISOString();i.version=a,i.updated=o,i.changelog=[...i.changelog??[],{version:a,date:o,reason:n}];let s=this.serializeFile(t,i);return await this.adapter.write(e,s),this.gitCommitKnowledge(e,s,`update(v${a}): ${i.title}\n\nReason: ${n}\nVersion: ${a}`),await this.indexCuratedFileBestEffort(e,t,i,`update`),{path:e,version:a}}async forget(e,t){if(e=this.guardPath(e),!await this.adapter.delete(e))throw Error(`Curated entry not found: ${e}`);let n=`.ai/curated/${e}`;return await this.store.deleteBySourcePath(n).catch(e=>{C.warn(`File deleted but vector cleanup failed`,{sourcePath:n,...s(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!l(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=d([`log`,`--format=%H|%aI|%s`,n,`-n`,String(t)],this.curatedDir);return r?r.split(`
2
2
  `).filter(Boolean).map(e=>{let[t,n,...r]=e.split(`|`);return{sha:t,date:n,message:r.join(`|`)}}):[]}async diff(e,t,n){if(e=this.guardPath(e),!l(this.curatedDir))return``;if(!n){let r=await this.history(e,2);if(r.length===0)return``;n=r[0].sha,r.length>1&&!t&&(t=r[1].sha)}return t&&n?d([`diff`,`${t}:entry.md`,`${n}:entry.md`],this.curatedDir)??``:n?d([`show`,`${n}:entry.md`],this.curatedDir)??``:``}async recover(e){if(e=this.guardPath(e),await this.adapter.exists(e))throw Error(`Entry already exists on filesystem: ${e}. Use update() instead.`);if(!l(this.curatedDir))return null;let t=this.knowledgeRefForPath(e);if(!t)return null;let n=d([`show`,`${t}:entry.md`],this.curatedDir);if(!n)return null;await this.adapter.write(e,n);let{frontmatter:r,content:i}=this.parseFile(n);return await this.indexCuratedFile(e,i,r),{path:e,version:r.version??1}}async listOrphaned(){if(!l(this.curatedDir))return[];let e=d([`for-each-ref`,`--format=%(refname)|%(subject)`,`${S}/`],this.curatedDir);if(!e)return[];let t=[];for(let n of e.split(`
3
- `).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${S}/`,``)}.md`;await this.adapter.exists(a)||t.push({ref:e,path:a,lastMessage:i})}return t}async read(e){e=this.guardPath(e);let t=await this.adapter.read(e);if(t==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:n,content:r}=this.parseFile(t),i=e.split(`/`)[0];return{path:e,title:n.title??e,category:i,tags:n.tags??[],version:n.version??1,created:n.created??``,updated:n.updated??``,contentPreview:r.slice(0,200),content:r}}async list(e){let t=[],n=e?.category?[e.category]:await this.discoverCategories();for(let r of n){let n=await this.adapter.list(r);for(let i of n){let n=await this.adapter.read(i.path);if(n==null)continue;let{frontmatter:a,content:o}=this.parseFile(n);e?.tag&&!(a.tags??[]).includes(e.tag)||t.push({path:i.path,title:a.title??i.path,category:r,tags:a.tags??[],version:a.version??1,created:a.created??``,updated:a.updated??``,contentPreview:o.slice(0,200)})}}return t}async reindexAll(){let e=await this.discoverCategories(),t=[],n=[];for(let r of e){let e=await this.adapter.list(r);for(let r of e){let e=r.path;try{let r=await this.adapter.read(e);if(r==null){t.push(`${e}: read failed`);continue}let{frontmatter:i,content:a}=this.parseFile(r);n.push({relativePath:e,content:a,frontmatter:i})}catch(n){C.error(`Failed to read curated file`,{relativePath:e,...s(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=await this.embedder.embedBatch(n.map(e=>e.content)),i=new Date().toISOString(),a=n.map(e=>{let t=`.ai/curated/${e.relativePath}`;return{id:this.hashId(t,0),content:e.content,sourcePath:t,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
4
- `).length,fileHash:this.hash(e.content),indexedAt:i,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});return await this.store.upsert(a,r),{indexed:n.length,errors:t}}gitCommitKnowledge(e,t,n){try{if(!l(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;u(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!l(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;d([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>f(e)).join(`/`);return t.split(`/`).every(e=>c.test(e))?`${S}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
3
+ `).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${S}/`,``)}.md`;await this.adapter.exists(a)||t.push({ref:e,path:a,lastMessage:i})}return t}async read(e){e=this.guardPath(e);let t=await this.adapter.read(e);if(t==null)throw Error(`Curated entry not found: ${e}`);let{frontmatter:n,content:r}=this.parseFile(t),i=e.split(`/`)[0];return{path:e,title:n.title??e,category:i,tags:n.tags??[],version:n.version??1,created:n.created??``,updated:n.updated??``,contentPreview:r.slice(0,200),content:r}}async list(e){let t=[],n=e?.category?[e.category]:await this.discoverCategories();for(let r of n){let n=await this.adapter.list(r);for(let i of n){let n=await this.adapter.read(i.path);if(n==null)continue;let{frontmatter:a,content:o}=this.parseFile(n);e?.tag&&!(a.tags??[]).includes(e.tag)||t.push({path:i.path,title:a.title??i.path,category:r,tags:a.tags??[],version:a.version??1,created:a.created??``,updated:a.updated??``,contentPreview:o.slice(0,200)})}}return t}async reindexAll(){let e=await this.discoverCategories(),t=[],n=[];for(let r of e){let e=await this.adapter.list(r);for(let r of e){let e=r.path;try{let r=await this.adapter.read(e);if(r==null){t.push(`${e}: read failed`);continue}let{frontmatter:i,content:a}=this.parseFile(r);n.push({relativePath:e,content:a,frontmatter:i})}catch(n){C.error(`Failed to read curated file`,{relativePath:e,...s(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=new Date().toISOString(),i=0;for(let e=0;e<n.length;e+=32){let a=n.slice(e,e+32);i+=await this.embedAndUpsertBatch(a,r,t)}return{indexed:i,errors:t}}async embedAndUpsertBatch(e,t,n){try{let r=await this.embedder.embedBatch(e.map(e=>e.content)),i=e.map(e=>{let n=`.ai/curated/${e.relativePath}`;return{id:this.hashId(n,0),content:e.content,sourcePath:n,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
4
+ `).length,fileHash:this.hash(e.content),indexedAt:t,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});try{return await this.store.upsert(i,r),e.length}catch(t){C.error(`Failed to upsert curated batch`,{batchSize:e.length,...s(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return C.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...s(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;C.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...s(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),o=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(o,t,n)}}gitCommitKnowledge(e,t,n){try{if(!l(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;u(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!l(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;d([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>f(e)).join(`/`);return t.split(`/`).every(e=>c.test(e))?`${S}/${t}`:null}async indexCuratedFile(e,t,n){let r=await this.embedder.embed(t),i=`.ai/curated/${e}`,a=new Date().toISOString(),o={id:this.hashId(i,0),content:t,sourcePath:i,contentType:`curated-knowledge`,headingPath:n.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:t.split(`
5
5
  `).length,fileHash:this.hash(t),indexedAt:a,origin:`curated`,tags:n.tags,category:n.category,version:n.version};await this.store.upsert([o],[r])}async indexCuratedFileBestEffort(e,t,n,r){if(a.instance().isDegraded(`embedder`)){C.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:r,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){C.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:r,...s(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||r(t))throw Error(`Invalid path: ${t}. Must be relative within .ai/curated/ directory.`);let n=t.split(`/`)[0];return this.validateCategoryName(n),t}validateCategoryName(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw Error(`Invalid category name: "${e}". Must be lowercase kebab-case (e.g., "decisions", "api-contracts").`)}validateContentSize(e){if(Buffer.byteLength(e,`utf-8`)>x)throw Error(`Content exceeds maximum size of ${x/1024}KB`)}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)}async uniqueRelativePath(e,t){let n=`${e}/${t}.md`;if(!await this.adapter.exists(n))return n;for(let n=2;n<=100;n++){let r=`${e}/${t}-${n}.md`;if(!await this.adapter.exists(r))return r}throw Error(`Too many entries with slug "${t}" in category "${e}"`)}hash(e){return t(`sha256`).update(e).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
6
6
  `)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
7
7
  `),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};export{b as n,y as r,w as t};
@@ -143,6 +143,13 @@ declare class CuratedKnowledgeManager {
143
143
  indexed: number;
144
144
  errors: string[];
145
145
  }>;
146
+ /**
147
+ * Embed and upsert a batch of curated items. On embedder failure, recursively
148
+ * retries with halved sub-batches to recover from worker-exit / oversized-batch
149
+ * errors. Upsert failures are reported directly without recursive retry.
150
+ * Returns the number of successfully indexed items.
151
+ */
152
+ private embedAndUpsertBatch;
146
153
  /**
147
154
  * Commit curated knowledge content to a git orphan ref.
148
155
  * Fires after successful filesystem write — never blocks or throws on failure.
@@ -1 +1 @@
1
- import{t as e}from"./curated-manager-CxKwx3Ym.js";import{randomUUID as t}from"node:crypto";import{readFileSync as n}from"node:fs";import{dirname as r,resolve as i}from"node:path";import{fileURLToPath as a,pathToFileURL as o}from"node:url";import{parseArgs as s}from"node:util";import{createLogger as c,serializeError as l}from"../../core/dist/index.js";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let n=this.now(),r=await this.options.createServer(),i={id:`${u}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};function _(){try{let e=i(r(a(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const v=c(`server`),y=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function b({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?y.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function x({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function S({config:e,log:t,reconfigureForWorkspace:n,roots:r}){if(r.length===0)return!1;let i=r[0].uri,o=i.startsWith(`file://`)?a(i):i;return t.info(`MCP roots resolved`,{rootUri:i,rootPath:o,rootCount:r.length}),n(e,o),e.allRoots=r.map(e=>{let t=e.uri;return t.startsWith(`file://`)?a(t):t}),!0}async function C({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:u=()=>process.cwd()}){let d=!1,f=!1,p,m=o.server,h=e=>{let t=l(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},g=()=>{d||(d=!0,s())},_=()=>{f||t!==`auto`||(f=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,l(e))}})())},v=t=>t.length===0||(p&&=(clearTimeout(p),void 0),g(),!S({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),!0);try{if(v((await m.listRoots()).roots))return;n.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(h(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:u(),...l(e)}),g(),_();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{cwd:u(),...l(e)}),g()}m.setNotificationHandler(r,async()=>{try{v((await m.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,l(e))}}),p=setTimeout(()=>{n.warn(`Timed out waiting for MCP roots/list_changed; starting in limited mode`,{cwd:u()}),g()},c)}function w(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function T(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===o(e).href}catch{return!1}}function E(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function D(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function O(){return T()?s({allowPositionals:!0,options:{transport:{type:`string`,default:w()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:w(),port:process.env.AIKIT_PORT??`3210`}}async function k(){let e=_(),n=O();process.on(`unhandledRejection`,e=>{v.error(`Unhandled rejection`,l(e))}),process.on(`uncaughtException`,e=>{v.error(`Uncaught exception — exiting`,l(e)),process.exit(1)});let r=(e,t)=>{e.then(async()=>{try{let{markPromoteRun:e,markPruneRun:n,prune:r,shouldRunStartupPrune:i,shouldRunWeeklyPromote:a}=await import(`../../tools/dist/index.js`),o=t();if(!o)return;if(i()){let e=await r({});n(),e.totalBytesFreed>0&&v.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:t,pruneLessons:i}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),a=await i(o.curated,o.stateStore,{dryRun:!1});a.pruned.length>0&&v.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let s=await t(o.curated,o.stateStore,{dryRun:!1});(s.groupsCreated>0||s.lessonsGrouped>0)&&v.info(`Startup lesson grouping complete`,{groupsCreated:s.groupsCreated,lessonsGrouped:s.lessonsGrouped})}if(a()){let{DEFAULT_PROMOTE_CONFIG:t,collectWorkspaceLessons:n,getGlobalCuratedDir:r,promoteLessons:i,scanForDuplicates:a}=await import(`./promotion-VH4M_cWb.js`).then(e=>e.o),{CuratedKnowledgeManager:s}=await import(`./curated-manager-CxKwx3Ym.js`).then(e=>e.n),c=o.curated,l=new s(r(),c.store,c.embedder),u=await n(),d={...t,dryRun:!1},f=await i(a(u,d),l,d);e(),f.promoted.length>0&&v.info(`Weekly lesson promotion complete`,{promoted:f.promoted.length,candidates:f.candidates.length})}}catch(e){v.warn(`Startup maintenance failed (non-critical)`,l(e))}}).catch(()=>{})};if(v.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let[{default:e},{loadConfig:i,resolveIndexMode:a},{registerDashboardRoutes:o,resolveDashboardDir:s},{registerSettingsRoutes:c,resolveSettingsDir:u},{createSettingsRouter:d},{authMiddleware:f,getOrCreateToken:p}]=await Promise.all([import(`express`),import(`./config-Ymr8iMyI.js`),import(`./dashboard-static-FmfoS46e.js`),import(`./settings-static-BtvyIrza.js`),import(`./routes-CR3fI-HJ.js`),import(`./auth-Bz5dmZgR.js`).then(e=>e.t)]),h=i();v.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path});let _=e();_.use(e.json({limit:`1mb`}));let y=Number(n.port),S=`http://localhost:${y}`,C=process.env.AIKIT_CORS_ORIGIN??S,w=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,T=D(`AIKIT_HTTP_MAX_SESSIONS`,8),O=D(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),k=D(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),A=x({limit:100,windowMs:6e4}),j=!1;_.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=b({requestOrigin:r,configuredOrigin:C,allowAnyOrigin:w,fallbackOrigin:S});if(i.warn&&!j&&(j=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let M=p();console.error(`[aikit] Auth token: ~/.aikit/token`),_.use(f(M)),_.use(`/mcp`,(e,t,n)=>{let r=E(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(A.allow(r)){n();return}let i=Math.max(1,Math.ceil(A.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),o(_,s(),v);let N=new Date().toISOString();_.use(`/settings/api`,d({log:v,mcpInfo:()=>({transport:`http`,port:y,pid:process.pid,startedAt:N})})),c(_,u(),v),_.get(`/health`,(e,t)=>{t.json({status:`ok`})});let P=!1,F=null,I=null,L=null,R=null,z=null,B=null,V=null,H=Promise.resolve(),U=async(e,n)=>{if(!P||!L||!R){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=H,i;H=new Promise(e=>{i=e}),await r;try{let r=E(e);if(!B){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new R({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{V=e,I?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&I?.onSessionEnd(e),V=null}});e.onclose=()=>{B===e&&(B=null),V===e.sessionId&&(V=null)},B=e,await L.connect(e)}let i=B;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(V=i.sessionId,I?.onSessionStart(i.sessionId,{transport:`http`}),I?.onSessionActivity(i.sessionId)):r&&I?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,l(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},W=async(e,t)=>{let n=E(e);if(z&&(!B||n!==V)){await z.handleRequest(e,t,e.body);return}await U(e,t)};_.post(`/mcp`,W),_.get(`/mcp`,W),_.delete(`/mcp`,W);let G=_.listen(y,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${y}/mcp`,port:y}),setTimeout(async()=>{try{let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:i},{checkForUpdates:o,autoUpgradeScaffold:s}]=await Promise.all([import(`./server-992x1P0e.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-BgHzxxCW.js`)]);o(),s();let c=a(h),u=e(h,c);L=u.server,R=i,P=!0,v.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),u.startInit(),u.ready.then(()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);I=new g(u.aikit.stateStore,{staleTimeoutMinutes:O,gcIntervalMinutes:k,onBeforeSessionDelete:e=>{if(V===e&&B){let e=B;B=null,V=null,e.close().catch(()=>void 0)}z?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!u.aikit?.curated||!u.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(u.aikit.curated,u.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),z=new m({createServer:()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);return t(u.aikit,h)},createTransport:e=>new i(e),maxSessions:T,sessionTimeoutMinutes:O,onSessionStart:e=>I?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>I?.onSessionActivity(e),onSessionEnd:e=>I?.onSessionEnd(e)}),I.startGC(),V&&(I.onSessionStart(V,{transport:`http`}),I.onSessionActivity(V)),v.info(`HTTP session runtime ready`,{maxSessions:T,sessionTimeoutMinutes:O,gcIntervalMinutes:k})}).catch(e=>v.error(`Failed to start session manager`,l(e))),c===`auto`?u.ready.then(async()=>{try{let e=h.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await u.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,l(e))}}).catch(e=>v.error(`AI Kit init or indexing failed`,l(e))):c===`smart`?u.ready.then(async()=>{try{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(u.aikit.indexer,h,u.aikit.store),n=u.aikit.store;F=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),u.setSmartScheduler(t),v.info(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>v.error(`AI Kit initialization failed`,l(e))):(u.ready.catch(e=>v.error(`AI Kit initialization failed`,l(e))),v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:c})),r(u.ready,()=>u.aikit?{curated:u.aikit.curated,stateStore:u.aikit.stateStore}:null)}catch(e){v.error(`Failed to load server modules`,l(e))}},100)}),K=async e=>{v.info(`Shutdown signal received`,{signal:e}),F?.stop(),I?.stop(),await z?.closeAll().catch(()=>void 0),V&&I?.onSessionEnd(V),B&&(await B.close().catch(()=>void 0),B=null,V=null),G.close(),L&&await L.close(),process.exit(0)};process.on(`SIGINT`,()=>K(`SIGINT`)),process.on(`SIGTERM`,()=>K(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:i},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-Ymr8iMyI.js`),import(`./server-992x1P0e.js`),import(`./version-check-BgHzxxCW.js`),import(`@modelcontextprotocol/sdk/types.js`)]),c=e();v.info(`Config loaded`,{sourceCount:c.sources.length,storePath:c.store.path}),a(),o();let u=n(c),d=i(c,u),{server:f,startInit:p,ready:m,runInitialIndex:h}=d,{StdioServerTransport:g}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),_=new g;await f.connect(_),v.info(`MCP server started`,{transport:`stdio`}),await C({config:c,indexMode:u,log:v,rootsChangedNotificationSchema:s,reconfigureForWorkspace:t,runInitialIndex:h,server:f,startInit:p});let y=null,b=()=>{y&&clearTimeout(y),y=setTimeout(async()=>{v.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=d.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),y.unref&&y.unref()};b(),process.stdin.on(`data`,()=>b()),m.catch(e=>{v.error(`Initialization failed — server will continue with limited tools`,l(e))}),u===`smart`?m.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,c,d.aikit.store),n=d.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),v.info(`Smart index scheduler started (stdio mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>v.error(`AI Kit init failed for smart scheduler`,l(e))):v.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u}),r(m,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}}export{e as CuratedKnowledgeManager,S as applyWorkspaceRoots,C as bootstrapWorkspaceRoots,x as createSlidingWindowRateLimiter,k as main,b as resolveCorsOrigin};
1
+ import{t as e}from"./curated-manager-BpxV59aR.js";import{randomUUID as t}from"node:crypto";import{readFileSync as n}from"node:fs";import{dirname as r,resolve as i}from"node:path";import{fileURLToPath as a,pathToFileURL as o}from"node:url";import{parseArgs as s}from"node:util";import{createLogger as c,serializeError as l}from"../../core/dist/index.js";const u=`__pending__:`;function d(e){return e.startsWith(u)}function f(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function p(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var m=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=f(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){p(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){p(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!d(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!d(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!d(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){p(e,503,-32003,`Session capacity reached`);return}let n=this.now(),r=await this.options.createServer(),i={id:`${u}${t()}`,transport:void 0,createdAt:n,lastAccessAt:n,server:r,requestChain:Promise.resolve()},a=this.options.createTransport({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{this.runtimes.delete(i.id),i.id=e,this.runtimes.set(e,i),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return i.transport=a,a.onclose=()=>{let e=i.transport.sessionId??i.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(i.id,i),await r.connect(a),i}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function h(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var g=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=h(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};function _(){try{let e=i(r(a(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}const v=c(`server`),y=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function b({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?y.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function x({limit:e,windowMs:t}){let n=new Map,r=(e,r)=>{let i=r-t,a=n.get(e)?.filter(e=>e>i)??[];return a.length===0?(n.delete(e),[]):(n.set(e,a),a)};return{allow(t,i=Date.now()){let a=r(t,i);return a.length>=e?!1:(a.push(i),n.set(t,a),!0)},getRetryAfterMs(n,i=Date.now()){let a=r(n,i);return a.length<e?0:Math.max(0,a[0]+t-i)}}}function S({config:e,log:t,reconfigureForWorkspace:n,roots:r}){if(r.length===0)return!1;let i=r[0].uri,o=i.startsWith(`file://`)?a(i):i;return t.info(`MCP roots resolved`,{rootUri:i,rootPath:o,rootCount:r.length}),n(e,o),e.allRoots=r.map(e=>{let t=e.uri;return t.startsWith(`file://`)?a(t):t}),!0}async function C({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:a,server:o,startInit:s,timeoutMs:c=5e3,getCwd:u=()=>process.cwd()}){let d=!1,f=!1,p,m=o.server,h=e=>{let t=l(e),n=`${String(e)} ${String(t.message??``)}`.toLowerCase();return n.includes(`method not found`)||n.includes(`not supported`)||n.includes(`unsupported`)||n.includes(`unknown method`)||n.includes(`roots/list`)},g=()=>{d||(d=!0,s())},_=()=>{f||t!==`auto`||(f=!0,(async()=>{try{await a()}catch(e){n.error(`Initial index failed`,l(e))}})())},v=t=>t.length===0||(p&&=(clearTimeout(p),void 0),g(),!S({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(_(),!0);try{if(v((await m.listRoots()).roots))return;n.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){if(h(e)){n.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:u(),...l(e)}),g(),_();return}n.warn(`MCP roots/list failed during bootstrap; waiting for roots/list_changed notification`,{cwd:u(),...l(e)}),g()}m.setNotificationHandler(r,async()=>{try{v((await m.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,l(e))}}),p=setTimeout(()=>{n.warn(`Timed out waiting for MCP roots/list_changed; starting in limited mode`,{cwd:u()}),g()},c)}function w(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function T(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===o(e).href}catch{return!1}}function E(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function D(e,t){let n=process.env[e];if(!n)return t;let r=Number.parseInt(n,10);return Number.isFinite(r)&&r>0?r:t}function O(){return T()?s({allowPositionals:!0,options:{transport:{type:`string`,default:w()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:w(),port:process.env.AIKIT_PORT??`3210`}}async function k(){let e=_(),n=O();process.on(`unhandledRejection`,e=>{v.error(`Unhandled rejection`,l(e))}),process.on(`uncaughtException`,e=>{v.error(`Uncaught exception — exiting`,l(e)),process.exit(1)});let r=(e,t)=>{e.then(async()=>{try{let{markPromoteRun:e,markPruneRun:n,prune:r,shouldRunStartupPrune:i,shouldRunWeeklyPromote:a}=await import(`../../tools/dist/index.js`),o=t();if(!o)return;if(i()){let e=await r({});n(),e.totalBytesFreed>0&&v.info(`Storage maintenance complete`,{forgeOrphans:e.forgeGroundOrphans.count,legacyLance:e.legacyLance.count,bytesFreed:e.totalBytesFreed});let{groupLessons:t,pruneLessons:i}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),a=await i(o.curated,o.stateStore,{dryRun:!1});a.pruned.length>0&&v.info(`Startup lesson prune complete`,{pruned:a.pruned.length});let s=await t(o.curated,o.stateStore,{dryRun:!1});(s.groupsCreated>0||s.lessonsGrouped>0)&&v.info(`Startup lesson grouping complete`,{groupsCreated:s.groupsCreated,lessonsGrouped:s.lessonsGrouped})}if(a()){let{DEFAULT_PROMOTE_CONFIG:t,collectWorkspaceLessons:n,getGlobalCuratedDir:r,promoteLessons:i,scanForDuplicates:a}=await import(`./promotion-BUn2DHpt.js`).then(e=>e.o),{CuratedKnowledgeManager:s}=await import(`./curated-manager-BpxV59aR.js`).then(e=>e.n),c=o.curated,l=new s(r(),c.store,c.embedder),u=await n(),d={...t,dryRun:!1},f=await i(a(u,d),l,d);e(),f.promoted.length>0&&v.info(`Weekly lesson promotion complete`,{promoted:f.promoted.length,candidates:f.candidates.length})}}catch(e){v.warn(`Startup maintenance failed (non-critical)`,l(e))}}).catch(()=>{})};if(v.info(`Starting MCP AI Kit server`,{version:e}),n.transport===`http`){let[{default:e},{loadConfig:i,resolveIndexMode:a},{registerDashboardRoutes:o,resolveDashboardDir:s},{registerSettingsRoutes:c,resolveSettingsDir:u},{createSettingsRouter:d},{authMiddleware:f,getOrCreateToken:p}]=await Promise.all([import(`express`),import(`./config-Ymr8iMyI.js`),import(`./dashboard-static-FmfoS46e.js`),import(`./settings-static-BtvyIrza.js`),import(`./routes-CR3fI-HJ.js`),import(`./auth-Bz5dmZgR.js`).then(e=>e.t)]),h=i();v.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path});let _=e();_.use(e.json({limit:`1mb`}));let y=Number(n.port),S=`http://localhost:${y}`,C=process.env.AIKIT_CORS_ORIGIN??S,w=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,T=D(`AIKIT_HTTP_MAX_SESSIONS`,8),O=D(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),k=D(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),A=x({limit:100,windowMs:6e4}),j=!1;_.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=b({requestOrigin:r,configuredOrigin:C,allowAnyOrigin:w,fallbackOrigin:S});if(i.warn&&!j&&(j=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let M=p();console.error(`[aikit] Auth token: ~/.aikit/token`),_.use(f(M)),_.use(`/mcp`,(e,t,n)=>{let r=E(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(A.allow(r)){n();return}let i=Math.max(1,Math.ceil(A.getRetryAfterMs(r)/1e3));t.setHeader(`Retry-After`,String(i)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})}),o(_,s(),v);let N=new Date().toISOString();_.use(`/settings/api`,d({log:v,mcpInfo:()=>({transport:`http`,port:y,pid:process.pid,startedAt:N})})),c(_,u(),v),_.get(`/health`,(e,t)=>{t.json({status:`ok`})});let P=!1,F=null,I=null,L=null,R=null,z=null,B=null,V=null,H=Promise.resolve(),U=async(e,n)=>{if(!P||!L||!R){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=H,i;H=new Promise(e=>{i=e}),await r;try{let r=E(e);if(!B){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new R({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{V=e,I?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&I?.onSessionEnd(e),V=null}});e.onclose=()=>{B===e&&(B=null),V===e.sessionId&&(V=null)},B=e,await L.connect(e)}let i=B;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(V=i.sessionId,I?.onSessionStart(i.sessionId,{transport:`http`}),I?.onSessionActivity(i.sessionId)):r&&I?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,l(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},W=async(e,t)=>{let n=E(e);if(z&&(!B||n!==V)){await z.handleRequest(e,t,e.body);return}await U(e,t)};_.post(`/mcp`,W),_.get(`/mcp`,W),_.delete(`/mcp`,W);let G=_.listen(y,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${y}/mcp`,port:y}),setTimeout(async()=>{try{let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:i},{checkForUpdates:o,autoUpgradeScaffold:s}]=await Promise.all([import(`./server-SG2YaDsH.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-BgHzxxCW.js`)]);o(),s();let c=a(h),u=e(h,c);L=u.server,R=i,P=!0,v.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),u.startInit(),u.ready.then(()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);I=new g(u.aikit.stateStore,{staleTimeoutMinutes:O,gcIntervalMinutes:k,onBeforeSessionDelete:e=>{if(V===e&&B){let e=B;B=null,V=null,e.close().catch(()=>void 0)}z?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!u.aikit?.curated||!u.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./evolution-BX_zTSdj.js`).then(e=>e.t),t=await e(u.aikit.curated,u.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),z=new m({createServer:()=>{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);return t(u.aikit,h)},createTransport:e=>new i(e),maxSessions:T,sessionTimeoutMinutes:O,onSessionStart:e=>I?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>I?.onSessionActivity(e),onSessionEnd:e=>I?.onSessionEnd(e)}),I.startGC(),V&&(I.onSessionStart(V,{transport:`http`}),I.onSessionActivity(V)),v.info(`HTTP session runtime ready`,{maxSessions:T,sessionTimeoutMinutes:O,gcIntervalMinutes:k})}).catch(e=>v.error(`Failed to start session manager`,l(e))),c===`auto`?u.ready.then(async()=>{try{let e=h.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await u.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,l(e))}}).catch(e=>v.error(`AI Kit init or indexing failed`,l(e))):c===`smart`?u.ready.then(async()=>{try{if(!u.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(u.aikit.indexer,h,u.aikit.store),n=u.aikit.store;F=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),u.setSmartScheduler(t),v.info(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>v.error(`AI Kit initialization failed`,l(e))):(u.ready.catch(e=>v.error(`AI Kit initialization failed`,l(e))),v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:c})),r(u.ready,()=>u.aikit?{curated:u.aikit.curated,stateStore:u.aikit.stateStore}:null)}catch(e){v.error(`Failed to load server modules`,l(e))}},100)}),K=async e=>{v.info(`Shutdown signal received`,{signal:e}),F?.stop(),I?.stop(),await z?.closeAll().catch(()=>void 0),V&&I?.onSessionEnd(V),B&&(await B.close().catch(()=>void 0),B=null,V=null),G.close(),L&&await L.close(),process.exit(0)};process.on(`SIGINT`,()=>K(`SIGINT`)),process.on(`SIGTERM`,()=>K(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:i},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-Ymr8iMyI.js`),import(`./server-SG2YaDsH.js`),import(`./version-check-BgHzxxCW.js`),import(`@modelcontextprotocol/sdk/types.js`)]),c=e();v.info(`Config loaded`,{sourceCount:c.sources.length,storePath:c.store.path}),a(),o();let u=n(c),d=i(c,u),{server:f,startInit:p,ready:m,runInitialIndex:h}=d,{StdioServerTransport:g}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),_=new g;await f.connect(_),v.info(`MCP server started`,{transport:`stdio`}),await C({config:c,indexMode:u,log:v,rootsChangedNotificationSchema:s,reconfigureForWorkspace:t,runInitialIndex:h,server:f,startInit:p});let y=null,b=()=>{y&&clearTimeout(y),y=setTimeout(async()=>{v.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=d.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),y.unref&&y.unref()};b(),process.stdin.on(`data`,()=>b()),m.catch(e=>{v.error(`Initialization failed — server will continue with limited tools`,l(e))}),u===`smart`?m.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,c,d.aikit.store),n=d.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),v.info(`Smart index scheduler started (stdio mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>v.error(`AI Kit init failed for smart scheduler`,l(e))):v.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u}),r(m,()=>d.aikit?{curated:d.aikit.curated,stateStore:d.aikit.stateStore}:null)}}export{e as CuratedKnowledgeManager,S as applyWorkspaceRoots,C as bootstrapWorkspaceRoots,x as createSlidingWindowRateLimiter,k as main,b as resolveCorsOrigin};
@@ -1,2 +1,2 @@
1
- import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{t}from"./curated-manager-CxKwx3Ym.js";import{f as n,r,u as i}from"./supersession-CWEne3av.js";import{existsSync as a,mkdirSync as o}from"node:fs";import{join as s}from"node:path";import{getGlobalDataDir as c,isUserInstalled as l,listWorkspaces as u}from"../../core/dist/index.js";var d=e({DEFAULT_PROMOTE_CONFIG:()=>f,collectWorkspaceLessons:()=>w,demoteLesson:()=>D,getGlobalCuratedDir:()=>C,promoteLessons:()=>E,scanForDuplicates:()=>T});const f={minWorkspaces:2,minAvgConfidence:80,similarityThreshold:.7,dryRun:!0};function p(e){return{minWorkspaces:Math.max(2,Math.trunc(e?.minWorkspaces??f.minWorkspaces)),minAvgConfidence:Math.min(100,Math.max(0,Math.trunc(e?.minAvgConfidence??f.minAvgConfidence))),similarityThreshold:Math.min(1,Math.max(0,e?.similarityThreshold??f.similarityThreshold)),dryRun:e?.dryRun??f.dryRun}}function m(e,t){let n=e.map(()=>[]);for(let i=0;i<e.length;i+=1)for(let a=i+1;a<e.length;a+=1)r(e[i].insight,e[a].insight)>=t&&(n[i].push(a),n[a].push(i));return n}function h(e){let t=new Set,n=[];for(let r=0;r<e.length;r+=1){if(t.has(r))continue;let i=[r],a=[];for(t.add(r);i.length>0;){let n=i.pop();if(n!==void 0){a.push(n);for(let r of e[n])t.has(r)||(t.add(r),i.push(r))}}n.push(a)}return n}function g(e){return new t(e,null,null)}function _(e){return(e??``).replace(/\s+/g,` `).trim()}function v(e){let t=_(e);return t.length<=80?t:`${t.slice(0,77).replace(/\s+\S*$/,``)}...`}function y(e){return i({title:v(e.insight),context:`Observed across ${e.foundIn.length} workspaces: ${e.foundIn.join(`, `)}`,insight:e.insight,evidence:[`Promoted from workspaces: ${e.foundIn.join(`, `)}`,`Average confidence: ${e.avgConfidence}/100`,`Reason: ${e.reason}`].join(`
1
+ import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{t}from"./curated-manager-BpxV59aR.js";import{f as n,r,u as i}from"./supersession-CWEne3av.js";import{existsSync as a,mkdirSync as o}from"node:fs";import{join as s}from"node:path";import{getGlobalDataDir as c,isUserInstalled as l,listWorkspaces as u}from"../../core/dist/index.js";var d=e({DEFAULT_PROMOTE_CONFIG:()=>f,collectWorkspaceLessons:()=>w,demoteLesson:()=>D,getGlobalCuratedDir:()=>C,promoteLessons:()=>E,scanForDuplicates:()=>T});const f={minWorkspaces:2,minAvgConfidence:80,similarityThreshold:.7,dryRun:!0};function p(e){return{minWorkspaces:Math.max(2,Math.trunc(e?.minWorkspaces??f.minWorkspaces)),minAvgConfidence:Math.min(100,Math.max(0,Math.trunc(e?.minAvgConfidence??f.minAvgConfidence))),similarityThreshold:Math.min(1,Math.max(0,e?.similarityThreshold??f.similarityThreshold)),dryRun:e?.dryRun??f.dryRun}}function m(e,t){let n=e.map(()=>[]);for(let i=0;i<e.length;i+=1)for(let a=i+1;a<e.length;a+=1)r(e[i].insight,e[a].insight)>=t&&(n[i].push(a),n[a].push(i));return n}function h(e){let t=new Set,n=[];for(let r=0;r<e.length;r+=1){if(t.has(r))continue;let i=[r],a=[];for(t.add(r);i.length>0;){let n=i.pop();if(n!==void 0){a.push(n);for(let r of e[n])t.has(r)||(t.add(r),i.push(r))}}n.push(a)}return n}function g(e){return new t(e,null,null)}function _(e){return(e??``).replace(/\s+/g,` `).trim()}function v(e){let t=_(e);return t.length<=80?t:`${t.slice(0,77).replace(/\s+\S*$/,``)}...`}function y(e){return i({title:v(e.insight),context:`Observed across ${e.foundIn.length} workspaces: ${e.foundIn.join(`, `)}`,insight:e.insight,evidence:[`Promoted from workspaces: ${e.foundIn.join(`, `)}`,`Average confidence: ${e.avgConfidence}/100`,`Reason: ${e.reason}`].join(`
2
2
  `),confidence:e.avgConfidence,tags:[`lesson`,`promoted`,`global`]})}async function b(e,t){let r=await e.list({category:`lessons`});return(await Promise.all(r.map(async r=>{let i=await e.read(r.path),a=n(i.content),o=_(a.insight);return o?{workspace:t,path:r.path,title:a.title??i.title??r.title,insight:o,confidence:a.confidence??0}:null}))).filter(e=>e!==null)}async function x(e){return(await b(e,`global`)).map(e=>e.insight)}function S(e,t,n){return t.some(t=>r(t,e)>=n)}function C(){let e=s(c(),`global-knowledge`,`.ai`,`curated`);return a(e)||o(e,{recursive:!0}),e}async function w(e){let t=new Map;if(!l())return t;for(let e of u()){let n=s(e.workspacePath,`.ai`,`curated`);if(!a(n))continue;let r=await b(g(n),e.partition);r.length>0&&t.set(e.partition,r)}return t}function T(e,t=f){let n=p(t),r=[...e.values()].flat();if(r.length===0)return[];let i=h(m(r,n.similarityThreshold)),a=[];for(let e of i){let t=e.map(e=>r[e]),i=[...new Set(t.map(e=>e.workspace))].sort();if(i.length<n.minWorkspaces)continue;let o=Math.round(t.reduce((e,t)=>e+t.confidence,0)/t.length),s=[...t].sort((e,t)=>t.confidence-e.confidence||e.title.localeCompare(t.title)||e.path.localeCompare(t.path))[0];a.push({insight:s.insight,foundIn:i,avgConfidence:o,action:o>=n.minAvgConfidence?`promote`:`skip`,reason:o>=n.minAvgConfidence?`Shared across ${i.length} workspaces`:`Below confidence threshold`})}return a.sort((e,t)=>Number(t.action===`promote`)-Number(e.action===`promote`)||t.foundIn.length-e.foundIn.length||t.avgConfidence-e.avgConfidence||e.insight.localeCompare(t.insight))}async function E(e,t,n=f){let r=p(n),i=[],a=await x(t);for(let n of e){if(n.action!==`promote`||S(n.insight,a,r.similarityThreshold)||r.dryRun)continue;let e=await t.remember(v(n.insight),y(n),`lessons`,[`lesson`,`promoted`,`global`]);i.push(e.path),a.push(n.insight)}return{candidates:e,promoted:i}}async function D(e,t){try{return await e.forget(t,`Demoted from global knowledge partition`),{removed:!0,path:t}}catch(e){if(e instanceof Error&&/not found/i.test(e.message))return{removed:!1,path:t};throw e}}export{E as a,C as i,w as n,d as o,D as r,T as s,f as t};
@@ -1,4 +1,4 @@
1
- import{r as e,t}from"./curated-manager-CxKwx3Ym.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-B4ITAs7F.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-CWEne3av.js";import{n as S,r as C}from"./resolve-sibling-1oDoO-Re.js";import{n as w,r as T}from"./evolution-BX_zTSdj.js";import{a as E,i as D,n as O,r as ee,s as te,t as ne}from"./promotion-VH4M_cWb.js";import{autoUpgradeScaffold as re,getCurrentVersion as ie,getUpgradeState as ae}from"./version-check-BgHzxxCW.js";import{createRequire as oe}from"node:module";import{createHash as k,randomBytes as se,randomUUID as ce,timingSafeEqual as le}from"node:crypto";import{existsSync as A,mkdirSync as j,readFileSync as M,readdirSync as ue,renameSync as de,rmSync as fe,statSync as pe,unlinkSync as me,writeFileSync as he}from"node:fs";import{basename as ge,dirname as _e,isAbsolute as ve,join as N,relative as ye,resolve as P,sep as be}from"node:path";import{fileURLToPath as xe}from"node:url";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as F,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as I}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,stratumCard as yn,summarizeCheckResult as bn,symbol as xn,testRun as Sn,timeUtils as Cn,trace as wn,truncateToTokenBudget as L,watchList as Tn,watchStart as En,watchStop as Dn,webFetch as On,webSearch as kn}from"../../tools/dist/index.js";import{mkdir as An,readFile as jn,readdir as Mn,rm as Nn,stat as Pn,unlink as Fn,writeFile as In}from"node:fs/promises";import{execFile as Ln,execSync as Rn}from"node:child_process";import{homedir as zn,tmpdir as Bn}from"node:os";import{McpServer as Vn,ResourceTemplate as Hn}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Un,field as Wn,normalizeResponse as Gn}from"../../elicitation/dist/index.js";import{completable as Kn}from"@modelcontextprotocol/sdk/server/completable.js";import{z as R}from"zod";import{getEngine as qn,registerBrowserTools as Jn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Yn,DependencyAnalyzer as Xn,DiagramGenerator as Zn,EntryPointAnalyzer as Qn,KnowledgeProducer as $n,PatternAnalyzer as er,StructureAnalyzer as tr,SymbolAnalyzer as nr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as rr,WasmRuntime as ir,initializeWasm as ar}from"../../chunker/dist/index.js";import{ERCache as or,ERClient as sr,EvolutionCollector as cr,PolicyStore as lr,PushAdapter as ur,mergeResults as dr}from"../../enterprise-bridge/dist/index.js";import{RESOURCE_MIME_TYPE as fr,registerAppResource as pr,registerAppTool as mr}from"@modelcontextprotocol/ext-apps/server";import{SqliteGraphStore as hr,allMigrations as gr,createSqliteAdapter as _r,createStateStore as vr,createStore as yr,runMigrations as br}from"../../store/dist/index.js";import{TemplateRegistry as xr,buildShell as Sr,dashboardTemplateDefinition as Cr,defaultRegistry as wr,flameGraphTemplateDefinition as Tr,isError as Er,isResult as Dr,kanbanTemplateDefinition as Or,listSortTemplateDefinition as kr,renderSurface as Ar}from"../../blocks-core/dist/index.mjs";import{createServer as jr}from"node:http";import{EmbedderProxy as Mr}from"../../embeddings/dist/index.js";import{FileHashCache as Nr,IncrementalIndexer as Pr}from"../../indexer/dist/index.js";function Fr(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return Gn(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,Un({confirmed:Wn.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,Un({selection:Wn.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,Un({selections:Wn.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,Un({text:Wn.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Ir={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Lr(e){return Ae(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Ir[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const Rr=3e4,zr=new Map;function Br(e,t,n){let r=zr.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(zr.set(e,{data:n,expires:Date.now()+t}),n))}function Vr(){zr.clear()}function Hr(e,t){return Br(`curated-paths`,Rr,async()=>(await e.list()).map(e=>e.path)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ur(e,t){return Br(`file-paths`,Rr,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Wr(e,t){return Br(`symbol-names`,Rr,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Gr(e,t){return t?_n(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Kr(e){return Nt().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function qr(e,t){return t?qe(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Jr(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
1
+ import{r as e,t}from"./curated-manager-BpxV59aR.js";import{a as n,i as r,n as i,o as a,r as o,s}from"./retention-B4ITAs7F.js";import{a as c,c as l,d as u,f as d,h as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,u as x}from"./supersession-CWEne3av.js";import{n as S,r as C}from"./resolve-sibling-1oDoO-Re.js";import{n as w,r as T}from"./evolution-BX_zTSdj.js";import{a as E,i as D,n as O,r as ee,s as te,t as ne}from"./promotion-BUn2DHpt.js";import{autoUpgradeScaffold as re,getCurrentVersion as ie,getUpgradeState as ae}from"./version-check-BgHzxxCW.js";import{createRequire as oe}from"node:module";import{createHash as k,randomBytes as se,randomUUID as ce,timingSafeEqual as le}from"node:crypto";import{existsSync as A,mkdirSync as j,readFileSync as M,readdirSync as ue,renameSync as de,rmSync as fe,statSync as pe,unlinkSync as me,writeFileSync as he}from"node:fs";import{basename as ge,dirname as _e,isAbsolute as ve,join as N,relative as ye,resolve as P,sep as be}from"node:path";import{fileURLToPath as xe}from"node:url";import{AIKIT_PATHS as Se,CONTENT_TYPES as Ce,CircuitBreaker as we,EMBEDDING_DEFAULTS as Te,HealthBus as Ee,KNOWLEDGE_ORIGINS as De,SOURCE_TYPES as Oe,TOKEN_BUDGETS as ke,addLogListener as Ae,computePartitionKey as je,createLogger as F,getGlobalDataDir as Me,getPartitionDir as Ne,isUserInstalled as Pe,listWorkspaces as Fe,serializeError as I}from"../../core/dist/index.js";import{FileCache as Ie,acquireLease as Le,addToWorkset as Re,audit as ze,bookendReorder as Be,changelog as Ve,check as He,checkpointDiff as Ue,checkpointGC as We,checkpointHistory as Ge,checkpointLatest as Ke,checkpointList as qe,checkpointLoad as Je,checkpointSave as Ye,codemod as Xe,compact as Ze,compressTerminalOutput as Qe,createRestorePoint as $e,createSearchSuccessResponse as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,digest as ot,encode as st,ensureLegacyStashImported as ct,envInfo as lt,evaluate as ut,evidenceMap as dt,fileSummary as ft,find as pt,findDeadSymbols as mt,findExamples as ht,forgeClassify as gt,forgeGround as _t,getWorkset as vt,gitContext as yt,graphAugmentSearch as bt,graphQuery as xt,guide as St,health as Ct,httpRequest as wt,laneCreate as Tt,laneDiff as Et,laneDiscard as Dt,laneList as Ot,laneMerge as kt,laneStatus as At,listActiveLeases as jt,listRestorePoints as Mt,listWorksets as Nt,measure as Pt,onboard as Ft,parseOutput as It,processList as Lt,processLogs as Rt,processStart as zt,processStatus as Bt,processStop as Vt,queueClear as Ht,queueCreate as Ut,queueDag as Wt,queueDelete as Gt,queueDone as Kt,queueFail as qt,queueGet as Jt,queueList as Yt,queueNext as Xt,queuePush as Zt,regexTest as Qt,releaseLease as $t,removeFromWorkset as en,rename as tn,replayAppend as nn,replayClear as rn,replayList as an,replayTrim as on,restoreFromPoint as sn,saveWorkset as cn,schemaValidate as ln,scopeMap as un,scoreCompliance as dn,sessionDigest as fn,sessionDigestSampling as pn,stashClear as mn,stashDelete as hn,stashGet as gn,stashList as _n,stashSet as vn,stratumCard as yn,summarizeCheckResult as bn,symbol as xn,testRun as Sn,timeUtils as Cn,trace as wn,truncateToTokenBudget as L,watchList as Tn,watchStart as En,watchStop as Dn,webFetch as On,webSearch as kn}from"../../tools/dist/index.js";import{mkdir as An,readFile as jn,readdir as Mn,rm as Nn,stat as Pn,unlink as Fn,writeFile as In}from"node:fs/promises";import{execFile as Ln,execSync as Rn}from"node:child_process";import{homedir as zn,tmpdir as Bn}from"node:os";import{McpServer as Vn,ResourceTemplate as Hn}from"@modelcontextprotocol/sdk/server/mcp.js";import{buildFormSchema as Un,field as Wn,normalizeResponse as Gn}from"../../elicitation/dist/index.js";import{completable as Kn}from"@modelcontextprotocol/sdk/server/completable.js";import{z as R}from"zod";import{getEngine as qn,registerBrowserTools as Jn}from"../../browser/dist/index.js";import{BlastRadiusAnalyzer as Yn,DependencyAnalyzer as Xn,DiagramGenerator as Zn,EntryPointAnalyzer as Qn,KnowledgeProducer as $n,PatternAnalyzer as er,StructureAnalyzer as tr,SymbolAnalyzer as nr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as rr,WasmRuntime as ir,initializeWasm as ar}from"../../chunker/dist/index.js";import{ERCache as or,ERClient as sr,EvolutionCollector as cr,PolicyStore as lr,PushAdapter as ur,mergeResults as dr}from"../../enterprise-bridge/dist/index.js";import{RESOURCE_MIME_TYPE as fr,registerAppResource as pr,registerAppTool as mr}from"@modelcontextprotocol/ext-apps/server";import{SqliteGraphStore as hr,allMigrations as gr,createSqliteAdapter as _r,createStateStore as vr,createStore as yr,runMigrations as br}from"../../store/dist/index.js";import{TemplateRegistry as xr,buildShell as Sr,dashboardTemplateDefinition as Cr,defaultRegistry as wr,flameGraphTemplateDefinition as Tr,isError as Er,isResult as Dr,kanbanTemplateDefinition as Or,listSortTemplateDefinition as kr,renderSurface as Ar}from"../../blocks-core/dist/index.mjs";import{createServer as jr}from"node:http";import{EmbedderProxy as Mr}from"../../embeddings/dist/index.js";import{FileHashCache as Nr,IncrementalIndexer as Pr}from"../../indexer/dist/index.js";function Fr(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return Gn(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,Un({confirmed:Wn.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,Un({selection:Wn.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,Un({selections:Wn.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,Un({text:Wn.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Ir={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Lr(e){return Ae(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Ir[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const Rr=3e4,zr=new Map;function Br(e,t,n){let r=zr.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(zr.set(e,{data:n,expires:Date.now()+t}),n))}function Vr(){zr.clear()}function Hr(e,t){return Br(`curated-paths`,Rr,async()=>(await e.list()).map(e=>e.path)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ur(e,t){return Br(`file-paths`,Rr,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Wr(e,t){return Br(`symbol-names`,Rr,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Gr(e,t){return t?_n(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Kr(e){return Nt().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function qr(e,t){return t?qe(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Jr(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
2
2
  `)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:R.string().optional().describe(`Path to analyze (default: workspace root)`)}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the full onboarding workflow for "${e??`.`}"`,``,`1. \`onboard({ path: "${e??`.`}" })\` — full codebase analysis`,`2. \`produce_knowledge({ path: "${e??`.`}" })\` — generate synthesis`,'3. `knowledge({ action: "remember", ... })` for key curated entries',"4. `status` to verify index health"].join(`
3
3
  `)}}]})),e.registerPrompt(`sessionStart`,{title:`Start AI Kit Session`,description:`Initialize an AI Kit session — check status, list knowledge, and resume from last checkpoint`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session start protocol:`,``,"1. `status({})` — check AI Kit health and onboard state",'2. `knowledge({ action: "list" })` — see stored knowledge entries','3. `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — resume prior work'].join(`
4
4
  `)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:R.string().describe(`Brief summary of decisions made, blockers encountered, and next steps`)}},async({summary:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session end protocol:`,``,'1. `knowledge({ action: "remember", title: "Session checkpoint: '+e.slice(0,60)+`...", content: "`+e.replace(/"/g,`\\"`)+'", category: "conventions" })` — persist findings',n===`smart`?`2. Smart indexing is active — index refreshes automatically`:"2. `reindex({})` — refresh search index if files changed",`3. Confirm session data saved`].join(`
@@ -1 +1 @@
1
- const e={Orchestrator:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`Auto (copilot)`],Planner:[`Claude Opus 4.6 (copilot)`,`GPT-5.4 (copilot)`,`Auto (copilot)`],Implementer:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Frontend:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`Gemini 3.1 Pro (Preview) (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Debugger:[`Claude Opus 4.6 (copilot)`,`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Refactor:[`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Security:[`Claude Opus 4.6 (copilot)`,`GPT-5.4 (copilot)`,`Auto (copilot)`],Documenter:[`GPT-5 mini (copilot)`,`GPT-5.4 mini (copilot)`,`Auto (copilot)`],Explorer:[`GPT-5 mini (copilot)`,`Gemini 3 Flash (Preview) (copilot)`,`Auto (copilot)`],"Researcher-Alpha":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],"Researcher-Beta":[`Claude Sonnet 4.6 (copilot)`,`Auto (copilot)`],"Researcher-Gamma":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Researcher-Delta":[`Gemini 3.1 Pro (Preview) (copilot)`,`Auto (copilot)`],"Code-Reviewer-Alpha":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Code-Reviewer-Beta":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],"Architect-Reviewer-Alpha":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Architect-Reviewer-Beta":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`]},t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,(Array.isArray(t)?t[0]:t)?.replace(/ \(copilot\)$/,``)||`Auto`])),n={Researcher:[`Alpha`,`Beta`,`Gamma`,`Delta`],"Code-Reviewer":[`Alpha`,`Beta`],"Architect-Reviewer":[`Alpha`,`Beta`]},r={Researcher:`Alpha`,"Code-Reviewer":`Alpha`,"Architect-Reviewer":`Alpha`};export{t as CLAUDE_MODELS,e as COPILOT_MODELS,r as PRIMARY_VARIANT,n as VARIANT_GROUPS};
1
+ const e={Orchestrator:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`Auto (copilot)`],Planner:[`GPT-5.4 (copilot)`,`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],Implementer:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Frontend:[`GPT-5.4 mini (copilot)`,`GPT-5.4 (copilot)`,`Gemini 3.1 Pro (Preview) (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Debugger:[`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],Refactor:[`GPT-5.4 (copilot)`,`GPT-5.3-Codex (copilot)`,`Auto (copilot)`],Security:[`Claude Opus 4.6 (copilot)`,`GPT-5.4 (copilot)`,`Auto (copilot)`],Documenter:[`GPT-5 mini (copilot)`,`GPT-5.4 mini (copilot)`,`Auto (copilot)`],Explorer:[`GPT-5 mini (copilot)`,`Gemini 3 Flash (Preview) (copilot)`,`Auto (copilot)`],"Researcher-Alpha":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],"Researcher-Beta":[`Claude Sonnet 4.6 (copilot)`,`Auto (copilot)`],"Researcher-Gamma":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Researcher-Delta":[`Gemini 3.1 Pro (Preview) (copilot)`,`Auto (copilot)`],"Code-Reviewer-Alpha":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Code-Reviewer-Beta":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`],"Architect-Reviewer-Alpha":[`GPT-5.4 (copilot)`,`Auto (copilot)`],"Architect-Reviewer-Beta":[`Claude Opus 4.6 (copilot)`,`Auto (copilot)`]},t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,(Array.isArray(t)?t[0]:t)?.replace(/ \(copilot\)$/,``)||`Auto`])),n={Researcher:[`Alpha`,`Beta`,`Gamma`,`Delta`],"Code-Reviewer":[`Alpha`,`Beta`],"Architect-Reviewer":[`Alpha`,`Beta`]},r={Researcher:`Alpha`,"Code-Reviewer":`Alpha`,"Architect-Reviewer":`Alpha`};export{t as CLAUDE_MODELS,e as COPILOT_MODELS,r as PRIMARY_VARIANT,n as VARIANT_GROUPS};