@vpxa/aikit 0.1.236 → 0.1.238
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/{curated-manager-BpxV59aR.js → curated-manager-xTfPLFMR.js} +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{promotion-BUn2DHpt.js → promotion-PdKQQktE.js} +1 -1
- package/packages/server/dist/{server-SG2YaDsH.js → server-CpQaZeTC.js} +1 -1
- package/packages/store/dist/index.d.ts +3 -1
- package/packages/store/dist/index.js +27 -27
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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=new Date().toISOString(),i=0;for(let e=0;e<n.length;e+=
|
|
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+=16){let a=n.slice(e,e+16);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
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(`
|
|
@@ -1,6 +1,6 @@
|
|
|
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=new Date().toISOString(),i=0;for(let e=0;e<n.length;e+=
|
|
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+=16){let a=n.slice(e,e+16);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
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(`
|
|
@@ -1 +1 @@
|
|
|
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
|
+
import{t as e}from"./curated-manager-xTfPLFMR.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-PdKQQktE.js`).then(e=>e.o),{CuratedKnowledgeManager:s}=await import(`./curated-manager-xTfPLFMR.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-CpQaZeTC.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-CpQaZeTC.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-
|
|
1
|
+
import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{t}from"./curated-manager-xTfPLFMR.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-
|
|
1
|
+
import{r as e,t}from"./curated-manager-xTfPLFMR.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-PdKQQktE.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(`
|
|
@@ -164,7 +164,9 @@ interface IGraphStore {
|
|
|
164
164
|
//#region packages/store/src/sqlite-adapter.d.ts
|
|
165
165
|
/**
|
|
166
166
|
* SQLite adapter — selects between native better-sqlite3 (preferred) and
|
|
167
|
-
* sql.js
|
|
167
|
+
* sql.js let skipNativeAdapter = false;
|
|
168
|
+
|
|
169
|
+
(WASM fallback). The fallback exists because better-sqlite3 is a
|
|
168
170
|
* native module whose prebuilt binary is not available in every environment
|
|
169
171
|
* (Codespaces, restricted CI, mismatched Node ABI).
|
|
170
172
|
*
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as n,readFileSync as r,renameSync as i,unlinkSync as a,writeFileSync as o}from"node:fs";import{basename as s,dirname as c,extname as l,join as u}from"node:path";import{AIKIT_PATHS as d,EMBEDDING_DEFAULTS as f,SEARCH_DEFAULTS as p,STORE_DEFAULTS as m,createLogger as h,serializeError as g,sourceTypeContentTypes as
|
|
1
|
+
import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as n,readFileSync as r,renameSync as i,unlinkSync as a,writeFileSync as o}from"node:fs";import{basename as s,dirname as c,extname as l,join as u}from"node:path";import{AIKIT_PATHS as d,EMBEDDING_DEFAULTS as f,SEARCH_DEFAULTS as p,STORE_DEFAULTS as m,createLogger as h,serializeError as g,sourceTypeContentTypes as _}from"../../core/dist/index.js";var ee=e(import.meta.url);function te(e){e.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
3
3
|
version INTEGER PRIMARY KEY,
|
|
4
4
|
name TEXT NOT NULL,
|
|
5
5
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
6
6
|
)
|
|
7
|
-
`)}function
|
|
7
|
+
`)}function v(e,t){te(e);let n=new Set(e.queryAll(`SELECT version FROM _migrations`).map(e=>e.version)),r=[...t].sort((e,t)=>e.version-t.version).filter(e=>!n.has(e.version));for(let t of r){e.exec(`BEGIN`);try{t.up(e),e.run(`INSERT INTO _migrations (version, name) VALUES (?, ?)`,[t.version,t.name]),e.exec(`COMMIT`)}catch(t){try{e.exec(`ROLLBACK`)}catch{}throw t}}}const y=[{version:1,name:`create state store tables`,up(e){e.exec(`
|
|
8
8
|
CREATE TABLE IF NOT EXISTS stash (
|
|
9
9
|
key TEXT PRIMARY KEY,
|
|
10
10
|
value TEXT NOT NULL,
|
|
@@ -79,17 +79,17 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
79
79
|
FROM leases_legacy;
|
|
80
80
|
|
|
81
81
|
DROP TABLE leases_legacy;
|
|
82
|
-
`)}}],y=h(`sqlite-adapter`),b=e(import.meta.url);var x=class{type=`better-sqlite3`;vectorCapable=!1;db=null;stmtCache=new Map;dbPath=``;DatabaseCtor=null;recovering=!1;async open(e){let t;try{t=b(`better-sqlite3`)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new t(e),this.dbPath=e,this.DatabaseCtor=t,this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`),this.runIntegrityCheck(e,t)||(this.db?.pragma(`journal_mode = WAL`),this.db?.pragma(`foreign_keys = ON`),this.db?.pragma(`synchronous = NORMAL`));try{b(`sqlite-vec`).load(this.db),this.vectorCapable=!0,y.info(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,y.warn(`sqlite-vec extension failed to load; vector search disabled`,g(e))}}exec(e){try{this.getDb().exec(e)}catch(t){if(this.isCorruptionError(t)){this.recover(),this.getDb().exec(e);return}throw t}}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){try{let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}catch(n){if(this.isCorruptionError(n))return this.recover(),this.queryAll(e,t);throw n}}run(e,t=[]){try{let n=this.prepareCached(e);t.length>0?n.run(...t):n.run()}catch(n){if(this.isCorruptionError(n)){this.recover(),this.run(e,t);return}throw n}}flush(){}close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}runIntegrityCheck(e,t){try{let t=this.db?.pragma(`integrity_check`);if(t.length===1&&t[0]?.integrity_check===`ok`)return!0;let n=t.map(e=>e.integrity_check).slice(0,5).join(`; `);y.warn(`Database integrity check failed — recreating`,{dbPath:e,issues:n})}catch(t){y.warn(`Integrity check query failed — recreating database`,{dbPath:e,error:g(t)})}try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(e)}catch{}try{a(`${e}-wal`)}catch{}try{a(`${e}-shm`)}catch{}return this.db=new t(e),y.info(`Database recreated successfully — full reindex required`,{dbPath:e}),!1}isCorruptionError(e){if(this.recovering)return!1;let t=e instanceof Error?e.message:String(e);return/database disk image is malformed|file is not a database|database or disk is full/.test(t)}recover(){if(this.recovering)throw Error(`BetterSqlite3Adapter: recovery already in progress`);this.recovering=!0;try{y.warn(`Runtime corruption detected — recovering database`,{dbPath:this.dbPath});try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(this.dbPath)}catch{}try{a(`${this.dbPath}-wal`)}catch{}try{a(`${this.dbPath}-shm`)}catch{}if(!this.DatabaseCtor)throw Error(`DatabaseCtor is not initialized`);this.db=this.DatabaseCtor(this.dbPath),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{b(`sqlite-vec`).load(this.db),this.vectorCapable=!0}catch{this.vectorCapable=!1}y.info(`Database recovered — full reindex required`,{dbPath:this.dbPath})}finally{this.recovering=!1}}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function S(e){return b.resolve(`sql.js/dist/${e}`)}var C=class{type=`sql.js`;vectorCapable=!1;db=null;dbPath=``;dirty=!1;inTransaction=!1;async open(e){this.dbPath=e;let n=(await import(`sql.js`)).default,i=await n({locateFile:e=>S(e)});if(t(e)){let t=r(e);this.db=new i.Database(t)}else this.db=new i.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.dirty=!0}pragma(e){this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=!this.inTransaction&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));i&&n.run(`SAVEPOINT fk_check`);try{if(t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(i){if(n.exec(`PRAGMA foreign_key_check`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(i)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export(),r=`${this.dbPath}.tmp`,a=c(this.dbPath);a&&!t(a)&&n(a,{recursive:!0}),o(r,Buffer.from(e)),i(r,this.dbPath),this.dirty=!1}close(){if(this.db){let e=this.db,t;try{this.flush()}catch(e){t=e;try{a(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};function w(){try{let e=u(b.resolve(`better-sqlite3/package.json`).replace(/[\\/]package\.json$/,``),`build`,`Release`,`better_sqlite3.node`);return t(e)?e:null}catch{return null}}async function re(){if(!w())return`missing`;try{let{execSync:e}=await import(`node:child_process`);return e(`"${process.execPath}" -e "require('better-sqlite3')"`,{stdio:`pipe`,timeout:15e3}),`ok`}catch(e){let t=e instanceof Error&&`stderr`in e?String(e.stderr):``;return/NODE_MODULE_VERSION/.test(t)?`abi-mismatch`:/Could not locate the bindings file|no native build was found/.test(t)?`missing`:`error`}}async function T(e=!1){try{let{execSync:n}=await import(`node:child_process`),r=b.resolve(`better-sqlite3/package.json`).replace(/[\\/]package\.json$/,``),i=r.replace(/[\\/]node_modules[\\/]better-sqlite3$/,``);if(e){let e=u(r,`build`,`Release`,`better_sqlite3.node`);if(t(e))try{a(e),y.info(`Deleted stale native binding before rebuild`,{path:e})}catch(t){y.warn(`Cannot delete stale native binding — file may be locked by another process`,{path:e,error:t instanceof Error?t.message:String(t)})}}return y.info(`Attempting native module rebuild for better-sqlite3`,{cwd:i}),n(`npm rebuild better-sqlite3`,{cwd:i,stdio:`pipe`,timeout:6e4}),y.info(`Native module rebuild completed successfully`),!0}catch(e){return y.warn(`Native module rebuild failed — continuing with sql.js fallback`,g(e)),!1}}let E=!1;function D(){return!!process.env.VITEST||process.argv.some(e=>e.includes(`vitest`))}async function O(e){if(!D()){let e=await re();e===`abi-mismatch`?(y.info(`Detected NODE_MODULE_VERSION mismatch via pre-flight probe — rebuilding before load`),await T(!0)&&y.info(`Pre-flight rebuild succeeded — proceeding with native adapter`)):e===`missing`&&(y.info(`No native binding found — attempting rebuild before load`),await T(!1))}let t=new x;try{return await t.open(e),t}catch(t){let n=t instanceof Error?t.message:String(t);if(!D()&&/NODE_MODULE_VERSION|Could not locate the bindings file|no native build was found/.test(n)&&await T(!1)){let t=new x;try{return await t.open(e),y.info(`better-sqlite3 recovered after native module rebuild`),t}catch{}}E||(E=!0,y.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,g(t)))}let n=new C;try{return await n.open(e),n}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function ie(e){let t=new C;return await t.open(e),t}const k=new Set([`sessions`,`stash`,`checkpoints`,`leases`,`signals`,`audit_log`,`replay_entries`,`session_metadata`]);function A(e){let t=l(e)||`.db`,n=s(e,t);return u(c(e),`${n}-control${t}`)}function j(e){return k.has(e)?`control`:`content`}function M(e,t={}){let n=t.splitEnabled??!1;return{splitEnabled:n,contentDbPath:t.contentDbPath??e,controlDbPath:t.controlDbPath??(n?A(e):e)}}function ae(e,t=process.env){let n=t.AIKIT_SPLIT_STATE?.trim().toLowerCase();return M(e,{splitEnabled:n===`1`||n===`true`||n===`yes`||n===`on`})}const N=`_state_partition_meta`;function P(e){return`"${e.replaceAll(`"`,`""`)}"`}function oe(e){let r=c(e);t(r)||n(r,{recursive:!0})}async function F(e){return oe(e),O(e)}function I(e,t){return e.queryAll(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`,[t]).length>0}function se(e,t){return e.queryAll(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,[t])[0]?.sql??void 0}function L(e,t){return e.queryAll(`PRAGMA table_info(${P(t)})`).map(e=>e.name)}function R(e,t){return e.queryAll(`SELECT COUNT(*) AS count FROM ${P(t)}`)[0]?.count??0}function z(e,t,n){if(!I(e,n))return;if(!I(t,n)){let r=se(e,n);if(!r)return;t.exec(r)}let r=L(t,n);if(r.length===0)return;let i=r.map(P).join(`, `),a=r.map(()=>`?`).join(`, `),o=e.queryAll(`SELECT ${i} FROM ${P(n)}`);if(o.length===0)return;let s=`INSERT OR REPLACE INTO ${P(n)} (${i}) VALUES (${a})`;for(let e of o)t.run(s,r.map(t=>e[t]??null))}function B(e){e.exec(`
|
|
83
|
-
CREATE TABLE IF NOT EXISTS ${
|
|
82
|
+
`)}}],b=h(`sqlite-adapter`),x=e(import.meta.url);var S=class{type=`better-sqlite3`;vectorCapable=!1;db=null;stmtCache=new Map;dbPath=``;DatabaseCtor=null;recovering=!1;async open(e){let t;try{t=x(`better-sqlite3`)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new t(e),this.dbPath=e,this.DatabaseCtor=t,this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`),this.runIntegrityCheck(e,t)||(this.db?.pragma(`journal_mode = WAL`),this.db?.pragma(`foreign_keys = ON`),this.db?.pragma(`synchronous = NORMAL`));try{x(`sqlite-vec`).load(this.db),this.vectorCapable=!0,b.info(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,b.warn(`sqlite-vec extension failed to load; vector search disabled`,g(e))}}exec(e){try{this.getDb().exec(e)}catch(t){if(this.isCorruptionError(t)){this.recover(),this.getDb().exec(e);return}throw t}}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){try{let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}catch(n){if(this.isCorruptionError(n))return this.recover(),this.queryAll(e,t);throw n}}run(e,t=[]){try{let n=this.prepareCached(e);t.length>0?n.run(...t):n.run()}catch(n){if(this.isCorruptionError(n)){this.recover(),this.run(e,t);return}throw n}}flush(){}close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}runIntegrityCheck(e,t){try{let t=this.db?.pragma(`integrity_check`);if(t.length===1&&t[0]?.integrity_check===`ok`)return!0;let n=t.map(e=>e.integrity_check).slice(0,5).join(`; `);b.warn(`Database integrity check failed — recreating`,{dbPath:e,issues:n})}catch(t){b.warn(`Integrity check query failed — recreating database`,{dbPath:e,error:g(t)})}try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(e)}catch{}try{a(`${e}-wal`)}catch{}try{a(`${e}-shm`)}catch{}return this.db=new t(e),b.info(`Database recreated successfully — full reindex required`,{dbPath:e}),!1}isCorruptionError(e){if(this.recovering)return!1;let t=e instanceof Error?e.message:String(e);return/database disk image is malformed|file is not a database|database or disk is full/.test(t)}recover(){if(this.recovering)throw Error(`BetterSqlite3Adapter: recovery already in progress`);this.recovering=!0;try{b.warn(`Runtime corruption detected — recovering database`,{dbPath:this.dbPath});try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(this.dbPath)}catch{}try{a(`${this.dbPath}-wal`)}catch{}try{a(`${this.dbPath}-shm`)}catch{}if(!this.DatabaseCtor)throw Error(`DatabaseCtor is not initialized`);this.db=this.DatabaseCtor(this.dbPath),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{x(`sqlite-vec`).load(this.db),this.vectorCapable=!0}catch{this.vectorCapable=!1}b.info(`Database recovered — full reindex required`,{dbPath:this.dbPath})}finally{this.recovering=!1}}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function ne(e){return x.resolve(`sql.js/dist/${e}`)}function re(e){return e.match(/^\s*(?:INSERT(?:\s+OR\s+\w+)?\s+INTO|UPDATE)\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1]??null}var C=class{type=`sql.js`;vectorCapable=!1;db=null;dbPath=``;dirty=!1;inTransaction=!1;foreignKeysEnabled=!1;async open(e){this.dbPath=e;let n=(await import(`sql.js`)).default,i=await n({locateFile:e=>ne(e)});if(t(e)){let t=r(e);this.db=new i.Database(t)}else this.db=new i.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.dirty=!0}pragma(e){let t=e.trim().toLowerCase();t===`foreign_keys = on`||t===`foreign_keys=on`?this.foreignKeysEnabled=!0:(t===`foreign_keys = off`||t===`foreign_keys=off`)&&(this.foreignKeysEnabled=!1),this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=re(e),a=this.foreignKeysEnabled&&!this.inTransaction&&i!==null&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));a&&n.run(`SAVEPOINT fk_check`);try{if(t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(a){if(n.exec(`PRAGMA foreign_key_check(${i})`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(a)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export(),r=`${this.dbPath}.tmp`,a=c(this.dbPath);a&&!t(a)&&n(a,{recursive:!0}),o(r,Buffer.from(e)),i(r,this.dbPath),this.dirty=!1}close(){if(this.db){let e=this.db,t;try{this.flush()}catch(e){t=e;try{a(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};function w(){try{return x.resolve(`better-sqlite3/package.json`).replace(/[\\/]package\.json$/,``)}catch{return null}}function T(){let e=w();if(!e)return null;let n=u(e,`build`,`Release`,`better_sqlite3.node`);return t(n)?n:null}async function ie(){let e=w();if(!e)return`package-missing`;if(!t(u(e,`build`,`Release`,`better_sqlite3.node`)))return`binding-missing`;try{let{execSync:e}=await import(`node:child_process`);return e(`"${process.execPath}" -e "require('better-sqlite3')"`,{stdio:`pipe`,timeout:15e3}),`ok`}catch(e){let t=e instanceof Error&&`stderr`in e?String(e.stderr):``;return/NODE_MODULE_VERSION/.test(t)?`abi-mismatch`:/Could not locate the bindings file|no native build was found/.test(t)?`binding-missing`:`error`}}async function ae(e=!1){let n=w();if(!n)return b.info(`better-sqlite3 package is not installed — skipping native rebuild`),!1;try{let{execSync:r}=await import(`node:child_process`),i=n.replace(/[\\/]node_modules[\\/]better-sqlite3$/,``);if(e){let e=u(n,`build`,`Release`,`better_sqlite3.node`);if(t(e))try{a(e),b.info(`Deleted stale native binding before rebuild`,{path:e})}catch(t){b.warn(`Cannot delete stale native binding — file may be locked by another process`,{path:e,error:t instanceof Error?t.message:String(t)})}}return b.info(`Attempting native module rebuild for better-sqlite3`,{cwd:i}),r(`npm rebuild better-sqlite3`,{cwd:i,stdio:`pipe`,timeout:6e4}),b.info(`Native module rebuild completed successfully`),!0}catch(e){return b.warn(`Native module rebuild failed — continuing with sql.js fallback`,g(e)),!1}}async function oe(){try{let{execSync:e}=await import(`node:child_process`),t=x.resolve(`@vpxa/aikit/package.json`).replace(/[\\/]package\.json$/,``);return b.info(`Attempting to install better-sqlite3 for native adapter recovery`,{cwd:t}),e(`npm install better-sqlite3 --no-save --package-lock=false`,{cwd:t,stdio:`pipe`,timeout:12e4}),b.info(`better-sqlite3 install completed successfully`),!0}catch(e){return b.warn(`better-sqlite3 install failed — continuing with sql.js fallback`,g(e)),!1}}let E=!1;function D(){return!!process.env.VITEST||process.argv.some(e=>e.includes(`vitest`))}async function O(e){if(!k.isVitestRuntime()){let e=await k.probeNativeModuleAbi();e===`abi-mismatch`?(b.info(`Detected NODE_MODULE_VERSION mismatch via pre-flight probe — rebuilding before load`),await k.tryRebuildNativeModule(!0)&&b.info(`Pre-flight rebuild succeeded — proceeding with native adapter`)):e===`binding-missing`?(b.info(`No native binding found — attempting rebuild before load`),await k.tryRebuildNativeModule(!1)):e===`package-missing`&&(b.info(`better-sqlite3 package is not installed — attempting install before load`),await oe())}{let t=k.createNativeAdapter();try{return await t.open(e),t}catch(t){let n=t instanceof Error?t.message:String(t);if(!k.isVitestRuntime()&&/NODE_MODULE_VERSION|Could not locate the bindings file|no native build was found/.test(n)&&await k.tryRebuildNativeModule(!1)){let t=k.createNativeAdapter();try{return await t.open(e),b.info(`better-sqlite3 recovered after native module rebuild`),t}catch{}}E||(E=!0,b.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,g(t)))}}let t=k.createFallbackAdapter();try{return await t.open(e),t}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function se(e){let t=new C;return await t.open(e),t}const k={BetterSqlite3Adapter:S,SqlJsAdapter:C,isVitestRuntime:D,resolveNativeModulePackageDir:w,resolveNativeBindingPath:T,probeNativeModuleAbi:ie,tryRebuildNativeModule:ae,createNativeAdapter:()=>new S,createFallbackAdapter:()=>new C},A=new Set([`sessions`,`stash`,`checkpoints`,`leases`,`signals`,`audit_log`,`replay_entries`,`session_metadata`]);function ce(e){let t=l(e)||`.db`,n=s(e,t);return u(c(e),`${n}-control${t}`)}function le(e){return A.has(e)?`control`:`content`}function j(e,t={}){let n=t.splitEnabled??!1;return{splitEnabled:n,contentDbPath:t.contentDbPath??e,controlDbPath:t.controlDbPath??(n?ce(e):e)}}function ue(e,t=process.env){let n=t.AIKIT_SPLIT_STATE?.trim().toLowerCase();return j(e,{splitEnabled:n===`1`||n===`true`||n===`yes`||n===`on`})}const M=`_state_partition_meta`;function N(e){return`"${e.replaceAll(`"`,`""`)}"`}function P(e){let r=c(e);t(r)||n(r,{recursive:!0})}async function F(e){return P(e),O(e)}function I(e,t){return e.queryAll(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`,[t]).length>0}function L(e,t){return e.queryAll(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,[t])[0]?.sql??void 0}function R(e,t){return e.queryAll(`PRAGMA table_info(${N(t)})`).map(e=>e.name)}function z(e,t){return e.queryAll(`SELECT COUNT(*) AS count FROM ${N(t)}`)[0]?.count??0}function B(e,t,n){if(!I(e,n))return;if(!I(t,n)){let r=L(e,n);if(!r)return;t.exec(r)}let r=R(t,n);if(r.length===0)return;let i=r.map(N).join(`, `),a=r.map(()=>`?`).join(`, `),o=e.queryAll(`SELECT ${i} FROM ${N(n)}`);if(o.length===0)return;let s=`INSERT OR REPLACE INTO ${N(n)} (${i}) VALUES (${a})`;for(let e of o)t.run(s,r.map(t=>e[t]??null))}function V(e){e.exec(`
|
|
83
|
+
CREATE TABLE IF NOT EXISTS ${M} (
|
|
84
84
|
key TEXT PRIMARY KEY,
|
|
85
85
|
value TEXT NOT NULL,
|
|
86
86
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
87
87
|
)
|
|
88
|
-
`)}function
|
|
88
|
+
`)}function H(e,t,n){V(e),e.run(`INSERT INTO ${M} (key, value, updated_at)
|
|
89
89
|
VALUES (?, ?, datetime('now'))
|
|
90
90
|
ON CONFLICT(key) DO UPDATE SET
|
|
91
91
|
value = excluded.value,
|
|
92
|
-
updated_at = datetime('now')`,[`split-state`,JSON.stringify({splitEnabled:t.splitEnabled,contentDbPath:t.contentDbPath,controlDbPath:t.controlDbPath,migratedTables:n})])}async function
|
|
92
|
+
updated_at = datetime('now')`,[`split-state`,JSON.stringify({splitEnabled:t.splitEnabled,contentDbPath:t.contentDbPath,controlDbPath:t.controlDbPath,migratedTables:n})])}async function U(e){let t=e.contentDbPath??e.controlDbPath;if(!t)throw Error(`migrateToSplitState requires at least one database path in config`);let n=j(t,e);if(!n.splitEnabled||n.controlDbPath===n.contentDbPath)return;let r=await F(n.contentDbPath),i=await F(n.controlDbPath);try{v(i,y);let e=[];for(let t of A){if(!I(r,t))continue;B(r,i,t);let n=z(r,t),a=z(i,t);if(a<n)throw Error(`Split-state migration verification failed for ${t}: source=${n} target=${a}`);e.push(t)}H(i,n,e)}finally{r.close(),i.close()}}var de=class{adapter=null;reopenPromise=null;dbPath;externalAdapter;constructor(e={}){if(e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=e.path??d.data;this.dbPath=u(t,`graph.db`),this.externalAdapter=!1}}async initialize(){if(this.externalAdapter){let e=this.getAdapter();this.createTables(e),this.migrateSchema(e),e.flush();return}let e=c(this.dbPath);t(e)||n(e,{recursive:!0}),this.adapter=await O(this.dbPath),this.configureAdapter(this.adapter),this.createTables(this.adapter),this.migrateSchema(this.adapter),this.adapter.flush()}configureAdapter(e){e.pragma(`journal_mode = WAL`),e.pragma(`foreign_keys = ON`)}createTables(e){e.exec(`
|
|
93
93
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
94
94
|
id TEXT PRIMARY KEY,
|
|
95
95
|
type TEXT NOT NULL,
|
|
@@ -154,13 +154,13 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
154
154
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
155
155
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
156
156
|
n.created_at AS node_created, n.community AS node_community
|
|
157
|
-
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
157
|
+
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(K(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(q(e)))}if(n===`incoming`||n===`both`){let t=`
|
|
158
158
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
159
159
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
160
160
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
161
161
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
162
162
|
n.created_at AS node_created, n.community AS node_community
|
|
163
|
-
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
163
|
+
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(K(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(q(e)))}return{nodes:a,edges:o}}async traverse(e,t){await this.ensureOpen();let n=t?.maxDepth??2,r=t?.direction??`both`,i=t?.edgeType,a=t?.limit??50,o=new Map,s=new Map,c=new Set,l=[{nodeId:e,depth:0}];for(;l.length>0&&o.size<a;){let e=l.shift();if(!e||c.has(e.nodeId)||e.depth>n)continue;c.add(e.nodeId);let t=await this.getNeighbors(e.nodeId,{direction:r,edgeType:i,limit:a-o.size});for(let r of t.nodes)o.has(r.id)||(o.set(r.id,r),e.depth+1<n&&l.push({nodeId:r.id,depth:e.depth+1}));for(let e of t.edges)s.set(e.id,e)}return{nodes:[...o.values()],edges:[...s.values()]}}async findNodes(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.namePattern&&(t.push(`name LIKE ?`),n.push(`%${e.namePattern}%`)),e.sourcePath&&(t.push(`source_path = ?`),n.push(e.sourcePath));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM nodes ${r} LIMIT ?`,[...n,i]).map(e=>G(e))}async findEdges(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.fromId&&(t.push(`from_id = ?`),n.push(e.fromId)),e.toId&&(t.push(`to_id = ?`),n.push(e.toId));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM edges ${r} LIMIT ?`,[...n,i]).map(e=>fe(e))}async deleteNode(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e,e]),this.run(`DELETE FROM nodes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async deleteBySourcePath(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE source_path = ?`,[e]);if(t.length===0)return 0;let n=this.getAdapter();n.exec(`BEGIN TRANSACTION`);try{for(let e of t)this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e.id,e.id]);this.run(`DELETE FROM nodes WHERE source_path = ?`,[e]),n.exec(`COMMIT`),n.flush()}catch(e){throw n.exec(`ROLLBACK`),e}return t.length}async clear(){await this.ensureOpen();let e=this.getAdapter();e.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps`),this.run(`DELETE FROM processes`),this.run(`DELETE FROM edges`),this.run(`DELETE FROM nodes`),e.exec(`COMMIT`)}catch(t){throw e.exec(`ROLLBACK`),t}e.flush()}async getStats(){await this.ensureOpen();let e=this.query(`SELECT COUNT(*) as count FROM nodes`)[0]?.count??0,t=this.query(`SELECT COUNT(*) as count FROM edges`)[0]?.count??0,n=this.query(`SELECT type, COUNT(*) as count FROM nodes GROUP BY type`),r={};for(let e of n)r[e.type]=e.count;let i=this.query(`SELECT type, COUNT(*) as count FROM edges GROUP BY type`),a={};for(let e of i)a[e.type]=e.count;return{nodeCount:e,edgeCount:t,nodeTypes:r,edgeTypes:a}}async validate(){await this.ensureOpen();let e=await this.getStats(),t=this.query(`SELECT e.id AS edgeId,
|
|
164
164
|
CASE
|
|
165
165
|
WHEN n1.id IS NULL THEN e.from_id
|
|
166
166
|
WHEN n2.id IS NULL THEN e.to_id
|
|
@@ -178,7 +178,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
178
178
|
VALUES (?, ?, ?, '{}', ?)`,[a,e,t,o]);for(let e=0;e<n.length;e++)this.run(`INSERT INTO process_steps (process_id, node_id, step_order) VALUES (?, ?, ?)`,[a,n[e],e]);s.exec(`COMMIT`),s.flush()}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){await this.ensureOpen();let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
|
|
179
179
|
FROM processes p
|
|
180
180
|
JOIN process_steps ps ON p.id = ps.process_id
|
|
181
|
-
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:W(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}releaseMemory(){if(this.adapter)try{this.adapter.exec(`PRAGMA shrink_memory`),this.adapter.exec(`PRAGMA wal_checkpoint(TRUNCATE)`)}catch{}}async close(){this.adapter&&=(this.externalAdapter||this.adapter.close(),null)}};function W(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function G(e){return{id:e.id,type:e.type,name:e.name,properties:W(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function
|
|
181
|
+
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:W(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}releaseMemory(){if(this.adapter)try{this.adapter.exec(`PRAGMA shrink_memory`),this.adapter.exec(`PRAGMA wal_checkpoint(TRUNCATE)`)}catch{}}async close(){this.adapter&&=(this.externalAdapter||this.adapter.close(),null)}};function W(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function G(e){return{id:e.id,type:e.type,name:e.name,properties:W(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function fe(e){return{id:e.id,fromId:e.from_id,toId:e.to_id,type:e.type,weight:e.weight??1,confidence:e.confidence??1,properties:W(e.properties)}}function K(e){return{id:e.edge_id,fromId:e.from_id,toId:e.to_id,type:e.edge_type,weight:e.weight??1,confidence:e.edge_confidence??1,properties:W(e.edge_props??`{}`)}}function q(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:W(e.node_props??`{}`),sourceRecordId:e.node_src_rec??void 0,sourcePath:e.node_src_path??void 0,createdAt:e.node_created,community:e.node_community??void 0}}function J(e){let t=0;for(let n=0;n<e.length;n++){let r=e[n]<0?-e[n]:e[n];r>t&&(t=r)}let n=new Int8Array(e.length);if(t===0)return Buffer.from(n.buffer,n.byteOffset,n.byteLength);let r=127/t;for(let t=0;t<e.length;t++){let i=Math.round(e[t]*r);n[t]=i<-127?-127:i>127?127:i}return Buffer.from(n.buffer,n.byteOffset,n.byteLength)}const Y=h(`sqlite-vec-store`);function pe(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}var X=class{adapter=null;externalAdapter;dbPath;embeddingDim;coarseDim;vectorEnabled=!1;ftsEnabled=!1;warnedVectorDisabled=!1;_draining=!1;_priorityQueue=[];_normalQueue=[];_onCloseHooks=[];constructor(e={}){if(this.embeddingDim=e.embeddingDim??f.dimensions,this.coarseDim=Math.min(128,this.embeddingDim),e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=j(e.path??`${m.path}/aikit.db`,e.partition);this.dbPath=t.contentDbPath,this.externalAdapter=!1}}async initialize(){if(!this.adapter){let e=c(this.dbPath);t(e)||n(e,{recursive:!0}),this.adapter=await O(this.dbPath)}this.configureConnectionPragmas(),this.vectorEnabled=this.adapter.vectorCapable,v(this.adapter,y),this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled?this.ensureVecTable():this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,Y.warn(`SqliteVecStore: vector search disabled (sqlite-vec extension not loaded). Hybrid search will return FTS-only results.`))}configureConnectionPragmas(){let e=this.getAdapter();e.pragma(`journal_mode = WAL`),e.pragma(`busy_timeout = 5000`)}getDiagnostics(){let e=this.adapter,t=e?e.constructor.name:`unknown`,n=null,r=this.externalAdapter?``:this.dbPath;if(r)try{let{statSync:e}=ee(`node:fs`);n=e(r).size}catch{n=null}return{adapterType:t,vectorSearchEnabled:this.vectorEnabled,ftsEnabled:this.ftsEnabled,degradedMode:!this.vectorEnabled,dbPath:r,dbSizeBytes:n,embeddingDim:this.embeddingDim,vectorDtype:`int8`}}createKnowledgeTable(){let e=this.getAdapter();e.exec(`
|
|
182
182
|
CREATE TABLE IF NOT EXISTS knowledge (
|
|
183
183
|
id TEXT PRIMARY KEY,
|
|
184
184
|
content TEXT NOT NULL,
|
|
@@ -203,7 +203,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
203
203
|
content,
|
|
204
204
|
tokenize = 'unicode61 remove_diacritics 2'
|
|
205
205
|
)
|
|
206
|
-
`),this.ftsEnabled=!0}catch(e){this.ftsEnabled=!1,
|
|
206
|
+
`),this.ftsEnabled=!0}catch(e){this.ftsEnabled=!1,Y.warn(`FTS5 unavailable — keyword search disabled`,g(e))}}ensureVecTable(){let e=this.getAdapter(),t=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type='table' AND name='vec_knowledge'`);if(t.length>0){let n=t[0].sql??``,r=n.match(/(?:float|int8)\[(\d+)\]/i),i=r?Number(r[1]):null,a=/int8\[/i.test(n);(i!==null&&i!==this.embeddingDim||!a)&&(Y.warn(`Vec table schema mismatch — dropping for recreation`,{existingDim:i,newDim:this.embeddingDim,wasInt8:a}),e.exec(`DROP TABLE vec_knowledge`))}e.exec(`
|
|
207
207
|
CREATE VIRTUAL TABLE IF NOT EXISTS vec_knowledge USING vec0(
|
|
208
208
|
embedding int8[${this.embeddingDim}] distance_metric=cosine,
|
|
209
209
|
+knowledge_id TEXT
|
|
@@ -213,7 +213,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
213
213
|
embedding int8[${this.coarseDim}] distance_metric=cosine,
|
|
214
214
|
+knowledge_id TEXT
|
|
215
215
|
)
|
|
216
|
-
`)}enqueueWrite(e,t=!1){return new Promise((n,r)=>{let i=async()=>{try{n(await e())}catch(e){r(e)}};t?this._priorityQueue.push(i):this._normalQueue.push(i),this._drain()})}async _drain(){if(!this._draining){this._draining=!0;try{for(;this._priorityQueue.length>0||this._normalQueue.length>0;){let e=this._priorityQueue.shift()??this._normalQueue.shift();e&&await e()}}finally{this._draining=!1}}}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async upsertInteractive(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t),!0)}}async upsertWithoutVector(e,t){return this.enqueueWrite(async()=>{let n=this.getAdapter(),r=e;n.exec(`BEGIN`);try{if(this.upsertKnowledgeRow(r),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[r.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[r.id,r.content])),this.vectorEnabled){let e=n.queryAll(`SELECT embedding FROM vec_knowledge WHERE knowledge_id = ?`,[t]);if(e.length>0){if(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]),this.coarseDim<this.embeddingDim){let e=n.queryAll(`SELECT embedding FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[t]);e.length>0&&(n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]))}}else
|
|
216
|
+
`)}enqueueWrite(e,t=!1){return new Promise((n,r)=>{let i=async()=>{try{n(await e())}catch(e){r(e)}};t?this._priorityQueue.push(i):this._normalQueue.push(i),this._drain()})}async _drain(){if(!this._draining){this._draining=!0;try{for(;this._priorityQueue.length>0||this._normalQueue.length>0;){let e=this._priorityQueue.shift()??this._normalQueue.shift();e&&await e()}}finally{this._draining=!1}}}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async upsertInteractive(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t),!0)}}async upsertWithoutVector(e,t){return this.enqueueWrite(async()=>{let n=this.getAdapter(),r=e;n.exec(`BEGIN`);try{if(this.upsertKnowledgeRow(r),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[r.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[r.id,r.content])),this.vectorEnabled){let e=n.queryAll(`SELECT embedding FROM vec_knowledge WHERE knowledge_id = ?`,[t]);if(e.length>0){if(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]),this.coarseDim<this.embeddingDim){let e=n.queryAll(`SELECT embedding FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[t]);e.length>0&&(n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]))}}else Y.warn(`upsertWithoutVector: source vector not found, record will lack vector`,{recordId:r.id,sourceRecordId:t})}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()})}upsertKnowledgeRow(e){this.getAdapter().run(`INSERT INTO knowledge (id, content, sourcePath, contentType, headingPath, chunkIndex,
|
|
217
217
|
totalChunks, startLine, endLine, fileHash, content_hash, indexedAt, origin, tags, category, version)
|
|
218
218
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
219
219
|
ON CONFLICT(id) DO UPDATE SET
|
|
@@ -231,7 +231,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
231
231
|
origin = excluded.origin,
|
|
232
232
|
tags = excluded.tags,
|
|
233
233
|
category = excluded.category,
|
|
234
|
-
version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(e.tags??[]),e.category??``,e.version])}async _upsertImpl(e,t){let n=this.getAdapter();n.exec(`BEGIN`);try{for(let r=0;r<e.length;r++){let i=e[r];if(this.upsertKnowledgeRow(i),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[i.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[i.id,i.content])),this.vectorEnabled&&(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[
|
|
234
|
+
version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(e.tags??[]),e.category??``,e.version])}async _upsertImpl(e,t){let n=this.getAdapter();n.exec(`BEGIN`);try{for(let r=0;r<e.length;r++){let i=e[r];if(this.upsertKnowledgeRow(i),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[i.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[i.id,i.content])),this.vectorEnabled&&(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[J(t[r]),i.id]),this.coarseDim<this.embeddingDim)){let e=t[r].subarray(0,this.coarseDim);n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[J(e),i.id])}}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()}async search(e,t){if(e.length===0)return[];if(!this.vectorEnabled)return this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,Y.warn(`search() called but vector backend is disabled — returning []`)),[];let n=this.getAdapter(),r=t?.limit??p.maxResults,i=t?.minScore??p.minScore,a=r*4,o=this.buildFilterSqlSuffix(t),s=`
|
|
235
235
|
SELECT k.*, v.distance AS _distance
|
|
236
236
|
FROM (
|
|
237
237
|
SELECT knowledge_id, distance
|
|
@@ -244,7 +244,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
244
244
|
${o.sql}
|
|
245
245
|
ORDER BY v.distance ASC
|
|
246
246
|
LIMIT ?
|
|
247
|
-
`,c;try{c=n.queryAll(s,[
|
|
247
|
+
`,c;try{c=n.queryAll(s,[J(e),a,...o.params,r])}catch(e){return Y.warn(`vector search failed`,g(e)),[]}return c.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=i).slice(0,r)}async coarseSearch(e,t){if(!this.vectorEnabled||this.coarseDim>=this.embeddingDim)return this.search(e,t);let n=this.getAdapter(),r=t?.limit??p.maxResults,i=t?.minScore??p.minScore,a=r*4,o=e.subarray(0,this.coarseDim),s=this.buildFilterSqlSuffix(t),c=`
|
|
248
248
|
SELECT k.*, v.distance AS _distance
|
|
249
249
|
FROM (
|
|
250
250
|
SELECT knowledge_id, distance
|
|
@@ -257,7 +257,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
257
257
|
${s.sql}
|
|
258
258
|
ORDER BY v.distance ASC
|
|
259
259
|
LIMIT ?
|
|
260
|
-
`,l;try{l=n.queryAll(c,[
|
|
260
|
+
`,l;try{l=n.queryAll(c,[J(o),a,...s.params,r])}catch(n){return Y.warn(`coarse vector search failed, falling back to full search`,g(n)),this.search(e,t)}return l.length===0?this.search(e,t):l.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=i).slice(0,r)}async ftsSearch(e,t){if(!e||e.trim().length===0||!this.ftsEnabled)return[];let n=this.getAdapter(),r=t?.limit??p.maxResults,i=this.buildFilterSqlSuffix(t,!0),a=`
|
|
261
261
|
SELECT k.*, bm25(knowledge_fts) AS _bm25
|
|
262
262
|
FROM knowledge_fts
|
|
263
263
|
JOIN knowledge k ON k.id = knowledge_fts.id
|
|
@@ -265,11 +265,11 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
265
265
|
${i.sql}
|
|
266
266
|
ORDER BY _bm25 ASC
|
|
267
267
|
LIMIT ?
|
|
268
|
-
`,o;try{let t=
|
|
268
|
+
`,o;try{let t=me(e);o=n.queryAll(a,[t,...i.params,r])}catch(e){return Y.warn(`fts search failed`,g(e)),[]}return o.map(e=>({record:this.fromRow(e),score:he(e._bm25)}))}async getById(e){let t=this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE id = ? LIMIT 1`,[e]);return t.length===0?null:this.fromRow(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){let t=this.getAdapter(),n=t.queryAll(`SELECT id FROM knowledge WHERE sourcePath = ?`,[e]);if(n.length===0)return 0;t.exec(`BEGIN`);try{for(let{id:e}of n)this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),this.ftsEnabled&&t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]);t.run(`DELETE FROM knowledge WHERE sourcePath = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),n.length}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async deleteByIdInteractive(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e),!0)}async _deleteByIdImpl(e){let t=this.getAdapter();if(t.queryAll(`SELECT id FROM knowledge WHERE id = ? LIMIT 1`,[e]).length===0)return!1;t.exec(`BEGIN`);try{this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),this.ftsEnabled&&t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]),t.run(`DELETE FROM knowledge WHERE id = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),!0}async getBySourcePath(e){return this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE sourcePath = ? ORDER BY chunkIndex ASC`,[e]).map(e=>this.fromRow(e))}async getStats(){let e=this.getAdapter(),t=e.queryAll(`SELECT COUNT(*) AS n FROM knowledge`)[0]?.n??0;if(t===0)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`sqlite-vec`,embeddingModel:f.model};let n=e.queryAll(`SELECT COUNT(DISTINCT sourcePath) AS n FROM knowledge`),r=e.queryAll(`SELECT contentType, COUNT(*) AS n FROM knowledge GROUP BY contentType`),i=e.queryAll(`SELECT MAX(indexedAt) AS ts FROM knowledge`),a={};for(let e of r)a[e.contentType]=e.n;return{totalRecords:t,totalFiles:n[0]?.n??0,contentTypeBreakdown:a,lastIndexedAt:i[0]?.ts??null,storeBackend:`sqlite-vec`,embeddingModel:f.model}}async listSourcePaths(){return this.getAdapter().queryAll(`SELECT DISTINCT sourcePath FROM knowledge ORDER BY sourcePath`).map(e=>e.sourcePath)}async createFtsIndex(){this.createFtsTable()}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){let e=this.getAdapter();this.ftsEnabled&&e.exec(`DROP TABLE IF EXISTS knowledge_fts`),this.vectorEnabled&&(this.coarseDim<this.embeddingDim&&e.exec(`DROP TABLE IF EXISTS vec_knowledge_coarse`),e.exec(`DROP TABLE IF EXISTS vec_knowledge`)),e.exec(`DROP TABLE IF EXISTS knowledge`),e.flush(),this.createKnowledgeTable(),this.createFtsTable(),this.vectorEnabled&&this.ensureVecTable()}releaseMemory(){if(this.adapter)try{this.adapter.exec(`PRAGMA shrink_memory`),this.adapter.exec(`PRAGMA wal_checkpoint(TRUNCATE)`)}catch{}}onBeforeClose(e){this._onCloseHooks.push(e)}async close(){for(let e of this._onCloseHooks)try{e()}catch{}for(this._onCloseHooks.length=0;this._priorityQueue.length>0||this._normalQueue.length>0||this._draining;)await new Promise(e=>setTimeout(e,5));this.adapter&&!this.externalAdapter&&this.adapter.close(),this.adapter=null}getAdapter(){if(!this.adapter)throw Error(`SqliteVecStore: not initialized — call initialize() first`);return this.adapter}buildFilterSqlSuffix(e,t=!1){if(!e)return{sql:``,params:[]};let n=[],r=[];if(e.contentType&&(n.push(`k.contentType = ?`),r.push(e.contentType)),e.sourceType){let t=_(e.sourceType);t.length>0&&(n.push(`k.contentType IN (${t.map(()=>`?`).join(`, `)})`),r.push(...t))}if(e.origin&&(n.push(`k.origin = ?`),r.push(e.origin)),e.category&&(n.push(`k.category = ?`),r.push(e.category)),e.tags&&e.tags.length>0){let t=e.tags.map(()=>`k.tags LIKE ?`);n.push(`(${t.join(` OR `)})`),r.push(...e.tags.map(e=>`%${e}%`))}if(n.length===0)return{sql:``,params:[]};let i=n.join(` AND `);return{sql:t?`AND ${i}`:`WHERE ${i}`,params:r}}fromRow(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,contentHash:e.content_hash||void 0,indexedAt:e.indexedAt,origin:e.origin,tags:pe(e.tags),category:e.category||void 0,version:e.version}}};function me(e){let t=e.replace(/["'()*:^-]/g,` `).trim();return t?t.split(/\s+/).filter(e=>e.length>0).map(e=>`"${e}"`).join(` OR `):`""`}function he(e){return e==null||Number.isNaN(e)?0:1-Math.exp(-Math.abs(e)/5)}function Z(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`,n=new Date(t);return Number.isNaN(n.getTime())?t:n.toISOString()}function Q(e){return`queryAll`in e&&`run`in e}function ge(e){return{get(t){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash WHERE key = ?`,[t])[0]},set(t,n){e.run(`INSERT INTO stash (key, value)
|
|
269
269
|
VALUES (?, ?)
|
|
270
270
|
ON CONFLICT(key) DO UPDATE SET
|
|
271
271
|
value = excluded.value,
|
|
272
|
-
updated_at = datetime('now')`,[t,n])},list(){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`)},has(t){return e.queryAll(`SELECT 1 AS present FROM stash WHERE key = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM stash WHERE key = ?`,[t])},clear(){e.run(`DELETE FROM stash`)}}}function
|
|
272
|
+
updated_at = datetime('now')`,[t,n])},list(){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`)},has(t){return e.queryAll(`SELECT 1 AS present FROM stash WHERE key = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM stash WHERE key = ?`,[t])},clear(){e.run(`DELETE FROM stash`)}}}function _e(e){return{save(t,n,r,i){e.run(`INSERT INTO checkpoints (id, label, data, notes)
|
|
273
273
|
VALUES (?, ?, ?, ?)
|
|
274
274
|
ON CONFLICT(id) DO UPDATE SET
|
|
275
275
|
label = excluded.label,
|
|
@@ -296,7 +296,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
296
296
|
ORDER BY created_at DESC, id DESC
|
|
297
297
|
LIMIT 1`;return e.queryAll(r,n)[0]},has(t){return e.queryAll(`SELECT 1 AS present FROM checkpoints WHERE id = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM checkpoints WHERE id = ?`,[t])},gc(t=10,n){let r=e.queryAll(`SELECT id, label, notes, created_at AS createdAt
|
|
298
298
|
FROM checkpoints
|
|
299
|
-
ORDER BY label, created_at DESC, id DESC`),i=n===void 0?void 0:Date.now()-n*864e5,a=new Map;for(let e of r){let t=a.get(e.label);t?t.push(e):a.set(e.label,[e])}let o=[];for(let e of a.values())e.forEach((e,n)=>{let r=Date.parse(e.createdAt);n<t&&!(i!==void 0&&!Number.isNaN(r)&&r<i)||o.push(e.id)});for(let t of o)e.run(`DELETE FROM checkpoints WHERE id = ?`,[t]);return o.length}}}function
|
|
299
|
+
ORDER BY label, created_at DESC, id DESC`),i=n===void 0?void 0:Date.now()-n*864e5,a=new Map;for(let e of r){let t=a.get(e.label);t?t.push(e):a.set(e.label,[e])}let o=[];for(let e of a.values())e.forEach((e,n)=>{let r=Date.parse(e.createdAt);n<t&&!(i!==void 0&&!Number.isNaN(r)&&r<i)||o.push(e.id)});for(let t of o)e.run(`DELETE FROM checkpoints WHERE id = ?`,[t]);return o.length}}}function ve(e){return{create(t,n){e.run(`INSERT INTO sessions (session_id, metadata)
|
|
300
300
|
VALUES (?, ?)
|
|
301
301
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
302
302
|
last_activity = datetime('now'),
|
|
@@ -312,7 +312,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
312
312
|
ORDER BY created_at, session_id`)},has(t){return e.queryAll(`SELECT 1 AS present FROM sessions WHERE session_id = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM sessions WHERE session_id = ?`,[t])},deleteStale(t){let n=`-${Math.max(0,t)} minutes`,r=e.queryAll(`SELECT COUNT(*) AS count
|
|
313
313
|
FROM sessions
|
|
314
314
|
WHERE last_activity < datetime('now', ?)`,[n])[0]?.count??0;return r>0&&e.run(`DELETE FROM sessions
|
|
315
|
-
WHERE last_activity < datetime('now', ?)`,[n]),r}}}function
|
|
315
|
+
WHERE last_activity < datetime('now', ?)`,[n]),r}}}function ye(e){return{post(t,n,r,i,a=300){return e.run(`INSERT INTO signals (workspace, key, value, agent, ttl_seconds, expires_at)
|
|
316
316
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' seconds'))`,[t,n,r,i??null,a,a]),e.queryAll(`SELECT last_insert_rowid() AS id`)[0]?.id??0},get(t,n){return e.queryAll(`SELECT id,
|
|
317
317
|
workspace,
|
|
318
318
|
key,
|
|
@@ -334,7 +334,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
334
334
|
WHERE workspace = ?
|
|
335
335
|
ORDER BY created_at ASC, id ASC`,[t])},clear(t,n){let r=n===void 0?e.queryAll(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ?`,[t])[0]?.count??0:e.queryAll(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ? AND key = ?`,[t,n])[0]?.count??0;return r>0&&(n===void 0?e.run(`DELETE FROM signals WHERE workspace = ?`,[t]):e.run(`DELETE FROM signals WHERE workspace = ? AND key = ?`,[t,n])),r},cleanExpired(){let t=e.queryAll(`SELECT COUNT(*) AS count
|
|
336
336
|
FROM signals
|
|
337
|
-
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM signals WHERE expires_at <= datetime('now')`),t}}}function
|
|
337
|
+
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM signals WHERE expires_at <= datetime('now')`),t}}}function be(e){return{upsert(t,n,r,i,a=10){e.run(`INSERT INTO leases (resource, holder, intent, workspace, ttl_minutes, expires_at)
|
|
338
338
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' minutes'))
|
|
339
339
|
ON CONFLICT(workspace, resource) DO UPDATE SET
|
|
340
340
|
holder = excluded.holder,
|
|
@@ -359,7 +359,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
359
359
|
WHERE workspace = ?
|
|
360
360
|
ORDER BY acquired_at ASC, resource ASC`,[t])},delete(t,n){e.run(`DELETE FROM leases WHERE resource = ? AND workspace = ?`,[t,n])},cleanExpired(){let t=e.queryAll(`SELECT COUNT(*) AS count
|
|
361
361
|
FROM leases
|
|
362
|
-
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM leases WHERE expires_at <= datetime('now')`),t}}}function
|
|
362
|
+
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM leases WHERE expires_at <= datetime('now')`),t}}}function xe(e){return{create(t,n){e.run(`INSERT INTO memory_meta (entry_id, tier)
|
|
363
363
|
VALUES (?, ?)
|
|
364
364
|
ON CONFLICT(entry_id) DO NOTHING`,[t,n??`working`])},get(t){return e.queryAll(`SELECT entry_id AS entryId,
|
|
365
365
|
tier,
|
|
@@ -395,11 +395,11 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
395
395
|
ORDER BY retention_score ASC,
|
|
396
396
|
COALESCE(last_accessed_at, created_at) ASC,
|
|
397
397
|
entry_id ASC
|
|
398
|
-
${a}`,r)}}}function
|
|
398
|
+
${a}`,r)}}}function Se(e){let t=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash WHERE key = ?`),n=e.prepare(`INSERT INTO stash (key, value)
|
|
399
399
|
VALUES (?, ?)
|
|
400
400
|
ON CONFLICT(key) DO UPDATE SET
|
|
401
401
|
value = excluded.value,
|
|
402
|
-
updated_at = datetime('now')`),r=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`),i=e.prepare(`SELECT 1 AS present FROM stash WHERE key = ?`),a=e.prepare(`DELETE FROM stash WHERE key = ?`),o=e.prepare(`DELETE FROM stash`);return{get(e){return t.get(e)},set(e,t){n.run(e,t)},list(){return r.all()},has(e){return i.get(e)!==void 0},delete(e){a.run(e)},clear(){o.run()}}}function
|
|
402
|
+
updated_at = datetime('now')`),r=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`),i=e.prepare(`SELECT 1 AS present FROM stash WHERE key = ?`),a=e.prepare(`DELETE FROM stash WHERE key = ?`),o=e.prepare(`DELETE FROM stash`);return{get(e){return t.get(e)},set(e,t){n.run(e,t)},list(){return r.all()},has(e){return i.get(e)!==void 0},delete(e){a.run(e)},clear(){o.run()}}}function $(e){let t=e.prepare(`INSERT INTO checkpoints (id, label, data, notes)
|
|
403
403
|
VALUES (?, ?, ?, ?)
|
|
404
404
|
ON CONFLICT(id) DO UPDATE SET
|
|
405
405
|
label = excluded.label,
|
|
@@ -426,7 +426,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
426
426
|
ORDER BY created_at DESC, id DESC
|
|
427
427
|
LIMIT 1`),l=e.prepare(`SELECT 1 AS present FROM checkpoints WHERE id = ?`),u=e.prepare(`DELETE FROM checkpoints WHERE id = ?`),d=e.prepare(`SELECT id, label, notes, created_at AS createdAt
|
|
428
428
|
FROM checkpoints
|
|
429
|
-
ORDER BY label, created_at DESC, id DESC`);return{save(e,n,r,i){t.run(e,n,r,i??null)},get(e){return n.get(e)},list(e,t){return e!==void 0&&t!==void 0?o.all(e,t):e===void 0?t===void 0?r.all():i.all(t):a.all(e)},latest(e){return e===void 0?s.get():c.get(e)},has(e){return l.get(e)!==void 0},delete(e){u.run(e)},gc(e=10,t){let n=d.all(),r=t===void 0?void 0:Date.now()-t*864e5,i=new Map;for(let e of n){let t=i.get(e.label);t?t.push(e):i.set(e.label,[e])}let a=[];for(let t of i.values())t.forEach((t,n)=>{let i=Date.parse(t.createdAt);n<e&&!(r!==void 0&&!Number.isNaN(i)&&i<r)||a.push(t.id)});for(let e of a)u.run(e);return a.length}}}function
|
|
429
|
+
ORDER BY label, created_at DESC, id DESC`);return{save(e,n,r,i){t.run(e,n,r,i??null)},get(e){return n.get(e)},list(e,t){return e!==void 0&&t!==void 0?o.all(e,t):e===void 0?t===void 0?r.all():i.all(t):a.all(e)},latest(e){return e===void 0?s.get():c.get(e)},has(e){return l.get(e)!==void 0},delete(e){u.run(e)},gc(e=10,t){let n=d.all(),r=t===void 0?void 0:Date.now()-t*864e5,i=new Map;for(let e of n){let t=i.get(e.label);t?t.push(e):i.set(e.label,[e])}let a=[];for(let t of i.values())t.forEach((t,n)=>{let i=Date.parse(t.createdAt);n<e&&!(r!==void 0&&!Number.isNaN(i)&&i<r)||a.push(t.id)});for(let e of a)u.run(e);return a.length}}}function Ce(e){let t=e.prepare(`INSERT INTO sessions (session_id, metadata)
|
|
430
430
|
VALUES (?, ?)
|
|
431
431
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
432
432
|
last_activity = datetime('now'),
|
|
@@ -442,7 +442,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
442
442
|
ORDER BY created_at, session_id`),a=e.prepare(`SELECT 1 AS present FROM sessions WHERE session_id = ?`),o=e.prepare(`DELETE FROM sessions WHERE session_id = ?`),s=e.prepare(`SELECT COUNT(*) AS count
|
|
443
443
|
FROM sessions
|
|
444
444
|
WHERE last_activity < datetime('now', ?)`),c=e.prepare(`DELETE FROM sessions
|
|
445
|
-
WHERE last_activity < datetime('now', ?)`);return{create(e,n){t.run(e,n??null)},touch(e){n.run(e)},get(e){return r.get(e)},list(){return i.all()},has(e){return a.get(e)!==void 0},delete(e){o.run(e)},deleteStale(e){let t=`-${Math.max(0,e)} minutes`,n=s.get(t)?.count??0;return n>0&&c.run(t),n}}}function
|
|
445
|
+
WHERE last_activity < datetime('now', ?)`);return{create(e,n){t.run(e,n??null)},touch(e){n.run(e)},get(e){return r.get(e)},list(){return i.all()},has(e){return a.get(e)!==void 0},delete(e){o.run(e)},deleteStale(e){let t=`-${Math.max(0,e)} minutes`,n=s.get(t)?.count??0;return n>0&&c.run(t),n}}}function we(e){let t=e.prepare(`INSERT INTO signals (workspace, key, value, agent, ttl_seconds, expires_at)
|
|
446
446
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' seconds'))`),n=e.prepare(`SELECT id,
|
|
447
447
|
workspace,
|
|
448
448
|
key,
|
|
@@ -464,7 +464,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
464
464
|
WHERE workspace = ?
|
|
465
465
|
ORDER BY created_at ASC, id ASC`),i=e.prepare(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ?`),a=e.prepare(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ? AND key = ?`),o=e.prepare(`DELETE FROM signals WHERE workspace = ?`),s=e.prepare(`DELETE FROM signals WHERE workspace = ? AND key = ?`),c=e.prepare(`SELECT COUNT(*) AS count
|
|
466
466
|
FROM signals
|
|
467
|
-
WHERE expires_at <= datetime('now')`),l=e.prepare(`DELETE FROM signals WHERE expires_at <= datetime('now')`);return{post(e,n,r,i,a=300){let o=t.run(e,n,r,i??null,a,a);return Number(o.lastInsertRowid)},get(e,t){return n.all(e,t)},list(e){return r.all(e)},clear(e,t){let n=t===void 0?i.get(e)?.count??0:a.get(e,t)?.count??0;return n>0&&(t===void 0?o.run(e):s.run(e,t)),n},cleanExpired(){let e=c.get()?.count??0;return e>0&&l.run(),e}}}function
|
|
467
|
+
WHERE expires_at <= datetime('now')`),l=e.prepare(`DELETE FROM signals WHERE expires_at <= datetime('now')`);return{post(e,n,r,i,a=300){let o=t.run(e,n,r,i??null,a,a);return Number(o.lastInsertRowid)},get(e,t){return n.all(e,t)},list(e){return r.all(e)},clear(e,t){let n=t===void 0?i.get(e)?.count??0:a.get(e,t)?.count??0;return n>0&&(t===void 0?o.run(e):s.run(e,t)),n},cleanExpired(){let e=c.get()?.count??0;return e>0&&l.run(),e}}}function Te(e){let t=e.prepare(`INSERT INTO leases (resource, holder, intent, workspace, ttl_minutes, expires_at)
|
|
468
468
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' minutes'))
|
|
469
469
|
ON CONFLICT(workspace, resource) DO UPDATE SET
|
|
470
470
|
holder = excluded.holder,
|
|
@@ -489,7 +489,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
489
489
|
WHERE workspace = ?
|
|
490
490
|
ORDER BY acquired_at ASC, resource ASC`),i=e.prepare(`DELETE FROM leases WHERE resource = ? AND workspace = ?`),a=e.prepare(`SELECT COUNT(*) AS count
|
|
491
491
|
FROM leases
|
|
492
|
-
WHERE expires_at <= datetime('now')`),o=e.prepare(`DELETE FROM leases WHERE expires_at <= datetime('now')`);return{upsert(e,n,r,i,a=10){t.run(e,n,i??null,r,a,a)},get(e,t){return n.get(e,t)},list(e){return r.all(e)},delete(e,t){i.run(e,t)},cleanExpired(){let e=a.get()?.count??0;return e>0&&o.run(),e}}}function
|
|
492
|
+
WHERE expires_at <= datetime('now')`),o=e.prepare(`DELETE FROM leases WHERE expires_at <= datetime('now')`);return{upsert(e,n,r,i,a=10){t.run(e,n,i??null,r,a,a)},get(e,t){return n.get(e,t)},list(e){return r.all(e)},delete(e,t){i.run(e,t)},cleanExpired(){let e=a.get()?.count??0;return e>0&&o.run(),e}}}function Ee(e){let t=e.prepare(`INSERT INTO memory_meta (entry_id, tier)
|
|
493
493
|
VALUES (?, ?)
|
|
494
494
|
ON CONFLICT(entry_id) DO NOTHING`),n=e.prepare(`SELECT entry_id AS entryId,
|
|
495
495
|
tier,
|
|
@@ -619,4 +619,4 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
619
619
|
ORDER BY retention_score ASC,
|
|
620
620
|
COALESCE(last_accessed_at, created_at) ASC,
|
|
621
621
|
entry_id ASC
|
|
622
|
-
LIMIT ?`);return{create(e,n){t.run(e,n??`working`)},get(e){return n.get(e)},touch(e){r.run(e)},updateScore(e,t){i.run(t,e)},updateConfidence(e,t){a.run(t,e)},updateTier(e,t){o.run(t,t,t,e)},setSuperseded(e,t){s.run(t,e)},list(e){return e?.tier!==void 0&&e?.belowScore!==void 0&&e?.limit!==void 0?h.all(e.tier,e.belowScore,e.limit):e?.tier!==void 0&&e?.belowScore!==void 0?m.all(e.tier,e.belowScore):e?.tier!==void 0&&e?.limit!==void 0?d.all(e.tier,e.limit):e?.tier===void 0?e?.belowScore!==void 0&&e?.limit!==void 0?p.all(e.belowScore,e.limit):e?.belowScore===void 0?e?.limit===void 0?c.all():l.all(e.limit):f.all(e.belowScore):u.all(e.tier)}}}function
|
|
622
|
+
LIMIT ?`);return{create(e,n){t.run(e,n??`working`)},get(e){return n.get(e)},touch(e){r.run(e)},updateScore(e,t){i.run(t,e)},updateConfidence(e,t){a.run(t,e)},updateTier(e,t){o.run(t,t,t,e)},setSuperseded(e,t){s.run(t,e)},list(e){return e?.tier!==void 0&&e?.belowScore!==void 0&&e?.limit!==void 0?h.all(e.tier,e.belowScore,e.limit):e?.tier!==void 0&&e?.belowScore!==void 0?m.all(e.tier,e.belowScore):e?.tier!==void 0&&e?.limit!==void 0?d.all(e.tier,e.limit):e?.tier===void 0?e?.belowScore!==void 0&&e?.limit!==void 0?p.all(e.belowScore,e.limit):e?.belowScore===void 0?e?.limit===void 0?c.all():l.all(e.limit):f.all(e.belowScore):u.all(e.tier)}}}function De(e){let t=Q(e)?ge(e):Se(e),n=Q(e)?ye(e):we(e),r=Q(e)?be(e):Te(e),i=Q(e)?ve(e):Ce(e),a=Q(e)?_e(e):$(e),o=Q(e)?xe(e):Ee(e);return{stashGet(e){return t.get(e)?.value},stashSet(e,n){t.set(e,n)},stashList(){return t.list()},stashDelete(e){return t.has(e)?(t.delete(e),!0):!1},stashClear(){t.clear()},signalPost(e,t,r,i,a){return n.post(e,t,r,i,a)},signalGet(e,t){return n.cleanExpired(),n.get(e,t).map(e=>({id:e.id,value:e.value,createdAt:Z(e.createdAt),expiresAt:Z(e.expiresAt),...e.agent?{agent:e.agent}:{}}))},signalList(e){return n.cleanExpired(),n.list(e).map(e=>({id:e.id,key:e.key,value:e.value,createdAt:Z(e.createdAt),...e.agent?{agent:e.agent}:{}}))},signalClear(e,t){return n.cleanExpired(),n.clear(e,t)},signalCleanExpired(){return n.cleanExpired()},leaseAcquire(e,t,n,i,a){r.cleanExpired();let o=r.get(e,n);return o&&o.holder!==t?!1:(r.upsert(e,t,n,i??o?.intent??void 0,a),!0)},leaseRelease(e,t,n){r.cleanExpired();let i=r.get(e,n);return!i||i.holder!==t?!1:(r.delete(e,n),!0)},leaseGet(e,t){r.cleanExpired();let n=r.get(e,t);if(n)return{resource:n.resource,holder:n.holder,workspace:n.workspace,acquiredAt:Z(n.acquiredAt),expiresAt:Z(n.expiresAt),...n.intent?{intent:n.intent}:{}}},leaseList(e){return r.cleanExpired(),r.list(e).map(e=>({resource:e.resource,holder:e.holder,acquiredAt:Z(e.acquiredAt),expiresAt:Z(e.expiresAt),...e.intent?{intent:e.intent}:{}}))},leaseCleanExpired(){return r.cleanExpired()},sessionCreate(e,t){i.create(e,t?JSON.stringify(t):void 0)},sessionTouch(e){i.touch(e)},sessionGet(e){let t=i.get(e);if(t)return{sessionId:t.sessionId,createdAt:t.createdAt,lastActivity:t.lastActivity,...t.metadata?{metadata:t.metadata}:{}}},sessionList(){return i.list().map(e=>({sessionId:e.sessionId,createdAt:e.createdAt,lastActivity:e.lastActivity}))},sessionDelete(e){return i.has(e)?(i.delete(e),!0):!1},sessionDeleteStale(e){return i.deleteStale(e)},checkpointSave(e,t,n,r){a.save(e,t,n,r)},checkpointLoad(e){let t=a.get(e);if(t)return{id:t.id,label:t.label,data:t.data,createdAt:t.createdAt,...t.notes?{notes:t.notes}:{}}},checkpointList(e,t){return a.list(e,t).map(e=>({id:e.id,label:e.label,createdAt:e.createdAt,...e.notes?{notes:e.notes}:{}}))},checkpointLatest(e){let t=a.latest(e);if(t)return{id:t.id,label:t.label,data:t.data,createdAt:t.createdAt,...t.notes?{notes:t.notes}:{}}},checkpointDelete(e){return a.has(e)?(a.delete(e),!0):!1},checkpointDiff(e,t){let n=a.get(e),r=a.get(t);if(!(!n||!r))return{from:n.data,to:r.data}},checkpointHistory(e,t){return a.list(e,t).map(e=>({id:e.id,label:e.label,createdAt:e.createdAt,...e.notes?{notes:e.notes}:{}}))},checkpointGc(e,t){return a.gc(e,t)},memoryMetaCreate(e,t){o.create(e,t)},memoryMetaGet(e){return o.get(e)},memoryMetaTouch(e){o.touch(e)},memoryMetaUpdateScore(e,t){o.updateScore(e,t)},memoryMetaUpdateConfidence(e,t){o.updateConfidence(e,t)},memoryMetaUpdateTier(e,t){o.updateTier(e,t)},memoryMetaSetSuperseded(e,t){o.setSuperseded(e,t)},memoryMetaList(e){return o.list(e)}}}async function Oe(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-BRKcJXVO.js`);return new t({path:e.path})}case`sqlite-vec`:return new X({path:e.path,adapter:e.adapter,embeddingDim:e.embeddingDim,partition:e.partition});default:{let t=e.backend;throw Error(`Unknown store backend: "${t}". Supported: lancedb, sqlite-vec`)}}}export{A as CONTROL_TABLES,de as SqliteGraphStore,X as SqliteVecStore,y as allMigrations,se as createSqlJsAdapter,O as createSqliteAdapter,De as createStateStore,Oe as createStore,le as getTablePartition,U as migrateToSplitState,ue as readStatePartitionConfigFromEnv,j as resolveStatePartitionConfig,v as runMigrations};
|