toolnet-memory 0.2.13 → 0.2.15
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/README.md +119 -26
- package/bundle/auto-integrate.js +600 -127
- package/bundle/doctor.js +3 -3
- package/bundle/full-index.js +8 -8
- package/bundle/mcp.js +7 -7
- package/bundle/opencode.js +637 -161
- package/bundle/runtime.js +11 -11
- package/bundle/semantic.js +6 -6
- package/bundle/setup.js +613 -187
- package/package.json +1 -1
package/bundle/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import"dotenv/config";import{existsSync as
|
|
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
|
|
3
|
-
`,{encoding:"utf8",mode:384}),
|
|
4
|
-
`)}};var oe=class{constructor(e){this.memory=e}memory;searcher=new te;contextBuilder=new re;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 se=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=>Or(n))}};function Or(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 Fr}from"node:crypto";var ne=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=Fr("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return $r(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function $r(o){let e=Math.sqrt(o.reduce((t,r)=>t+r*r,0));return e===0?o:o.map(t=>t/e)}var Re=class{constructor(e,t=new ne){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 Qe(){let o=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=o?new se({token:o,model:e}):null;return new Re(t)}import*as b from"typescript";var I=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 ie(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 ae=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 h=l.depth+1;n.push({symbol:f,depth:h}),a.push({id:d,depth:h})}}return n}};var ce=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 le=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 Kr(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 pe=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=>Kr(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 Br={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function qr(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function Ze(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var de=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 h=s.filter(y=>y.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(y.type));for(let y of h){if(m.has(y.from))continue;m.add(y.from);let E=this.graph.getSymbol(y.from);if(!E)continue;let P=f.depth+1,W=`${p.symbol.id}:${E.id}`;n.set(W,{symbol:E,relation:y.type,depth:P,sourceSymbolId:p.symbol.id});let T=Br[y.type]??1;i+=Math.max(1,T-(P-1)),d.push({id:E.id,depth:P})}}}let a=[...n.values()].sort((p,m)=>p.depth-m.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(Ze);return l.length===0&&l.push(...c.filter(p=>!Ze(p)).slice(0,10)),{risk:qr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as Hr}from"node:child_process";import{promisify as Wr}from"node:util";var Te=Wr(Hr);function Ur(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 Vr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function Xe(o){let e="";try{e=(await Te("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 Te("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Vr(s),ranges:Ur(a)})}try{let r=await Te("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 me=class{constructor(e){this.graph=e;this.mapper=new pe(e),this.blast=new de(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await Xe(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 D=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 Jr}from"node:crypto";import{readFile as Yr}from"node:fs/promises";import{join as Qr}from"node:path";function et(o){return Jr("sha256").update(o).digest("hex")}var fe=class{sanitizer=new L;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 Yr(Qr(t,l),"utf8")}catch{continue}let d=m.split(/\r?\n/),f=p.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(f.length>0)for(let h of f)c.push(...this.chunkRange({projectId:e,filePath:l,lines:d,symbol:h,startLine:h.startLine,endLine:h.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),h=s.slice(m-1,f).join(`
|
|
5
|
-
`).trim();if(
|
|
6
|
-
`)),ar=await s.embedMany(ir);for(let v=0;v<M.length;v++){let k=M[v],A=ar[v];if(!(!k||!A||A.length===0)){if(T===void 0&&(T=A.length),A.length!==T){console.warn(`[code-semantic] skip dimension mismatch: ${A.length} != ${T}`);continue}this.vectors.upsert({id:k.id,projectId:e,vector:A,metadata:{contentHash:k.contentHash,filePath:k.filePath,symbolName:k.symbolName,symbolType:k.symbolType,startLine:k.startLine,endLine:k.endLine}}),P++}}}let ve=this.vectors.exportProject(e),Fe=P>0||y>0||!d||d.model!==i;return Fe&&await c.save({version:1,projectId:e,model:i,dimensions:ve[0]?.vector.length??T??0,updatedAt:new Date().toISOString(),records:ve}),{chunks:l.length,vectorsLoaded:f,vectorsIndexed:P,vectorsRemoved:y,totalVectors:ve.length,savedChunks:m,savedVectors:Fe}}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(N(e)),i=[];for(let a of s){let c=this.chunks.get(a.id);if(!c)continue;let l=new Set(N([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),p=0;for(let y of n)l.has(y)&&p++;let m=n.size===0?0:p/n.size,d=Math.max(0,a.score),f=tt(c.filePath,e),h=(d*.75+m*.25)*f;i.push({chunk:c,score:h,vectorScore:d,lexicalScore:m})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}};import*as x from"typescript";import*as u from"typescript";var vi=new Set([u.SyntaxKind.EqualsToken,u.SyntaxKind.PlusEqualsToken,u.SyntaxKind.MinusEqualsToken,u.SyntaxKind.AsteriskEqualsToken,u.SyntaxKind.SlashEqualsToken,u.SyntaxKind.PercentEqualsToken,u.SyntaxKind.QuestionQuestionEqualsToken,u.SyntaxKind.AmpersandAmpersandEqualsToken,u.SyntaxKind.BarBarEqualsToken]);function Xr(o){return o.replaceAll("\\","/").toLowerCase()}var G=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=Xr(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 Se=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),rt=new Set(["CALLS","CALL_REFERENCE"]),w=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,rt)}callees(e,t){return this.relatedOutgoing(e,t,rt)}dependents(e,t){return this.relatedIncoming(e,t,Se)}dependencies(e,t){return this.relatedOutgoing(e,t,Se)}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=>Se.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=>Se.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 ot=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Me(o){return o.replaceAll("\\","/").toLowerCase()}function eo(o){let e=Me(o);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function to(o){let e=Me(o.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var z=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new G(this.graph).detect(e).map(i=>i.symbolId)),n=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||eo(i.filePath)||s.has(i.id)||to(i)||r.filter(f=>f.to===i.id&&ot.has(f.type)).length>0)continue;let c=r.filter(f=>f.from===i.id&&ot.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")),Me(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 ro=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),K=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(i=>ro.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 jo}from"node:os";import{join as ko}from"node:path";import{DeleteObjectCommand as oo,GetObjectCommand as so,HeadObjectCommand as no,ListObjectsV2Command as io,PutObjectCommand as ao,S3Client as co}from"@aws-sdk/client-s3";import{getSignedUrl as lo}from"@aws-sdk/s3-request-presigner";var be=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new co({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 ao({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await lo(this.client,new so({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 no({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 oo({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new io({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 st,mkdir as po,readFile as mo,readdir as fo,rm as uo,stat as nt,writeFile as go}from"node:fs/promises";import{dirname as ho,join as yo,relative as it,resolve as So}from"node:path";var B=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return So(this.root,t)}async put(e,t){let r=this.path(e);await po(ho(r),{recursive:!0}),await go(r,t)}async get(e){try{return await mo(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 st(this.path(e)),!0}catch{return!1}}async delete(e){await uo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await st(t)}catch{return r}let s=async i=>{let a=await fo(i,{withFileTypes:!0});for(let c of a){let l=yo(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await nt(l);r.push({key:it(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await nt(t);return n.isDirectory()?await s(t):r.push({key:it(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as bo,GetObjectCommand as xo,HeadObjectCommand as Co,ListObjectsV2Command as wo,PutObjectCommand as vo,S3Client as Eo}from"@aws-sdk/client-s3";import{getSignedUrl as Po}from"@aws-sdk/s3-request-presigner";var q=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Eo({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,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 vo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Po(this.client,new xo({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(`${this.name} 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 Co({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 bo({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new wo({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}};function Ae(o,e){return console.warn(e),new B(o)}function at(o){let e=o.localRoot??ko(jo(),".toolnet-memory","storage");if(o.provider==="r2"){let t=o.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new q({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ae(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(o.provider==="s3"){let t=o.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new q({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ae(e,"[storage] S3 credentials missing. Using local fallback.")}if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new be({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ae(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new B(e)}var xe=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 Ro(o){return new Promise(e=>setTimeout(e,o))}async function ct(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 Ro(c+l)}throw n}var To=new Set(["put","get","getText","delete","list"]);function lt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:To.has(r)?(...n)=>ct(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function pt(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 dt(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 Ce=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=pt(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=dt(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 Fo}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as $o}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as mt}from"zod";var ft={query:mt.string(),limit:mt.number().int().min(1).max(20).optional()};async function ut(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 H}from"zod";var gt={type:H.enum(["activity","decision","rule","todo","summary"]),content:H.string().min(1),tags:H.array(H.string()).optional(),importance:H.enum(["critical","high","normal","temporary"]).optional()};async function ht(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 Mo}from"zod";var yt={id:Mo.string().min(1)};async function St(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 Ao}from"zod";var bt={name:Ao.string().min(1)};async function xt(o,e){return o.graph.findByName(o.project.id,e.name)}import{z as Lo}from"zod";function j(o,e){let t=o.graph.getSymbol(e);if(t&&t.projectId===o.project.id)return t;let r=new w(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 C(o){return{id:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,endLine:o.endLine}}var Ct={symbolId:Lo.string().min(1)};async function wt(o,e){let t=j(o,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let s=new w(o.graph).callers(o.project.id,t.id);return{found:!0,symbol:C(t),count:s.length,callers:s.map(C)}}import{z as vt}from"zod";var Et={query:vt.string().min(1),limit:vt.number().int().min(1).max(50).optional()};async function Pt(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 jt}from"zod";var kt={query:jt.string().optional(),memoryLimit:jt.number().int().min(1).max(20).optional()};async function Rt(o,e){let t=ie(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 Io}from"zod";var No=["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"],R=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 No){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 Tt={reason:Io.string().optional()};async function Mt(o,e){if(!o.storage)throw new Error("Storage unavailable");return new R(o.storage).create(o.project.id,e.reason??"manual-mcp")}async function At(o){if(!o.storage)throw new Error("Storage unavailable");return new R(o.storage).list(o.project.id)}import{z as _o}from"zod";var Lt={snapshotId:_o.string().min(1)};async function Nt(o,e){if(!o.storage)throw new Error("Storage unavailable");let t=new R(o.storage);return await t.create(o.project.id,"before-rollback"),t.restore(o.project.id,e.snapshotId)}import{z as Le}from"zod";var It={symbolId:Le.string().min(1),direction:Le.enum(["callers","callees"]).optional(),depth:Le.number().int().min(1).max(10).optional()};async function _t(o,e){let t=new ae(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 Ot}from"zod";var Ft={symbolId:Ot.string().min(1),depth:Ot.number().int().min(1).max(10).optional()};async function $t(o,e){let t=o.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let s=new le(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 Dt(o){return{project:{id:o.project.id,name:o.project.name,rootPath:o.project.rootPath},architecture:ie(o.graph,o.project.id)}}import{z as Gt}from"zod";var zt={filePath:Gt.string().min(1),direction:Gt.enum(["dependencies","dependents","both"]).optional()};async function Kt(o,e){let r=new K(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 Bt}from"zod";var qt={query:Bt.string().min(1),limit:Bt.number().int().min(1).max(20).optional()};async function Ht(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 Ne}from"zod";var Wt={mode:Ne.enum(["git_diff","file"]).optional(),filePath:Ne.string().optional(),depth:Ne.number().int().min(1).max(10).optional()};async function Ut(o,e){let t=new me(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 Oo}from"zod";var Vt={symbol:Oo.string().min(1)};async function Jt(o,e){let t=j(o,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let s=new w(o.graph).dependents(o.project.id,t.id);return{found:!0,symbol:C(t),count:s.length,dependents:s.map(C)}}import{z as Ie}from"zod";var Yt={from:Ie.string().min(1),to:Ie.string().min(1),maxDepth:Ie.number().int().min(1).max(30).optional()};async function Qt(o,e){let t=j(o,e.from),r=j(o,e.to);if(!t||!r)return{found:!1,fromFound:!!t,toFound:!!r,path:[],edges:[]};let n=new w(o.graph).shortestPath(o.project.id,t.id,r.id,e.maxDepth??12);return{found:n.found,distance:n.distance,from:C(t),to:C(r),path:n.symbols.map(C),edges:n.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as _e}from"zod";var Zt={symbol:_e.string().min(1),depth:_e.number().int().min(1).max(5).optional(),limit:_e.number().int().min(1).max(200).optional()};async function Xt(o,e){let t=j(o,e.symbol);if(!t)return{found:!1,query:e.symbol};let s=new w(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:C(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:C(i.symbol)})),outgoing:s.outgoing.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:C(i.symbol)}))}}import{z as Oe}from"zod";var tr={confidence:Oe.enum(["high","medium","low","all"]).optional(),filePath:Oe.string().min(1).optional(),limit:Oe.number().int().min(1).max(500).optional()},er={high:3,medium:2,low:1};async function rr(o,e){let r=new z(o.graph).analyze(o.project.id);if(e.confidence&&e.confidence!=="all"){let i=er[e.confidence];r=r.filter(a=>er[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 g(o){return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}function Do(o){let e=new Fo({name:"toolnet-memory",version:"0.1.0"});return e.tool("memory_search","Search relevant long-term memory for the current project.",ft,async t=>g(await ut(o,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",gt,async t=>g(await ht(o,t))),e.tool("memory_forget","Delete a memory by id.",yt,async t=>g(await St(o,t))),e.tool("find_symbol","Find code symbols by exact name.",bt,async t=>g(await xt(o,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Ct,async t=>g(await wt(o,t))),e.tool("code_search","Search indexed code symbols and files.",Et,async t=>g(await Pt(o,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",kt,async t=>g(await Rt(o,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",It,async t=>g(await _t(o,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Ft,async t=>g(await $t(o,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>g(await Dt(o))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",zt,async t=>g(await Kt(o,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",qt,async t=>g(await Ht(o,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Tt,async t=>g(await Mt(o,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>g(await At(o))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Lt,async t=>g(await Nt(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.",Wt,async t=>g(await Ut(o,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Vt,async t=>g(await Jt(o,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Yt,async t=>g(await Qt(o,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Zt,async t=>g(await Xt(o,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",tr,async t=>g(await rr(o,t))),e}async function or(o){let e=Do(o),t=new $o;await e.connect(t)}import{closeSync as Go,mkdirSync as zo,openSync as Ko,readFileSync as Bo,unlinkSync as sr,writeFileSync as qo}from"node:fs";import{tmpdir as Ho}from"node:os";import{join as nr}from"node:path";function Wo(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var we=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=nr(Ho(),"toolnet-memory-locks");zo(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=nr(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Ko(this.path,"wx");qo(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Go(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(Bo(this.path,"utf8"));Number.isInteger(s.pid)&&Wo(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{sr(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{sr(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};async function Uo(){let o=$e(),e=new V().detect(),t=at({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),r=lt(t,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),s=new Ce(r,e.id,e.name,e.remote??e.name),n=new we(e.id);await n.acquire();let i=()=>{n.release().finally(()=>process.exit(0))};process.once("SIGINT",i),process.once("SIGTERM",i);let a=new Z,c=new xe(s);a.importRecords(await c.load(e.id));let l=new oe(a),p=new I,m=await new D(s).load(e.id);m&&p.import(m.symbols,m.edges);let d=new ce(p),f=new ye({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Qe(),graph:p});await f.initialize(),await or({project:e,memory:a,retrieval:l,graph:p,references:d,codeSemantic:f,memoryStore:c,storage:s})}Uo().catch(o=>{console.error(o),process.exit(1)});
|
|
1
|
+
import"dotenv/config";import{existsSync as yr,readFileSync as Sr}from"node:fs";import{homedir as br}from"node:os";import{join as Er}from"node:path";function Cr(r){let e=r.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 xr(){let r=process.env.TOOLNET_GLOBAL_ENV??Er(br(),".config","toolnet-memory",".env");if(!yr(r))return;let e=Sr(r,"utf8");for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7));let s=o.indexOf("=");if(s<=0)continue;let n=o.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=Cr(o.slice(s+1)))}}xr();function D(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function F(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function ze(){return{memory:{autoCapture:D(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:D(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:D(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:D(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:F(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:F(process.env.MEMORY_RERANK_TOP,10),finalContext:F(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:F(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:D(process.env.S3_FORCE_PATH_STYLE,!1)},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:F(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var vr={critical:100,high:75,normal:50,temporary:20};function qe(r){return vr[r]}function He(r,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":r==="rule"||r==="decision"?"high":r==="todo"?"normal":r==="activity"||r==="summary"?"temporary":"normal"}import{createHash as Pr}from"node:crypto";import{existsSync as Le,mkdirSync as wr,readFileSync as Ar,renameSync as Rr,writeFileSync as jr}from"node:fs";import{basename as Lr,dirname as Y,join as Q,parse as Ye,resolve as K}from"node:path";var Je=".toolnet",Mr="project.json";function Tr(r){return Pr("sha256").update(r).digest("hex").slice(0,16)}function Me(r){return Q(r,Je,Mr)}function Ir(r){return Le(Me(r))}function _r(r,e){let t=K(r),o=Ye(t).root;for(;;){if(Ir(t))return t;if(t===o||e&&t===K(e))break;let s=Y(t);if(s===t)break;t=s}return null}function kr(r){let e=K(r),t=Ye(e).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(n=>Le(Q(e,n))))return e;if(e===t)break;let s=Y(e);if(s===e)break;e=s}return K(r)}function Nr(r){let e;try{e=JSON.parse(Ar(r,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${r}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let o=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:Y(Y(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:o,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:o,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 Ve(r,e){let t=Q(r,Je);wr(t,{recursive:!0});let o=Me(r),s=`${o}.tmp-${process.pid}`;jr(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Rr(s,o)}function We(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}var J=class{detect(e=process.cwd()){let t=K(e),o=kr(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>Le(Q(o,d))),i=_r(t,n?o:void 0);if(i){let d=Me(i),f=Nr(d);return f.rootPath!==i&&(f.rootPath=i,f.updatedAt=new Date().toISOString(),Ve(i,f)),We(f,i)}let a=new Date().toISOString(),c=Lr(o),l={version:1,id:Tr(o),name:c,remote:c,rootPath:o,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Ve(o,l),We(l,o)}};import{randomUUID as Ur}from"node:crypto";var Or=[{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}],Z=class{scan(e){let t=[];for(let o of Or){let s=new RegExp(o.regex.source,o.regex.flags);for(let n of e.matchAll(s))t.push({type:o.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var k=class{scanner=new Z;sanitize(e){let t=e,o=this.scanner.scan(e),s=new Set;for(let n of o)s.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:o.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[o,s]of Object.entries(e)){let n=o.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[o]="[REDACTED]":t[o]=this.sanitizeValue(s)}return t}return e}};var Dr=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Fr=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 Qe(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Fr.has(e)))}function Kr(r,e){let t=Qe(r),o=Qe(e);if(t.size===0||o.size===0)return 0;let s=0;for(let i of t)o.has(i)&&s++;let n=new Set([...t,...o]).size;return s/n}function Ze(r){return new Set(r.tags.filter(e=>!Dr.has(e.toLowerCase())))}var X=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let o=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=Ze(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(o&&i&&o===i)return!0;let a=Ze(n);for(let c of s)if(a.has(c))return!0;return Kr(e.content,n.content)>=.6})}};var Gr={critical:100,high:75,normal:50,temporary:20},$r={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function Xe(r,e,t=new Date){let o;if(e==="temporary"&&(o=30),r==="activity"&&(o=Math.min(o??14,14)),r==="summary"&&(o=Math.min(o??30,30)),!!o)return new Date(t.getTime()+o*864e5).toISOString()}function Te(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function Br(r){return!!r.metadata?.supersededBy}function Ie(r,e=Date.now()){return!Te(r,e)&&!Br(r)}function G(r,e=Date.now()){if(!Ie(r,e))return 0;let t=Gr[r.importance];if(r.importance==="critical")return t;let o=$r[r.type]??180,n=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,n/o);return t*i}var ee=class{memories=new Map;sanitizer=new k;conflicts=new X;remember(e){let t=new Date().toISOString(),o=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??He(e.type,o),n={id:Ur(),projectId:e.projectId,type:e.type,content:o,importance:s,importanceScore:qe(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??Xe(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 o of e)o?.id&&(this.memories.set(o.id,o),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,o)=>o.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Ie(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(o=>o.type===t)}search(e){let t=e.query.trim().toLowerCase(),o=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=G(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(d=>i.includes(d)).length,c=s.length===0?0:a/s.length,l=G(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,o)}pruneExpired(e,t=Date.now()){let o=0;for(let[s,n]of this.memories)n.projectId===e&&Te(n,t)&&(this.memories.delete(s),o++);return o}pruneSuperseded(e,t=30,o=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;o-new Date(c).getTime()>=n&&(this.memories.delete(i),s++)}return s}clearProject(e){let t=0;for(let[o,s]of this.memories)s.projectId===e&&(this.memories.delete(o),t++);return t}};function N(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var te=class{score(e,t){let o=N(e),s=N([t.content,...t.tags??[],t.type].join(" "));if(o.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 o){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/o.length}};function et(r,e=Date.now()){let t=r.updatedAt??r.createdAt,o=new Date(t).getTime();if(!Number.isFinite(o))return 0;let s=Math.max(0,e-o)/864e5;return Math.exp(-Math.LN2*s/30)}function tt(r){return G(r)/100}var zr={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function rt(r){return zr[r]??.4}var re=class{analyze(e){let t=e.toLowerCase(),o=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&o.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&o.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&o.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&o.push("summary"),{query:e,preferredTypes:o}}};var oe=class{bm25=new te;analyzer=new re;search(e,t,o={}){let s=o.topK??8,n=o.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(o.types?.length&&!o.types.includes(c.type))continue;let l=this.bm25.score(e,c),d=et(c),f=tt(c),m=rt(c.type);i.preferredTypes.includes(c.type)&&(m=Math.min(1,m+.25));let u=l*.55+f*.2+d*.15+m*.1;l<=0||u<n||a.push({memory:c,score:u,scores:{keyword:l,recency:d,importance:f,type:m}})}return a.sort((c,l)=>l.score-c.score).slice(0,s)}};var se=class{build(e,t=6e3){let o=[],s=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(s+a.length>t)break;o.push(a),s+=a.length}return o.join(`
|
|
4
|
+
`)}};var ne=class{constructor(e){this.memory=e}memory;searcher=new oe;contextBuilder=new se;search(e,t,o={}){return this.searcher.search(t,this.memory.list(e),o)}context(e,t,o={}){let s=this.search(e,t,o);return this.contextBuilder.build(s)}};var ot=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function ie(r){let e=ot.find(t=>t.id===r);if(!e)throw new Error(`Unsupported AI provider: ${r}`);return e}function ae(r){return ot.some(e=>e.id===r)}function p(r){return process.env[r]?.trim()||void 0}function h(...r){return r.find(e=>!!e?.trim())}function st(){if(p("GROQ_API_KEY"))return"groq";if(p("DEEPSEEK_API_KEY"))return"deepseek";if(p("NVIDIA_API_KEY")||p("NVIDIA_NIM_API_KEY"))return"nvidia";if(p("OPENROUTER_API_KEY"))return"openrouter";if(p("ALIBABA_API_KEY")||p("DASHSCOPE_API_KEY"))return"alibaba";if(p("GEMINI_API_KEY")||p("GOOGLE_API_KEY"))return"gemini";if(p("CLOUDFLARE_API_TOKEN")&&p("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(p("HF_TOKEN"))return"huggingface";if(p("OLLAMA_MODEL")||p("OLLAMA_BASE_URL"))return"ollama"}function qr(){let r=p("TOOLNET_LLM_PROVIDER");return r&&ae(r)?r:st()??"openai-compatible"}function _e(r){let e=ie(r);switch(r){case"alibaba":return{provider:r,apiKey:h(p("ALIBABA_API_KEY"),p("DASHSCOPE_API_KEY")),baseUrl:h(p("ALIBABA_BASE_URL"),p("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:h(p("ALIBABA_MODEL"),p("DASHSCOPE_MODEL"))};case"openrouter":return{provider:r,apiKey:p("OPENROUTER_API_KEY"),baseUrl:h(p("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:p("OPENROUTER_MODEL")};case"groq":return{provider:r,apiKey:p("GROQ_API_KEY"),baseUrl:h(p("GROQ_BASE_URL"),e.defaultBaseUrl),model:p("GROQ_MODEL")};case"deepseek":return{provider:r,apiKey:p("DEEPSEEK_API_KEY"),baseUrl:h(p("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:h(p("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:r,apiKey:h(p("NVIDIA_API_KEY"),p("NVIDIA_NIM_API_KEY")),baseUrl:h(p("NVIDIA_BASE_URL"),p("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:h(p("NVIDIA_MODEL"),p("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:r,apiKey:h(p("GEMINI_API_KEY"),p("GOOGLE_API_KEY")),baseUrl:h(p("GEMINI_BASE_URL"),e.defaultBaseUrl),model:p("GEMINI_MODEL")};case"huggingface":return{provider:r,apiKey:p("HF_TOKEN"),baseUrl:h(p("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:h(p("HF_LLM_MODEL"),p("HF_MODEL"))};case"ollama":return{provider:r,apiKey:p("OLLAMA_API_KEY"),baseUrl:h(p("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:p("OLLAMA_MODEL")};case"cloudflare":return{provider:r,accountId:p("CLOUDFLARE_ACCOUNT_ID"),apiKey:p("CLOUDFLARE_API_TOKEN"),baseUrl:p("CLOUDFLARE_AI_BASE_URL"),model:p("CLOUDFLARE_MODEL")};case"custom":return{provider:r,apiKey:p("CUSTOM_AI_API_KEY"),baseUrl:p("CUSTOM_AI_BASE_URL"),model:p("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:h(p("OPENAI_API_KEY"),p("MODEL_API_KEY")),baseUrl:h(p("OPENAI_BASE_URL"),p("MODEL_BASE_URL")),model:h(p("OPENAI_MODEL"),p("MODEL_NAME"))}}}function Hr(){let r=p("TOOLNET_LLM_PROVIDER"),e=r&&ae(r)?r:qr(),t=ie(e),o=_e(e);return{provider:e,apiKey:h(p("TOOLNET_LLM_API_KEY"),o.apiKey),baseUrl:h(p("TOOLNET_LLM_BASE_URL"),o.baseUrl,t.defaultBaseUrl),model:h(p("TOOLNET_LLM_MODEL"),o.model,t.defaultModel),accountId:h(p("TOOLNET_LLM_ACCOUNT_ID"),o.accountId)}}function Vr(){let r=p("TOOLNET_EMBEDDING_PROVIDER");return r==="local"?"local":r&&ae(r)?r:p("HF_TOKEN")||p("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Wr(){let r=Vr();if(r==="local")return{provider:"local",model:h(p("TOOLNET_EMBEDDING_MODEL"),p("LOCAL_EMBEDDING_MODEL"))};let e=ie(r),t,o,s,n;switch(r){case"huggingface":t=p("HF_TOKEN"),o=p("HF_INFERENCE_BASE_URL"),s=p("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=p("OPENAI_API_KEY"),o=p("OPENAI_BASE_URL"),s=p("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=p("CLOUDFLARE_API_TOKEN"),o=p("CLOUDFLARE_AI_BASE_URL"),s=p("CLOUDFLARE_EMBEDDING_MODEL"),n=p("CLOUDFLARE_ACCOUNT_ID");break;default:t=_e(r).apiKey,o=_e(r).baseUrl,s=p(`${r.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}return{provider:r,apiKey:h(p("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:h(p("TOOLNET_EMBEDDING_BASE_URL"),o,e.defaultBaseUrl),model:h(p("TOOLNET_EMBEDDING_MODEL"),s),accountId:h(p("TOOLNET_EMBEDDING_ACCOUNT_ID"),n)}}function nt(){let r=Hr(),e=Wr();return{llm:r,embedding:e,legacy:{llm:!p("TOOLNET_LLM_PROVIDER")&&!!st(),embedding:!p("TOOLNET_EMBEDDING_PROVIDER")&&!!(p("HF_TOKEN")||p("HF_EMBEDDING_MODEL"))}}}var ce=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`,o=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(!o.ok)throw new Error(`HF embedding failed: ${o.status} ${await o.text()}`);let s=await o.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>Yr(n))}};function Yr(r){if(!Array.isArray(r))throw new Error("Invalid embedding");if(r.length>0&&typeof r[0]=="number")return r;if(r.length>0&&Array.isArray(r[0])){let e=r;if(e.length===0)return[];let t=e[0].length,o=new Array(t).fill(0);for(let s of e)for(let n=0;n<t;n++)o[n]+=s[n]??0;for(let s=0;s<t;s++)o[s]/=e.length;return o}throw new Error("Unsupported embedding shape")}import{createHash as Jr}from"node:crypto";var le=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),o=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of o){let i=Jr("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return Qr(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function Qr(r){let e=Math.sqrt(r.reduce((t,o)=>t+o*o,0));return e===0?r:r.map(t=>t/e)}var de=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),o=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:e})});if(!o.ok)throw new Error(`Embedding failed: ${o.status} ${await o.text()}`);let n=(await o.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!n||n.length!==e.length||n.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return n}};var ke=class{constructor(e,t=new le){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 Zr(){let r=nt().embedding;return r.provider==="local"?null:r.provider==="huggingface"?!r.apiKey||!r.model?null:new ce({token:r.apiKey,model:r.model}):r.baseUrl&&r.model?new de({apiKey:r.apiKey,baseUrl:r.baseUrl,model:r.model}):null}function it(){return new ke(Zr())}import*as C from"typescript";var O=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(o=>o.projectId===e&&(o.name===t||o.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 o of e)this.addSymbol(o);for(let o of t)this.addEdge(o)}clearProject(e){for(let[t,o]of this.symbols)o.projectId===e&&this.symbols.delete(t);for(let[t,o]of this.edges)o.projectId===e&&this.edges.delete(t)}};function pe(r,e){let t=r.allSymbols(e),o=r.allEdges(e),s=i=>t.filter(a=>a.type===i).length,n=i=>o.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:o.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 me=class{constructor(e){this.graph=e}graph;callees(e,t,o=3){return this.walk(e,t,"out",o)}callers(e,t,o=3){return this.walk(e,t,"in",o)}walk(e,t,o,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 d=o==="out"?c.filter(f=>f.from===l.id):c.filter(f=>f.to===l.id);for(let f of d){let m=o==="out"?f.to:f.from;if(i.has(m))continue;i.add(m);let u=this.graph.getSymbol(m);if(!u)continue;let S=l.depth+1;n.push({symbol:u,depth:S}),a.push({id:m,depth:S})}}return n}};var fe=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 ue=class{constructor(e){this.graph=e}graph;analyze(e,t,o=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>=o)continue;let l=s.filter(d=>d.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(d.type));for(let d of l){if(n.has(d.from))continue;n.add(d.from);let f=this.graph.getSymbol(d.from);if(!f)continue;let m=c.depth+1;a.push({symbol:f,depth:m,relation:d.type}),i.push({id:d.from,depth:m})}}return a}};function ro(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var ge=class{constructor(e){this.graph=e}graph;map(e,t){let o=this.graph.allSymbols(e),s=[];for(let n of t){let i=o.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>ro(l,n));if(c.length===0){let l=i.find(d=>d.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 oo={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function so(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function at(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var he=class{constructor(e){this.graph=e}graph;analyze(e,t,o=4){let s=this.graph.allEdges(e),n=new Map,i=0;for(let d of t){d.fileStatus==="deleted"?i+=8:d.fileStatus==="renamed"?i+=5:i+=2,d.symbol.type==="interface"&&(i+=5),d.symbol.type==="class"&&(i+=3);let f=new Set([d.symbol.id]),m=[{id:d.symbol.id,depth:0}];for(;m.length;){let u=m.shift();if(u.depth>=o)continue;let S=s.filter(b=>b.to===u.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(b.type));for(let b of S){if(f.has(b.from))continue;f.add(b.from);let A=this.graph.getSymbol(b.from);if(!A)continue;let R=u.depth+1,W=`${d.symbol.id}:${A.id}`;n.set(W,{symbol:A,relation:b.type,depth:R,sourceSymbolId:d.symbol.id});let T=oo[b.type]??1;i+=Math.max(1,T-(R-1)),m.push({id:A.id,depth:R})}}}let a=[...n.values()].sort((d,f)=>d.depth-f.depth),c=[...new Set(a.map(d=>d.symbol.filePath))],l=c.filter(at);return l.length===0&&l.push(...c.filter(d=>!at(d)).slice(0,10)),{risk:so(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as no}from"node:child_process";import{promisify as io}from"node:util";var Ne=io(no);function ao(r){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let o of r.matchAll(t)){let s=Number(o[1]),n=Number(o[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function co(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function ct(r){let e="";try{e=(await Ne("git",["diff","HEAD","--name-status","--no-renames"],{cwd:r,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let o of e.split(/\r?\n/).filter(Boolean)){let[s,...n]=o.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await Ne("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:co(s),ranges:ao(a)})}try{let o=await Ne("git",["ls-files","--others","--exclude-standard"],{cwd:r});for(let s of o.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===s)||t.push({filePath:s,status:"added",ranges:[]})}catch{}return t}var ye=class{constructor(e){this.graph=e;this.mapper=new ge(e),this.blast=new he(e)}graph;mapper;blast;async analyzeGitDiff(e,t,o={}){let s=await ct(t),n=this.mapper.map(e,s),i=this.blast.analyze(e,n,o.maxDepth??4);return{mode:"git_diff",changes:s,...i}}analyzeFile(e,t,o={}){let s=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,s,o.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 lo}from"node:crypto";import{readFile as po}from"node:fs/promises";import{join as mo}from"node:path";function lt(r){return lo("sha256").update(r).digest("hex")}var Se=class{sanitizer=new k;async build(e,t,o,s={}){let n=s.maxLines??80,i=s.overlapLines??10,a=new Map;for(let l of o){let d=a.get(l.filePath)??[];d.push(l),a.set(l.filePath,d)}let c=[];for(let[l,d]of a){let f;try{f=await po(mo(t,l),"utf8")}catch{continue}let m=f.split(/\r?\n/),u=d.filter(S=>S.type!=="file"&&typeof S.startLine=="number"&&typeof S.endLine=="number");if(u.length>0)for(let S of u)c.push(...this.chunkRange({projectId:e,filePath:l,lines:m,symbol:S,startLine:S.startLine,endLine:S.endLine,maxLines:n,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:l,lines:m,startLine:1,endLine:Math.max(1,m.length),maxLines:n,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:o,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)),d=[],f=c,m=0;for(;f<=l;){let u=Math.min(l,f+i-1),S=s.slice(f-1,u).join(`
|
|
5
|
+
`).trim();if(S){let b=this.sanitizer.sanitize(S).text,A=lt(b),R=[t,o,n?.id??"file",String(m),A].join(":");d.push({id:lt(R).slice(0,32),projectId:t,filePath:o,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:f,endLine:u,content:b,contentHash:A})}if(u>=l)break;f=u-a+1,m++}return d}};var be=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 Ee=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 Ce=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[o,s]of this.records)s.projectId===e&&(this.records.delete(o),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let o of e)!o?.id||!o?.projectId||!Array.isArray(o.vector)||(this.records.set(o.id,o),t++);return t}search(e,t,o=10){let s=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=fo(t,n.vector);s.push({id:n.id,score:i,metadata:n.metadata})}return s.sort((n,i)=>i.score-n.score).slice(0,o)}size(){return this.records.size}};function fo(r,e){if(r.length===0||e.length===0||r.length!==e.length)return 0;let t=0,o=0,s=0;for(let n=0;n<r.length;n++){let i=r[n]??0,a=e[n]??0;t+=i*a,o+=i*i,s+=a*a}return o===0||s===0?0:t/(Math.sqrt(o)*Math.sqrt(s))}function dt(r,e){let t=r.toLowerCase().replaceAll("\\","/"),o=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(o);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 xe=class{constructor(e){this.options=e}options;vectors=new Ce;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:o,embeddings:s,graph:n,model:i}=this.options,a=new be(o),c=new Ee(o),l=await new Se().build(e,t,n.allSymbols(e));this.chunks.clear();for(let E of l)this.chunks.set(E.id,E);let d=await a.load(e),f=!d||d.chunks.length!==l.length||d.chunks.some(E=>!this.chunks.has(E.id));f&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:l});let m=await c.load(e),u=0;m&&m.model===i&&(u=this.vectors.importRecords(m.records));let S=new Set(l.map(E=>E.id)),b=0;for(let E of this.vectors.exportProject(e))S.has(E.id)||this.vectors.remove(E.id)&&b++;let A=l.filter(E=>{let I=this.vectors.get(E.id);return I?I.metadata?.contentHash!==E.contentHash:!0}),R=0,W=8,T=this.vectors.exportProject(e)[0]?.vector.length;for(let E=0;E<A.length;E+=W){let I=A.slice(E,E+W),gr=I.map(w=>[`file: ${w.filePath}`,w.symbolName?`symbol: ${w.symbolName}`:"",w.symbolType?`type: ${w.symbolType}`:"",w.content].filter(Boolean).join(`
|
|
6
|
+
`)),hr=await s.embedMany(gr);for(let w=0;w<I.length;w++){let L=I[w],_=hr[w];if(!(!L||!_||_.length===0)){if(T===void 0&&(T=_.length),_.length!==T){console.warn(`[code-semantic] skip dimension mismatch: ${_.length} != ${T}`);continue}this.vectors.upsert({id:L.id,projectId:e,vector:_,metadata:{contentHash:L.contentHash,filePath:L.filePath,symbolName:L.symbolName,symbolType:L.symbolType,startLine:L.startLine,endLine:L.endLine}}),R++}}}let je=this.vectors.exportProject(e),Ue=R>0||b>0||!m||m.model!==i;return Ue&&await c.save({version:1,projectId:e,model:i,dimensions:je[0]?.vector.length??T??0,updatedAt:new Date().toISOString(),records:je}),{chunks:l.length,vectorsLoaded:u,vectorsIndexed:R,vectorsRemoved:b,totalVectors:je.length,savedChunks:f,savedVectors:Ue}}async search(e,t=8){let o=await this.options.embeddings.embed(e),s=this.vectors.search(this.options.projectId,o,Math.max(t*4,20)),n=new Set(N(e)),i=[];for(let a of s){let c=this.chunks.get(a.id);if(!c)continue;let l=new Set(N([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),d=0;for(let b of n)l.has(b)&&d++;let f=n.size===0?0:d/n.size,m=Math.max(0,a.score),u=dt(c.filePath,e),S=(m*.75+f*.25)*u;i.push({chunk:c,score:S,vectorScore:m,lexicalScore:f})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}};import*as x from"typescript";import*as g from"typescript";var zi=new Set([g.SyntaxKind.EqualsToken,g.SyntaxKind.PlusEqualsToken,g.SyntaxKind.MinusEqualsToken,g.SyntaxKind.AsteriskEqualsToken,g.SyntaxKind.SlashEqualsToken,g.SyntaxKind.PercentEqualsToken,g.SyntaxKind.QuestionQuestionEqualsToken,g.SyntaxKind.AmpersandAmpersandEqualsToken,g.SyntaxKind.BarBarEqualsToken]);function uo(r){return r.replaceAll("\\","/").toLowerCase()}var B=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e),s=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,o);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 o=uo(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let n=null,i=0;if(o.startsWith("bin/"))n="cli",i=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(o))n="cli",i=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(o))n="main",i=90,s.push("main/server file");else if(o.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(o))n="runtime",i=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(o)){let c=t.filter(d=>d.to===e.id&&d.type!=="DEFINES").length,l=t.filter(d=>d.from===e.id&&d.type!=="DEFINES").length;(o.startsWith("packages/")||c===0||l>0)&&(n="package",i=o.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 ve=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),pt=new Set(["CALLS","CALL_REFERENCE"]),P=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let o=t.trim().toLowerCase();return o?this.graph.allSymbols(e).filter(s=>s.name.toLowerCase().includes(o)||(s.qualifiedName?.toLowerCase().includes(o)??!1)||s.filePath.toLowerCase().includes(o)).sort((s,n)=>{let i=s.name.toLowerCase()===o,a=n.name.toLowerCase()===o;return i!==a?i?-1:1:s.filePath.localeCompare(n.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,pt)}callees(e,t){return this.relatedOutgoing(e,t,pt)}dependents(e,t){return this.relatedIncoming(e,t,ve)}dependencies(e,t){return this.relatedOutgoing(e,t,ve)}neighborhood(e,t,o=1){let s=this.graph.getSymbol(t);return!s||s.projectId!==e?null:{center:s,incoming:this.walk(e,t,"incoming",o),outgoing:this.walk(e,t,"outgoing",o)}}shortestPath(e,t,o,s=12){let n=this.graph.getSymbol(t),i=this.graph.getSymbol(o);if(!n||!i||n.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===o)return{found:!0,distance:0,symbols:[n],edges:[]};let a=this.graph.allEdges(e).filter(m=>ve.has(m.type)),c=new Map;for(let m of a){let u=c.get(m.from)??[];u.push(m),c.set(m.from,u)}let l=[{id:t,depth:0}],d=new Set([t]),f=new Map;for(;l.length>0;){let m=l.shift();if(!(m.depth>=s)){for(let u of c.get(m.id)??[])if(!d.has(u.to)){if(d.add(u.to),f.set(u.to,{node:m.id,edge:u}),u.to===o)return this.buildPath(t,o,f);l.push({id:u.to,depth:m.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,o){let s=[t],n=[],i=t;for(;i!==e;){let c=o.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,o,s){let n=this.graph.allEdges(e).filter(l=>ve.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 d of n){if(!(o==="incoming"?d.to===l.id:d.from===l.id))continue;let m=o==="incoming"?d.from:d.to;if(a.has(m))continue;let u=this.graph.getSymbol(m);u&&(a.add(m),c.push({symbol:u,depth:l.depth+1,via:d}),i.push({id:m,depth:l.depth+1}))}}return c}relatedIncoming(e,t,o){return[...new Set(this.graph.allEdges(e).filter(n=>n.to===t&&o.has(n.type)).map(n=>n.from))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}relatedOutgoing(e,t,o){return[...new Set(this.graph.allEdges(e).filter(n=>n.from===t&&o.has(n.type)).map(n=>n.to))].map(n=>this.graph.getSymbol(n)).filter(n=>!!n)}};var mt=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Oe(r){return r.replaceAll("\\","/").toLowerCase()}function go(r){let e=Oe(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function ho(r){let e=Oe(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var U=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e),s=new Set(new B(this.graph).detect(e).map(i=>i.symbolId)),n=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||go(i.filePath)||s.has(i.id)||ho(i)||o.filter(u=>u.to===i.id&&mt.has(u.type)).length>0)continue;let c=o.filter(u=>u.from===i.id&&mt.has(u.type)),l=["no incoming usage edge"],d=50;(i.type==="function"||i.type==="method")&&(d+=20,l.push("callable symbol")),i.type==="property"&&(d-=15),c.length===0&&(d+=10,l.push("no outgoing dependency")),Oe(i.filePath).includes("/internal/")&&(d+=10,l.push("internal implementation")),i.name.startsWith("_")&&(d+=5);let m=d>=75?"high":d>=55?"medium":"low";n.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:m,score:d,reasons:l})}return n.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var yo=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),z=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e).filter(i=>yo.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,d=0;for(let f of o){let m=s.get(f.from),u=s.get(f.to);!m||!u||m.filePath===u.filePath||(m.filePath===i&&(a.add(u.filePath),l++),u.filePath===i&&(c.add(m.filePath),d++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:l,incomingEdges:d}})}};import{homedir as Go}from"node:os";import{join as $o}from"node:path";import{DeleteObjectCommand as So,GetObjectCommand as bo,HeadObjectCommand as Eo,ListObjectsV2Command as Co,PutObjectCommand as xo,S3Client as vo}from"@aws-sdk/client-s3";import{getSignedUrl as Po}from"@aws-sdk/s3-request-presigner";var Pe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new vo({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,o="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new xo({Bucket:this.bucket,Key:e,Body:s,ContentType:o}))}async get(e){let t=await Po(this.client,new bo({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`HF download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.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 Eo({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 So({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let s=await this.client.send(new Co({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});o=s.IsTruncated?s.NextContinuationToken:void 0}while(o);return t}};import{access as ft,mkdir as wo,readFile as Ao,readdir as Ro,rm as jo,stat as ut,writeFile as Lo}from"node:fs/promises";import{dirname as Mo,join as To,relative as gt,resolve as Io}from"node:path";var q=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Io(this.root,t)}async put(e,t){let o=this.path(e);await wo(Mo(o),{recursive:!0}),await Lo(o,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 ft(this.path(e)),!0}catch{return!1}}async delete(e){await jo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),o=[];try{await ft(t)}catch{return o}let s=async i=>{let a=await Ro(i,{withFileTypes:!0});for(let c of a){let l=To(i,c.name);if(c.isDirectory()){await s(l);continue}let d=await ut(l);o.push({key:gt(this.root,l),size:d.size,updatedAt:d.mtime.toISOString()})}},n=await ut(t);return n.isDirectory()?await s(t):o.push({key:gt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),o}};import{DeleteObjectCommand as _o,GetObjectCommand as ko,HeadObjectCommand as No,ListObjectsV2Command as Oo,PutObjectCommand as Do,S3Client as Fo}from"@aws-sdk/client-s3";import{getSignedUrl as Ko}from"@aws-sdk/s3-request-presigner";var H=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Fo({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Do({Bucket:this.bucket,Key:e,Body:s,ContentType:o}))}async get(e){let t=await Ko(this.client,new ko({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`${this.name} download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.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 No({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 _o({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let s=await this.client.send(new Oo({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});o=s.IsTruncated?s.NextContinuationToken:void 0}while(o);return t}};function De(r,e){return console.warn(e),new q(r)}function ht(r){let e=r.localRoot??$o(Go(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new H({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):De(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new H({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):De(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new Pe({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):De(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new q(e)}var we=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 o=JSON.parse(t);if(!Array.isArray(o))throw new Error("Invalid memory snapshot");return o}async save(e,t){let o=JSON.stringify(t,null,2);await this.storage.put(this.key(e),o,"application/json")}};function Bo(r){return new Promise(e=>setTimeout(e,r))}async function yt(r,e={}){let t=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await r()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,o*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Bo(c+l)}throw n}var Uo=new Set(["put","get","getText","delete","list"]);function St(r,e={}){return new Proxy(r,{get(t,o){let s=Reflect.get(t,o,t);return typeof s!="function"?s:Uo.has(o)?(...n)=>yt(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function bt(r){let e=r.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 Et(r){let e=r.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 o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(o)return`${o[1]}memory/records/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),o)return`${o[1]}memory/vectors/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),o)return`${o[1]}code/graph/${o[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 Ae=class{constructor(e,t,o,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=o,this.folder=bt(s??o),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(),o=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"&&(o=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,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=Et(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,o){return await this.ensureRegistered(),this.provider.put(this.key(e),t,o)}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 Qo}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Zo}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Ct}from"zod";var xt={query:Ct.string(),limit:Ct.number().int().min(1).max(20).optional()};async function vt(r,e){return r.retrieval.search(r.project.id,e.query,{topK:e.limit??8}).map(o=>({id:o.memory.id,type:o.memory.type,content:o.memory.content,importance:o.memory.importance,score:o.score,tags:o.memory.tags}))}import{z as V}from"zod";var Pt={type:V.enum(["activity","decision","rule","todo","summary"]),content:V.string().min(1),tags:V.array(V.string()).optional(),importance:V.enum(["critical","high","normal","temporary"]).optional()};async function wt(r,e){let t=r.memory.remember({projectId:r.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),t}import{z as zo}from"zod";var At={id:zo.string().min(1)};async function Rt(r,e){let t=r.memory.delete(e.id);return t&&r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),{deleted:t}}import{z as qo}from"zod";var jt={name:qo.string().min(1)};async function Lt(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as Ho}from"zod";function j(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let o=new P(r.graph),s=o.findSymbols(r.project.id,e).find(n=>n.name===e||n.qualifiedName===e);return s||(o.findSymbols(r.project.id,e)[0]??null)}function v(r){return{id:r.id,name:r.name,qualifiedName:r.qualifiedName,type:r.type,filePath:r.filePath,startLine:r.startLine,endLine:r.endLine}}var Mt={symbolId:Ho.string().min(1)};async function Tt(r,e){let t=j(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let s=new P(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:v(t),count:s.length,callers:s.map(v)}}import{z as It}from"zod";var _t={query:It.string().min(1),limit:It.number().int().min(1).max(50).optional()};async function kt(r,e){let t=e.query.toLowerCase(),o=e.limit??20;return r.graph.allSymbols(r.project.id).filter(s=>s.name.toLowerCase().includes(t)||s.qualifiedName?.toLowerCase().includes(t)||s.filePath.toLowerCase().includes(t)).slice(0,o)}import{z as Nt}from"zod";var Ot={query:Nt.string().optional(),memoryLimit:Nt.number().int().min(1).max(20).optional()};async function Dt(r,e){let t=pe(r.graph,r.project.id),o=r.memory.recent(r.project.id,5),s=e.query?r.retrieval.search(r.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:t,recent:o,relevant:s.map(n=>n.memory)}}import{z as Wo}from"zod";var Vo=["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"],M=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",o){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let d of Vo){let f=`${i}/${d}`,m=await this.storage.get(f);m&&(await this.storage.put(`${a}/${d}`,m,"application/json"),c.push(d))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:o};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 o=this.snapshotPrefix(e,t),s=await this.storage.getText(`${o}/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(`${o}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let o=this.snapshotPrefix(e,t),s=await this.storage.list(o);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 Ft={reason:Wo.string().optional()};async function Kt(r,e){if(!r.storage)throw new Error("Storage unavailable");return new M(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function Gt(r){if(!r.storage)throw new Error("Storage unavailable");return new M(r.storage).list(r.project.id)}import{z as Yo}from"zod";var $t={snapshotId:Yo.string().min(1)};async function Bt(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new M(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as Fe}from"zod";var Ut={symbolId:Fe.string().min(1),direction:Fe.enum(["callers","callees"]).optional(),depth:Fe.number().int().min(1).max(10).optional()};async function zt(r,e){let t=new me(r.graph),o=e.direction??"callees",s=e.depth??3,n=o==="callers"?t.callers(r.project.id,e.symbolId,s):t.callees(r.project.id,e.symbolId,s);return{direction:o,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 qt}from"zod";var Ht={symbolId:qt.string().min(1),depth:qt.number().int().min(1).max(10).optional()};async function Vt(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let s=new ue(r.graph).analyze(r.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 Wt(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:pe(r.graph,r.project.id)}}import{z as Yt}from"zod";var Jt={filePath:Yt.string().min(1),direction:Yt.enum(["dependencies","dependents","both"]).optional()};async function Qt(r,e){let o=new z(r.graph).analyze(r.project.id).find(c=>c.filePath===e.filePath);if(!o)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let s=r.graph.allSymbols(r.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:o.filePath,outgoingEdges:o.outgoingEdges,incomingEdges:o.incomingEdges,dependencies:a==="dependents"?[]:o.dependencies.map(i),dependents:a==="dependencies"?[]:o.dependents.map(i)}}import{z as Zt}from"zod";var Xt={query:Zt.string().min(1),limit:Zt.number().int().min(1).max(20).optional()};async function er(r,e){return r.codeSemantic?{available:!0,results:(await r.codeSemantic.search(e.query,e.limit??8)).map(o=>({id:o.chunk.id,filePath:o.chunk.filePath,symbol:o.chunk.symbolName,symbolType:o.chunk.symbolType,startLine:o.chunk.startLine,endLine:o.chunk.endLine,score:o.score,vectorScore:o.vectorScore,lexicalScore:o.lexicalScore,content:o.chunk.content}))}:{available:!1,results:[]}}import{z as Ke}from"zod";var tr={mode:Ke.enum(["git_diff","file"]).optional(),filePath:Ke.string().optional(),depth:Ke.number().int().min(1).max(10).optional()};async function rr(r,e){let t=new ye(r.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(r.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(r.project.id,r.project.rootPath,{maxDepth:e.depth})}import{z as Jo}from"zod";var or={symbol:Jo.string().min(1)};async function sr(r,e){let t=j(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let s=new P(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:v(t),count:s.length,dependents:s.map(v)}}import{z as Ge}from"zod";var nr={from:Ge.string().min(1),to:Ge.string().min(1),maxDepth:Ge.number().int().min(1).max(30).optional()};async function ir(r,e){let t=j(r,e.from),o=j(r,e.to);if(!t||!o)return{found:!1,fromFound:!!t,toFound:!!o,path:[],edges:[]};let n=new P(r.graph).shortestPath(r.project.id,t.id,o.id,e.maxDepth??12);return{found:n.found,distance:n.distance,from:v(t),to:v(o),path:n.symbols.map(v),edges:n.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as $e}from"zod";var ar={symbol:$e.string().min(1),depth:$e.number().int().min(1).max(5).optional(),limit:$e.number().int().min(1).max(200).optional()};async function cr(r,e){let t=j(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let s=new P(r.graph).neighborhood(r.project.id,t.id,e.depth??1);if(!s)return{found:!1,query:e.symbol};let n=e.limit??50;return{found:!0,center:v(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:v(i.symbol)})),outgoing:s.outgoing.slice(0,n).map(i=>({depth:i.depth,via:i.via?.type,symbol:v(i.symbol)}))}}import{z as Be}from"zod";var dr={confidence:Be.enum(["high","medium","low","all"]).optional(),filePath:Be.string().min(1).optional(),limit:Be.number().int().min(1).max(500).optional()},lr={high:3,medium:2,low:1};async function pr(r,e){let o=new U(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=lr[e.confidence];o=o.filter(a=>lr[a.confidence]>=i)}e.filePath&&(o=o.filter(i=>i.filePath===e.filePath));let s=o.length,n=e.limit??100;return{total:s,high:o.filter(i=>i.confidence==="high").length,medium:o.filter(i=>i.confidence==="medium").length,low:o.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:o.slice(0,n)}}function y(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}function Xo(r){let e=new Qo({name:"toolnet-memory",version:"0.1.0"});return e.tool("memory_search","Search relevant long-term memory for the current project.",xt,async t=>y(await vt(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Pt,async t=>y(await wt(r,t))),e.tool("memory_forget","Delete a memory by id.",At,async t=>y(await Rt(r,t))),e.tool("find_symbol","Find code symbols by exact name.",jt,async t=>y(await Lt(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Mt,async t=>y(await Tt(r,t))),e.tool("code_search","Search indexed code symbols and files.",_t,async t=>y(await kt(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",Ot,async t=>y(await Dt(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Ut,async t=>y(await zt(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Ht,async t=>y(await Vt(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>y(await Wt(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Jt,async t=>y(await Qt(r,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Xt,async t=>y(await er(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Ft,async t=>y(await Kt(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>y(await Gt(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",$t,async t=>y(await Bt(r,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.",tr,async t=>y(await rr(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",or,async t=>y(await sr(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",nr,async t=>y(await ir(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",ar,async t=>y(await cr(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",dr,async t=>y(await pr(r,t))),e}async function mr(r){let e=Xo(r),t=new Zo;await e.connect(t)}import{closeSync as es,mkdirSync as ts,openSync as rs,readFileSync as os,unlinkSync as fr,writeFileSync as ss}from"node:fs";import{tmpdir as ns}from"node:os";import{join as ur}from"node:path";function is(r){try{return process.kill(r,0),!0}catch(e){return e?.code==="EPERM"}}var Re=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=ur(ns(),"toolnet-memory-locks");ts(t,{recursive:!0});let o=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=ur(t,`${o}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=rs(this.path,"wx");ss(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),es(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let o=!0;try{let s=JSON.parse(os(this.path,"utf8"));Number.isInteger(s.pid)&&is(s.pid)&&(o=!1)}catch{o=!0}if(!o)throw new Error("ToolNet Memory is already running for this project");try{fr(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{fr(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};async function as(){let r=ze(),e=new J().detect(),t=ht({provider:r.storage.provider,huggingface:r.storage.huggingface,localRoot:r.storage.localRoot}),o=St(t,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),s=new Ae(o,e.id,e.name,e.remote??e.name),n=new Re(e.id);await n.acquire();let i=()=>{n.release().finally(()=>process.exit(0))};process.once("SIGINT",i),process.once("SIGTERM",i);let a=new ee,c=new we(s);a.importRecords(await c.load(e.id));let l=new ne(a),d=new O,f=await new $(s).load(e.id);f&&d.import(f.symbols,f.edges);let m=new fe(d),u=new xe({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:it(),graph:d});await u.initialize(),await mr({project:e,memory:a,retrieval:l,graph:d,references:m,codeSemantic:u,memoryStore:c,storage:s})}as().catch(r=>{console.error(r),process.exit(1)});
|