@vpxa/aikit 0.1.174 → 0.1.175

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.
Files changed (38) hide show
  1. package/package.json +3 -3
  2. package/packages/blocks-core/dist/index.d.ts +2 -1
  3. package/packages/blocks-core/dist/index.js +1 -1
  4. package/packages/cli/dist/index.js +16 -16
  5. package/packages/cli/dist/{init-BVU1RVy5.js → init-BDZpaO7q.js} +1 -1
  6. package/packages/cli/dist/{scaffold-BB6OrTuA.js → scaffold-BdUnq1xy.js} +1 -1
  7. package/packages/core/dist/index.d.ts +29 -1
  8. package/packages/dashboard/dist/assets/{index-ehoWAjDs.js → index-4HQiq-qo.js} +2 -2
  9. package/packages/dashboard/dist/index.html +1 -1
  10. package/packages/present/dist/index.html +45 -45
  11. package/packages/server/dist/auth-BfqgawfR.js +1 -0
  12. package/packages/server/dist/config-DAnAxrUW.js +1 -0
  13. package/packages/server/dist/{curated-manager-BkSgtNC2.js → curated-manager-BnP6VqvL.js} +4 -4
  14. package/packages/server/dist/index.js +1 -1
  15. package/packages/server/dist/proxy.d.ts +32 -0
  16. package/packages/server/dist/proxy.js +4 -0
  17. package/packages/server/dist/server-B0gtRiNa.js +2909 -0
  18. package/packages/server/dist/supersession-DJQGXMWm.js +2 -0
  19. package/packages/settings-ui/dist/assets/{index-DSTxXokO.js → index-DLcLvASh.js} +2 -2
  20. package/packages/store/dist/index.d.ts +135 -1
  21. package/packages/store/dist/index.js +447 -12
  22. package/packages/tools/dist/index.d.ts +72 -30
  23. package/packages/tools/dist/index.js +72 -73
  24. package/{scaffold/general → packages}/viewers/README.md +1 -1
  25. package/scaffold/dist/definitions/prompts.mjs +1 -1
  26. package/scaffold/dist/definitions/protocols.mjs +2 -0
  27. package/scaffold/dist/definitions/skills/aikit.mjs +1 -1
  28. package/scaffold/dist/definitions/skills/c4-architecture.mjs +1 -1
  29. package/scaffold/dist/definitions/skills/docs.mjs +1 -1
  30. package/scaffold/dist/definitions/tools.mjs +1 -1
  31. package/packages/server/dist/config-Dsu2Kd3U.js +0 -1
  32. package/packages/server/dist/server-CqEB0MaC.js +0 -2901
  33. /package/packages/cli/dist/{templates-D-eA4QVK.js → templates-Do9eni2d.js} +0 -0
  34. /package/packages/server/dist/{dashboard-static-BfIe0Si1.js → dashboard-static-CnXafYTs.js} +0 -0
  35. /package/packages/server/dist/{routes-gbC5Wmr9.js → routes-CR3fI-HJ.js} +0 -0
  36. /package/packages/server/dist/{settings-static-BosGZSPf.js → settings-static-BkVLqWOr.js} +0 -0
  37. /package/packages/server/dist/{version-check-Bj07vc5x.js → version-check-BgHzxxCW.js} +0 -0
  38. /package/packages/store/dist/{lance-store-BIP1LEiS.js → lance-store-BRKcJXVO.js} +0 -0
@@ -0,0 +1 @@
1
+ import"node:module";import{randomBytes as e,timingSafeEqual as t}from"node:crypto";import*as n from"node:fs";import{join as r}from"node:path";import{homedir as i}from"node:os";var a=Object.defineProperty,o=((e,t)=>{let n={};for(var r in e)a(n,r,{get:e[r],enumerable:!0});return t||a(n,Symbol.toStringTag,{value:`Module`}),n})({authMiddleware:()=>d,getOrCreateToken:()=>u,readToken:()=>f});const s=r(i(),`.aikit`);function c(e){let t=e?.tokenDir??s;return{tokenDir:t,tokenFile:r(t,`token`)}}function l(e,n){let r=Buffer.from(e),i=Buffer.from(n);return r.length===i.length?t(r,i):!1}function u(t){let{tokenDir:r,tokenFile:i}=c(t);if(n.existsSync(i)){let e=n.readFileSync(i,`utf-8`).trim();if(e.length>0)return e}n.existsSync(r)||n.mkdirSync(r,{recursive:!0,mode:448});let a=e(32).toString(`hex`);return n.writeFileSync(i,a,{mode:384}),a}function d(e){return(t,n,r)=>{if(t.path===`/health`||t.path===`/healthz`){r();return}let i=t.headers.authorization;if(!i?.startsWith(`Bearer `)){n.status(401).json({error:`Unauthorized: Bearer token required`});return}if(!l(i.slice(7).trim(),e)){n.status(401).json({error:`Unauthorized: Invalid token`});return}r()}}function f(e){try{let{tokenFile:t}=c(e);return n.readFileSync(t,`utf-8`).trim()}catch{return}}export{f as n,o as t};
@@ -0,0 +1 @@
1
+ import{_ as e,a as t,l as n,t as r}from"./supersession-DJQGXMWm.js";import{existsSync as i,readFileSync as a}from"node:fs";import{dirname as o,resolve as s}from"node:path";import{fileURLToPath as c}from"node:url";import{AIKIT_PATHS as l,EMBEDDING_DEFAULTS as u,createLogger as d,getPartitionDir as f,isUserInstalled as p,registerWorkspace as m,serializeError as h}from"../../core/dist/index.js";const g=o(c(import.meta.url)),_=d(`server`),v=[`auto`,`manual`,`smart`],y={model:u.model,dimensions:u.dimensions,childProcess:!0,idleTimeoutMs:6e4};function b(e){return typeof e==`string`&&v.includes(e)}function x(e,t,n){let r=s(e),i=s(t);if(!r.startsWith(i))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return r}function S(e){let t=process.env.AIKIT_INDEX_MODE;if(b(t))return t;if(e.indexMode)return e.indexMode;let n=process.env.AIKIT_AUTO_INDEX;return n===void 0?e.autoIndex===void 0?`smart`:e.autoIndex?`auto`:`manual`:n===`true`?`auto`:`manual`}function C(){let c=process.env.AIKIT_CONFIG_PATH??(i(s(process.cwd(),`aikit.config.json`))?s(process.cwd(),`aikit.config.json`):s(g,`..`,`..`,`..`,`aikit.config.json`));try{if(!i(c))return _.info(`No config file found, using defaults`,{configPath:c}),w();let u=a(c,`utf-8`),d=JSON.parse(u);if(d.embedding={...y,...d.embedding},d.memory={retention:{...t,...d.memory?.retention},lessons:{...n,...d.memory?.lessons},consolidation:{...e,...d.memory?.consolidation},supersession:{...r,...d.memory?.supersession}},!d.sources||!Array.isArray(d.sources)||d.sources.length===0)throw Error(`Config must have at least one source`);if(!d.store?.path)throw Error(`Config must specify store.path`);if(d.autoIndex!==void 0&&typeof d.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(d.indexMode!==void 0&&!b(d.indexMode))throw Error(`Config indexMode must be one of: ${v.join(`, `)}`);let f=o(c);return d.sources=d.sources.map(e=>({...e,path:x(s(f,e.path),f,`source`)})),d.store.path=x(s(f,d.store.path),f,`store`),d.curated=d.curated??{path:l.aiCurated},d.curated.path=x(s(f,d.curated.path),f,`curated`),T(d,f),d.indexMode=S(d),d}catch(e){return _.error(`Failed to load config`,{configPath:c,...h(e)}),_.warn(`Falling back to default configuration`,{configPath:c}),w()}}function w(){let i=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),a={sources:[{path:i,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{...y},store:{backend:`sqlite-vec`,path:s(i,l.data)},curated:{path:s(i,l.aiCurated)},memory:{retention:{...t},lessons:{...n},consolidation:{...e},supersession:{...r}},onboardDir:s(i,l.aiContext),stateDir:s(i,l.state)};return T(a,i),a.indexMode=S(a),a}function T(e,t){if(!p())return;let n=m(t);e.store.path=s(f(n.partition)),e.onboardDir=s(f(n.partition),`onboard`),e.stateDir=s(f(n.partition),`state`),e.curated={path:s(f(n.partition),`curated`)}}function E(e,t){if(!i(t))throw Error(`Workspace root does not exist: ${t}`);_.info(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),_.info(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){_.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...h(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],e.store.path=s(t,l.data),e.curated={path:s(t,l.aiCurated)},e.onboardDir=s(t,l.aiContext),e.stateDir=s(t,l.state),T(e,t)}export{C as loadConfig,E as reconfigureForWorkspace,S as resolveIndexMode};
@@ -1,7 +1,7 @@
1
- import{dirname as e,isAbsolute as t,join as n}from"node:path";import{createLogger as r,serializeError as i}from"../../core/dist/index.js";import{createHash as a}from"node:crypto";import{GIT_REF_SLUG_PATTERN as o,gitAvailable as s,gitCommitToRef as c,gitExec as l,slugForRef as u}from"../../tools/dist/index.js";import{mkdir as d,readFile as f,readdir as p,stat as m,unlink as h,writeFile as g}from"node:fs/promises";var _=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await d(this.baseDir,{recursive:!0})}async read(e){let t=n(this.baseDir,e);try{return await f(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(t,r,i){let a=n(this.baseDir,t);await d(e(a),{recursive:!0}),await g(a,r,{encoding:`utf-8`,flag:i?.exclusive?`wx`:`w`})}async delete(e){let t=n(this.baseDir,e);try{return await h(t),!0}catch(e){if(e.code===`ENOENT`)return!1;throw e}}async list(e){let t=[],r=e?[e]:await this.listDirectories();for(let e of r){let r=n(this.baseDir,e),i;try{i=await p(r)}catch{continue}for(let r of i){if(!r.endsWith(`.md`))continue;let i=`${e}/${r}`,a=n(this.baseDir,i);try{let e=await m(a);t.push({path:i,size:e.size})}catch{}}}return t}async exists(e){let t=n(this.baseDir,e);try{return await m(t),!0}catch{return!1}}async listDirectories(){try{return(await p(this.baseDir,{withFileTypes:!0})).filter(e=>e.isDirectory()&&/^[a-z][a-z0-9-]*$/.test(e.name)).map(e=>e.name)}catch{return[]}}async close(){}};const v=50*1024,y=`refs/aikit/knowledge`,b=r(`server`);var x=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new _(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}try{await this.indexCuratedFile(a,t,s)}catch(e){throw await this.adapter.delete(a).catch(()=>{}),Error(`Remember failed: wrote file but indexing failed — rolled back. ${e.message}`)}return this.gitCommitKnowledge(a,c,`remember: ${e}\n\nCategory: ${n}\nTags: ${r.join(`, `)}`),{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),await this.indexCuratedFile(e,t,i),this.gitCommitKnowledge(e,s,`update(v${a}): ${i.title}\n\nReason: ${n}\nVersion: ${a}`),{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=>{b.warn(`File deleted but vector cleanup failed`,{sourcePath:n,...i(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!s(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=l([`log`,`--format=%H|%aI|%s`,n,`-n`,String(t)],this.curatedDir);return r?r.split(`
1
+ import{createHash as e}from"node:crypto";import{dirname as t,isAbsolute as n,join as r}from"node:path";import{createLogger as i,serializeError as a}from"../../core/dist/index.js";import{GIT_REF_SLUG_PATTERN as o,gitAvailable as s,gitCommitToRef as c,gitExec as l,slugForRef as u}from"../../tools/dist/index.js";import{mkdir as d,readFile as f,readdir as p,stat as m,unlink as h,writeFile as g}from"node:fs/promises";var _=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await d(this.baseDir,{recursive:!0})}async read(e){let t=r(this.baseDir,e);try{return await f(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,n,i){let a=r(this.baseDir,e);await d(t(a),{recursive:!0}),await g(a,n,{encoding:`utf-8`,flag:i?.exclusive?`wx`:`w`})}async delete(e){let t=r(this.baseDir,e);try{return await h(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=r(this.baseDir,e),i;try{i=await p(n)}catch{continue}for(let n of i){if(!n.endsWith(`.md`))continue;let i=`${e}/${n}`,a=r(this.baseDir,i);try{let e=await m(a);t.push({path:i,size:e.size})}catch{}}}return t}async exists(e){let t=r(this.baseDir,e);try{return await m(t),!0}catch{return!1}}async listDirectories(){try{return(await p(this.baseDir,{withFileTypes:!0})).filter(e=>e.isDirectory()&&/^[a-z][a-z0-9-]*$/.test(e.name)).map(e=>e.name)}catch{return[]}}async close(){}};const v=50*1024,y=`refs/aikit/knowledge`,b=i(`server`);var x=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new _(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}try{await this.indexCuratedFile(a,t,s)}catch(e){throw await this.adapter.delete(a).catch(()=>{}),Error(`Remember failed: wrote file but indexing failed — rolled back. ${e.message}`)}return this.gitCommitKnowledge(a,c,`remember: ${e}\n\nCategory: ${n}\nTags: ${r.join(`, `)}`),{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),await this.indexCuratedFile(e,t,i),this.gitCommitKnowledge(e,s,`update(v${a}): ${i.title}\n\nReason: ${n}\nVersion: ${a}`),{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=>{b.warn(`File deleted but vector cleanup failed`,{sourcePath:n,...a(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!s(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=l([`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),!s(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?l([`diff`,`${t}:entry.md`,`${n}:entry.md`],this.curatedDir)??``:n?l([`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(!s(this.curatedDir))return null;let t=this.knowledgeRefForPath(e);if(!t)return null;let n=l([`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(!s(this.curatedDir))return[];let e=l([`for-each-ref`,`--format=%(refname)|%(subject)`,`${y}/`],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(`${y}/`,``)}.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){b.error(`Failed to read curated file`,{relativePath:e,...i(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=await this.embedder.embedBatch(n.map(e=>e.content)),a=new Date().toISOString(),o=n.map(e=>{let t=`.ai/curated/${e.relativePath}`;return{id:this.hashId(t,0),content:e.content,sourcePath:t,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
4
- `).length,fileHash:this.hash(e.content),indexedAt:a,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});return await this.store.upsert(o,r),{indexed:n.length,errors:t}}gitCommitKnowledge(e,t,n){try{if(!s(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;c(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!s(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;l([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>u(e)).join(`/`);return t.split(`/`).every(e=>o.test(e))?`${y}/${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
- `).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 discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let n=e.replace(/^\.ai\/curated\//,``);if(n.endsWith(`.md`)||(n+=`.md`),n.includes(`..`)||t(n))throw Error(`Invalid path: ${n}. Must be relative within .ai/curated/ directory.`);let r=n.split(`/`)[0];return this.validateCategoryName(r),n}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`)>v)throw Error(`Content exceeds maximum size of ${v/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 a(`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(`
3
+ `).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${y}/`,``)}.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){b.error(`Failed to read curated file`,{relativePath:e,...a(n)}),t.push(`${e}: read failed`)}}}if(n.length===0)return{indexed:0,errors:t};let r=await this.embedder.embedBatch(n.map(e=>e.content)),i=new Date().toISOString(),o=n.map(e=>{let t=`.ai/curated/${e.relativePath}`;return{id:this.hashId(t,0),content:e.content,sourcePath:t,contentType:`curated-knowledge`,headingPath:e.frontmatter.title,chunkIndex:0,totalChunks:1,startLine:1,endLine:e.content.split(`
4
+ `).length,fileHash:this.hash(e.content),indexedAt:i,origin:`curated`,tags:e.frontmatter.tags,category:e.frontmatter.category,version:e.frontmatter.version}});return await this.store.upsert(o,r),{indexed:n.length,errors:t}}gitCommitKnowledge(e,t,n){try{if(!s(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;c(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!s(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;l([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>u(e)).join(`/`);return t.split(`/`).every(e=>o.test(e))?`${y}/${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
+ `).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 discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||n(t))throw Error(`Invalid path: ${t}. Must be relative within .ai/curated/ directory.`);let r=t.split(`/`)[0];return this.validateCategoryName(r),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`)>v)throw Error(`Content exceeds maximum size of ${v/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(t){return e(`sha256`).update(t).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
6
6
  `)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
7
7
  `),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};export{_ as n,x as t};
@@ -1 +1 @@
1
- import{t as e}from"./curated-manager-BkSgtNC2.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),process.on(`uncaughtException`,e=>{d.error(`Uncaught exception — exiting`,c(e)),process.exit(1)}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-Dsu2Kd3U.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-gbC5Wmr9.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-CqEB0MaC.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,l,s.aikit.store),n=s.aikit.store;g=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-Dsu2Kd3U.js`),import(`./server-CqEB0MaC.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{d.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=f.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`smart`?h.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
1
+ import{t as e}from"./curated-manager-BnP6VqvL.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";var u=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)}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.options.staleTimeoutMinutes??30;return this.stateStore.sessionDeleteStale(e)}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}};const d=r(a(import.meta.url)),f=(()=>{try{let e=i(d,`..`,`..`,`..`,`package.json`);return JSON.parse(n(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),p=c(`server`);function m(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const h=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===o(e).href}catch{return!1}})();function g(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}const{values:_}=h?s({allowPositionals:!0,options:{transport:{type:`string`,default:m()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:m(),port:process.env.AIKIT_PORT??`3210`}};async function v(){if(process.on(`unhandledRejection`,e=>{p.error(`Unhandled rejection`,l(e))}),process.on(`uncaughtException`,e=>{p.error(`Uncaught exception — exiting`,l(e)),process.exit(1)}),p.info(`Starting MCP AI Kit server`,{version:f}),_.transport===`http`){let[{default:e},{loadConfig:n,resolveIndexMode:r},{registerDashboardRoutes:i,resolveDashboardDir:a},{registerSettingsRoutes:o,resolveSettingsDir:s},{createSettingsRouter:c},{authMiddleware:d,getOrCreateToken:f}]=await Promise.all([import(`express`),import(`./config-DAnAxrUW.js`),import(`./dashboard-static-CnXafYTs.js`),import(`./settings-static-BkVLqWOr.js`),import(`./routes-CR3fI-HJ.js`),import(`./auth-BfqgawfR.js`).then(e=>e.t)]),m=n();p.info(`Config loaded`,{sourceCount:m.sources.length,storePath:m.store.path});let h=e();h.use(e.json());let v=Number(_.port);h.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${v}`),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 y=f();console.error(`[aikit] Auth token: ~/.aikit/token`),h.use(d(y)),i(h,a(),p);let b=new Date().toISOString();h.use(`/settings/api`,c({log:p,mcpInfo:()=>({transport:`http`,port:v,pid:process.pid,startedAt:b})})),o(h,s(),p),h.get(`/health`,(e,t)=>{t.json({status:`ok`})});let x=!1,S=null,C=null,w=null,T=null,E=null,D=null,O=Promise.resolve(),k=async(e,n)=>{if(!x||!w||!T){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=O,i;O=new Promise(e=>{i=e}),await r;try{let r=g(e);if(!E){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new T({sessionIdGenerator:()=>t(),onsessioninitialized:async e=>{D=e,C?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&C?.onSessionEnd(e),D=null}});e.onclose=()=>{E===e&&(E=null),D===e.sessionId&&(D=null)},E=e,await w.connect(e)}let i=E;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(D=i.sessionId,C?.onSessionStart(i.sessionId,{transport:`http`}),C?.onSessionActivity(i.sessionId)):r&&C?.onSessionActivity(r))}catch(e){if(p.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()}};h.post(`/mcp`,k),h.get(`/mcp`,k),h.delete(`/mcp`,k);let A=h.listen(v,`127.0.0.1`,()=>{p.info(`MCP server listening`,{url:`http://127.0.0.1:${v}/mcp`,port:v}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:n},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-B0gtRiNa.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-BgHzxxCW.js`)]);i(),a();let o=r(m),s=e(m,o);w=s.server,T=n,x=!0,p.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),s.ready.then(()=>{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);C=new u(s.aikit.stateStore),C.startGC(),D&&(C.onSessionStart(D,{transport:`http`}),C.onSessionActivity(D))}).catch(e=>p.error(`Failed to start session manager`,l(e))),o===`auto`?s.ready.then(async()=>{try{let e=m.sources.map(e=>e.path).join(`, `);p.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),p.info(`Initial index complete`)}catch(e){p.error(`Initial index failed; will retry on aikit_reindex`,l(e))}}).catch(e=>p.error(`AI Kit init or indexing failed`,l(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,m,s.aikit.store),n=s.aikit.store;S=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),p.info(`Smart index scheduler started (HTTP mode)`)}catch(e){p.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>p.error(`AI Kit initialization failed`,l(e))):(s.ready.catch(e=>p.error(`AI Kit initialization failed`,l(e))),p.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){p.error(`Failed to load server modules`,l(e))}},100)}),j=async e=>{p.info(`Shutdown signal received`,{signal:e}),S?.stop(),C?.stop(),D&&C?.onSessionEnd(D),E&&(await E.close().catch(()=>void 0),E=null,D=null),A.close(),w&&await w.close(),process.exit(0)};process.on(`SIGINT`,()=>j(`SIGINT`)),process.on(`SIGTERM`,()=>j(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:i,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-DAnAxrUW.js`),import(`./server-B0gtRiNa.js`),import(`./version-check-BgHzxxCW.js`),import(`@modelcontextprotocol/sdk/types.js`)]),c=e();p.info(`Config loaded`,{sourceCount:c.sources.length,storePath:c.store.path}),i(),o();let u=n(c),d=r(c,u),{server:f,startInit:m,ready:h,runInitialIndex:g}=d,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await f.connect(v),p.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?a(n):n;return p.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(c,r),c.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?a(t):t}),!0},b=!1;try{b=y((await f.server.listRoots()).roots),b||p.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){p.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...l(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{p.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);f.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await f.server.listRoots()).roots))}catch(t){p.warn(`roots/list retry failed after notification`,l(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{p.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),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{p.error(`Initialization failed — server will continue with limited tools`,l(e))}),u===`auto`?g().catch(e=>p.error(`Initial index failed`,l(e))):u===`smart`?h.then(async()=>{try{if(!d.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(d.aikit.indexer,c,d.aikit.store),n=d.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),d.setSmartScheduler(t),p.info(`Smart index scheduler started (stdio mode)`)}catch(e){p.error(`Failed to start smart index scheduler`,l(e))}}).catch(e=>p.error(`AI Kit init failed for smart scheduler`,l(e))):p.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}v().catch(e=>{p.error(`Fatal error`,l(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
@@ -0,0 +1,32 @@
1
+ import { spawn } from "node:child_process";
2
+ //#region packages/server/src/auth.d.ts
3
+ interface TokenOptions {
4
+ tokenDir?: string;
5
+ }
6
+ /**
7
+ * Read token from ~/.aikit/token.
8
+ */
9
+ declare function readToken(options?: TokenOptions): string | undefined;
10
+ //#endregion
11
+ //#region packages/server/src/proxy.d.ts
12
+ interface ProxyOptions {
13
+ port?: number;
14
+ autoStart?: boolean;
15
+ }
16
+ interface ProxyRuntime {
17
+ input: NodeJS.ReadableStream;
18
+ output: NodeJS.WritableStream;
19
+ error: NodeJS.WritableStream;
20
+ fetchImpl: typeof fetch;
21
+ spawnImpl: typeof spawn;
22
+ readTokenImpl: typeof readToken;
23
+ sleep: (ms: number) => Promise<void>;
24
+ }
25
+ /**
26
+ * Run the stdio-to-HTTP proxy.
27
+ * Reads JSON-RPC from stdin, POSTs to the HTTP daemon, and writes responses to stdout.
28
+ */
29
+ declare function runProxy(options?: ProxyOptions, runtimeOverrides?: Partial<ProxyRuntime>): Promise<void>;
30
+ declare function isDaemonAlive(baseUrl: string, fetchImpl?: typeof fetch): Promise<boolean>;
31
+ //#endregion
32
+ export { ProxyOptions, ProxyRuntime, isDaemonAlive, runProxy };
@@ -0,0 +1,4 @@
1
+ import{n as e}from"./auth-BfqgawfR.js";import{fileURLToPath as t}from"node:url";import{spawn as n}from"node:child_process";import{createInterface as r}from"node:readline";const i={input:process.stdin,output:process.stdout,error:process.stderr,fetchImpl:globalThis.fetch,spawnImpl:n,readTokenImpl:e,sleep:e=>new Promise(t=>setTimeout(t,e))};async function a(e={},t={}){let n={...i,...t},a=s(e.port),c=`http://127.0.0.1:${a}`,h=await o(c,n.fetchImpl);if(!h&&e.autoStart!==!1)try{l(a,n),await u(c,1e4,n),h=!0}catch(e){n.error.write(`[aikit-proxy] ${m(e)}\n`)}else h||n.error.write(`[aikit-proxy] Daemon not running and autoStart=false
2
+ `);let g=n.readTokenImpl();if(!g){n.error.write(`[aikit-proxy] No token found at ~/.aikit/token
3
+ `);return}let _=r({input:n.input,crlfDelay:1/0}),v;for await(let e of _)if(e.trim())try{let t=await n.fetchImpl(`${c}/mcp`,{method:`POST`,headers:d(g,v),body:e}),r=t.headers.get(`mcp-session-id`);r&&(v=r);let i=await t.text();i&&f(n.output,i)}catch(t){f(n.output,p(e,t))}}async function o(e,t=globalThis.fetch){try{return(await t(`${e}/health`,{method:`GET`,signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}function s(e){if(typeof e==`number`&&Number.isFinite(e)&&e>0)return e;let t=Number.parseInt(process.env.AIKIT_PORT??``,10);return Number.isFinite(t)&&t>0?t:3210}function c(){return t(new URL(`./index.js`,import.meta.url))}function l(e,t){t.spawnImpl(process.execPath,[c(),`--transport`,`http`,`--port`,String(e)],{env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)},detached:!0,stdio:`ignore`}).unref(),t.error.write(`[aikit-proxy] Started daemon on port ${e}\n`)}async function u(e,t,n){let r=Date.now();for(;Date.now()-r<t;){if(await o(e,n.fetchImpl))return;await n.sleep(200)}throw Error(`Daemon did not start within ${t}ms`)}function d(e,t){return{"Content-Type":`application/json`,Authorization:`Bearer ${e}`,...t?{"Mcp-Session-Id":t}:{}}}function f(e,t){e.write(t.endsWith(`
4
+ `)?t:`${t}\n`)}function p(e,t){let n=null;try{n=JSON.parse(e).id??null}catch{n=null}return JSON.stringify({jsonrpc:`2.0`,id:n,error:{code:-32603,message:`Proxy error: ${m(t)}`}})}function m(e){return e instanceof Error?e.message:`Unknown error`}export{o as isDaemonAlive,a as runProxy};