toolnet-memory 0.2.2 → 0.2.3
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/bundle/agy.js +20 -20
- package/bundle/codex.js +33 -33
- package/bundle/context-runtime.js +9 -9
- package/bundle/context.js +12 -12
- package/bundle/doctor.js +2 -2
- package/bundle/full-index.js +8 -8
- package/bundle/learner.js +4 -4
- package/bundle/mcp.js +6 -6
- package/bundle/opencode.js +36 -36
- package/bundle/project-manual.js +7 -7
- package/bundle/snapshot.js +3 -3
- package/bundle/work-continuity.js +4 -4
- package/package.json +1 -1
package/bundle/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import"dotenv/config";import{existsSync as sr,readFileSync as nr}from"node:fs";import{homedir as ir}from"node:os";import{join as ar}from"node:path";function cr(o){let e=o.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function lr(){let o=process.env.TOOLNET_GLOBAL_ENV??ar(ir(),".config","toolnet-memory",".env");if(!sr(o))return;let e=nr(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let n=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=cr(r.slice(s+1)))}}lr();function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),ur(s,r)}function
|
|
4
|
-
`)}};var
|
|
5
|
-
`).trim();if(g){let h=this.sanitizer.sanitize(g).text,C=Ye(h),w=[t,r,n?.id??"file",String(d),C].join(":");p.push({id:Ye(w).slice(0,32),projectId:t,filePath:r,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:
|
|
6
|
-
`)),or=await s.embedMany(rr);for(let x=0;x<T.length;x++){let P=T[x],M=or[x];if(!(!P||!M||M.length===0)){if(R===void 0&&(R=M.length),M.length!==R){console.warn(`[code-semantic] skip dimension mismatch: ${M.length} != ${R}`);continue}this.vectors.upsert({id:P.id,projectId:e,vector:M,metadata:{contentHash:P.contentHash,filePath:P.filePath,symbolName:P.symbolName,symbolType:P.symbolType,startLine:P.startLine,endLine:P.endLine}}),w++}}}let be=this.vectors.exportProject(e),Ne=w>0||h>0||!d||d.model!==i;return Ne&&await c.save({version:1,projectId:e,model:i,dimensions:be[0]?.vector.length??R??0,updatedAt:new Date().toISOString(),records:be}),{chunks:l.length,vectorsLoaded:m,vectorsIndexed:w,vectorsRemoved:h,totalVectors:be.length,savedChunks:f,savedVectors:Ne}}async search(e,t=8){let r=await this.options.embeddings.embed(e),s=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),n=new Set(L(e)),i=[];for(let a of s){let c=this.chunks.get(a.id);if(!c)continue;let l=new Set(L([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),p=0;for(let h of n)l.has(h)&&p++;let f=n.size===0?0:p/n.size,d=Math.max(0,a.score),m=Qe(c.filePath,e),g=(d*.75+f*.25)*m;i.push({chunk:c,score:g,vectorScore:d,lexicalScore:f})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}};import di from"typescript";import v from"typescript";var yi=new Set([v.SyntaxKind.EqualsToken,v.SyntaxKind.PlusEqualsToken,v.SyntaxKind.MinusEqualsToken,v.SyntaxKind.AsteriskEqualsToken,v.SyntaxKind.SlashEqualsToken,v.SyntaxKind.PercentEqualsToken,v.SyntaxKind.QuestionQuestionEqualsToken,v.SyntaxKind.AmpersandAmpersandEqualsToken,v.SyntaxKind.BarBarEqualsToken]);function Jr(o){return o.replaceAll("\\","/").toLowerCase()}var _=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,r);a&&s.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let n=new Map;for(let i of s){let a=i.kind==="route"?i.symbolId:i.filePath,c=n.get(a);(!c||i.score>c.score)&&n.set(a,i)}return[...n.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let r=Jr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let n=null,i=0;if(r.startsWith("bin/"))n="cli",i=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))n="cli",i=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))n="main",i=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))n="runtime",i=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let c=t.filter(p=>p.to===e.id&&p.type!=="DEFINES").length,l=t.filter(p=>p.from===e.id&&p.type!=="DEFINES").length;(r.startsWith("packages/")||c===0||l>0)&&(n="package",i=r.startsWith("packages/")?70:55,s.push("package/public index"))}return n?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,s.push("no incoming dependency")),{kind:n,score:i,reasons:s}):null}};var ue=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Ze=new Set(["CALLS","CALL_REFERENCE"]),b=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let r=t.trim().toLowerCase();return r?this.graph.allSymbols(e).filter(s=>s.name.toLowerCase().includes(r)||(s.qualifiedName?.toLowerCase().includes(r)??!1)||s.filePath.toLowerCase().includes(r)).sort((s,n)=>{let i=s.name.toLowerCase()===r,a=n.name.toLowerCase()===r;return i!==a?i?-1:1:s.filePath.localeCompare(n.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Ze)}callees(e,t){return this.relatedOutgoing(e,t,Ze)}dependents(e,t){return this.relatedIncoming(e,t,ue)}dependencies(e,t){return this.relatedOutgoing(e,t,ue)}neighborhood(e,t,r=1){let s=this.graph.getSymbol(t);return!s||s.projectId!==e?null:{center:s,incoming:this.walk(e,t,"incoming",r),outgoing:this.walk(e,t,"outgoing",r)}}shortestPath(e,t,r,s=12){let n=this.graph.getSymbol(t),i=this.graph.getSymbol(r);if(!n||!i||n.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===r)return{found:!0,distance:0,symbols:[n],edges:[]};let a=this.graph.allEdges(e).filter(d=>ue.has(d.type)),c=new Map;for(let d of a){let m=c.get(d.from)??[];m.push(d),c.set(d.from,m)}let l=[{id:t,depth:0}],p=new Set([t]),f=new Map;for(;l.length>0;){let d=l.shift();if(!(d.depth>=s)){for(let m of c.get(d.id)??[])if(!p.has(m.to)){if(p.add(m.to),f.set(m.to,{node:d.id,edge:m}),m.to===r)return this.buildPath(t,r,f);l.push({id:m.to,depth:d.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,r){let s=[t],n=[],i=t;for(;i!==e;){let c=r.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};n.push(c.edge),i=c.node,s.push(i)}s.reverse(),n.reverse();let a=s.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:n.length,symbols:a,edges:n}}walk(e,t,r,s){let n=this.graph.allEdges(e).filter(l=>ue.has(l.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let l=i.shift();if(!(l.depth>=s))for(let p of n){if(!(r==="incoming"?p.to===l.id:p.from===l.id))continue;let d=r==="incoming"?p.from:p.to;if(a.has(d))continue;let m=this.graph.getSymbol(d);m&&(a.add(d),c.push({symbol:m,depth:l.depth+1,via:p}),i.push({id:d,depth:l.depth+1}))}}return c}relatedIncoming(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.to===t&&r.has(n.type)).map(n=>n.from))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}relatedOutgoing(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.from===t&&r.has(n.type)).map(n=>n.to))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}};var Xe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function je(o){return o.replaceAll("\\","/").toLowerCase()}function Yr(o){let e=je(o);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Qr(o){let e=je(o.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var F=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new _(this.graph).detect(e).map(i=>i.symbolId)),n=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Yr(i.filePath)||s.has(i.id)||Qr(i)||r.filter(m=>m.to===i.id&&Xe.has(m.type)).length>0)continue;let c=r.filter(m=>m.from===i.id&&Xe.has(m.type)),l=["no incoming usage edge"],p=50;(i.type==="function"||i.type==="method")&&(p+=20,l.push("callable symbol")),i.type==="property"&&(p-=15),c.length===0&&(p+=10,l.push("no outgoing dependency")),je(i.filePath).includes("/internal/")&&(p+=10,l.push("internal implementation")),i.name.startsWith("_")&&(p+=5);let d=p>=75?"high":p>=55?"medium":"low";n.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:d,score:p,reasons:l})}return n.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var Zr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),$=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(i=>Zr.has(i.type)),s=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,l=0,p=0;for(let f of r){let d=s.get(f.from),m=s.get(f.to);!d||!m||d.filePath===m.filePath||(d.filePath===i&&(a.add(m.filePath),l++),m.filePath===i&&(c.add(d.filePath),p++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:l,incomingEdges:p}})}};import{homedir as go}from"node:os";import{join as ho}from"node:path";import{DeleteObjectCommand as Xr,GetObjectCommand as eo,HeadObjectCommand as to,ListObjectsV2Command as ro,PutObjectCommand as oo,S3Client as so}from"@aws-sdk/client-s3";import{getSignedUrl as no}from"@aws-sdk/s3-request-presigner";var ge=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new so({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new oo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await no(this.client,new eo({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new to({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Xr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new ro({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as et,mkdir as io,readFile as ao,readdir as co,rm as lo,stat as tt,writeFile as po}from"node:fs/promises";import{dirname as mo,join as fo,relative as rt,resolve as uo}from"node:path";var D=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return uo(this.root,t)}async put(e,t){let r=this.path(e);await io(mo(r),{recursive:!0}),await po(r,t)}async get(e){try{return await ao(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await et(this.path(e)),!0}catch{return!1}}async delete(e){await lo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await et(t)}catch{return r}let s=async i=>{let a=await co(i,{withFileTypes:!0});for(let c of a){let l=fo(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await tt(l);r.push({key:rt(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await tt(t);return n.isDirectory()?await s(t):r.push({key:rt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function ot(o){let e=o.localRoot??ho(go(),".toolnet-memory","storage");if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new ge({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new D(e))}return new D(e)}var he=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};function yo(o){return new Promise(e=>setTimeout(e,o))}async function st(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await yo(c+l)}throw n}var So=new Set(["put","get","getText","delete","list"]);function nt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:So.has(r)?(...n)=>st(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function it(o){let e=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function at(o){let e=o.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var ye=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=it(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
|
|
7
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=at(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{McpServer as jo}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Ro}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as ct}from"zod";var lt={query:ct.string(),limit:ct.number().int().min(1).max(20).optional()};async function pt(o,e){return o.retrieval.search(o.project.id,e.query,{topK:e.limit??8}).map(r=>({id:r.memory.id,type:r.memory.type,content:r.memory.content,importance:r.memory.importance,score:r.score,tags:r.memory.tags}))}import{z as G}from"zod";var dt={type:G.enum(["activity","decision","rule","todo","summary"]),content:G.string().min(1),tags:G.array(G.string()).optional(),importance:G.enum(["critical","high","normal","temporary"]).optional()};async function mt(o,e){let t=o.memory.remember({projectId:o.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),t}import{z as bo}from"zod";var ft={id:bo.string().min(1)};async function ut(o,e){let t=o.memory.delete(e.id);return t&&o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),{deleted:t}}import{z as xo}from"zod";var gt={name:xo.string().min(1)};async function ht(o,e){return o.graph.findByName(o.project.id,e.name)}import{z as Co}from"zod";function E(o,e){let t=o.graph.getSymbol(e);if(t&&t.projectId===o.project.id)return t;let r=new b(o.graph),s=r.findSymbols(o.project.id,e).find(n=>n.name===e||n.qualifiedName===e);return s||(r.findSymbols(o.project.id,e)[0]??null)}function S(o){return{id:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,endLine:o.endLine}}var yt={symbolId:Co.string().min(1)};async function St(o,e){let t=E(o,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let s=new b(o.graph).callers(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,callers:s.map(S)}}import{z as bt}from"zod";var xt={query:bt.string().min(1),limit:bt.number().int().min(1).max(50).optional()};async function Ct(o,e){let t=e.query.toLowerCase(),r=e.limit??20;return o.graph.allSymbols(o.project.id).filter(s=>s.name.toLowerCase().includes(t)||s.qualifiedName?.toLowerCase().includes(t)||s.filePath.toLowerCase().includes(t)).slice(0,r)}import{z as wt}from"zod";var vt={query:wt.string().optional(),memoryLimit:wt.number().int().min(1).max(20).optional()};async function Et(o,e){let t=re(o.graph,o.project.id),r=o.memory.recent(o.project.id,5),s=e.query?o.retrieval.search(o.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:t,recent:r,relevant:s.map(n=>n.memory)}}import{z as vo}from"zod";var wo=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],j=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of wo){let f=`${i}/${p}`,d=await this.storage.get(f);d&&(await this.storage.put(`${a}/${p}`,d,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};var Pt={reason:vo.string().optional()};async function jt(o,e){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).create(o.project.id,e.reason??"manual-mcp")}async function Rt(o){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).list(o.project.id)}import{z as Eo}from"zod";var Tt={snapshotId:Eo.string().min(1)};async function Mt(o,e){if(!o.storage)throw new Error("Storage unavailable");let t=new j(o.storage);return await t.create(o.project.id,"before-rollback"),t.restore(o.project.id,e.snapshotId)}import{z as Re}from"zod";var kt={symbolId:Re.string().min(1),direction:Re.enum(["callers","callees"]).optional(),depth:Re.number().int().min(1).max(10).optional()};async function Lt(o,e){let t=new oe(o.graph),r=e.direction??"callees",s=e.depth??3,n=r==="callers"?t.callers(o.project.id,e.symbolId,s):t.callees(o.project.id,e.symbolId,s);return{direction:r,depth:s,results:n.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as Nt}from"zod";var At={symbolId:Nt.string().min(1),depth:Nt.number().int().min(1).max(10).optional()};async function It(o,e){let t=o.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let s=new ne(o.graph).analyze(o.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:s.map(n=>({id:n.symbol.id,name:n.symbol.name,qualifiedName:n.symbol.qualifiedName,filePath:n.symbol.filePath,type:n.symbol.type,relation:n.relation,depth:n.depth}))}}async function Ot(o){return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:re(o.graph,o.project.id)}}import{z as _t}from"zod";var Ft={filePath:_t.string().min(1),direction:_t.enum(["dependencies","dependents","both"]).optional()};async function $t(o,e){let r=new $(o.graph).analyze(o.project.id).find(c=>c.filePath===e.filePath);if(!r)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let s=o.graph.allSymbols(o.project.id).filter(c=>c.type==="file"),n=new Map(s.map(c=>[c.filePath,c])),i=c=>({id:n.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:r.filePath,outgoingEdges:r.outgoingEdges,incomingEdges:r.incomingEdges,dependencies:a==="dependents"?[]:r.dependencies.map(i),dependents:a==="dependencies"?[]:r.dependents.map(i)}}import{z as Dt}from"zod";var Gt={query:Dt.string().min(1),limit:Dt.number().int().min(1).max(20).optional()};async function zt(o,e){return o.codeSemantic?{available:!0,results:(await o.codeSemantic.search(e.query,e.limit??8)).map(r=>({id:r.chunk.id,filePath:r.chunk.filePath,symbol:r.chunk.symbolName,symbolType:r.chunk.symbolType,startLine:r.chunk.startLine,endLine:r.chunk.endLine,score:r.score,vectorScore:r.vectorScore,lexicalScore:r.lexicalScore,content:r.chunk.content}))}:{available:!1,results:[]}}import{z as Te}from"zod";var Bt={mode:Te.enum(["git_diff","file"]).optional(),filePath:Te.string().optional(),depth:Te.number().int().min(1).max(10).optional()};async function qt(o,e){let t=new ce(o.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(o.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(o.project.id,o.project.rootPath,{maxDepth:e.depth})}import{z as Po}from"zod";var Kt={symbol:Po.string().min(1)};async function Ht(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let s=new b(o.graph).dependents(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,dependents:s.map(S)}}import{z as Me}from"zod";var Wt={from:Me.string().min(1),to:Me.string().min(1),maxDepth:Me.number().int().min(1).max(30).optional()};async function Vt(o,e){let t=E(o,e.from),r=E(o,e.to);if(!t||!r)return{found:!1,fromFound:!!t,toFound:!!r,path:[],edges:[]};let n=new b(o.graph).shortestPath(o.project.id,t.id,r.id,e.maxDepth??12);return{found:n.found,distance:n.distance,from:S(t),to:S(r),path:n.symbols.map(S),edges:n.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as ke}from"zod";var Ut={symbol:ke.string().min(1),depth:ke.number().int().min(1).max(5).optional(),limit:ke.number().int().min(1).max(200).optional()};async function Jt(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol};let s=new b(o.graph).neighborhood(o.project.id,t.id,e.depth??1);if(!s)return{found:!1,query:e.symbol};let n=e.limit??50;return{found:!0,center:S(s.center),incomingCount:s.incoming.length,outgoingCount:s.outgoing.length,incoming:s.incoming.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)})),outgoing:s.outgoing.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)}))}}import{z as Le}from"zod";var Qt={confidence:Le.enum(["high","medium","low","all"]).optional(),filePath:Le.string().min(1).optional(),limit:Le.number().int().min(1).max(500).optional()},Yt={high:3,medium:2,low:1};async function Zt(o,e){let r=new F(o.graph).analyze(o.project.id);if(e.confidence&&e.confidence!=="all"){let i=Yt[e.confidence];r=r.filter(a=>Yt[a.confidence]>=i)}e.filePath&&(r=r.filter(i=>i.filePath===e.filePath));let s=r.length,n=e.limit??100;return{total:s,high:r.filter(i=>i.confidence==="high").length,medium:r.filter(i=>i.confidence==="medium").length,low:r.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:r.slice(0,n)}}function u(o){return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}function To(o){let e=new jo({name:"toolnet-memory",version:"0.1.0"});return e.tool("memory_search","Search relevant long-term memory for the current project.",lt,async t=>u(await pt(o,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",dt,async t=>u(await mt(o,t))),e.tool("memory_forget","Delete a memory by id.",ft,async t=>u(await ut(o,t))),e.tool("find_symbol","Find code symbols by exact name.",gt,async t=>u(await ht(o,t))),e.tool("find_callers","Find functions or methods calling a symbol.",yt,async t=>u(await St(o,t))),e.tool("code_search","Search indexed code symbols and files.",xt,async t=>u(await Ct(o,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",vt,async t=>u(await Et(o,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",kt,async t=>u(await Lt(o,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",At,async t=>u(await It(o,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>u(await Ot(o))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Ft,async t=>u(await $t(o,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Gt,async t=>u(await zt(o,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Pt,async t=>u(await jt(o,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>u(await Rt(o))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Tt,async t=>u(await Mt(o,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",Bt,async t=>u(await qt(o,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Kt,async t=>u(await Ht(o,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Wt,async t=>u(await Vt(o,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Ut,async t=>u(await Jt(o,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Qt,async t=>u(await Zt(o,t))),e}async function Xt(o){let e=To(o),t=new Ro;await e.connect(t)}import{closeSync as Mo,mkdirSync as ko,openSync as Lo,readFileSync as No,unlinkSync as er,writeFileSync as Ao}from"node:fs";import{tmpdir as Io}from"node:os";import{join as tr}from"node:path";function Oo(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var Se=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=tr(Io(),"toolnet-memory-locks");ko(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=tr(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Lo(this.path,"wx");Ao(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Mo(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let s=JSON.parse(No(this.path,"utf8"));Number.isInteger(s.pid)&&Oo(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{er(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{er(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};async function _o(){let o=Ae(),e=new H().detect(),t=ot({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),r=nt(t,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),s=new ye(r,e.id,e.name,e.remote??e.name),n=new Se(e.id);await n.acquire();let i=()=>{n.release().finally(()=>process.exit(0))};process.once("SIGINT",i),process.once("SIGTERM",i);let a=new U,c=new he(s);a.importRecords(await c.load(e.id));let l=new X(a),p=new N,f=await new O(s).load(e.id);f&&p.import(f.symbols,f.edges);let d=new se(p),m=new fe({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Ve(),graph:p});await m.initialize(),await Xt({project:e,memory:a,retrieval:l,graph:p,references:d,codeSemantic:m,memoryStore:c,storage:s})}_o().catch(o=>{console.error(o),process.exit(1)});
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function lr(){let o=process.env.TOOLNET_GLOBAL_ENV??ar(ir(),".config","toolnet-memory",".env");if(!sr(o))return;let e=nr(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let n=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=cr(r.slice(s+1)))}}lr();function q(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function A(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function Ie(){return{memory:{autoCapture:q(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:q(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:q(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:q(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:A(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:A(process.env.MEMORY_RERANK_TOP,10),finalContext:A(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:A(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:A(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var pr={critical:100,high:75,normal:50,temporary:20};function Oe(o){return pr[o]}function _e(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":o==="rule"||o==="decision"?"high":o==="todo"?"normal":o==="activity"||o==="summary"?"temporary":"normal"}import{createHash as dr}from"node:crypto";import{existsSync as Ce,mkdirSync as mr,readFileSync as fr,renameSync as ur,writeFileSync as gr}from"node:fs";import{basename as hr,dirname as K,join as W,parse as De,resolve as I}from"node:path";var Ge=".toolnet",yr="project.json";function Sr(o){return dr("sha256").update(o).digest("hex").slice(0,16)}function we(o){return W(o,Ge,yr)}function br(o){return Ce(we(o))}function xr(o,e){let t=I(o),r=De(t).root;for(;;){if(br(t))return t;if(t===r||e&&t===I(e))break;let s=K(t);if(s===t)break;t=s}return null}function Cr(o){let e=I(o),t=De(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Ce(W(e,n))))return e;if(e===t)break;let s=K(e);if(s===e)break;e=s}return I(o)}function wr(o){let e;try{e=JSON.parse(fr(o,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${o}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:K(K(o)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Fe(o,e){let t=W(o,Ge);mr(t,{recursive:!0});let r=we(o),s=`${r}.tmp-${process.pid}`;gr(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),ur(s,r)}function $e(o,e){return{id:o.id,name:o.name,remote:o.remote,rootPath:e,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var H=class{detect(e=process.cwd()){let t=I(e),r=Cr(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Ce(W(r,p))),i=xr(t,n?r:void 0);if(i){let p=we(i),m=wr(p);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),Fe(i,m)),$e(m,i)}let a=new Date().toISOString(),c=hr(r),l={version:1,id:Sr(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Fe(r,l),$e(l,r)}};import{randomUUID as kr}from"node:crypto";var vr=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],V=class{scan(e){let t=[];for(let r of vr){let s=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(s))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var k=class{scanner=new V;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let n of r)s.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Er=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Pr=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function ze(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Pr.has(e)))}function jr(o,e){let t=ze(o),r=ze(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let n=new Set([...t,...r]).size;return s/n}function Be(o){return new Set(o.tags.filter(e=>!Er.has(e.toLowerCase())))}var U=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=Be(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=Be(n);for(let c of s)if(a.has(c))return!0;return jr(e.content,n.content)>=.6})}};var Rr={critical:100,high:75,normal:50,temporary:20},Tr={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function qe(o,e,t=new Date){let r;if(e==="temporary"&&(r=30),o==="activity"&&(r=Math.min(r??14,14)),o==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function ve(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function Mr(o){return!!o.metadata?.supersededBy}function Ee(o,e=Date.now()){return!ve(o,e)&&!Mr(o)}function O(o,e=Date.now()){if(!Ee(o,e))return 0;let t=Rr[o.importance];if(o.importance==="critical")return t;let r=Tr[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var J=class{memories=new Map;sanitizer=new k;conflicts=new U;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??_e(e.type,r),n={id:kr(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:Oe(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??qe(e.type,s,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Ee(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,s=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=O(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=s.filter(p=>i.includes(p)).length,c=s.length===0?0:a/s.length,l=O(n)/500;return{memory:n,score:c+l,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[s,n]of this.memories)n.projectId===e&&ve(n,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),s++)}return s}clearProject(e){let t=0;for(let[r,s]of this.memories)s.projectId===e&&(this.memories.delete(r),t++);return t}};function L(o){return o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var Y=class{score(e,t){let r=L(e),s=L([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function Ke(o,e=Date.now()){let t=o.updatedAt??o.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let s=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*s/30)}function He(o){return O(o)/100}var Lr={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function We(o){return Lr[o]??.4}var Q=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var Z=class{bm25=new Y;analyzer=new Q;search(e,t,r={}){let s=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=Ke(c),m=He(c),d=We(c.type);i.preferredTypes.includes(c.type)&&(d=Math.min(1,d+.25));let f=l*.55+m*.2+p*.15+d*.1;l<=0||f<n||a.push({memory:c,score:f,scores:{keyword:l,recency:p,importance:m,type:d}})}return a.sort((c,l)=>l.score-c.score).slice(0,s)}};var X=class{build(e,t=6e3){let r=[],s=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(s+a.length>t)break;r.push(a),s+=a.length}return r.join(`
|
|
4
|
+
`)}};var ee=class{constructor(e){this.memory=e}memory;searcher=new Z;contextBuilder=new X;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let s=this.search(e,t,r);return this.contextBuilder.build(s)}};var te=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>Nr(n))}};function Nr(o){if(!Array.isArray(o))throw new Error("Invalid embedding");if(o.length>0&&typeof o[0]=="number")return o;if(o.length>0&&Array.isArray(o[0])){let e=o;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let n=0;n<t;n++)r[n]+=s[n]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as Ar}from"node:crypto";var re=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of r){let i=Ar("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return Ir(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function Ir(o){let e=Math.sqrt(o.reduce((t,r)=>t+r*r,0));return e===0?o:o.map(t=>t/e)}var Pe=class{constructor(e,t=new re){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Ve(){let o=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=o?new te({token:o,model:e}):null;return new Pe(t)}import Hs from"typescript";var N=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function oe(o,e){let t=o.allSymbols(e),r=o.allEdges(e),s=i=>t.filter(a=>a.type===i).length,n=i=>r.filter(a=>a.type===i).length;return{files:s("file"),classes:s("class"),interfaces:s("interface"),functions:s("function"),methods:s("method"),properties:s("property"),routes:s("route"),symbols:t.length,edges:r.length,calls:n("CALLS"),callReferences:n("CALL_REFERENCE"),imports:n("IMPORTS"),inherits:n("INHERITS"),implements:n("IMPLEMENTS"),usesType:n("USES_TYPE"),tests:n("TESTS"),routeEdges:n("ROUTE"),writes:n("WRITES")}}var se=class{constructor(e){this.graph=e}graph;callees(e,t,r=3){return this.walk(e,t,"out",r)}callers(e,t,r=3){return this.walk(e,t,"in",r)}walk(e,t,r,s){let n=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(l=>l.type==="CALLS"||l.type==="CALL_REFERENCE");for(;a.length;){let l=a.shift();if(l.depth>=s)continue;let p=r==="out"?c.filter(m=>m.from===l.id):c.filter(m=>m.to===l.id);for(let m of p){let d=r==="out"?m.to:m.from;if(i.has(d))continue;i.add(d);let f=this.graph.getSymbol(d);if(!f)continue;let g=l.depth+1;n.push({symbol:f,depth:g}),a.push({id:d,depth:g})}}return n}};var ne=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};var ie=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=r)continue;let l=s.filter(p=>p.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(p.type));for(let p of l){if(n.has(p.from))continue;n.add(p.from);let m=this.graph.getSymbol(p.from);if(!m)continue;let d=c.depth+1;a.push({symbol:m,depth:d,relation:p.type}),i.push({id:p.from,depth:d})}}return a}};function $r(o,e){return e.ranges.length===0?!0:typeof o.startLine!="number"||typeof o.endLine!="number"?!1:e.ranges.some(t=>o.startLine<=t.endLine&&o.endLine>=t.startLine)}var ae=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let n of t){let i=r.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>$r(l,n));if(c.length===0){let l=i.find(p=>p.type==="file");l&&s.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:n.status,direct:!0})}return s}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Dr={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Gr(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function Ue(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var ce=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let m=new Set([p.symbol.id]),d=[{id:p.symbol.id,depth:0}];for(;d.length;){let f=d.shift();if(f.depth>=r)continue;let g=s.filter(h=>h.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(h.type));for(let h of g){if(m.has(h.from))continue;m.add(h.from);let C=this.graph.getSymbol(h.from);if(!C)continue;let w=f.depth+1,B=`${p.symbol.id}:${C.id}`;n.set(B,{symbol:C,relation:h.type,depth:w,sourceSymbolId:p.symbol.id});let R=Dr[h.type]??1;i+=Math.max(1,R-(w-1)),d.push({id:C.id,depth:w})}}}let a=[...n.values()].sort((p,m)=>p.depth-m.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(Ue);return l.length===0&&l.push(...c.filter(p=>!Ue(p)).slice(0,10)),{risk:Gr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as zr}from"node:child_process";import{promisify as Br}from"node:util";var je=Br(zr);function qr(o){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of o.matchAll(t)){let s=Number(r[1]),n=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function Kr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function Je(o){let e="";try{e=(await je("git",["diff","HEAD","--name-status","--no-renames"],{cwd:o,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await je("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Kr(s),ranges:qr(a)})}try{let r=await je("git",["ls-files","--others","--exclude-standard"],{cwd:o});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===s)||t.push({filePath:s,status:"added",ranges:[]})}catch{}return t}var le=class{constructor(e){this.graph=e;this.mapper=new ae(e),this.blast=new ce(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await Je(t),n=this.mapper.map(e,s),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:s,...i}}analyzeFile(e,t,r={}){let s=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,s,r.maxDepth??4)}}};var _=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};import{createHash as Hr}from"node:crypto";import{readFile as Wr}from"node:fs/promises";import{join as Vr}from"node:path";function Ye(o){return Hr("sha256").update(o).digest("hex")}var pe=class{sanitizer=new k;async build(e,t,r,s={}){let n=s.maxLines??80,i=s.overlapLines??10,a=new Map;for(let l of r){let p=a.get(l.filePath)??[];p.push(l),a.set(l.filePath,p)}let c=[];for(let[l,p]of a){let m;try{m=await Wr(Vr(t,l),"utf8")}catch{continue}let d=m.split(/\r?\n/),f=p.filter(g=>g.type!=="file"&&typeof g.startLine=="number"&&typeof g.endLine=="number");if(f.length>0)for(let g of f)c.push(...this.chunkRange({projectId:e,filePath:l,lines:d,symbol:g,startLine:g.startLine,endLine:g.endLine,maxLines:n,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:l,lines:d,startLine:1,endLine:Math.max(1,d.length),maxLines:n,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:n,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),l=Math.min(s.length,Math.max(c,e.endLine)),p=[],m=c,d=0;for(;m<=l;){let f=Math.min(l,m+i-1),g=s.slice(m-1,f).join(`
|
|
5
|
+
`).trim();if(g){let h=this.sanitizer.sanitize(g).text,C=Ye(h),w=[t,r,n?.id??"file",String(d),C].join(":");p.push({id:Ye(w).slice(0,32),projectId:t,filePath:r,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:m,endLine:f,content:h,contentHash:C})}if(f>=l)break;m=f-a+1,d++}return p}};var de=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var me=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var fe=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=Ur(t,n.vector);s.push({id:n.id,score:i,metadata:n.metadata})}return s.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function Ur(o,e){if(o.length===0||e.length===0||o.length!==e.length)return 0;let t=0,r=0,s=0;for(let n=0;n<o.length;n++){let i=o[n]??0,a=e[n]??0;t+=i*a,r+=i*i,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}function Qe(o,e){let t=o.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var ue=class{constructor(e){this.options=e}options;vectors=new fe;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:s,graph:n,model:i}=this.options,a=new de(r),c=new me(r),l=await new pe().build(e,t,n.allSymbols(e));this.chunks.clear();for(let y of l)this.chunks.set(y.id,y);let p=await a.load(e),m=!p||p.chunks.length!==l.length||p.chunks.some(y=>!this.chunks.has(y.id));m&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:l});let d=await c.load(e),f=0;d&&d.model===i&&(f=this.vectors.importRecords(d.records));let g=new Set(l.map(y=>y.id)),h=0;for(let y of this.vectors.exportProject(e))g.has(y.id)||this.vectors.remove(y.id)&&h++;let C=l.filter(y=>{let T=this.vectors.get(y.id);return T?T.metadata?.contentHash!==y.contentHash:!0}),w=0,B=8,R=this.vectors.exportProject(e)[0]?.vector.length;for(let y=0;y<C.length;y+=B){let T=C.slice(y,y+B),rr=T.map(x=>[`file: ${x.filePath}`,x.symbolName?`symbol: ${x.symbolName}`:"",x.symbolType?`type: ${x.symbolType}`:"",x.content].filter(Boolean).join(`
|
|
6
|
+
`)),or=await s.embedMany(rr);for(let x=0;x<T.length;x++){let P=T[x],M=or[x];if(!(!P||!M||M.length===0)){if(R===void 0&&(R=M.length),M.length!==R){console.warn(`[code-semantic] skip dimension mismatch: ${M.length} != ${R}`);continue}this.vectors.upsert({id:P.id,projectId:e,vector:M,metadata:{contentHash:P.contentHash,filePath:P.filePath,symbolName:P.symbolName,symbolType:P.symbolType,startLine:P.startLine,endLine:P.endLine}}),w++}}}let xe=this.vectors.exportProject(e),Ae=w>0||h>0||!d||d.model!==i;return Ae&&await c.save({version:1,projectId:e,model:i,dimensions:xe[0]?.vector.length??R??0,updatedAt:new Date().toISOString(),records:xe}),{chunks:l.length,vectorsLoaded:f,vectorsIndexed:w,vectorsRemoved:h,totalVectors:xe.length,savedChunks:m,savedVectors:Ae}}async search(e,t=8){let r=await this.options.embeddings.embed(e),s=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),n=new Set(L(e)),i=[];for(let a of s){let c=this.chunks.get(a.id);if(!c)continue;let l=new Set(L([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),p=0;for(let h of n)l.has(h)&&p++;let m=n.size===0?0:p/n.size,d=Math.max(0,a.score),f=Qe(c.filePath,e),g=(d*.75+m*.25)*f;i.push({chunk:c,score:g,vectorScore:d,lexicalScore:m})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}};import di from"typescript";import v from"typescript";var yi=new Set([v.SyntaxKind.EqualsToken,v.SyntaxKind.PlusEqualsToken,v.SyntaxKind.MinusEqualsToken,v.SyntaxKind.AsteriskEqualsToken,v.SyntaxKind.SlashEqualsToken,v.SyntaxKind.PercentEqualsToken,v.SyntaxKind.QuestionQuestionEqualsToken,v.SyntaxKind.AmpersandAmpersandEqualsToken,v.SyntaxKind.BarBarEqualsToken]);function Jr(o){return o.replaceAll("\\","/").toLowerCase()}var F=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,r);a&&s.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let n=new Map;for(let i of s){let a=i.kind==="route"?i.symbolId:i.filePath,c=n.get(a);(!c||i.score>c.score)&&n.set(a,i)}return[...n.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let r=Jr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let n=null,i=0;if(r.startsWith("bin/"))n="cli",i=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))n="cli",i=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))n="main",i=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))n="runtime",i=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let c=t.filter(p=>p.to===e.id&&p.type!=="DEFINES").length,l=t.filter(p=>p.from===e.id&&p.type!=="DEFINES").length;(r.startsWith("packages/")||c===0||l>0)&&(n="package",i=r.startsWith("packages/")?70:55,s.push("package/public index"))}return n?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,s.push("no incoming dependency")),{kind:n,score:i,reasons:s}):null}};var ge=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Ze=new Set(["CALLS","CALL_REFERENCE"]),b=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let r=t.trim().toLowerCase();return r?this.graph.allSymbols(e).filter(s=>s.name.toLowerCase().includes(r)||(s.qualifiedName?.toLowerCase().includes(r)??!1)||s.filePath.toLowerCase().includes(r)).sort((s,n)=>{let i=s.name.toLowerCase()===r,a=n.name.toLowerCase()===r;return i!==a?i?-1:1:s.filePath.localeCompare(n.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Ze)}callees(e,t){return this.relatedOutgoing(e,t,Ze)}dependents(e,t){return this.relatedIncoming(e,t,ge)}dependencies(e,t){return this.relatedOutgoing(e,t,ge)}neighborhood(e,t,r=1){let s=this.graph.getSymbol(t);return!s||s.projectId!==e?null:{center:s,incoming:this.walk(e,t,"incoming",r),outgoing:this.walk(e,t,"outgoing",r)}}shortestPath(e,t,r,s=12){let n=this.graph.getSymbol(t),i=this.graph.getSymbol(r);if(!n||!i||n.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===r)return{found:!0,distance:0,symbols:[n],edges:[]};let a=this.graph.allEdges(e).filter(d=>ge.has(d.type)),c=new Map;for(let d of a){let f=c.get(d.from)??[];f.push(d),c.set(d.from,f)}let l=[{id:t,depth:0}],p=new Set([t]),m=new Map;for(;l.length>0;){let d=l.shift();if(!(d.depth>=s)){for(let f of c.get(d.id)??[])if(!p.has(f.to)){if(p.add(f.to),m.set(f.to,{node:d.id,edge:f}),f.to===r)return this.buildPath(t,r,m);l.push({id:f.to,depth:d.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,r){let s=[t],n=[],i=t;for(;i!==e;){let c=r.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};n.push(c.edge),i=c.node,s.push(i)}s.reverse(),n.reverse();let a=s.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:n.length,symbols:a,edges:n}}walk(e,t,r,s){let n=this.graph.allEdges(e).filter(l=>ge.has(l.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let l=i.shift();if(!(l.depth>=s))for(let p of n){if(!(r==="incoming"?p.to===l.id:p.from===l.id))continue;let d=r==="incoming"?p.from:p.to;if(a.has(d))continue;let f=this.graph.getSymbol(d);f&&(a.add(d),c.push({symbol:f,depth:l.depth+1,via:p}),i.push({id:d,depth:l.depth+1}))}}return c}relatedIncoming(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.to===t&&r.has(n.type)).map(n=>n.from))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}relatedOutgoing(e,t,r){return[...new Set(this.graph.allEdges(e).filter(n=>n.from===t&&r.has(n.type)).map(n=>n.to))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}};var Xe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Re(o){return o.replaceAll("\\","/").toLowerCase()}function Yr(o){let e=Re(o);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Qr(o){let e=Re(o.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var $=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new F(this.graph).detect(e).map(i=>i.symbolId)),n=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Yr(i.filePath)||s.has(i.id)||Qr(i)||r.filter(f=>f.to===i.id&&Xe.has(f.type)).length>0)continue;let c=r.filter(f=>f.from===i.id&&Xe.has(f.type)),l=["no incoming usage edge"],p=50;(i.type==="function"||i.type==="method")&&(p+=20,l.push("callable symbol")),i.type==="property"&&(p-=15),c.length===0&&(p+=10,l.push("no outgoing dependency")),Re(i.filePath).includes("/internal/")&&(p+=10,l.push("internal implementation")),i.name.startsWith("_")&&(p+=5);let d=p>=75?"high":p>=55?"medium":"low";n.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:d,score:p,reasons:l})}return n.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var Zr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),D=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(i=>Zr.has(i.type)),s=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,l=0,p=0;for(let m of r){let d=s.get(m.from),f=s.get(m.to);!d||!f||d.filePath===f.filePath||(d.filePath===i&&(a.add(f.filePath),l++),f.filePath===i&&(c.add(d.filePath),p++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:l,incomingEdges:p}})}};import{homedir as go}from"node:os";import{join as ho}from"node:path";import{DeleteObjectCommand as Xr,GetObjectCommand as eo,HeadObjectCommand as to,ListObjectsV2Command as ro,PutObjectCommand as oo,S3Client as so}from"@aws-sdk/client-s3";import{getSignedUrl as no}from"@aws-sdk/s3-request-presigner";var he=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new so({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new oo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await no(this.client,new eo({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new to({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Xr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new ro({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as et,mkdir as io,readFile as ao,readdir as co,rm as lo,stat as tt,writeFile as po}from"node:fs/promises";import{dirname as mo,join as fo,relative as rt,resolve as uo}from"node:path";var G=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return uo(this.root,t)}async put(e,t){let r=this.path(e);await io(mo(r),{recursive:!0}),await po(r,t)}async get(e){try{return await ao(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await et(this.path(e)),!0}catch{return!1}}async delete(e){await lo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await et(t)}catch{return r}let s=async i=>{let a=await co(i,{withFileTypes:!0});for(let c of a){let l=fo(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await tt(l);r.push({key:rt(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await tt(t);return n.isDirectory()?await s(t):r.push({key:rt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function ot(o){let e=o.localRoot??ho(go(),".toolnet-memory","storage");if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new he({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new G(e))}return new G(e)}var ye=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};function yo(o){return new Promise(e=>setTimeout(e,o))}async function st(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await yo(c+l)}throw n}var So=new Set(["put","get","getText","delete","list"]);function nt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:So.has(r)?(...n)=>st(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function it(o){let e=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function at(o){let e=o.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var Se=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=it(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
|
|
7
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=at(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{McpServer as jo}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Ro}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as ct}from"zod";var lt={query:ct.string(),limit:ct.number().int().min(1).max(20).optional()};async function pt(o,e){return o.retrieval.search(o.project.id,e.query,{topK:e.limit??8}).map(r=>({id:r.memory.id,type:r.memory.type,content:r.memory.content,importance:r.memory.importance,score:r.score,tags:r.memory.tags}))}import{z}from"zod";var dt={type:z.enum(["activity","decision","rule","todo","summary"]),content:z.string().min(1),tags:z.array(z.string()).optional(),importance:z.enum(["critical","high","normal","temporary"]).optional()};async function mt(o,e){let t=o.memory.remember({projectId:o.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),t}import{z as bo}from"zod";var ft={id:bo.string().min(1)};async function ut(o,e){let t=o.memory.delete(e.id);return t&&o.memoryStore&&await o.memoryStore.save(o.project.id,o.memory.exportProject(o.project.id)),{deleted:t}}import{z as xo}from"zod";var gt={name:xo.string().min(1)};async function ht(o,e){return o.graph.findByName(o.project.id,e.name)}import{z as Co}from"zod";function E(o,e){let t=o.graph.getSymbol(e);if(t&&t.projectId===o.project.id)return t;let r=new b(o.graph),s=r.findSymbols(o.project.id,e).find(n=>n.name===e||n.qualifiedName===e);return s||(r.findSymbols(o.project.id,e)[0]??null)}function S(o){return{id:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,endLine:o.endLine}}var yt={symbolId:Co.string().min(1)};async function St(o,e){let t=E(o,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let s=new b(o.graph).callers(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,callers:s.map(S)}}import{z as bt}from"zod";var xt={query:bt.string().min(1),limit:bt.number().int().min(1).max(50).optional()};async function Ct(o,e){let t=e.query.toLowerCase(),r=e.limit??20;return o.graph.allSymbols(o.project.id).filter(s=>s.name.toLowerCase().includes(t)||s.qualifiedName?.toLowerCase().includes(t)||s.filePath.toLowerCase().includes(t)).slice(0,r)}import{z as wt}from"zod";var vt={query:wt.string().optional(),memoryLimit:wt.number().int().min(1).max(20).optional()};async function Et(o,e){let t=oe(o.graph,o.project.id),r=o.memory.recent(o.project.id,5),s=e.query?o.retrieval.search(o.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:t,recent:r,relevant:s.map(n=>n.memory)}}import{z as vo}from"zod";var wo=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],j=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of wo){let m=`${i}/${p}`,d=await this.storage.get(m);d&&(await this.storage.put(`${a}/${p}`,d,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};var Pt={reason:vo.string().optional()};async function jt(o,e){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).create(o.project.id,e.reason??"manual-mcp")}async function Rt(o){if(!o.storage)throw new Error("Storage unavailable");return new j(o.storage).list(o.project.id)}import{z as Eo}from"zod";var Tt={snapshotId:Eo.string().min(1)};async function Mt(o,e){if(!o.storage)throw new Error("Storage unavailable");let t=new j(o.storage);return await t.create(o.project.id,"before-rollback"),t.restore(o.project.id,e.snapshotId)}import{z as Te}from"zod";var kt={symbolId:Te.string().min(1),direction:Te.enum(["callers","callees"]).optional(),depth:Te.number().int().min(1).max(10).optional()};async function Lt(o,e){let t=new se(o.graph),r=e.direction??"callees",s=e.depth??3,n=r==="callers"?t.callers(o.project.id,e.symbolId,s):t.callees(o.project.id,e.symbolId,s);return{direction:r,depth:s,results:n.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as Nt}from"zod";var At={symbolId:Nt.string().min(1),depth:Nt.number().int().min(1).max(10).optional()};async function It(o,e){let t=o.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let s=new ie(o.graph).analyze(o.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:s.map(n=>({id:n.symbol.id,name:n.symbol.name,qualifiedName:n.symbol.qualifiedName,filePath:n.symbol.filePath,type:n.symbol.type,relation:n.relation,depth:n.depth}))}}async function Ot(o){return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:oe(o.graph,o.project.id)}}import{z as _t}from"zod";var Ft={filePath:_t.string().min(1),direction:_t.enum(["dependencies","dependents","both"]).optional()};async function $t(o,e){let r=new D(o.graph).analyze(o.project.id).find(c=>c.filePath===e.filePath);if(!r)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let s=o.graph.allSymbols(o.project.id).filter(c=>c.type==="file"),n=new Map(s.map(c=>[c.filePath,c])),i=c=>({id:n.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:r.filePath,outgoingEdges:r.outgoingEdges,incomingEdges:r.incomingEdges,dependencies:a==="dependents"?[]:r.dependencies.map(i),dependents:a==="dependencies"?[]:r.dependents.map(i)}}import{z as Dt}from"zod";var Gt={query:Dt.string().min(1),limit:Dt.number().int().min(1).max(20).optional()};async function zt(o,e){return o.codeSemantic?{available:!0,results:(await o.codeSemantic.search(e.query,e.limit??8)).map(r=>({id:r.chunk.id,filePath:r.chunk.filePath,symbol:r.chunk.symbolName,symbolType:r.chunk.symbolType,startLine:r.chunk.startLine,endLine:r.chunk.endLine,score:r.score,vectorScore:r.vectorScore,lexicalScore:r.lexicalScore,content:r.chunk.content}))}:{available:!1,results:[]}}import{z as Me}from"zod";var Bt={mode:Me.enum(["git_diff","file"]).optional(),filePath:Me.string().optional(),depth:Me.number().int().min(1).max(10).optional()};async function qt(o,e){let t=new le(o.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(o.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(o.project.id,o.project.rootPath,{maxDepth:e.depth})}import{z as Po}from"zod";var Kt={symbol:Po.string().min(1)};async function Ht(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let s=new b(o.graph).dependents(o.project.id,t.id);return{found:!0,symbol:S(t),count:s.length,dependents:s.map(S)}}import{z as ke}from"zod";var Wt={from:ke.string().min(1),to:ke.string().min(1),maxDepth:ke.number().int().min(1).max(30).optional()};async function Vt(o,e){let t=E(o,e.from),r=E(o,e.to);if(!t||!r)return{found:!1,fromFound:!!t,toFound:!!r,path:[],edges:[]};let n=new b(o.graph).shortestPath(o.project.id,t.id,r.id,e.maxDepth??12);return{found:n.found,distance:n.distance,from:S(t),to:S(r),path:n.symbols.map(S),edges:n.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as Le}from"zod";var Ut={symbol:Le.string().min(1),depth:Le.number().int().min(1).max(5).optional(),limit:Le.number().int().min(1).max(200).optional()};async function Jt(o,e){let t=E(o,e.symbol);if(!t)return{found:!1,query:e.symbol};let s=new b(o.graph).neighborhood(o.project.id,t.id,e.depth??1);if(!s)return{found:!1,query:e.symbol};let n=e.limit??50;return{found:!0,center:S(s.center),incomingCount:s.incoming.length,outgoingCount:s.outgoing.length,incoming:s.incoming.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)})),outgoing:s.outgoing.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:S(i.symbol)}))}}import{z as Ne}from"zod";var Qt={confidence:Ne.enum(["high","medium","low","all"]).optional(),filePath:Ne.string().min(1).optional(),limit:Ne.number().int().min(1).max(500).optional()},Yt={high:3,medium:2,low:1};async function Zt(o,e){let r=new $(o.graph).analyze(o.project.id);if(e.confidence&&e.confidence!=="all"){let i=Yt[e.confidence];r=r.filter(a=>Yt[a.confidence]>=i)}e.filePath&&(r=r.filter(i=>i.filePath===e.filePath));let s=r.length,n=e.limit??100;return{total:s,high:r.filter(i=>i.confidence==="high").length,medium:r.filter(i=>i.confidence==="medium").length,low:r.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:r.slice(0,n)}}function u(o){return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}function To(o){let e=new jo({name:"toolnet-memory",version:"0.1.0"});return e.tool("memory_search","Search relevant long-term memory for the current project.",lt,async t=>u(await pt(o,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",dt,async t=>u(await mt(o,t))),e.tool("memory_forget","Delete a memory by id.",ft,async t=>u(await ut(o,t))),e.tool("find_symbol","Find code symbols by exact name.",gt,async t=>u(await ht(o,t))),e.tool("find_callers","Find functions or methods calling a symbol.",yt,async t=>u(await St(o,t))),e.tool("code_search","Search indexed code symbols and files.",xt,async t=>u(await Ct(o,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",vt,async t=>u(await Et(o,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",kt,async t=>u(await Lt(o,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",At,async t=>u(await It(o,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>u(await Ot(o))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Ft,async t=>u(await $t(o,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Gt,async t=>u(await zt(o,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Pt,async t=>u(await jt(o,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>u(await Rt(o))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Tt,async t=>u(await Mt(o,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",Bt,async t=>u(await qt(o,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Kt,async t=>u(await Ht(o,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Wt,async t=>u(await Vt(o,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Ut,async t=>u(await Jt(o,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Qt,async t=>u(await Zt(o,t))),e}async function Xt(o){let e=To(o),t=new Ro;await e.connect(t)}import{closeSync as Mo,mkdirSync as ko,openSync as Lo,readFileSync as No,unlinkSync as er,writeFileSync as Ao}from"node:fs";import{tmpdir as Io}from"node:os";import{join as tr}from"node:path";function Oo(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var be=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=tr(Io(),"toolnet-memory-locks");ko(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=tr(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Lo(this.path,"wx");Ao(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Mo(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let s=JSON.parse(No(this.path,"utf8"));Number.isInteger(s.pid)&&Oo(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{er(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{er(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};async function _o(){let o=Ie(),e=new H().detect(),t=ot({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),r=nt(t,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),s=new Se(r,e.id,e.name,e.remote??e.name),n=new be(e.id);await n.acquire();let i=()=>{n.release().finally(()=>process.exit(0))};process.once("SIGINT",i),process.once("SIGTERM",i);let a=new J,c=new ye(s);a.importRecords(await c.load(e.id));let l=new ee(a),p=new N,m=await new _(s).load(e.id);m&&p.import(m.symbols,m.edges);let d=new ne(p),f=new ue({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Ve(),graph:p});await f.initialize(),await Xt({project:e,memory:a,retrieval:l,graph:p,references:d,codeSemantic:f,memoryStore:c,storage:s})}_o().catch(o=>{console.error(o),process.exit(1)});
|