@vpxa/aikit 0.1.380 → 0.1.382
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/claude-desktop/dist/manifest.json +1 -1
- package/packages/cli/dist/index.js +3 -3
- package/packages/cli/dist/{init-BTsNYC02.js → init-DMj2ctyd.js} +1 -1
- package/packages/cli/dist/{templates-CRs_gkfS.js → templates-DLra78_O.js} +30 -30
- package/packages/server/dist/bin.js +2 -2
- package/packages/server/dist/{config-DZskEKrY.js → config-CQKoGfwD.js} +1 -1
- package/packages/server/dist/{config-Bz8Uyzuq.js → config-DX1KYSbN.js} +1 -1
- package/packages/server/dist/{curated-manager-CBKTmAjM.js → curated-manager-D4MOFQ-t.js} +1 -1
- package/packages/server/dist/{dashboard-static-NghHzTNh.js → dashboard-static-C6RP0VA7.js} +1 -1
- package/packages/server/dist/{dashboard-static-gAOiHHqI.js → dashboard-static-DdsIJd-u.js} +1 -1
- package/packages/server/dist/index.d.ts +1 -1
- package/packages/server/dist/index.js +2 -2
- package/packages/server/dist/{observations-CfglxBMB.js → observations-BhMmh4uj.js} +1 -1
- package/packages/server/dist/{observations-CrQU_HVm.js → observations-Cri43dvk.js} +1 -1
- package/packages/server/dist/register-tools-C49Lkpvq.js +3044 -0
- package/packages/server/dist/register-tools-i_1kjBhi.js +3043 -0
- package/packages/server/dist/{server-C43D7SrT.js → server-CTUxU4KX.js} +11 -11
- package/packages/server/dist/{server-BmVdf84Q.js → server-Dm2u4PSm.js} +11 -11
- package/packages/server/dist/{server-http-YQ9jxThI.js → server-http-D8Wemu8Y.js} +1 -1
- package/packages/server/dist/{server-http-BCpGwi0k.js → server-http-DcgFpWra.js} +1 -1
- package/packages/server/dist/{server-stdio-3hhuJU8B.js → server-stdio-Bpoo8KOT.js} +1 -1
- package/packages/server/dist/{server-stdio-CuLAgQjc.js → server-stdio-CskpvBew.js} +1 -1
- package/packages/server/dist/{settings-static-DcTUiqr7.js → settings-static-C0oT3Ctk.js} +1 -1
- package/packages/server/dist/{settings-static-PjpMR9Q7.js → settings-static-DVMG47Oh.js} +1 -1
- package/packages/server/dist/startup-maintenance-cbRSFMY5.js +21 -0
- package/packages/server/dist/startup-maintenance-kHH8tjds.js +20 -0
- package/packages/tools/dist/index.d.ts +23 -3
- package/packages/tools/dist/index.js +111 -105
- package/scaffold/dist/adapters/_shared.mjs +1 -1
- package/scaffold/dist/adapters/hermes.mjs +1 -1
- package/scaffold/dist/definitions/agents.mjs +1 -1
- package/scaffold/dist/definitions/bodies.mjs +21 -16
- package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
- package/scaffold/dist/definitions/flows.mjs +5 -5
- package/scaffold/dist/definitions/hooks.mjs +1 -1
- package/scaffold/dist/definitions/protocols.mjs +26 -26
- package/scaffold/dist/definitions/skills/aikit.mjs +2 -152
- package/scaffold/dist/definitions/skills/browser-use.mjs +1 -1
- package/scaffold/dist/definitions/skills/c4-architecture.mjs +5 -5
- package/scaffold/dist/definitions/skills/docs.mjs +12 -10
- package/scaffold/dist/definitions/skills/multi-agents-development.mjs +4 -4
- package/scaffold/dist/definitions/skills/orchestrator.mjs +50 -8
- package/packages/server/dist/register-tools-Dgu64Px5.js +0 -3034
- package/packages/server/dist/register-tools-jgdif5r4.js +0 -3035
- package/packages/server/dist/startup-maintenance-B4xWqEjc.js +0 -20
- package/packages/server/dist/startup-maintenance-BnTozHs1.js +0 -21
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{fileURLToPath as e,pathToFileURL as t}from"node:url";import{parseArgs as n}from"node:util";import{HealthBus as r,createLogger as i,safeCwdOrHome as a,serializeError as o}from"../../core/dist/index.js";import{readFileSync as s}from"node:fs";import{dirname as c,isAbsolute as l,join as u,resolve as d}from"node:path";import{mkdir as f,readFile as p,readdir as m,stat as h,unlink as g,writeFile as _}from"node:fs/promises";import{createHash as v}from"node:crypto";import{GIT_REF_SLUG_PATTERN as y,gitAvailable as b,gitCommitToRef as x,gitExec as S,slugForRef as C}from"../../tools/dist/index.js";function w(){try{let t=d(c(e(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(s(t,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function T(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function E(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}const D=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function O({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?D.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function k({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 A(t){return t.startsWith(`file://`)?e(t):t}function j(e){let t=d(e);return process.platform===`win32`?t.toLowerCase():t}function M(e){let t=new Map;for(let n of e){let e=A(n.uri);t.set(j(e),e)}return[...t.values()].sort((e,t)=>j(e).localeCompare(j(t)))}function N({config:e,roots:t}){let n=M(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=j(r),t=n.find(t=>j(t)===e);if(t)return t}return n[0]}function P({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=M(r);if(i.length===0)return!1;let a=N({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:o&&j(o)===j(a)?`configured-source`:`stable-sorted-root`}),n(e,a),e.allRoots=i,!0}async function F({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:s,server:c,startInit:l,timeoutMs:u=5e3,getCwd:d=()=>process.env.AIKIT_WORKSPACE_ROOT??a(),version:f=`0.0.0`}){let p=!1,m=!1,h,g=c.server,_=e=>{let t=o(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`)||n.includes(`timed out`)},v=()=>{p||(p=!0,l())},y=()=>{m||t!==`auto`||(m=!0,(async()=>{try{await s()}catch(e){n.error(`Initial index failed`,{version:f,...o(e)})}})())};v();let b=t=>t.length===0||(h&&=(clearTimeout(h),void 0),!P({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(v(),y(),!0),x=t=>{let r=e.sources?.[0]?.path;r?(n.debug(`${t}; using configured source path`,{configuredRoot:r,cwd:d()}),v(),y()):(n.warn(`${t}; falling back to cwd workspace`,{cwd:d()}),P({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:d()}]})&&(v(),y()))};try{if(b((await g.listRoots()).roots))return;x(`MCP roots returned empty`)}catch(e){if(_(e)){x(`MCP roots/list not supported`);return}n.warn(`MCP roots/list failed; setting up roots/list_changed handler`,{version:f,cwd:d(),...o(e)}),x(`MCP roots/list failed`)}g.setNotificationHandler(r,async()=>{try{b((await g.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,{version:f,...o(e)})}}),h=setTimeout(()=>{n.debug(`Roots never arrived via roots/list_changed; fallback applied at startup`,{})},u),h.unref&&h.unref()}var I=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await f(this.baseDir,{recursive:!0})}async read(e){let t=u(this.baseDir,e);try{return await p(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,n){let r=u(this.baseDir,e);await f(c(r),{recursive:!0}),await _(r,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`})}async delete(e){let t=u(this.baseDir,e);try{return await g(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=u(this.baseDir,e),r;try{r=await m(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,i=u(this.baseDir,r);try{let e=await h(i);t.push({path:r,size:e.size,mtimeMs:e.mtimeMs})}catch{}}}return t}async exists(e){let t=u(this.baseDir,e);try{return await h(t),!0}catch{return!1}}async listDirectories(){try{return(await m(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 L=50*1024,R=`refs/aikit/knowledge`,z=i(`server`);var B=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new I(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.normalizeTags(r),a=this.slugify(e),o=await this.uniqueRelativePath(n,a),s=new Date().toISOString(),c={title:e,category:n,tags:i,created:s,updated:s,version:1,origin:`curated`,changelog:[{version:1,date:s,reason:`Initial creation`}]},l=this.serializeFile(t,c);try{await this.adapter.write(o,l,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${o}" — retry the operation`):e}return this.gitCommitKnowledge(o,l,`remember: ${e}\n\nCategory: ${n}\nTags: ${i.join(`, `)}`),await this.indexCuratedFileBestEffort(o,t,c,`remember`),{path:o}}async upsertAutoKnowledge(e,t,n,r,i=[],a=`Auto-knowledge refresh`){e=this.guardPath(e),this.validateCategoryName(r),this.validateContentSize(n),this.ensureCategoryPath(e,r);let o=this.normalizeTags(i),s=await this.adapter.read(e);if(s==null){let i=new Date().toISOString(),a={title:t,category:r,tags:o,created:i,updated:i,version:1,origin:`
|
|
2
|
+
import{fileURLToPath as e,pathToFileURL as t}from"node:url";import{parseArgs as n}from"node:util";import{HealthBus as r,createLogger as i,safeCwdOrHome as a,serializeError as o}from"../../core/dist/index.js";import{readFileSync as s}from"node:fs";import{dirname as c,isAbsolute as l,join as u,resolve as d}from"node:path";import{mkdir as f,readFile as p,readdir as m,stat as h,unlink as g,writeFile as _}from"node:fs/promises";import{createHash as v}from"node:crypto";import{GIT_REF_SLUG_PATTERN as y,gitAvailable as b,gitCommitToRef as x,gitExec as S,slugForRef as C}from"../../tools/dist/index.js";function w(){try{let t=d(c(e(import.meta.url)),`..`,`..`,`..`,`package.json`);return JSON.parse(s(t,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function T(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function E(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}const D=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i;function O({requestOrigin:e,configuredOrigin:t,allowAnyOrigin:n,fallbackOrigin:r}){let i=t??r;return i===`*`?n?{allowOrigin:`*`,warn:!1}:e?D.test(e)?{allowOrigin:e,warn:!1}:{allowOrigin:null,warn:!0}:{allowOrigin:r,warn:!1}:{allowOrigin:i,warn:!1}}function k({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 A(t){return t.startsWith(`file://`)?e(t):t}function j(e){let t=d(e);return process.platform===`win32`?t.toLowerCase():t}function M(e){let t=new Map;for(let n of e){let e=A(n.uri);t.set(j(e),e)}return[...t.values()].sort((e,t)=>j(e).localeCompare(j(t)))}function N({config:e,roots:t}){let n=M(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=j(r),t=n.find(t=>j(t)===e);if(t)return t}return n[0]}function P({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let i=M(r);if(i.length===0)return!1;let a=N({config:e,roots:i.map(e=>({uri:e}))});if(!a)return!1;let o=e.sources?.[0]?.path;return t.debug(`MCP roots resolved`,{rootPath:a,rootCount:i.length,selectedBy:o&&j(o)===j(a)?`configured-source`:`stable-sorted-root`}),n(e,a),e.allRoots=i,!0}async function F({config:e,indexMode:t,log:n,rootsChangedNotificationSchema:r,reconfigureForWorkspace:i,runInitialIndex:s,server:c,startInit:l,timeoutMs:u=5e3,getCwd:d=()=>process.env.AIKIT_WORKSPACE_ROOT??a(),version:f=`0.0.0`}){let p=!1,m=!1,h,g=c.server,_=e=>{let t=o(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`)||n.includes(`timed out`)},v=()=>{p||(p=!0,l())},y=()=>{m||t!==`auto`||(m=!0,(async()=>{try{await s()}catch(e){n.error(`Initial index failed`,{version:f,...o(e)})}})())};v();let b=t=>t.length===0||(h&&=(clearTimeout(h),void 0),!P({config:e,log:n,reconfigureForWorkspace:i,roots:t}))?!1:(v(),y(),!0),x=t=>{let r=e.sources?.[0]?.path;r?(n.debug(`${t}; using configured source path`,{configuredRoot:r,cwd:d()}),v(),y()):(n.warn(`${t}; falling back to cwd workspace`,{cwd:d()}),P({config:e,log:n,reconfigureForWorkspace:i,roots:[{uri:d()}]})&&(v(),y()))};try{if(b((await g.listRoots()).roots))return;x(`MCP roots returned empty`)}catch(e){if(_(e)){x(`MCP roots/list not supported`);return}n.warn(`MCP roots/list failed; setting up roots/list_changed handler`,{version:f,cwd:d(),...o(e)}),x(`MCP roots/list failed`)}g.setNotificationHandler(r,async()=>{try{b((await g.listRoots()).roots)}catch(e){n.warn(`roots/list retry failed after notification`,{version:f,...o(e)})}}),h=setTimeout(()=>{n.debug(`Roots never arrived via roots/list_changed; fallback applied at startup`,{})},u),h.unref&&h.unref()}var I=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await f(this.baseDir,{recursive:!0})}async read(e){let t=u(this.baseDir,e);try{return await p(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,n){let r=u(this.baseDir,e);await f(c(r),{recursive:!0}),await _(r,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`})}async delete(e){let t=u(this.baseDir,e);try{return await g(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=u(this.baseDir,e),r;try{r=await m(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,i=u(this.baseDir,r);try{let e=await h(i);t.push({path:r,size:e.size,mtimeMs:e.mtimeMs})}catch{}}}return t}async exists(e){let t=u(this.baseDir,e);try{return await h(t),!0}catch{return!1}}async listDirectories(){try{return(await m(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 L=50*1024,R=`refs/aikit/knowledge`,z=i(`server`);var B=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new I(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.normalizeTags(r),a=this.slugify(e),o=await this.uniqueRelativePath(n,a),s=new Date().toISOString(),c={title:e,category:n,tags:i,created:s,updated:s,version:1,origin:`curated`,changelog:[{version:1,date:s,reason:`Initial creation`}]},l=this.serializeFile(t,c);try{await this.adapter.write(o,l,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${o}" — retry the operation`):e}return this.gitCommitKnowledge(o,l,`remember: ${e}\n\nCategory: ${n}\nTags: ${i.join(`, `)}`),await this.indexCuratedFileBestEffort(o,t,c,`remember`),{path:o}}async upsertAutoKnowledge(e,t,n,r,i=[],a=`Auto-knowledge refresh`){e=this.guardPath(e),this.validateCategoryName(r),this.validateContentSize(n),this.ensureCategoryPath(e,r);let o=this.normalizeTags(i),s=await this.adapter.read(e);if(s==null){let i=new Date().toISOString(),a={title:t,category:r,tags:o,created:i,updated:i,version:1,origin:`auto`,changelog:[{version:1,date:i,reason:`Initial creation`}]},s=this.serializeFile(n,a);try{await this.adapter.write(e,s,{exclusive:!0})}catch(t){throw t.code===`EEXIST`?Error(`Concurrent write collision for "${e}" — retry the operation`):t}return this.gitCommitKnowledge(e,s,`remember: ${t}\n\nCategory: ${r}\nTags: ${o.join(`, `)}`),await this.indexCuratedFileBestEffort(e,n,a,`remember`),{path:e,status:`created`,version:1}}let{frontmatter:c,content:l}=this.parseFile(s),u=this.normalizeTags(c.tags??[]),d=t.trim()||c.title;if(l===n&&c.category===r&&c.title===d&&this.sameTags(u,o))return{path:e,status:`unchanged`,version:c.version??1};let f=(c.version??1)+1,p=new Date().toISOString();c.title=d,c.category=r,c.tags=o,c.version=f,c.updated=p,c.changelog=[...c.changelog??[],{version:f,date:p,reason:a}];let m=this.serializeFile(n,c);return await this.adapter.write(e,m),this.gitCommitKnowledge(e,m,`update(v${f}): ${c.title}\n\nReason: ${a}\nVersion: ${f}`),await this.indexCuratedFileBestEffort(e,n,c,`update`),{path:e,status:`updated`,version:f}}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=>{z.warn(`File deleted but vector cleanup failed`,{sourcePath:n,...o(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!b(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=S([`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),!b(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?S([`diff`,`${t}:entry.md`,`${n}:entry.md`],this.curatedDir)??``:n?S([`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(!b(this.curatedDir))return null;let t=this.knowledgeRefForPath(e);if(!t)return null;let n=S([`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(!b(this.curatedDir))return[];let e=S([`for-each-ref`,`--format=%(refname)|%(subject)`,`${R}/`],this.curatedDir);if(!e)return[];let t=[];for(let n of e.split(`
|
|
4
4
|
`).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${R}/`,``)}.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){return(await this.listPage(e)).entries}async listPage(e){let t=e?.category?[e.category]:await this.discoverCategories(),n=[];for(let e of t){let t=await this.adapter.list(e);for(let r of t)n.push({path:r.path,category:e,mtimeMs:r.mtimeMs??0})}let r=Math.max(0,e?.offset??0),i=e?.limit==null?null:Math.max(1,e.limit),a=(e?.order??`asc`)===`desc`?-1:1,o=e?.orderBy??`path`;if(o===`path`||o===`updated`){let t=this.sortCandidateMetadata(n,o,a);if(e?.tag){let n=i==null?void 0:r+i+1,{entries:a,scannedAll:o}=await this.readCandidateEntries(t,{tag:e.tag,maxMatches:n}),s=i==null?a.slice(r):a.slice(r,r+i),c=i!=null&&(a.length>r+s.length||!o);return{entries:s,totalCount:o?a.length:r+s.length+ +!!c,totalCountIsExact:o,limit:i,offset:r,hasMore:c}}let s=i==null?t.slice(r):t.slice(r,r+i),{entries:c}=await this.readCandidateEntries(s);return{entries:c,totalCount:t.length,totalCountIsExact:!0,limit:i,offset:r,hasMore:i!=null&&r+c.length<t.length}}let{entries:s}=await this.readCandidateEntries(n,{tag:e?.tag}),c=s.sort((e,t)=>{switch(o){case`created`:return(Date.parse(e.created)-Date.parse(t.created))*a;case`updated`:return(Date.parse(e.updated)-Date.parse(t.updated))*a;case`path`:return e.path.localeCompare(t.path)*a;default:return 0}}),l=i==null?c.slice(r):c.slice(r,r+i);return{entries:l,totalCount:c.length,totalCountIsExact:!0,limit:i,offset:r,hasMore:i!=null&&r+l.length<c.length}}async count(e){if(e?.tag)return(await this.listPage({...e,limit:void 0})).totalCount;let t=e?.category?[e.category]:await this.discoverCategories(),n=0;for(let e of t)n+=(await this.adapter.list(e)).length;return n}async listPaths(e){let t=e?.category?[e.category]:await this.discoverCategories(),n=[];for(let e of t){let t=await this.adapter.list(e);n.push(...t.map(e=>e.path))}n.sort((e,t)=>e.localeCompare(t));let r=Math.max(0,e?.offset??0),i=e?.limit==null?null:Math.max(1,e.limit);return i==null?n.slice(r):n.slice(r,r+i)}sortCandidateMetadata(e,t,n){return[...e].sort((e,r)=>t===`updated`?(e.mtimeMs-r.mtimeMs)*n:e.path.localeCompare(r.path)*n)}async readCandidateEntries(e,t){let n=[];for(let r of e){let e=await this.adapter.read(r.path);if(e==null)continue;let{frontmatter:i,content:a}=this.parseFile(e),o=i.tags??[];if(!(t?.tag&&!o.includes(t.tag))&&(n.push({path:r.path,title:i.title??r.path,category:r.category,tags:o,version:i.version??1,created:i.created??``,updated:i.updated??``,contentPreview:a.slice(0,200)}),t?.maxMatches!=null&&n.length>=t.maxMatches))return{entries:n,scannedAll:!1}}return{entries:n,scannedAll:!0}}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){z.error(`Failed to read curated file`,{relativePath:e,...o(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){z.error(`Failed to upsert curated batch`,{batchSize:e.length,...o(t)});for(let t of e)n.push(`${t.relativePath}: upsert failed`);return 0}}catch(r){if(e.length===1)return z.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...o(r)}),n.push(`${e[0].relativePath}: reindex failed`),0;z.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...o(r)});let i=Math.ceil(e.length/2),a=e.slice(0,i),s=e.slice(i);return await this.embedAndUpsertBatch(a,t,n)+await this.embedAndUpsertBatch(s,t,n)}}gitCommitKnowledge(e,t,n){try{if(!b(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;x(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!b(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;S([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>C(e)).join(`/`);return t.split(`/`).every(e=>y.test(e))?`${R}/${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,i){if(r.instance().isDegraded(`embedder`)){z.debug(`Skipping vector indexing — embedder degraded`,{relativePath:e,operation:i,subsystem:`embedder`});return}try{await this.indexCuratedFile(e,t,n)}catch(t){z.warn(`Curated file persisted but vector indexing deferred`,{relativePath:e,operation:i,...o(t)})}}async discoverCategories(){return this.adapter.listDirectories()}guardPath(e){let t=e.replace(/^\.ai\/curated\//,``);if(t.endsWith(`.md`)||(t+=`.md`),t.includes(`..`)||l(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`)>L)throw Error(`Content exceeds maximum size of ${L/1024}KB`)}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)}normalizeTags(e){return[...new Set(e.map(e=>e.trim()).filter(Boolean))]}sameTags(e,t){if(e.length!==t.length)return!1;let n=new Set(e);return t.every(e=>n.has(e))}ensureCategoryPath(e,t){if(!e.startsWith(`${t}/`))throw Error(`Curated path "${e}" must stay within category "${t}"`)}async uniqueRelativePath(e,t){let n=`${e}/${t}.md`;if(!await this.adapter.exists(n))return n;for(let n=2;n<=100;n++){let r=`${e}/${t}-${n}.md`;if(!await this.adapter.exists(r))return r}throw Error(`Too many entries with slug "${t}" in category "${e}"`)}hash(e){return v(`sha256`).update(e).digest(`hex`).slice(0,16)}hashId(e,t){return this.hash(`${e}::${t}`)}serializeFile(e,t){return`${[`---`,`title: "${t.title.replace(/"/g,`\\"`)}"`,`category: ${t.category}`,`tags: [${t.tags.map(e=>`"${e}"`).join(`, `)}]`,`created: ${t.created}`,`updated: ${t.updated}`,`version: ${t.version}`,`origin: ${t.origin}`,`changelog:`,...t.changelog.map(e=>` - version: ${e.version}\n date: ${e.date}\n reason: "${e.reason.replace(/"/g,`\\"`)}"`),`---`].join(`
|
|
7
7
|
`)}\n\n${e}\n`}parseFile(e){let t=e.match(/^---\n([\s\S]*?)\n---\n\n?([\s\S]*)$/);if(!t)return{frontmatter:{title:`Untitled`,category:`notes`,tags:[],created:``,updated:``,version:1,origin:`curated`,changelog:[]},content:e};let n=t[1],r=t[2].trim(),i={},a=[],o=n.split(`
|
|
8
|
-
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
8
|
+
`),s=!1,c={};for(let e of o){if(/^changelog:\s*$/.test(e)){s=!0;continue}if(s){let t=e.match(/^\s+-\s+version:\s*(\d+)$/);if(t){c.version!=null&&a.push(c),c={version:parseInt(t[1],10)};continue}let n=e.match(/^\s+date:\s*(.+)$/);if(n){c.date=n[1].trim();continue}let r=e.match(/^\s+reason:\s*"?(.*?)"?\s*$/);if(r){c.reason=r[1];continue}/^\w/.test(e)&&(s=!1,c.version!=null&&a.push(c),c={});continue}let t=e.match(/^(\w+):\s*(.*)$/);if(t){let e=t[1],n=t[2];typeof n==`string`&&n.startsWith(`[`)&&n.endsWith(`]`)?n=n.slice(1,-1).split(`,`).map(e=>e.trim().replace(/^"|"$/g,``)).filter(e=>e.length>0):typeof n==`string`&&/^\d+$/.test(n)?n=parseInt(n,10):typeof n==`string`&&n.startsWith(`"`)&&n.endsWith(`"`)&&(n=n.slice(1,-1)),i[e]=n}}return c.version!=null&&a.push(c),{frontmatter:{title:i.title??`Untitled`,category:i.category??`notes`,tags:i.tags??[],created:i.created??``,updated:i.updated??``,version:i.version??1,origin:`curated`,changelog:a},content:r}}};const V=i(`server`);function H(e,t){return t?{version:e,...o(t)}:{version:e}}function U(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function W(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===t(e).href}catch{return!1}}function G(){return W()?n({allowPositionals:!0,options:{transport:{type:`string`,default:U()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:U(),port:process.env.AIKIT_PORT??`3210`}}async function K(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let t=w(),n=G();if(process.on(`unhandledRejection`,e=>{V.error(`Unhandled rejection`,H(t,e))}),process.on(`uncaughtException`,e=>{V.error(`Uncaught exception — exiting`,H(t,e)),process.exit(1)}),V.info(`Starting MCP AI Kit server`,{version:t}),n.transport===`http`){let{startHttpMode:e}=await import(`./server-http-D8Wemu8Y.js`);await e(t,n.port)}else{let{startStdioMode:e}=await import(`./server-stdio-Bpoo8KOT.js`);await e(t)}}K();export{T as a,k as i,I as n,E as o,F as r,O as s,B as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{D as e,I as t,K as n,M as r}from"./startup-maintenance-kHH8tjds.js";import{fileURLToPath as i}from"node:url";import{AIKIT_RUNTIME_PATHS as a,DEFAULT_SERVER_NAME as o,EMBEDDING_DEFAULTS as s,computePartitionKey as c,createLogger as l,getPartitionDir as u,migrateLegacyWorkspaceLayout as d,safeCwd as f,serializeError as p}from"../../core/dist/index.js";import{existsSync as m,mkdirSync as h,readFileSync as g,writeFileSync as _}from"node:fs";import{dirname as v,isAbsolute as y,relative as b,resolve as x}from"node:path";import{homedir as S}from"node:os";const C=v(i(import.meta.url)),w=l(`server`),T=[`auto`,`manual`,`smart`],E={model:s.model,dimensions:s.dimensions,childProcess:!0,idleTimeoutMs:3e5};function D(e){return typeof e==`string`&&T.includes(e)}function O(e,t,n){let r=x(e),i=b(x(t),r);if(i.startsWith(`..`)||y(i))throw Error(`Config ${n} path escapes allowed root: ${e} is not under ${t}`);return r}function k(e,t){let n=x(e),r=b(x(t),n);return!(r.startsWith(`..`)||y(r))}function A(e){return u(c(e))}function j(e,t,n,r,i){let a=r?x(t,r):t;if(!n)return O(a,t,i);let o=x(e,n);return k(o,t)?r&&x(o)===x(t)?O(a,t,i):O(o,t,i):O(a,t,i)}function M(e){let t=[e.store?.path,e.curated?.path,e.onboardDir,e.stateDir,e.skillDir];for(let e of t)e&&h(e,{recursive:!0})}function N(e,t){d(t);let n=A(t);e.store={...e.store,path:j(t,n,e.store?.path,a.data,`store`)},e.curated={...e.curated,path:j(t,n,e.curated?.path,a.curated,`curated`)},e.onboardDir=j(t,n,e.onboardDir,a.onboard,`onboard`),e.stateDir=j(t,n,e.stateDir,a.state,`state`),e.skillDir=j(t,n,e.skillDir,a.skills,`skillDir`)}function P(e){let t=process.env.AIKIT_INDEX_MODE;if(D(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 F(){let i=f(),a=process.env.AIKIT_CONFIG_PATH??(i&&m(x(i,`aikit.config.json`))?x(i,`aikit.config.json`):x(C,`..`,`..`,`..`,`aikit.config.json`));try{if(!m(a))return w.info(`No config file found, using defaults`,{configPath:a}),L();let i=g(a,`utf-8`),o=JSON.parse(i),s={...E,...o.embedding};if(o.embedding=s,o.memory={retention:{...r,...o.memory?.retention},lessons:{...t,...o.memory?.lessons},consolidation:{...n,...o.memory?.consolidation},supersession:{...e,...o.memory?.supersession}},o.logging?.errorDetails!==void 0&&typeof o.logging.errorDetails!=`boolean`)throw Error(`Config logging.errorDetails must be a boolean`);if(o.logging={errorDetails:o.logging?.errorDetails===!0},!o.sources||!Array.isArray(o.sources)||o.sources.length===0)throw Error(`Config must have at least one source`);if(!o.store?.path)throw Error(`Config must specify store.path`);if(o.autoIndex!==void 0&&typeof o.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(o.indexMode!==void 0&&!D(o.indexMode))throw Error(`Config indexMode must be one of: ${T.join(`, `)}`);if(typeof s.model!=`string`||s.model.trim()===``)throw Error(`Config embedding.model must be a non-empty string`);if(s.nativeDim!==void 0&&(!Number.isInteger(s.nativeDim)||s.nativeDim<=0))throw Error(`Config embedding.nativeDim must be a positive integer`);if(s.dimensions!==void 0&&(!Number.isInteger(s.dimensions)||s.dimensions<=0))throw Error(`Config embedding.dimensions must be a positive integer`);if(s.dimensions!==void 0&&s.nativeDim!==void 0&&s.dimensions>s.nativeDim)throw Error(`Config embedding.dimensions must not exceed embedding.nativeDim`);if(s.queryPrefix!==void 0&&typeof s.queryPrefix!=`string`)throw Error(`Config embedding.queryPrefix must be a string`);let c=v(a);return o.sources=o.sources.map(e=>({...e,path:O(x(c,e.path),c,`source`)})),R(o,a),N(o,c),o.layeredKnowledge===void 0&&(o.layeredKnowledge=process.env.AIKIT_LAYERED_KNOWLEDGE===`true`),o.indexMode=P(o),o}catch(e){let t=`Failed to load config from ${a}. ${e instanceof Error?e.message:String(e)}`;console.error(`\n ⚠ CONFIG ERROR — ${t}\n Check that the file exists, is valid JSON, and all required fields are present.\n`),w.error(`Failed to load config`,{configPath:a,...p(e)}),w.warn(`Falling back to default configuration`,{configPath:a});let n=L();return n.configError=t,n}}const I=[`.git/**`,`**/node_modules/**`,`*.lock`,`pnpm-lock.yaml`,`package-lock.json`,`**/dist/**`,`**/build/**`,`**/out/**`,`**/.output/**`,`**/cdk.out/**`,`**/.next/**`,`**/.nuxt/**`,`**/.vercel/**`,`**/.serverless/**`,`**/.turbo/**`,`**/.cache/**`,`**/.parcel-cache/**`,`**/coverage/**`,`**/.terraform/**`,`**/__pycache__/**`,`**/.venv/**`,`**/.docusaurus/**`,`**/.temp/**`,`**/tmp/**`];function L(){let i=process.env.AIKIT_WORKSPACE_ROOT??f()??S(),s=A(i),c={sources:[{path:i,excludePatterns:[...I]}],serverName:o,indexing:{chunkSize:800,chunkOverlap:150,minChunkSize:100},embedding:{...E},store:{backend:`sqlite-vec`,path:x(s,a.data)},curated:{path:x(s,a.curated)},memory:{retention:{...r},lessons:{...t},consolidation:{...n},supersession:{...e}},logging:{errorDetails:!1},onboardDir:x(s,a.onboard),stateDir:x(s,a.state)};return c.indexMode=P(c),c}function R(e,t){let n=e.configVersion??0;if(n>=1)return e;if(n<1)for(let t of e.sources){t.excludePatterns=t.excludePatterns??[];let e=new Set(t.excludePatterns);for(let n of I)e.has(n)||t.excludePatterns.push(n)}e.configVersion=1;try{_(t,`${JSON.stringify(e,null,2)}\n`,`utf-8`),w.info(`Config auto-upgraded`,{from:n,to:1,configPath:t})}catch(e){w.warn(`Failed to write upgraded config`,{configPath:t,...p(e)})}return e}function z(e,t){if(!m(t))throw Error(`Workspace root does not exist: ${t}`);d(t),w.debug(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),w.debug(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){w.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...p(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],N(e,t),M(e)}export{I as DEFAULT_EXCLUDE_PATTERNS,F as loadConfig,z as reconfigureForWorkspace,P as resolveIndexMode};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{D as e,I as t,K as n,M as r}from"./startup-maintenance-cbRSFMY5.js";import{fileURLToPath as i}from"node:url";import{AIKIT_RUNTIME_PATHS as a,DEFAULT_SERVER_NAME as o,EMBEDDING_DEFAULTS as s,computePartitionKey as c,createLogger as l,getPartitionDir as u,migrateLegacyWorkspaceLayout as d,safeCwd as f,serializeError as p}from"../../core/dist/index.js";import{existsSync as m,mkdirSync as h,readFileSync as g,writeFileSync as _}from"node:fs";import{dirname as v,isAbsolute as y,relative as b,resolve as x}from"node:path";import{homedir as S}from"node:os";const C=v(i(import.meta.url)),w=l(`server`),T=[`auto`,`manual`,`smart`],E={model:s.model,dimensions:s.dimensions,childProcess:!0,idleTimeoutMs:3e5};function D(e){return typeof e==`string`&&T.includes(e)}function O(e,t,n){let r=x(e),i=b(x(t),r);if(i.startsWith(`..`)||y(i))throw Error(`Config ${n} path escapes allowed root: ${e} is not under ${t}`);return r}function k(e,t){let n=x(e),r=b(x(t),n);return!(r.startsWith(`..`)||y(r))}function A(e){return u(c(e))}function j(e,t,n,r,i){let a=r?x(t,r):t;if(!n)return O(a,t,i);let o=x(e,n);return k(o,t)?r&&x(o)===x(t)?O(a,t,i):O(o,t,i):O(a,t,i)}function M(e){let t=[e.store?.path,e.curated?.path,e.onboardDir,e.stateDir,e.skillDir];for(let e of t)e&&h(e,{recursive:!0})}function N(e,t){d(t);let n=A(t);e.store={...e.store,path:j(t,n,e.store?.path,a.data,`store`)},e.curated={...e.curated,path:j(t,n,e.curated?.path,a.curated,`curated`)},e.onboardDir=j(t,n,e.onboardDir,a.onboard,`onboard`),e.stateDir=j(t,n,e.stateDir,a.state,`state`),e.skillDir=j(t,n,e.skillDir,a.skills,`skillDir`)}function P(e){let t=process.env.AIKIT_INDEX_MODE;if(D(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 F(){let i=f(),a=process.env.AIKIT_CONFIG_PATH??(i&&m(x(i,`aikit.config.json`))?x(i,`aikit.config.json`):x(C,`..`,`..`,`..`,`aikit.config.json`));try{if(!m(a))return w.info(`No config file found, using defaults`,{configPath:a}),L();let i=g(a,`utf-8`),o=JSON.parse(i),s={...E,...o.embedding};if(o.embedding=s,o.memory={retention:{...r,...o.memory?.retention},lessons:{...t,...o.memory?.lessons},consolidation:{...n,...o.memory?.consolidation},supersession:{...e,...o.memory?.supersession}},o.logging?.errorDetails!==void 0&&typeof o.logging.errorDetails!=`boolean`)throw Error(`Config logging.errorDetails must be a boolean`);if(o.logging={errorDetails:o.logging?.errorDetails===!0},!o.sources||!Array.isArray(o.sources)||o.sources.length===0)throw Error(`Config must have at least one source`);if(!o.store?.path)throw Error(`Config must specify store.path`);if(o.autoIndex!==void 0&&typeof o.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(o.indexMode!==void 0&&!D(o.indexMode))throw Error(`Config indexMode must be one of: ${T.join(`, `)}`);if(typeof s.model!=`string`||s.model.trim()===``)throw Error(`Config embedding.model must be a non-empty string`);if(s.nativeDim!==void 0&&(!Number.isInteger(s.nativeDim)||s.nativeDim<=0))throw Error(`Config embedding.nativeDim must be a positive integer`);if(s.dimensions!==void 0&&(!Number.isInteger(s.dimensions)||s.dimensions<=0))throw Error(`Config embedding.dimensions must be a positive integer`);if(s.dimensions!==void 0&&s.nativeDim!==void 0&&s.dimensions>s.nativeDim)throw Error(`Config embedding.dimensions must not exceed embedding.nativeDim`);if(s.queryPrefix!==void 0&&typeof s.queryPrefix!=`string`)throw Error(`Config embedding.queryPrefix must be a string`);let c=v(a);return o.sources=o.sources.map(e=>({...e,path:O(x(c,e.path),c,`source`)})),R(o,a),N(o,c),o.layeredKnowledge===void 0&&(o.layeredKnowledge=process.env.AIKIT_LAYERED_KNOWLEDGE===`true`),o.indexMode=P(o),o}catch(e){let t=`Failed to load config from ${a}. ${e instanceof Error?e.message:String(e)}`;console.error(`\n ⚠ CONFIG ERROR — ${t}\n Check that the file exists, is valid JSON, and all required fields are present.\n`),w.error(`Failed to load config`,{configPath:a,...p(e)}),w.warn(`Falling back to default configuration`,{configPath:a});let n=L();return n.configError=t,n}}const I=[`.git/**`,`**/node_modules/**`,`*.lock`,`pnpm-lock.yaml`,`package-lock.json`,`**/dist/**`,`**/build/**`,`**/out/**`,`**/.output/**`,`**/cdk.out/**`,`**/.next/**`,`**/.nuxt/**`,`**/.vercel/**`,`**/.serverless/**`,`**/.turbo/**`,`**/.cache/**`,`**/.parcel-cache/**`,`**/coverage/**`,`**/.terraform/**`,`**/__pycache__/**`,`**/.venv/**`,`**/.docusaurus/**`,`**/.temp/**`,`**/tmp/**`];function L(){let i=process.env.AIKIT_WORKSPACE_ROOT??f()??S(),s=A(i),c={sources:[{path:i,excludePatterns:[...I]}],serverName:o,indexing:{chunkSize:800,chunkOverlap:150,minChunkSize:100},embedding:{...E},store:{backend:`sqlite-vec`,path:x(s,a.data)},curated:{path:x(s,a.curated)},memory:{retention:{...r},lessons:{...t},consolidation:{...n},supersession:{...e}},logging:{errorDetails:!1},onboardDir:x(s,a.onboard),stateDir:x(s,a.state)};return c.indexMode=P(c),c}function R(e,t){let n=e.configVersion??0;if(n>=1)return e;if(n<1)for(let t of e.sources){t.excludePatterns=t.excludePatterns??[];let e=new Set(t.excludePatterns);for(let n of I)e.has(n)||t.excludePatterns.push(n)}e.configVersion=1;try{_(t,`${JSON.stringify(e,null,2)}\n`,`utf-8`),w.info(`Config auto-upgraded`,{from:n,to:1,configPath:t})}catch(e){w.warn(`Failed to write upgraded config`,{configPath:t,...p(e)})}return e}function z(e,t){if(!m(t))throw Error(`Workspace root does not exist: ${t}`);d(t),w.debug(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),w.debug(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){w.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...p(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],N(e,t),M(e)}export{I as DEFAULT_EXCLUDE_PATTERNS,F as loadConfig,z as reconfigureForWorkspace,P as resolveIndexMode};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{HealthBus as e,createLogger as t,serializeError as n}from"../../core/dist/index.js";import{dirname as r,isAbsolute as i,join as a}from"node:path";import{mkdir as o,readFile as s,readdir as c,stat as l,unlink as u,writeFile as d}from"node:fs/promises";import{createHash as f}from"node:crypto";import{GIT_REF_SLUG_PATTERN as p,gitAvailable as m,gitCommitToRef as h,gitExec as g,slugForRef as _}from"../../tools/dist/index.js";var v=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await o(this.baseDir,{recursive:!0})}async read(e){let t=a(this.baseDir,e);try{return await s(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,n){let i=a(this.baseDir,e);await o(r(i),{recursive:!0}),await d(i,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`})}async delete(e){let t=a(this.baseDir,e);try{return await u(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=a(this.baseDir,e),r;try{r=await c(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,i=a(this.baseDir,r);try{let e=await l(i);t.push({path:r,size:e.size,mtimeMs:e.mtimeMs})}catch{}}}return t}async exists(e){let t=a(this.baseDir,e);try{return await l(t),!0}catch{return!1}}async listDirectories(){try{return(await c(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 y=50*1024,b=`refs/aikit/knowledge`,x=t(`server`);var S=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new v(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.normalizeTags(r),a=this.slugify(e),o=await this.uniqueRelativePath(n,a),s=new Date().toISOString(),c={title:e,category:n,tags:i,created:s,updated:s,version:1,origin:`curated`,changelog:[{version:1,date:s,reason:`Initial creation`}]},l=this.serializeFile(t,c);try{await this.adapter.write(o,l,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${o}" — retry the operation`):e}return this.gitCommitKnowledge(o,l,`remember: ${e}\n\nCategory: ${n}\nTags: ${i.join(`, `)}`),await this.indexCuratedFileBestEffort(o,t,c,`remember`),{path:o}}async upsertAutoKnowledge(e,t,n,r,i=[],a=`Auto-knowledge refresh`){e=this.guardPath(e),this.validateCategoryName(r),this.validateContentSize(n),this.ensureCategoryPath(e,r);let o=this.normalizeTags(i),s=await this.adapter.read(e);if(s==null){let i=new Date().toISOString(),a={title:t,category:r,tags:o,created:i,updated:i,version:1,origin:`
|
|
1
|
+
import{HealthBus as e,createLogger as t,serializeError as n}from"../../core/dist/index.js";import{dirname as r,isAbsolute as i,join as a}from"node:path";import{mkdir as o,readFile as s,readdir as c,stat as l,unlink as u,writeFile as d}from"node:fs/promises";import{createHash as f}from"node:crypto";import{GIT_REF_SLUG_PATTERN as p,gitAvailable as m,gitCommitToRef as h,gitExec as g,slugForRef as _}from"../../tools/dist/index.js";var v=class{baseDir;constructor(e){this.baseDir=e}async initialize(){await o(this.baseDir,{recursive:!0})}async read(e){let t=a(this.baseDir,e);try{return await s(t,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async write(e,t,n){let i=a(this.baseDir,e);await o(r(i),{recursive:!0}),await d(i,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`})}async delete(e){let t=a(this.baseDir,e);try{return await u(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=a(this.baseDir,e),r;try{r=await c(n)}catch{continue}for(let n of r){if(!n.endsWith(`.md`))continue;let r=`${e}/${n}`,i=a(this.baseDir,r);try{let e=await l(i);t.push({path:r,size:e.size,mtimeMs:e.mtimeMs})}catch{}}}return t}async exists(e){let t=a(this.baseDir,e);try{return await l(t),!0}catch{return!1}}async listDirectories(){try{return(await c(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 y=50*1024,b=`refs/aikit/knowledge`,x=t(`server`);var S=class{curatedDir;store;embedder;adapter;constructor(e,t,n,r=new v(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.normalizeTags(r),a=this.slugify(e),o=await this.uniqueRelativePath(n,a),s=new Date().toISOString(),c={title:e,category:n,tags:i,created:s,updated:s,version:1,origin:`curated`,changelog:[{version:1,date:s,reason:`Initial creation`}]},l=this.serializeFile(t,c);try{await this.adapter.write(o,l,{exclusive:!0})}catch(e){throw e.code===`EEXIST`?Error(`Concurrent write collision for "${o}" — retry the operation`):e}return this.gitCommitKnowledge(o,l,`remember: ${e}\n\nCategory: ${n}\nTags: ${i.join(`, `)}`),await this.indexCuratedFileBestEffort(o,t,c,`remember`),{path:o}}async upsertAutoKnowledge(e,t,n,r,i=[],a=`Auto-knowledge refresh`){e=this.guardPath(e),this.validateCategoryName(r),this.validateContentSize(n),this.ensureCategoryPath(e,r);let o=this.normalizeTags(i),s=await this.adapter.read(e);if(s==null){let i=new Date().toISOString(),a={title:t,category:r,tags:o,created:i,updated:i,version:1,origin:`auto`,changelog:[{version:1,date:i,reason:`Initial creation`}]},s=this.serializeFile(n,a);try{await this.adapter.write(e,s,{exclusive:!0})}catch(t){throw t.code===`EEXIST`?Error(`Concurrent write collision for "${e}" — retry the operation`):t}return this.gitCommitKnowledge(e,s,`remember: ${t}\n\nCategory: ${r}\nTags: ${o.join(`, `)}`),await this.indexCuratedFileBestEffort(e,n,a,`remember`),{path:e,status:`created`,version:1}}let{frontmatter:c,content:l}=this.parseFile(s),u=this.normalizeTags(c.tags??[]),d=t.trim()||c.title;if(l===n&&c.category===r&&c.title===d&&this.sameTags(u,o))return{path:e,status:`unchanged`,version:c.version??1};let f=(c.version??1)+1,p=new Date().toISOString();c.title=d,c.category=r,c.tags=o,c.version=f,c.updated=p,c.changelog=[...c.changelog??[],{version:f,date:p,reason:a}];let m=this.serializeFile(n,c);return await this.adapter.write(e,m),this.gitCommitKnowledge(e,m,`update(v${f}): ${c.title}\n\nReason: ${a}\nVersion: ${f}`),await this.indexCuratedFileBestEffort(e,n,c,`update`),{path:e,status:`updated`,version:f}}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 r=`.ai/curated/${e}`;return await this.store.deleteBySourcePath(r).catch(e=>{x.warn(`File deleted but vector cleanup failed`,{sourcePath:r,...n(e)})}),this.gitDeleteKnowledgeRef(e),{path:e}}async history(e,t=20){if(e=this.guardPath(e),!m(this.curatedDir))return[];let n=this.knowledgeRefForPath(e);if(!n)return[];let r=g([`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),!m(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?g([`diff`,`${t}:entry.md`,`${n}:entry.md`],this.curatedDir)??``:n?g([`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(!m(this.curatedDir))return null;let t=this.knowledgeRefForPath(e);if(!t)return null;let n=g([`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(!m(this.curatedDir))return[];let e=g([`for-each-ref`,`--format=%(refname)|%(subject)`,`${b}/`],this.curatedDir);if(!e)return[];let t=[];for(let n of e.split(`
|
|
3
3
|
`).filter(Boolean)){let[e,...r]=n.split(`|`),i=r.join(`|`),a=`${e.replace(`${b}/`,``)}.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){return(await this.listPage(e)).entries}async listPage(e){let t=e?.category?[e.category]:await this.discoverCategories(),n=[];for(let e of t){let t=await this.adapter.list(e);for(let r of t)n.push({path:r.path,category:e,mtimeMs:r.mtimeMs??0})}let r=Math.max(0,e?.offset??0),i=e?.limit==null?null:Math.max(1,e.limit),a=(e?.order??`asc`)===`desc`?-1:1,o=e?.orderBy??`path`;if(o===`path`||o===`updated`){let t=this.sortCandidateMetadata(n,o,a);if(e?.tag){let n=i==null?void 0:r+i+1,{entries:a,scannedAll:o}=await this.readCandidateEntries(t,{tag:e.tag,maxMatches:n}),s=i==null?a.slice(r):a.slice(r,r+i),c=i!=null&&(a.length>r+s.length||!o);return{entries:s,totalCount:o?a.length:r+s.length+ +!!c,totalCountIsExact:o,limit:i,offset:r,hasMore:c}}let s=i==null?t.slice(r):t.slice(r,r+i),{entries:c}=await this.readCandidateEntries(s);return{entries:c,totalCount:t.length,totalCountIsExact:!0,limit:i,offset:r,hasMore:i!=null&&r+c.length<t.length}}let{entries:s}=await this.readCandidateEntries(n,{tag:e?.tag}),c=s.sort((e,t)=>{switch(o){case`created`:return(Date.parse(e.created)-Date.parse(t.created))*a;case`updated`:return(Date.parse(e.updated)-Date.parse(t.updated))*a;case`path`:return e.path.localeCompare(t.path)*a;default:return 0}}),l=i==null?c.slice(r):c.slice(r,r+i);return{entries:l,totalCount:c.length,totalCountIsExact:!0,limit:i,offset:r,hasMore:i!=null&&r+l.length<c.length}}async count(e){if(e?.tag)return(await this.listPage({...e,limit:void 0})).totalCount;let t=e?.category?[e.category]:await this.discoverCategories(),n=0;for(let e of t)n+=(await this.adapter.list(e)).length;return n}async listPaths(e){let t=e?.category?[e.category]:await this.discoverCategories(),n=[];for(let e of t){let t=await this.adapter.list(e);n.push(...t.map(e=>e.path))}n.sort((e,t)=>e.localeCompare(t));let r=Math.max(0,e?.offset??0),i=e?.limit==null?null:Math.max(1,e.limit);return i==null?n.slice(r):n.slice(r,r+i)}sortCandidateMetadata(e,t,n){return[...e].sort((e,r)=>t===`updated`?(e.mtimeMs-r.mtimeMs)*n:e.path.localeCompare(r.path)*n)}async readCandidateEntries(e,t){let n=[];for(let r of e){let e=await this.adapter.read(r.path);if(e==null)continue;let{frontmatter:i,content:a}=this.parseFile(e),o=i.tags??[];if(!(t?.tag&&!o.includes(t.tag))&&(n.push({path:r.path,title:i.title??r.path,category:r.category,tags:o,version:i.version??1,created:i.created??``,updated:i.updated??``,contentPreview:a.slice(0,200)}),t?.maxMatches!=null&&n.length>=t.maxMatches))return{entries:n,scannedAll:!1}}return{entries:n,scannedAll:!0}}async reindexAll(){let e=await this.discoverCategories(),t=[],r=[];for(let i of e){let e=await this.adapter.list(i);for(let i of e){let e=i.path;try{let n=await this.adapter.read(e);if(n==null){t.push(`${e}: read failed`);continue}let{frontmatter:i,content:a}=this.parseFile(n);r.push({relativePath:e,content:a,frontmatter:i})}catch(r){x.error(`Failed to read curated file`,{relativePath:e,...n(r)}),t.push(`${e}: read failed`)}}}if(r.length===0)return{indexed:0,errors:t};let i=new Date().toISOString(),a=0;for(let e=0;e<r.length;e+=16){let n=r.slice(e,e+16);a+=await this.embedAndUpsertBatch(n,i,t)}return{indexed:a,errors:t}}async embedAndUpsertBatch(e,t,r){try{let i=await this.embedder.embedBatch(e.map(e=>e.content)),a=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(a,i),e.length}catch(t){x.error(`Failed to upsert curated batch`,{batchSize:e.length,...n(t)});for(let t of e)r.push(`${t.relativePath}: upsert failed`);return 0}}catch(i){if(e.length===1)return x.error(`Failed to embed curated item`,{relativePath:e[0].relativePath,...n(i)}),r.push(`${e[0].relativePath}: reindex failed`),0;x.warn(`Curated embed batch failed, retrying with smaller chunks`,{batchSize:e.length,...n(i)});let a=Math.ceil(e.length/2),o=e.slice(0,a),s=e.slice(a);return await this.embedAndUpsertBatch(o,t,r)+await this.embedAndUpsertBatch(s,t,r)}}gitCommitKnowledge(e,t,n){try{if(!m(this.curatedDir))return;let r=this.knowledgeRefForPath(e);if(!r)return;h(r,`entry.md`,t,n,this.curatedDir)}catch{}}gitDeleteKnowledgeRef(e){try{if(!m(this.curatedDir))return;let t=this.knowledgeRefForPath(e);if(!t)return;g([`update-ref`,`-d`,t],this.curatedDir)}catch{}}knowledgeRefForPath(e){let t=e.replace(/\.md$/,``).split(`/`).map(e=>_(e)).join(`/`);return t.split(`/`).every(e=>p.test(e))?`${b}/${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(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{w as e}from"./startup-maintenance-kHH8tjds.js";import{fileURLToPath as t}from"node:url";import{createReadStream as n,existsSync as r,statSync as i}from"node:fs";import{dirname as a,extname as o,join as s,resolve as c,sep as l}from"node:path";const u=import.meta.dirname??a(t(import.meta.url)),d={".html":`text/html`,".js":`application/javascript`,".css":`text/css`,".json":`application/json`,".png":`image/png`,".svg":`image/svg+xml`,".ico":`image/x-icon`,".woff":`font/woff`,".woff2":`font/woff2`};function f(t){return t?s(t,`..`,`..`,`dashboard`,`dist`):e(`dashboard`)??s(u,`..`,`..`,`dashboard`,`dist`)}function p(e,t){let n=t.replace(/^\/_dashboard\/?/,``)||`index.html`;try{n=decodeURIComponent(n)}catch{}let a=c(e,n);if(!(a===e||a.startsWith(`${e}${l}`)))return{kind:`forbidden`};try{if(i(a).isFile())return{kind:`file`,path:a,contentType:d[o(a)]??`application/octet-stream`}}catch{}let u=s(e,`index.html`);return r(u)?{kind:`spa`,path:u,contentType:`text/html`}:{kind:`not-found`}}function m(e,t,i){return r(t)?(e.get(`/_dashboard{/*path}`,(e,r)=>{let i=p(t,e.path);if(i.kind===`forbidden`){r.status(403).end(`Forbidden`);return}if(i.kind===`not-found`){r.status(404).end(`Not found`);return}r.setHeader(`Content-Type`,i.contentType),i.kind===`file`&&/\.[a-f0-9]{8,}\.(js|css)$/i.test(i.path)?r.setHeader(`Cache-Control`,`public, max-age=31536000, immutable`):r.setHeader(`Cache-Control`,`no-cache`),n(i.path).pipe(r)}),i.info(`Dashboard available`,{url:`/_dashboard/`,dir:t}),!0):!1}export{m as registerDashboardRoutes,f as resolveDashboardDir,p as resolveDashboardRequest};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{w as e}from"./startup-maintenance-cbRSFMY5.js";import{fileURLToPath as t}from"node:url";import{createReadStream as n,existsSync as r,statSync as i}from"node:fs";import{dirname as a,extname as o,join as s,resolve as c,sep as l}from"node:path";const u=import.meta.dirname??a(t(import.meta.url)),d={".html":`text/html`,".js":`application/javascript`,".css":`text/css`,".json":`application/json`,".png":`image/png`,".svg":`image/svg+xml`,".ico":`image/x-icon`,".woff":`font/woff`,".woff2":`font/woff2`};function f(t){return t?s(t,`..`,`..`,`dashboard`,`dist`):e(`dashboard`)??s(u,`..`,`..`,`dashboard`,`dist`)}function p(e,t){let n=t.replace(/^\/_dashboard\/?/,``)||`index.html`;try{n=decodeURIComponent(n)}catch{}let a=c(e,n);if(!(a===e||a.startsWith(`${e}${l}`)))return{kind:`forbidden`};try{if(i(a).isFile())return{kind:`file`,path:a,contentType:d[o(a)]??`application/octet-stream`}}catch{}let u=s(e,`index.html`);return r(u)?{kind:`spa`,path:u,contentType:`text/html`}:{kind:`not-found`}}function m(e,t,i){return r(t)?(e.get(`/_dashboard{/*path}`,(e,r)=>{let i=p(t,e.path);if(i.kind===`forbidden`){r.status(403).end(`Forbidden`);return}if(i.kind===`not-found`){r.status(404).end(`Not found`);return}r.setHeader(`Content-Type`,i.contentType),i.kind===`file`&&/\.[a-f0-9]{8,}\.(js|css)$/i.test(i.path)?r.setHeader(`Cache-Control`,`public, max-age=31536000, immutable`):r.setHeader(`Cache-Control`,`no-cache`),n(i.path).pipe(r)}),i.info(`Dashboard available`,{url:`/_dashboard/`,dir:t}),!0):!1}export{m as registerDashboardRoutes,f as resolveDashboardDir,p as resolveDashboardRequest};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e,i as t,n,r,t as i}from"./server-utils-De-aZNQa.js";import{n as a,r as o,t as s}from"./workspace-bootstrap-DTnTU8p2.js";import{t as c}from"./curated-manager-
|
|
1
|
+
import{a as e,i as t,n,r,t as i}from"./server-utils-De-aZNQa.js";import{n as a,r as o,t as s}from"./workspace-bootstrap-DTnTU8p2.js";import{t as c}from"./curated-manager-D4MOFQ-t.js";import{pathToFileURL as l}from"node:url";import{parseArgs as u}from"node:util";import{createLogger as d,serializeError as f}from"../../core/dist/index.js";import{join as p,resolve as m}from"node:path";import{mkdir as h,writeFile as g}from"node:fs/promises";function _(e){if(!e.meta?.title)return`# Diagram
|
|
2
2
|
|
|
3
3
|
*Missing metadata*
|
|
4
4
|
`;if(!e.diagram_type)return`# Diagram
|
|
@@ -351,4 +351,4 @@ svg text{fill:var(--body);font-family:var(--sans);font-size:12px}
|
|
|
351
351
|
<\/script>
|
|
352
352
|
</body>
|
|
353
353
|
</html>`}const U=`<!-- DIAGRAM:SVG -->`;function W(e){let t=e.indexOf(U);if(t===-1)return null;let n=t+20,r=e.indexOf(U,n);if(r===-1)return null;let i=e.slice(n,r).trim();if(i.startsWith(`<svg`))return i;let a=e.slice(Math.max(0,t),r+20),o=a.match(/viewBox="([^"]+)"/),s=o?o[1]:`0 0 1200 800`,c=a.match(/width="(\d+)"/),l=c?c[1]:`1200`,u=a.match(/height="(\d+)"/);return[`<svg xmlns="http://www.w3.org/2000/svg" viewBox="${s}" width="${l}" height="${u?u[1]:`800`}">`,` <defs>`,` <style>`,` text { font-family: system-ui, -apple-system, sans-serif; }`,` .title { font-size: 20px; font-weight: 600; fill: #fff; }`,` .subtitle { font-size: 14px; fill: #94a3b8; }`,` </style>`,` </defs>`,i,`</svg>`].join(`
|
|
354
|
-
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-
|
|
354
|
+
`)}function he(e){let t=e.match(/<title>([^<]+)<\/title>/);return t?t[1]:`diagram`}async function ge(e,t,n){let r=m(n);await h(r,{recursive:!0});let i=he(e).replace(/[^a-zA-Z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase().slice(0,80)||`diagram`,a=p(r,`${i}.html`);await g(a,e,`utf-8`);let o=null,s=W(e);s&&(o=p(r,`${i}.svg`),await g(o,s,`utf-8`));let c=null;return t&&(c=p(r,`${i}.md`),await g(c,t,`utf-8`)),{htmlPath:a,svgPath:o,mdPath:c}}const G=10*1024*1024,K=2e3;function _e(e){try{return JSON.stringify(e)}catch{return``}}function ve(e){switch(e.diagram_type){case`architecture`:return ae(e);case`workflow`:return H(e);case`sequence`:return R(e);case`dataflow`:return ce(e);case`lifecycle`:return P(e)}}function q(e,t={}){Y(e);let n=J(e);if(n.length>0)throw Error(`Diagram validation failed: ${n.join(`; `)}`);let r=t.title??e.meta.title,i=t.subtitle??e.meta.subtitle,a=t.dualOutput??!0,{svg:o,cardsHtml:s,detailData:c}=ve(e),l=c&&Object.keys(c).length>0?`\n<script id="diagram-node-data" type="application/json">${_e(c)}<\/script>`:``,u=e.meta?.palette===`warm`?`warm`:`technical`;return{html:me().replaceAll(`[TITLE]`,X(r)).replaceAll(`[SUBTITLE]`,X(i??``)).replaceAll(`[PALETTE]`,u===`warm`?` data-palette="warm"`:``).replaceAll(`<!-- DIAGRAM:SVG -->`,o).replaceAll(`<!-- DIAGRAM:CARDS -->`,s).replace(`</body>`,`${l}\n</body>`),markdown:a?_(e):void 0}}function ye(e,t={}){return q(e,{...t,dualOutput:!1}).html}function be(e){return _(e)}function xe(e){try{return Y(e),J(e)}catch(e){return[e.message]}}function J(e){if(!e||typeof e!=`object`)return[`Input must be an object`];if(!e.diagram_type)return[`Missing diagram_type`];if(!e.meta?.title)return[`meta.title is required`];if(e.schema_version!==1)return[`schema_version must be 1`];let t=e.diagram_type,n=e,r=n.components??n.nodes??n.participants??n.states??[],i=n.connections??n.edges??n.messages??n.flows??n.transitions??[],a=new Set(r.map(e=>e.id));if(a.size!==r.length)return[`${t}: Node/component IDs must be unique`];for(let e of i){if(e.from&&!a.has(e.from))return[`${t}: Edge references unknown source "${e.from}"`];if(e.to&&!a.has(e.to))return[`${t}: Edge references unknown target "${e.to}"`]}return[]}function Y(e){let t=JSON.stringify(e),n=Buffer.byteLength(t,`utf-8`);if(n>G)throw Error(`Input too large: ${(n/1024/1024).toFixed(1)}MB (max ${G/1024/1024}MB)`);let r=e,i=r.components??r.nodes??r.participants??[];if(i.length>500)throw Error(`Too many components/nodes: ${i.length} (max 500)`);let a=r.connections??r.edges??r.messages??r.flows??r.transitions??[];if(a.length>K)throw Error(`Too many edges/connections: ${a.length} (max ${K})`)}function Se(e){return e.replace(/[^a-zA-Z0-9-_]/g,`_`).toLowerCase().slice(0,120)}function X(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return String(e??``).replace(/[&<>"']/g,e=>t[e]??e)}const Z=d(`server`);function Q(e,t){return t?{version:e,...f(t)}:{version:e}}function $(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}function Ce(){let e=process.argv[1];if(!e)return!1;try{return import.meta.url===l(e).href}catch{return!1}}function we(){return Ce()?u({allowPositionals:!0,options:{transport:{type:`string`,default:$()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}).values:{transport:$(),port:process.env.AIKIT_PORT??`3210`}}async function Te(){let e=t=>{t.name===`ExperimentalWarning`&&t.message.includes(`SQLite`)||(process.off(`warning`,e),process.emitWarning(t),process.on(`warning`,e))};process.on(`warning`,e);let n=t(),r=we();if(process.on(`unhandledRejection`,e=>{Z.error(`Unhandled rejection`,Q(n,e))}),process.on(`uncaughtException`,e=>{Z.error(`Uncaught exception — exiting`,Q(n,e)),process.exit(1)}),Z.info(`Starting MCP AI Kit server`,{version:n}),r.transport===`http`){let{startHttpMode:e}=await import(`./server-http-DcgFpWra.js`);await e(n,r.port)}else{let{startStdioMode:e}=await import(`./server-stdio-CskpvBew.js`);await e(n)}}export{c as CuratedKnowledgeManager,s as applyWorkspaceRoots,a as bootstrapWorkspaceRoots,i as createSlidingWindowRateLimiter,ge as exportDiagram,W as extractSvg,n as getSessionIdHeader,Te as main,r as readPositiveIntEnv,t as readVersion,ye as renderHtml,be as renderMd,q as renderToResult,e as resolveCorsOrigin,Se as sanitizeTitle,o as selectWorkspaceRoot,xe as validate};
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
import{createLogger as e}from"../../core/dist/index.js";import{randomUUID as t}from"node:crypto";const n=e(`observation-capture`),r=[`check`,`test_run`,`search`,`trace`],i=[/\bAuthorization\s*:\s*Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,/\bBearer\s+[A-Za-z0-9\-._~+/]+=*/g,/\b(?:sk|ghp|gho|glpat|xoxb|xoxp)-[A-Za-z0-9\-._]{20,}\b/g,/\b(?:token|key|secret|password|auth(?:orization)?)\s*[=:]\s*['"]?[^\s'"&]{8,}/gi,/\b(?:token|key|secret|password|auth(?:orization)?)=[^\s&]+/gi,/\b[A-Z][A-Z0-9_]*(?:PASSWORD|SECRET|TOKEN|AUTH)[A-Z0-9_]*\b\s*[=:]\s*['"]?[^\s'"]+/g,/\b[A-Z][A-Z0-9_]*KEY[A-Z0-9_]*\b\s*[=:]\s*['"]?[^\s'"]{8,}/g,/-----BEGIN [\w\s]+-----[\s\S]*?-----END [\w\s]+-----/g],a=new Set([`env`,`auth`,`config`]),o=2e3,s={enabled:!0,rateLimit:10,captureFrom:[...r],minContentLength:50};var c=class{maxPerMinute;timestamps=[];constructor(e){this.maxPerMinute=e}canCapture(e=Date.now()){return this.prune(e),this.timestamps.length<this.maxPerMinute}record(e=Date.now()){this.prune(e),this.timestamps.push(e)}setLimit(e){this.maxPerMinute=e,this.prune(Date.now())}prune(e){let t=e-6e4;this.timestamps=this.timestamps.filter(e=>e>t)}};function l(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function u(e){return typeof e==`string`?e:l(e)?[Array.isArray(e.content)?e.content.filter(e=>l(e)).map(e=>typeof e.text==`string`?e.text:``).filter(e=>e.length>0).join(`
|
|
3
3
|
`):``,e.structuredContent==null?``:JSON.stringify(e.structuredContent,null,2)].filter(e=>e.length>0).join(`
|
|
4
4
|
|
|
5
|
-
`):JSON.stringify(e)}function d(e,t=500){return e.length<=t?e:e.slice(0,t)}function f(e){let t=e.toLowerCase();return[...a].some(e=>t===e||t.includes(e))}function p(e){let t=e;for(let e of i)t=t.replace(e,`[REDACTED]`);return t.length>o&&(t=`${t.slice(0,o)}\n...[truncated]`),t}function m(e,t){let n=t?.args??{},r=[];switch(t?.workspace&&r.push(`workspace=${t.workspace}`),e){case`check`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`test_run`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),typeof n.grep==`string`&&r.push(`grep=${n.grep}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`search`:typeof n.query==`string`&&r.push(`query=${n.query}`);break;case`trace`:typeof n.start==`string`&&r.push(`start=${n.start}`),typeof n.direction==`string`&&r.push(`direction=${n.direction}`);break;default:break}return r.length>0?r.join(` | `):void 0}var h=class{stateStore;curatedStore;rateLimiter;config;constructor(e,t,n){this.stateStore=e,this.curatedStore=t,this.config={...s,...n,captureFrom:n?.captureFrom?[...n.captureFrom]:[...r]},this.rateLimiter=new c(this.config.rateLimit)}getConfig(){return{...this.config,captureFrom:[...this.config.captureFrom]}}updateConfig(e){this.config={...this.config,...e,captureFrom:e.captureFrom?[...e.captureFrom]:[...this.config.captureFrom]},e.rateLimit!==void 0&&this.rateLimiter.setLimit(e.rateLimit)}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}registerTool(e){this.config.captureFrom.includes(e)||this.config.captureFrom.push(e)}unregisterTool(e){this.config.captureFrom=this.config.captureFrom.filter(t=>t!==e)}async processToolResult(e,t,r){if(!this.config.enabled||f(e)||!this.config.captureFrom.includes(e)||!this.rateLimiter.canCapture())return null;let i=this.extractObservation(e,t,r);if(!i)return null;let a=p(i.content).trim();if(a.length<this.config.minContentLength)return null;let o={...i,content:d(a).trim()},s={...o,content:a};this.rateLimiter.record();try{await this.storeObservation(s)}catch(t){n.warn(`Failed to store observation`,{toolName:e,error:t instanceof Error?t.message:String(t)})}return o}extractObservation(e,t,n){let r=u(t);if(r.trim().length===0)return null;switch(e){case`check`:return this.extractFromCheck(t,r,n);case`test_run`:return this.extractFromTestRun(t,r,n);case`search`:return this.extractFromSearch(r,n);case`trace`:return this.extractFromTrace(r,n);default:return null}}extractFromCheck(e,t,n){return l(e)&&e.isError===!0||/\berror\b/i.test(t)||/failed/i.test(t)?this.buildObservation(`check`,`error`,t,n):null}extractFromTestRun(e,t,n){let r=l(e)&&l(e.structuredContent)?e.structuredContent:void 0,i=typeof r?.failedTests==`number`?r.failedTests:void 0
|
|
5
|
+
`):JSON.stringify(e)}function d(e,t=500){return e.length<=t?e:e.slice(0,t)}function f(e){let t=e.toLowerCase();return[...a].some(e=>t===e||t.includes(e))}function p(e){let t=e;for(let e of i)t=t.replace(e,`[REDACTED]`);return t.length>o&&(t=`${t.slice(0,o)}\n...[truncated]`),t}function m(e,t){let n=t?.args??{},r=[];switch(t?.workspace&&r.push(`workspace=${t.workspace}`),e){case`check`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`test_run`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),typeof n.grep==`string`&&r.push(`grep=${n.grep}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`search`:typeof n.query==`string`&&r.push(`query=${n.query}`);break;case`trace`:typeof n.start==`string`&&r.push(`start=${n.start}`),typeof n.direction==`string`&&r.push(`direction=${n.direction}`);break;default:break}return r.length>0?r.join(` | `):void 0}var h=class{stateStore;curatedStore;rateLimiter;config;constructor(e,t,n){this.stateStore=e,this.curatedStore=t,this.config={...s,...n,captureFrom:n?.captureFrom?[...n.captureFrom]:[...r]},this.rateLimiter=new c(this.config.rateLimit)}getConfig(){return{...this.config,captureFrom:[...this.config.captureFrom]}}updateConfig(e){this.config={...this.config,...e,captureFrom:e.captureFrom?[...e.captureFrom]:[...this.config.captureFrom]},e.rateLimit!==void 0&&this.rateLimiter.setLimit(e.rateLimit)}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}registerTool(e){this.config.captureFrom.includes(e)||this.config.captureFrom.push(e)}unregisterTool(e){this.config.captureFrom=this.config.captureFrom.filter(t=>t!==e)}async processToolResult(e,t,r){if(!this.config.enabled||f(e)||!this.config.captureFrom.includes(e)||!this.rateLimiter.canCapture())return null;let i=this.extractObservation(e,t,r);if(!i)return null;let a=p(i.content).trim();if(a.length<this.config.minContentLength)return null;let o={...i,content:d(a).trim()},s={...o,content:a};this.rateLimiter.record();try{await this.storeObservation(s)}catch(t){n.warn(`Failed to store observation`,{toolName:e,error:t instanceof Error?t.message:String(t)})}return o}extractObservation(e,t,n){let r=u(t);if(r.trim().length===0)return null;switch(e){case`check`:return this.extractFromCheck(t,r,n);case`test_run`:return this.extractFromTestRun(t,r,n);case`search`:return this.extractFromSearch(r,n);case`trace`:return this.extractFromTrace(r,n);default:return null}}extractFromCheck(e,t,n){return l(e)&&e.isError===!0||/\berror\b/i.test(t)||/failed/i.test(t)?this.buildObservation(`check`,`error`,t,n):null}extractFromTestRun(e,t,n){let r=l(e)&&l(e.structuredContent)?e.structuredContent:void 0,i=typeof r?.failedTests==`number`?r.failedTests:void 0,a=typeof i==`number`;return l(e)&&e.isError===!0||a&&i>0||!a&&(/\bFAIL\b/.test(t)||/\btest.*failed\b/i.test(t))?this.buildObservation(`test_run`,`test_failure`,t,n):null}extractFromSearch(e,t){if(!/\b(convention|pattern)\b/i.test(e))return null;let n=/\bconvention\b/i.test(e)?`convention`:`pattern`;return this.buildObservation(`search`,n,e,t)}extractFromTrace(e,t){return this.buildObservation(`trace`,`insight`,e,t)}buildObservation(e,n,r,i){return{id:t(),source:e,type:n,content:r,context:m(e,i),timestamp:new Date().toISOString()}}async storeObservation(e){let t=`Observation ${e.source} ${e.type} ${e.timestamp}`,n=[`Source: ${e.source}`,`Type: ${e.type}`,`Captured: ${e.timestamp}`,e.context?`Context: ${e.context}`:null,``,e.content].filter(e=>e!==null).join(`
|
|
6
6
|
`),r=await this.curatedStore.remember(t,n,`context`,[`observation`,`source-${e.source}`,`type-${e.type}`]);this.stateStore.memoryMetaCreate(r.path,`working`)}};export{s as DEFAULT_OBSERVATION_CONFIG,h as ObservationEngine};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{createLogger as e}from"../../core/dist/index.js";import{randomUUID as t}from"node:crypto";const n=e(`observation-capture`),r=[`check`,`test_run`,`search`,`trace`],i=[/\bAuthorization\s*:\s*Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,/\bBearer\s+[A-Za-z0-9\-._~+/]+=*/g,/\b(?:sk|ghp|gho|glpat|xoxb|xoxp)-[A-Za-z0-9\-._]{20,}\b/g,/\b(?:token|key|secret|password|auth(?:orization)?)\s*[=:]\s*['"]?[^\s'"&]{8,}/gi,/\b(?:token|key|secret|password|auth(?:orization)?)=[^\s&]+/gi,/\b[A-Z][A-Z0-9_]*(?:PASSWORD|SECRET|TOKEN|AUTH)[A-Z0-9_]*\b\s*[=:]\s*['"]?[^\s'"]+/g,/\b[A-Z][A-Z0-9_]*KEY[A-Z0-9_]*\b\s*[=:]\s*['"]?[^\s'"]{8,}/g,/-----BEGIN [\w\s]+-----[\s\S]*?-----END [\w\s]+-----/g],a=new Set([`env`,`auth`,`config`]),o=2e3,s={enabled:!0,rateLimit:10,captureFrom:[...r],minContentLength:50};var c=class{maxPerMinute;timestamps=[];constructor(e){this.maxPerMinute=e}canCapture(e=Date.now()){return this.prune(e),this.timestamps.length<this.maxPerMinute}record(e=Date.now()){this.prune(e),this.timestamps.push(e)}setLimit(e){this.maxPerMinute=e,this.prune(Date.now())}prune(e){let t=e-6e4;this.timestamps=this.timestamps.filter(e=>e>t)}};function l(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function u(e){return typeof e==`string`?e:l(e)?[Array.isArray(e.content)?e.content.filter(e=>l(e)).map(e=>typeof e.text==`string`?e.text:``).filter(e=>e.length>0).join(`
|
|
2
2
|
`):``,e.structuredContent==null?``:JSON.stringify(e.structuredContent,null,2)].filter(e=>e.length>0).join(`
|
|
3
3
|
|
|
4
|
-
`):JSON.stringify(e)}function d(e,t=500){return e.length<=t?e:e.slice(0,t)}function f(e){let t=e.toLowerCase();return[...a].some(e=>t===e||t.includes(e))}function p(e){let t=e;for(let e of i)t=t.replace(e,`[REDACTED]`);return t.length>o&&(t=`${t.slice(0,o)}\n...[truncated]`),t}function m(e,t){let n=t?.args??{},r=[];switch(t?.workspace&&r.push(`workspace=${t.workspace}`),e){case`check`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`test_run`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),typeof n.grep==`string`&&r.push(`grep=${n.grep}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`search`:typeof n.query==`string`&&r.push(`query=${n.query}`);break;case`trace`:typeof n.start==`string`&&r.push(`start=${n.start}`),typeof n.direction==`string`&&r.push(`direction=${n.direction}`);break;default:break}return r.length>0?r.join(` | `):void 0}var h=class{stateStore;curatedStore;rateLimiter;config;constructor(e,t,n){this.stateStore=e,this.curatedStore=t,this.config={...s,...n,captureFrom:n?.captureFrom?[...n.captureFrom]:[...r]},this.rateLimiter=new c(this.config.rateLimit)}getConfig(){return{...this.config,captureFrom:[...this.config.captureFrom]}}updateConfig(e){this.config={...this.config,...e,captureFrom:e.captureFrom?[...e.captureFrom]:[...this.config.captureFrom]},e.rateLimit!==void 0&&this.rateLimiter.setLimit(e.rateLimit)}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}registerTool(e){this.config.captureFrom.includes(e)||this.config.captureFrom.push(e)}unregisterTool(e){this.config.captureFrom=this.config.captureFrom.filter(t=>t!==e)}async processToolResult(e,t,r){if(!this.config.enabled||f(e)||!this.config.captureFrom.includes(e)||!this.rateLimiter.canCapture())return null;let i=this.extractObservation(e,t,r);if(!i)return null;let a=p(i.content).trim();if(a.length<this.config.minContentLength)return null;let o={...i,content:d(a).trim()},s={...o,content:a};this.rateLimiter.record();try{await this.storeObservation(s)}catch(t){n.warn(`Failed to store observation`,{toolName:e,error:t instanceof Error?t.message:String(t)})}return o}extractObservation(e,t,n){let r=u(t);if(r.trim().length===0)return null;switch(e){case`check`:return this.extractFromCheck(t,r,n);case`test_run`:return this.extractFromTestRun(t,r,n);case`search`:return this.extractFromSearch(r,n);case`trace`:return this.extractFromTrace(r,n);default:return null}}extractFromCheck(e,t,n){return l(e)&&e.isError===!0||/\berror\b/i.test(t)||/failed/i.test(t)?this.buildObservation(`check`,`error`,t,n):null}extractFromTestRun(e,t,n){let r=l(e)&&l(e.structuredContent)?e.structuredContent:void 0,i=typeof r?.failedTests==`number`?r.failedTests:void 0
|
|
4
|
+
`):JSON.stringify(e)}function d(e,t=500){return e.length<=t?e:e.slice(0,t)}function f(e){let t=e.toLowerCase();return[...a].some(e=>t===e||t.includes(e))}function p(e){let t=e;for(let e of i)t=t.replace(e,`[REDACTED]`);return t.length>o&&(t=`${t.slice(0,o)}\n...[truncated]`),t}function m(e,t){let n=t?.args??{},r=[];switch(t?.workspace&&r.push(`workspace=${t.workspace}`),e){case`check`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`test_run`:typeof n.cwd==`string`&&r.push(`cwd=${n.cwd}`),typeof n.grep==`string`&&r.push(`grep=${n.grep}`),Array.isArray(n.files)&&n.files.length>0&&r.push(`files=${n.files.join(`, `)}`);break;case`search`:typeof n.query==`string`&&r.push(`query=${n.query}`);break;case`trace`:typeof n.start==`string`&&r.push(`start=${n.start}`),typeof n.direction==`string`&&r.push(`direction=${n.direction}`);break;default:break}return r.length>0?r.join(` | `):void 0}var h=class{stateStore;curatedStore;rateLimiter;config;constructor(e,t,n){this.stateStore=e,this.curatedStore=t,this.config={...s,...n,captureFrom:n?.captureFrom?[...n.captureFrom]:[...r]},this.rateLimiter=new c(this.config.rateLimit)}getConfig(){return{...this.config,captureFrom:[...this.config.captureFrom]}}updateConfig(e){this.config={...this.config,...e,captureFrom:e.captureFrom?[...e.captureFrom]:[...this.config.captureFrom]},e.rateLimit!==void 0&&this.rateLimiter.setLimit(e.rateLimit)}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}registerTool(e){this.config.captureFrom.includes(e)||this.config.captureFrom.push(e)}unregisterTool(e){this.config.captureFrom=this.config.captureFrom.filter(t=>t!==e)}async processToolResult(e,t,r){if(!this.config.enabled||f(e)||!this.config.captureFrom.includes(e)||!this.rateLimiter.canCapture())return null;let i=this.extractObservation(e,t,r);if(!i)return null;let a=p(i.content).trim();if(a.length<this.config.minContentLength)return null;let o={...i,content:d(a).trim()},s={...o,content:a};this.rateLimiter.record();try{await this.storeObservation(s)}catch(t){n.warn(`Failed to store observation`,{toolName:e,error:t instanceof Error?t.message:String(t)})}return o}extractObservation(e,t,n){let r=u(t);if(r.trim().length===0)return null;switch(e){case`check`:return this.extractFromCheck(t,r,n);case`test_run`:return this.extractFromTestRun(t,r,n);case`search`:return this.extractFromSearch(r,n);case`trace`:return this.extractFromTrace(r,n);default:return null}}extractFromCheck(e,t,n){return l(e)&&e.isError===!0||/\berror\b/i.test(t)||/failed/i.test(t)?this.buildObservation(`check`,`error`,t,n):null}extractFromTestRun(e,t,n){let r=l(e)&&l(e.structuredContent)?e.structuredContent:void 0,i=typeof r?.failedTests==`number`?r.failedTests:void 0,a=typeof i==`number`;return l(e)&&e.isError===!0||a&&i>0||!a&&(/\bFAIL\b/.test(t)||/\btest.*failed\b/i.test(t))?this.buildObservation(`test_run`,`test_failure`,t,n):null}extractFromSearch(e,t){if(!/\b(convention|pattern)\b/i.test(e))return null;let n=/\bconvention\b/i.test(e)?`convention`:`pattern`;return this.buildObservation(`search`,n,e,t)}extractFromTrace(e,t){return this.buildObservation(`trace`,`insight`,e,t)}buildObservation(e,n,r,i){return{id:t(),source:e,type:n,content:r,context:m(e,i),timestamp:new Date().toISOString()}}async storeObservation(e){let t=`Observation ${e.source} ${e.type} ${e.timestamp}`,n=[`Source: ${e.source}`,`Type: ${e.type}`,`Captured: ${e.timestamp}`,e.context?`Context: ${e.context}`:null,``,e.content].filter(e=>e!==null).join(`
|
|
5
5
|
`),r=await this.curatedStore.remember(t,n,`context`,[`observation`,`source-${e.source}`,`type-${e.type}`]);this.stateStore.memoryMetaCreate(r.path,`working`)}};export{s as DEFAULT_OBSERVATION_CONFIG,h as ObservationEngine};
|