toolnet-memory 0.2.9 → 0.2.11

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.
@@ -1,8 +1,8 @@
1
- import{closeSync as Gr,mkdirSync as zr,openSync as Br,rmSync as Hr,writeFileSync as Kr}from"node:fs";import{join as De}from"node:path";import{existsSync as dt,readFileSync as pt}from"node:fs";import{homedir as mt}from"node:os";import{join as ut}from"node:path";function ft(n){let e=n.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 gt(){let n=process.env.TOOLNET_GLOBAL_ENV??ut(mt(),".config","toolnet-memory",".env");if(!dt(n))return;let e=pt(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let i=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=ft(r.slice(s+1)))}}gt();function U(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function O(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function ze(){return{memory:{autoCapture:U(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:U(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:U(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:U(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:O(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:O(process.env.MEMORY_RERANK_TOP,10),finalContext:O(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:O(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:O(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ht}from"node:crypto";import{existsSync as Te,mkdirSync as yt,readFileSync as St,renameSync as bt,writeFileSync as xt}from"node:fs";import{basename as wt,dirname as J,join as Y,parse as Ke,resolve as F}from"node:path";var We=".toolnet",Et="project.json";function Ct(n){return ht("sha256").update(n).digest("hex").slice(0,16)}function ke(n){return Y(n,We,Et)}function vt(n){return Te(ke(n))}function Pt(n,e){let t=F(n),r=Ke(t).root;for(;;){if(vt(t))return t;if(t===r||e&&t===F(e))break;let s=J(t);if(s===t)break;t=s}return null}function Rt(n){let e=F(n),t=Ke(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(i=>Te(Y(e,i))))return e;if(e===t)break;let s=J(e);if(s===e)break;e=s}return F(n)}function Tt(n){let e;try{e=JSON.parse(St(n,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${n}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:J(J(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Be(n,e){let t=Y(n,We);yt(t,{recursive:!0});let r=ke(n),s=`${r}.tmp-${process.pid}`;xt(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),bt(s,r)}function He(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}var q=class{detect(e=process.cwd()){let t=F(e),r=Rt(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Te(Y(r,l))),o=Pt(t,i?r:void 0);if(o){let l=ke(o),u=Tt(l);return u.rootPath!==o&&(u.rootPath=o,u.updatedAt=new Date().toISOString(),Be(o,u)),He(u,o)}let a=new Date().toISOString(),m=wt(r),c={version:1,id:Ct(r),name:m,remote:m,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Be(r,c),He(c,r)}};var kt=[{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 r of kt){let s=new RegExp(r.regex.source,r.regex.flags);for(let i of e.matchAll(s))t.push({type:r.type,value:i[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var _=class{scanner=new Z;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let i of r)s.add(i.type),t=t.split(i.value).join(`[REDACTED:${i.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let i=r.toLowerCase();i.includes("password")||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Q=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(i=>Lt(i))}};function Lt(n){if(!Array.isArray(n))throw new Error("Invalid embedding");if(n.length>0&&typeof n[0]=="number")return n;if(n.length>0&&Array.isArray(n[0])){let e=n;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let i=0;i<t;i++)r[i]+=s[i]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as jt}from"node:crypto";var X=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 o=jt("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[o]+=1}return At(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function At(n){let e=Math.sqrt(n.reduce((t,r)=>t+r*r,0));return e===0?n:n.map(t=>t/e)}var Le=class{constructor(e,t=new X){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Ve(){let n=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=n?new Q({token:n,model:e}):null;return new Le(t)}import{readdir as Ot}from"node:fs/promises";import{extname as Ft,join as _t,relative as $t}from"node:path";import{basename as Nt}from"node:path";var Mt=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),It=new Set([".pem",".key",".p12",".pfx"]);function Ue(n){let e=Nt(n).toLowerCase();if(Mt.has(e))return!0;for(let t of It)if(e.endsWith(t))return!0;return!1}var Dt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Gt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function je(n){let e=[];async function t(r){let s=await Ot(r,{withFileTypes:!0});for(let i of s){if(Gt.has(i.name))continue;let o=_t(r,i.name);if(i.isDirectory()){await t(o);continue}Dt.has(Ft(i.name))&&(Ue(o)||e.push($t(n,o)))}}return await t(n),e.sort()}import{readFile as zt}from"node:fs/promises";import{join as Bt}from"node:path";import{createHash as Ht}from"node:crypto";import*as E from"typescript";function Je(n,e){return Ht("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function Ae(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Ne(n,e,t){let r=Bt(e,t),s=await zt(r,"utf8"),i=E.createSourceFile(t,s,E.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?E.ScriptKind.TSX:E.ScriptKind.TS),o=[],a=[],m=[],c=[],l={id:Je(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:i.getLineAndCharacterOfPosition(i.end).line+1};o.push(l);let u=[],d=[];function f(g,x,y,w){let P=Je(n,`${t}:${y}:${w??x}:${g.pos}`);return o.push({id:P,projectId:n,name:x,qualifiedName:w??x,type:y,filePath:t,startLine:Ae(i,g),endLine:i.getLineAndCharacterOfPosition(g.end).line+1}),P}function h(g){if(!E.isStringLiteral(g.moduleSpecifier))return;let x=[],y=g.importClause;if(y?.name&&x.push({localName:y.name.text,importedName:"default",kind:"default"}),y?.namedBindings&&E.isNamedImports(y.namedBindings))for(let w of y.namedBindings.elements)x.push({localName:w.name.text,importedName:w.propertyName?.text??w.name.text,kind:"named"});y?.namedBindings&&E.isNamespaceImport(y.namedBindings)&&x.push({localName:y.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:g.moduleSpecifier.text,bindings:x})}function p(g,x){for(let y of g.heritageClauses??[])for(let w of y.types){let P=w.expression.getText(i).split(".").at(-1)??"";P&&c.push({fromId:x,targetName:P,type:y.token===E.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function b(g){let x=!1,y=!1;if(E.isImportDeclaration(g)&&h(g),E.isInterfaceDeclaration(g)&&f(g,g.name.text,"interface",g.name.text),E.isClassDeclaration(g)&&g.name){let w=f(g,g.name.text,"class",g.name.text);p(g,w),d.push({id:w,name:g.name.text}),y=!0}if(E.isFunctionDeclaration(g)&&g.name){let w=f(g,g.name.text,"function",g.name.text);u.push(w),x=!0}if(E.isMethodDeclaration(g)&&g.name){let w=g.name.getText(i),P=d.at(-1)?.name,v=f(g,w,"method",P?`${P}.${w}`:w);u.push(v),x=!0}if(E.isCallExpression(g)&&(E.isIdentifier(g.expression)&&m.push({callerId:u.at(-1),calleeName:g.expression.text,line:Ae(i,g)}),E.isPropertyAccessExpression(g.expression))){let w=g.expression;m.push({callerId:u.at(-1),qualifier:w.expression.getText(i),calleeName:w.name.text,line:Ae(i,g)})}E.forEachChild(g,b),x&&u.pop(),y&&d.pop()}return b(i),{filePath:t,symbols:o,imports:a,calls:m,heritage:c}}import{createHash as Kt}from"node:crypto";import{dirname as Wt,extname as Vt,normalize as Ut,posix as Jt}from"node:path";var $=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 qt(n,e,t,r){return Kt("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function j(n){return Ut(n).replaceAll("\\","/")}function Me(n,e,t){if(!e.startsWith("."))return;let r=j(Jt.join(Wt(n),e)),s=Vt(r),i;if(s===".js"){let o=r.slice(0,-3);i=[`${o}.ts`,`${o}.tsx`,`${o}.js`,`${o}.jsx`]}else if(s===".mjs"){let o=r.slice(0,-4);i=[`${o}.mts`,`${o}.ts`,`${o}.mjs`]}else if(s===".cjs"){let o=r.slice(0,-4);i=[`${o}.cts`,`${o}.ts`,`${o}.cjs`]}else s?i=[r]:i=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return i.find(o=>t.has(j(o)))}var D=class{build(e,t){let r=new $,s=new Map;for(let o of t)for(let a of o.symbols)r.addSymbol(a),a.type==="file"&&s.set(j(o.filePath),a);let i=new Set(s.keys());for(let o of t){let a=j(o.filePath),m=s.get(a);if(m){for(let c of o.symbols)c.id!==m.id&&r.addEdge(this.edge(e,m.id,"DEFINES",c.id));for(let c of o.imports){let l=Me(a,c.source,i);if(!l)continue;let u=s.get(l);u&&r.addEdge(this.edge(e,m.id,"IMPORTS",u.id,{source:c.source}))}for(let c of o.heritage){let l=r.findByName(e,c.targetName).filter(u=>u.type==="class"||u.type==="interface");for(let u of l)r.addEdge(this.edge(e,c.fromId,c.type,u.id))}for(let c of o.calls){if(!c.callerId)continue;let l=this.resolveCallTargets(e,o,c.calleeName,c.qualifier,t,r,i);for(let u of l)u.id!==c.callerId&&r.addEdge(this.edge(e,c.callerId,"CALLS",u.id,{line:c.line,qualifier:c.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,i,o,a){let m=j(t.filePath),c=o.findByName(e,r).filter(l=>j(l.filePath)===m);if(!s&&c.length)return c;if(s)for(let l of t.imports){if(!l.bindings.find(f=>f.kind==="namespace"&&f.localName===s))continue;let d=Me(m,l.source,a);if(d)return o.findByName(e,r).filter(f=>j(f.filePath)===d)}for(let l of t.imports){let u=l.bindings.find(p=>p.localName===r);if(!u)continue;let d=Me(m,l.source,a);if(!d)continue;let f=u.importedName==="default"?r:u.importedName,h=o.findByName(e,f).filter(p=>j(p.filePath)===d);if(h.length)return h}return o.findByName(e,r).filter(l=>l.type==="function"||l.type==="method")}edge(e,t,r,s,i){return{id:qt(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:i}}};var ee=class{async index(e,t){let r=await je(t),s=[];for(let o of r)try{s.push(await Ne(e,t,o))}catch(a){console.warn(`[indexer] skipped ${o}:`,a instanceof Error?a.message:a)}let i=new D().build(e,s);return{files:s.length,symbols:i.allSymbols(e).length,edges:i.allEdges(e).length,graph:i}}};import{execFile as Yt}from"node:child_process";import{promisify as Zt}from"node:util";var po=Zt(Yt);var G=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 Qt}from"node:crypto";import{readFile as Xt}from"node:fs/promises";import{join as er}from"node:path";function qe(n){return Qt("sha256").update(n).digest("hex")}var te=class{sanitizer=new _;async build(e,t,r,s={}){let i=s.maxLines??80,o=s.overlapLines??10,a=new Map;for(let c of r){let l=a.get(c.filePath)??[];l.push(c),a.set(c.filePath,l)}let m=[];for(let[c,l]of a){let u;try{u=await Xt(er(t,c),"utf8")}catch{continue}let d=u.split(/\r?\n/),f=l.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(f.length>0)for(let h of f)m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:i,overlapLines:o}));else m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,startLine:1,endLine:Math.max(1,d.length),maxLines:i,overlapLines:o}))}return m}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:i,maxLines:o}=e,a=Math.min(e.overlapLines,Math.max(0,o-1)),m=Math.max(1,e.startLine),c=Math.min(s.length,Math.max(m,e.endLine)),l=[],u=m,d=0;for(;u<=c;){let f=Math.min(c,u+o-1),h=s.slice(u-1,f).join(`
4
- `).trim();if(h){let p=this.sanitizer.sanitize(h).text,b=qe(p),g=[t,r,i?.id??"file",String(d),b].join(":");l.push({id:qe(g).slice(0,32),projectId:t,filePath:r,symbolId:i?.id,symbolName:i?.qualifiedName??i?.name,symbolType:i?.type,startLine:u,endLine:f,content:p,contentHash:b})}if(f>=c)break;u=f-a+1,d++}return l}};var re=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 se=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 oe=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let i of this.records.values()){if(i.projectId!==e)continue;let o=tr(t,i.vector);s.push({id:i.id,score:o,metadata:i.metadata})}return s.sort((i,o)=>o.score-i.score).slice(0,r)}size(){return this.records.size}};function tr(n,e){if(n.length===0||e.length===0||n.length!==e.length)return 0;let t=0,r=0,s=0;for(let i=0;i<n.length;i++){let o=n[i]??0,a=e[i]??0;t+=o*a,r+=o*o,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}function Ie(n){return n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function Ye(n,e){let t=n.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var ne=class{constructor(e){this.options=e}options;vectors=new oe;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:s,graph:i,model:o}=this.options,a=new re(r),m=new se(r),c=await new te().build(e,t,i.allSymbols(e));this.chunks.clear();for(let v of c)this.chunks.set(v.id,v);let l=await a.load(e),u=!l||l.chunks.length!==c.length||l.chunks.some(v=>!this.chunks.has(v.id));u&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:c});let d=await m.load(e),f=0;d&&d.model===o&&(f=this.vectors.importRecords(d.records));let h=new Set(c.map(v=>v.id)),p=0;for(let v of this.vectors.exportProject(e))h.has(v.id)||this.vectors.remove(v.id)&&p++;let b=c.filter(v=>{let k=this.vectors.get(v.id);return k?k.metadata?.contentHash!==v.contentHash:!0}),g=0,x=8,y=this.vectors.exportProject(e)[0]?.vector.length;for(let v=0;v<b.length;v+=x){let k=b.slice(v,v+x),ct=k.map(T=>[`file: ${T.filePath}`,T.symbolName?`symbol: ${T.symbolName}`:"",T.symbolType?`type: ${T.symbolType}`:"",T.content].filter(Boolean).join(`
5
- `)),lt=await s.embedMany(ct);for(let T=0;T<k.length;T++){let L=k[T],N=lt[T];if(!(!L||!N||N.length===0)){if(y===void 0&&(y=N.length),N.length!==y){console.warn(`[code-semantic] skip dimension mismatch: ${N.length} != ${y}`);continue}this.vectors.upsert({id:L.id,projectId:e,vector:N,metadata:{contentHash:L.contentHash,filePath:L.filePath,symbolName:L.symbolName,symbolType:L.symbolType,startLine:L.startLine,endLine:L.endLine}}),g++}}}let w=this.vectors.exportProject(e),P=g>0||p>0||!d||d.model!==o;return P&&await m.save({version:1,projectId:e,model:o,dimensions:w[0]?.vector.length??y??0,updatedAt:new Date().toISOString(),records:w}),{chunks:c.length,vectorsLoaded:f,vectorsIndexed:g,vectorsRemoved:p,totalVectors:w.length,savedChunks:u,savedVectors:P}}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)),i=new Set(Ie(e)),o=[];for(let a of s){let m=this.chunks.get(a.id);if(!m)continue;let c=new Set(Ie([m.filePath,m.symbolName??"",m.symbolType??"",m.content].join(" "))),l=0;for(let p of i)c.has(p)&&l++;let u=i.size===0?0:l/i.size,d=Math.max(0,a.score),f=Ye(m.filePath,e),h=(d*.75+u*.25)*f;o.push({chunk:m,score:h,vectorScore:d,lexicalScore:u})}return o.sort((a,m)=>m.score-a.score).slice(0,t)}size(){return this.chunks.size}};import{createHash as rr}from"node:crypto";import{dirname as sr,relative as ie,resolve as ae}from"node:path";import*as C from"typescript";function M(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function Ze(n){return rr("sha256").update(n).digest("hex").slice(0,24)}function z(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}function or(n){let e=n;if(e.name&&C.isIdentifier(e.name))return e.name.text}var ce=class{constructor(e){this.graph=e}graph;async resolveProject(e,t){let r=this.loadConfig(t),s=C.createProgram({rootNames:r.fileNames,options:r.options}),i=s.getTypeChecker(),o=[];for(let a of s.getSourceFiles()){if(a.isDeclarationFile)continue;let m=ae(a.fileName),c=M(ie(t,m));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=u=>{if(C.isCallExpression(u)){let d=this.resolveCall({projectId:e,rootPath:t,source:a,node:u,checker:i});d&&o.push(d)}C.isClassDeclaration(u)&&o.push(...this.resolveHeritage({projectId:e,rootPath:t,source:a,node:u,checker:i})),C.forEachChild(u,l)};l(a)}return{version:1,projectId:e,updatedAt:new Date().toISOString(),total:o.length,exact:o.filter(a=>a.confidence==="exact").length,high:o.filter(a=>a.confidence==="high").length,fallback:o.filter(a=>a.confidence==="fallback").length,resolutions:o}}resolveCall(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a;if(a=o.getResolvedSignature(i)?.declaration,!a){let c=o.getSymbolAtLocation(i.expression);a=c?.valueDeclaration??c?.declarations?.[0]}return a?this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:i,declaration:a,expression:i.expression.getText(s),kind:"CALL"}):this.fallbackCall(t,r,s,i)}resolveHeritage(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a=[];for(let m of i.heritageClauses??[])for(let c of m.types){let l=o.getSymbolAtLocation(c.expression),u=l?.valueDeclaration??l?.declarations?.[0];if(!u)continue;let d=this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:c,declaration:u,expression:c.getText(s),kind:m.token===C.SyntaxKind.ExtendsKeyword?"EXTENDS":"IMPLEMENTS"});d&&a.push(d)}return a}fromDeclaration(e){let t=e.declaration.getSourceFile();if(t.isDeclarationFile)return null;let r=M(ie(e.rootPath,ae(t.fileName)));if(r.startsWith("../")||r.includes("node_modules/"))return null;let s=z(t,e.declaration),i=or(e.declaration)??e.expression.split(".").at(-1),o=this.findGraphSymbol(e.projectId,r,s,i),a=M(ie(e.rootPath,ae(e.source.fileName)));return{id:Ze([e.projectId,a,z(e.source,e.sourceNode),e.kind,r,s].join(":")),projectId:e.projectId,kind:e.kind,sourceFile:a,sourceLine:z(e.source,e.sourceNode),expression:e.expression,targetFile:r,targetLine:s,targetName:i,targetQualifiedName:o?.qualifiedName,targetSymbolId:o?.id,confidence:o?"exact":"high",resolver:"typescript-checker"}}fallbackCall(e,t,r,s){let i=s.expression.getText(r).split(".").at(-1);if(!i)return null;let o=this.graph.findByName(e,i).filter(c=>c.type==="function"||c.type==="method");if(o.length!==1)return null;let a=o[0],m=M(ie(t,ae(r.fileName)));return{id:Ze(`${e}:${m}:${z(r,s)}:${a.id}`),projectId:e,kind:"CALL",sourceFile:m,sourceLine:z(r,s),expression:s.expression.getText(r),targetFile:a.filePath,targetLine:a.startLine,targetName:a.name,targetQualifiedName:a.qualifiedName,targetSymbolId:a.id,confidence:"fallback",resolver:"graph-fallback"}}findGraphSymbol(e,t,r,s){let o=this.graph.allSymbols(e).filter(a=>M(a.filePath)===M(t)).filter(a=>typeof a.startLine=="number"&&typeof a.endLine=="number"&&a.startLine<=r&&a.endLine>=r);if(s){let a=o.find(m=>m.name===s||(m.qualifiedName?.endsWith(`.${s}`)??!1));if(a)return a}return o.sort((a,m)=>(a.endLine??0)-(a.startLine??0)-((m.endLine??0)-(m.startLine??0)))[0]}loadConfig(e){let t=C.findConfigFile(e,C.sys.fileExists,"tsconfig.json");if(t){let s=C.readConfigFile(t,C.sys.readFile);if(s.error)throw new Error(C.flattenDiagnosticMessageText(s.error.messageText,`
6
- `));return C.parseJsonConfigFileContent(s.config,C.sys,sr(t))}return{fileNames:C.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,checkJs:!1,target:C.ScriptTarget.ES2022,module:C.ModuleKind.NodeNext,moduleResolution:C.ModuleResolutionKind.NodeNext,skipLibCheck:!0,noEmit:!0}}}};import{createHash as nr}from"node:crypto";import{dirname as ir,relative as B,resolve as H}from"node:path";import*as S from"typescript";function R(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function Oe(...n){return nr("sha256").update(n.join(":")).digest("hex").slice(0,24)}function K(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}var ar=new Set(["get","post","put","patch","delete","options","head"]),cr=new Set([S.SyntaxKind.EqualsToken,S.SyntaxKind.PlusEqualsToken,S.SyntaxKind.MinusEqualsToken,S.SyntaxKind.AsteriskEqualsToken,S.SyntaxKind.SlashEqualsToken,S.SyntaxKind.PercentEqualsToken,S.SyntaxKind.QuestionQuestionEqualsToken,S.SyntaxKind.AmpersandAmpersandEqualsToken,S.SyntaxKind.BarBarEqualsToken]),le=class{constructor(e){this.graph=e}graph;enrich(e,t,r){let s={routes:0,tests:0,usesType:0,writes:0,callReferences:0,properties:0},i=this.loadConfig(t),o=S.createProgram({rootNames:i.fileNames,options:i.options}),a=o.getTypeChecker();for(let m of o.getSourceFiles()){if(m.isDeclarationFile)continue;let c=R(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=this.fileNode(e,c);if(!l)continue;let u=d=>{if(S.isCallExpression(d)&&this.addRoute(e,t,m,l,d,a)&&s.routes++,S.isTypeReferenceNode(d)&&this.addTypeUse(e,t,m,d,a)&&s.usesType++,S.isBinaryExpression(d)&&cr.has(d.operatorToken.kind)){let f=this.addWrite(e,t,m,d.left,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}if((S.isPrefixUnaryExpression(d)||S.isPostfixUnaryExpression(d))&&(d.operator===S.SyntaxKind.PlusPlusToken||d.operator===S.SyntaxKind.MinusMinusToken)){let f=this.addWrite(e,t,m,d.operand,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}S.forEachChild(d,u)};u(m)}return s.tests+=this.addTestEdges(e),r&&(s.callReferences+=this.addResolvedCalls(e,r)),s}addRoute(e,t,r,s,i,o){if(!S.isPropertyAccessExpression(i.expression))return!1;let a=i.expression.name.text.toLowerCase();if(!ar.has(a))return!1;let m=i.arguments[0];if(!m||!(S.isStringLiteral(m)||S.isNoSubstitutionTemplateLiteral(m)))return!1;let c=m.text;if(!c.startsWith("/"))return!1;let l=K(r,i),u=Oe(e,r.fileName,l,a,c);this.graph.getSymbol(u)||(this.graph.addSymbol({id:u,projectId:e,name:`${a.toUpperCase()} ${c}`,qualifiedName:`${a.toUpperCase()} ${c}`,type:"route",filePath:s.filePath,startLine:l,endLine:l}),this.graph.addEdge(this.edge(e,s.id,"DEFINES",u)));let d=i.arguments.at(-1);if(d){let f=this.resolveNodeSymbol(e,t,d,o);f&&this.graph.addEdge(this.edge(e,u,"ROUTE",f.id,{method:a.toUpperCase(),path:c}))}return!0}addTypeUse(e,t,r,s,i){let o=this.resolveNodeSymbol(e,t,s.typeName,i);if(!o)return!1;let a=this.containingSymbol(e,R(B(t,H(r.fileName))),K(r,s));return!a||a.id===o.id?!1:(this.graph.addEdge(this.edge(e,a.id,"USES_TYPE",o.id)),!0)}addWrite(e,t,r,s,i){let o=this.resolveTsSymbol(s,i),a=o?.valueDeclaration??o?.declarations?.[0];if(!a)return{added:!1,propertyCreated:!1};let m=a.getSourceFile();if(m.isDeclarationFile)return{added:!1,propertyCreated:!1};let c=R(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))return{added:!1,propertyCreated:!1};let l=K(m,a),u=this.findSymbolAt(e,c,l),d=!1;if(!u||u.type==="file"){let p=o?.getName()??s.getText(r),b=Oe(e,c,"property",p,l);if(u=this.graph.getSymbol(b),!u){u={id:b,projectId:e,name:p,qualifiedName:p,type:"property",filePath:c,startLine:l,endLine:l},this.graph.addSymbol(u);let g=this.fileNode(e,c);g&&this.graph.addEdge(this.edge(e,g.id,"DEFINES",u.id)),d=!0}}if(!u)return{added:!1,propertyCreated:d};let f=R(B(t,H(r.fileName))),h=this.containingSymbol(e,f,K(r,s));return!h||h.id===u.id?{added:!1,propertyCreated:d}:(this.graph.addEdge(this.edge(e,h.id,"WRITES",u.id,{expression:s.getText(r)})),{added:!0,propertyCreated:d})}addTestEdges(e){let t=this.graph.allEdges(e),r=0;for(let s of t){if(s.type!=="IMPORTS")continue;let i=this.graph.getSymbol(s.from),o=this.graph.getSymbol(s.to);!i||!o||!this.isTestFile(i.filePath)||this.isTestFile(o.filePath)||(this.graph.addEdge(this.edge(e,i.id,"TESTS",o.id)),r++)}return r}addResolvedCalls(e,t){let r=0;for(let s of t.resolutions){if(s.kind!=="CALL"||!s.targetSymbolId)continue;let i=this.graph.getSymbol(s.targetSymbolId);if(!i)continue;let o=this.containingSymbol(e,s.sourceFile,s.sourceLine);!o||o.id===i.id||this.graph.allEdges(e).some(m=>m.type==="CALLS"&&m.from===o.id&&m.to===i.id)||(this.graph.addEdge(this.edge(e,o.id,"CALL_REFERENCE",i.id,{expression:s.expression,confidence:s.confidence,resolver:s.resolver})),r++)}return r}resolveNodeSymbol(e,t,r,s){let i=this.resolveTsSymbol(r,s),o=i?.valueDeclaration??i?.declarations?.[0];if(!o)return;let a=o.getSourceFile();if(a.isDeclarationFile)return;let m=R(B(t,H(a.fileName)));if(!(m.startsWith("../")||m.includes("node_modules/")))return this.findSymbolAt(e,m,K(a,o),i?.getName())}resolveTsSymbol(e,t){let r=t.getSymbolAtLocation(e);if(r&&r.flags&S.SymbolFlags.Alias)try{r=t.getAliasedSymbol(r)}catch{}return r}containingSymbol(e,t,r){return this.graph.allSymbols(e).filter(s=>R(s.filePath)===R(t)&&typeof s.startLine=="number"&&typeof s.endLine=="number"&&s.startLine<=r&&s.endLine>=r).sort((s,i)=>(s.endLine??0)-(s.startLine??0)-((i.endLine??0)-(i.startLine??0)))[0]}findSymbolAt(e,t,r,s){let i=this.graph.allSymbols(e).filter(o=>R(o.filePath)===R(t)&&typeof o.startLine=="number"&&typeof o.endLine=="number"&&o.startLine<=r&&o.endLine>=r).sort((o,a)=>(o.endLine??0)-(o.startLine??0)-((a.endLine??0)-(a.startLine??0)));if(s){let o=i.find(a=>a.name===s||(a.qualifiedName?.endsWith(`.${s}`)??!1));if(o)return o}return i[0]}fileNode(e,t){return this.graph.allSymbols(e).find(r=>r.type==="file"&&R(r.filePath)===R(t))}isTestFile(e){let t=R(e).toLowerCase();return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)}edge(e,t,r,s,i){return{id:Oe(e,t,r,s,JSON.stringify(i??{})),projectId:e,from:t,to:s,type:r,metadata:i}}loadConfig(e){let t=S.findConfigFile(e,S.sys.fileExists,"tsconfig.json");if(t){let r=S.readConfigFile(t,S.sys.readFile);return S.parseJsonConfigFileContent(r.config,S.sys,ir(t))}return{fileNames:S.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,noEmit:!0,skipLibCheck:!0,target:S.ScriptTarget.ES2022,module:S.ModuleKind.NodeNext,moduleResolution:S.ModuleResolutionKind.NodeNext}}}};function lr(n){return n.replaceAll("\\","/").toLowerCase()}var I=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let o of t){if(o.type!=="route"&&o.type!=="file")continue;let a=this.classify(o,r);a&&s.push({symbolId:o.id,filePath:o.filePath,name:o.name,kind:a.kind,score:a.score,reasons:a.reasons})}let i=new Map;for(let o of s){let a=o.kind==="route"?o.symbolId:o.filePath,m=i.get(a);(!m||o.score>m.score)&&i.set(a,o)}return[...i.values()].sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath))}classify(e,t){let r=lr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let i=null,o=0;if(r.startsWith("bin/"))i="cli",o=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))i="cli",o=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))i="main",o=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))i="runtime",o=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let m=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,c=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(r.startsWith("packages/")||m===0||c>0)&&(i="package",o=r.startsWith("packages/")?70:55,s.push("package/public index"))}return i?(t.filter(m=>m.to===e.id&&m.type!=="DEFINES").length===0&&(o+=10,s.push("no incoming dependency")),{kind:i,score:o,reasons:s}):null}};var dr={CALL_REFERENCE:6,CALLS:4,IMPORTS:3,USES_TYPE:4,WRITES:5,ROUTE:4,TESTS:1,INHERITS:5,IMPLEMENTS:5,DEFINES:.25},de=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(c=>[c.id,c])),i=new Map,o=c=>{let l=i.get(c);return l||(l={symbols:0,incoming:0,outgoing:0,weightedIncoming:0,weightedOutgoing:0,writes:0,callReferences:0,crossFile:0},i.set(c,l)),l};for(let c of t)o(c.filePath).symbols++;for(let c of r){let l=s.get(c.from),u=s.get(c.to);if(!l||!u)continue;let d=dr[c.type]??1,f=o(l.filePath),h=o(u.filePath);f.outgoing++,h.incoming++,f.weightedOutgoing+=d,h.weightedIncoming+=d,c.type==="WRITES"&&f.writes++,c.type==="CALL_REFERENCE"&&f.callReferences++,l.filePath!==u.filePath&&(f.crossFile++,h.crossFile++)}let a=[...i.entries()].map(([c,l])=>{let u=Number((l.symbols*.4+l.weightedIncoming*1.75+l.weightedOutgoing*.65+l.crossFile*1.5+l.writes*3+l.callReferences*2).toFixed(2)),d=[];return l.incoming>=10&&d.push("high incoming dependency"),l.crossFile>=10&&d.push("high cross-file coupling"),l.callReferences>=5&&d.push("many exact call references"),l.writes>0&&d.push("contains write relationships"),l.symbols>=10&&d.push("high symbol density"),{filePath:c,score:u,symbols:l.symbols,incoming:l.incoming,outgoing:l.outgoing,reasons:d}}).filter(c=>c.score>0).sort((c,l)=>l.score-c.score||c.filePath.localeCompare(l.filePath));if(a.length===0)return[];let m=Math.max(1,Math.min(30,Math.ceil(a.length*.15)));return a.slice(0,m)}};function pr(n){return n.replaceAll("\\","/").toLowerCase()}var mr={CALL_REFERENCE:6,CALLS:4,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:6,IMPLEMENTS:6,ROUTE:3,TESTS:1},pe=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(a=>[a.id,a])),i=[...new Set(t.map(a=>a.filePath))].sort(),o=new Map;for(let a of i)o.set(a,this.classifyPath(a));for(let a=0;a<3;a++){let m=!1;for(let c of i){let l=o.get(c);if(!l||l.layer!=="unknown")continue;let u=new Map;for(let f of r){let h=s.get(f.from),p=s.get(f.to);if(!h||!p||h.filePath===p.filePath)continue;let b=null;if(h.filePath===c?b=p.filePath:p.filePath===c&&(b=h.filePath),!b)continue;let g=o.get(b);if(!g||g.layer==="unknown"||g.layer==="tests")continue;let x=mr[f.type]??1;u.set(g.layer,(u.get(g.layer)??0)+x)}let d=[...u.entries()].sort((f,h)=>h[1]-f[1]||f[0].localeCompare(h[0]))[0];d&&d[1]>=4&&(o.set(c,{filePath:c,layer:d[0],confidence:.65,reasons:[`graph-neighbor vote=${d[1]}`]}),m=!0)}if(!m)break}return i.map(a=>o.get(a))}classifyPath(e){let t=pr(e);return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)?{filePath:e,layer:"tests",confidence:1,reasons:["test path"]}:t.startsWith("bin/")||t.includes("/mcp/")||t.includes("/cli/")||t.includes("/api/")||t.includes("/routes/")||t.includes("/hooks/")?{filePath:e,layer:"interface",confidence:.9,reasons:["interface boundary"]}:t.includes("/runtime/")||t.includes("/processor/")||t.includes("/retrieval/")||t.includes("/snapshot/")||t.includes("/code-intelligence/")?{filePath:e,layer:"application",confidence:.85,reasons:["application orchestration"]}:t.includes("/core/")||t.includes("/memory/")||/(^|\/)types\.[^.]+$/.test(t)?{filePath:e,layer:"domain",confidence:.9,reasons:["domain/core logic"]}:t.includes("/storage/")||t.includes("/production/")||t.includes("/security/")||t.includes("/config/")||t.includes("/utils/")?{filePath:e,layer:"infrastructure",confidence:.85,reasons:["infrastructure boundary"]}:{filePath:e,layer:"unknown",confidence:.35,reasons:[]}}};import{createHash as ur}from"node:crypto";var fr={CALL_REFERENCE:7,CALLS:3,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:7,IMPLEMENTS:7,ROUTE:4,TESTS:1};function gr(n){return ur("sha256").update(n).digest("hex").slice(0,12)}function me(n){return n.replaceAll("\\","/")}function hr(n){let t=me(n).split("/").filter(Boolean);return t[0]==="src"&&t[1]?`src/${t[1]}`:t[0]==="packages"&&t[1]?`packages/${t[1]}`:t[0]==="tests"?"tests":t[0]==="bin"?"bin":t[0]??"root"}function yr(n){let e=n.replace(/^src\//,"").replace(/^packages\//,"");return{"code-intelligence":"Code Intelligence",memory:"Memory",storage:"Storage",retrieval:"Retrieval",runtime:"Runtime",mcp:"MCP",hooks:"Hooks",security:"Security",snapshot:"Snapshots",production:"Production",capture:"Capture",processor:"Processor",core:"Core",tests:"Tests",bin:"CLI",sdk:"SDK",cli:"CLI"}[e]??e}var ue=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(d=>[d.id,d])),i=[...new Set(t.map(d=>me(d.filePath)))].sort(),o=new Map,a=(d,f)=>{let h=[d,f].sort();return`${h[0]}\0${h[1]}`};for(let d of r){let f=s.get(d.from),h=s.get(d.to);if(!f||!h)continue;let p=me(f.filePath),b=me(h.filePath);if(p===b)continue;let g=fr[d.type]??0;if(g<=0)continue;let x=a(p,b),y=o.get(x);y?y.weight+=g:o.set(x,{a:[p,b].sort()[0],b:[p,b].sort()[1],weight:g})}let m=new Map;for(let d of i){let f=hr(d),h=m.get(f)??[];h.push(d),m.set(f,h)}let c=[];for(let[d,f]of m){if(f.sort(),f.length<=30){c.push({subsystem:d,files:f});continue}let h=new Set(f),p=new Map;for(let y of f)p.set(y,new Set);for(let y of o.values())!h.has(y.a)||!h.has(y.b)||y.weight>=8&&(p.get(y.a)?.add(y.b),p.get(y.b)?.add(y.a));let b=new Set,g=[];for(let y of f){if(b.has(y))continue;let w=[y],P=[];for(b.add(y);w.length>0;){let v=w.shift();P.push(v);for(let k of p.get(v)??[])b.has(k)||(b.add(k),w.push(k))}g.push(P.sort())}let x=[];for(let y of g)y.length>=2?c.push({subsystem:d,files:y}):x.push(...y);x.length>0&&c.push({subsystem:`${d}/residual`,files:x.sort()})}let l=c.map(d=>({subsystem:d.subsystem,files:[...d.files]}));for(let d=0;d<3;d++){let f=!1;e:for(let h=0;h<l.length;h++){let p=l[h];if(!(!p||p.files.length>3))for(let b=0;b<l.length;b++){if(h===b)continue;let g=l[b];if(!g)continue;let x=0,y=new Set(p.files),w=new Set(g.files);for(let P of o.values())(y.has(P.a)&&w.has(P.b)||y.has(P.b)&&w.has(P.a))&&(x+=P.weight);if(x>=20){g.files=[...new Set([...g.files,...p.files])].sort(),l.splice(h,1),f=!0;break e}}}if(!f)break}let u=[];for(let d of l){let f=new Set(d.files),h=0,p=0;for(let w of o.values()){let P=f.has(w.a),v=f.has(w.b);P&&v?h+=w.weight:(P||v)&&(p+=w.weight)}let b=h+p,g=d.subsystem.replace(/\/residual$/,""),x=yr(g),y=d.subsystem.endsWith("/residual")?`${x} Misc`:x;u.push({id:`cluster-${gr(`${d.subsystem}:${d.files.join("|")}`)}`,label:y,subsystem:g,files:d.files,size:d.files.length,internalWeight:h,externalWeight:p,cohesion:b>0?Number((h/b).toFixed(4)):0})}return u.sort((d,f)=>f.size-d.size||f.cohesion-d.cohesion||d.label.localeCompare(f.label))}};var fe=class{constructor(e){this.graph=e;this.entryPoints=new I(e),this.hotspots=new de(e),this.layers=new pe(e),this.clusters=new ue(e)}graph;entryPoints;hotspots;layers;clusters;analyze(e){let t=this.entryPoints.detect(e),r=this.hotspots.analyze(e),s=this.layers.detect(e),i=this.clusters.detect(e),o=new Set(this.graph.allSymbols(e).map(a=>a.filePath));return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{files:o.size,entryPoints:t.length,hotspots:r.length,layers:s.length,clusters:i.length},entryPoints:t,hotspots:r,layers:s,clusters:i}}};var Qe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Fe(n){return n.replaceAll("\\","/").toLowerCase()}function Sr(n){let e=Fe(n);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function br(n){let e=Fe(n.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var ge=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new I(this.graph).detect(e).map(o=>o.symbolId)),i=[];for(let o of t){if(!["function","method","class","interface","property"].includes(o.type)||Sr(o.filePath)||s.has(o.id)||br(o)||r.filter(f=>f.to===o.id&&Qe.has(f.type)).length>0)continue;let m=r.filter(f=>f.from===o.id&&Qe.has(f.type)),c=["no incoming usage edge"],l=50;(o.type==="function"||o.type==="method")&&(l+=20,c.push("callable symbol")),o.type==="property"&&(l-=15),m.length===0&&(l+=10,c.push("no outgoing dependency")),Fe(o.filePath).includes("/internal/")&&(l+=10,c.push("internal implementation")),o.name.startsWith("_")&&(l+=5);let d=l>=75?"high":l>=55?"medium":"low";i.push({symbolId:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,confidence:d,score:l,reasons:c})}return i.sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath)||o.name.localeCompare(a.name))}};var xr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),he=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(o=>xr.has(o.type)),s=new Map(t.map(o=>[o.id,o]));return[...new Set(t.map(o=>o.filePath))].sort().map(o=>{let a=new Set,m=new Set,c=0,l=0;for(let u of r){let d=s.get(u.from),f=s.get(u.to);!d||!f||d.filePath===f.filePath||(d.filePath===o&&(a.add(f.filePath),c++),f.filePath===o&&(m.add(d.filePath),l++))}return{filePath:o,dependencies:[...a].sort(),dependents:[...m].sort(),outgoingEdges:c,incomingEdges:l}})}};var ye=class{constructor(e){this.graph=e}graph;analyze(e){let t=new ge(this.graph).analyze(e),r=new he(this.graph).analyze(e);return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{deadCodeCandidates:t.length,highConfidenceDeadCode:t.filter(s=>s.confidence==="high").length,files:r.length},deadCode:t,dependencies:r}}};var Se=class{constructor(e){this.graph=e}graph;build(e,t,r){let s=this.graph.allSymbols(e),i=this.graph.allEdges(e),o=new Map(t?.layers.map(p=>[p.filePath,p.layer])??[]),a=new Map;for(let p of t?.clusters??[])for(let b of p.files)a.set(b,{id:p.id,label:p.label});let m=new Map(t?.hotspots.map(p=>[p.filePath,p.score])??[]),c=new Map(r?.deadCode.map(p=>[p.symbolId,{confidence:p.confidence,score:p.score}])??[]),l=new Map,u=new Map;for(let p of i)u.set(p.from,(u.get(p.from)??0)+1),l.set(p.to,(l.get(p.to)??0)+1);let d=s.map(p=>{let b=a.get(p.filePath);return{id:p.id,name:p.name,qualifiedName:p.qualifiedName,type:p.type,filePath:p.filePath,layer:o.get(p.filePath),cluster:b?.id,clusterLabel:b?.label,hotspotScore:m.get(p.filePath),deadCode:c.get(p.id),incoming:l.get(p.id)??0,outgoing:u.get(p.id)??0}}),f=new Set(d.map(p=>p.id)),h=i.filter(p=>f.has(p.from)&&f.has(p.to)).map(p=>({source:p.from,target:p.to,type:p.type,confidence:typeof p.metadata?.confidence=="string"?p.metadata.confidence:void 0,resolver:typeof p.metadata?.resolver=="string"?p.metadata.resolver:void 0}));return{version:1,projectId:e,generatedAt:new Date().toISOString(),summary:{nodes:d.length,links:h.length,files:new Set(d.map(p=>p.filePath)).size,clusters:new Set(d.map(p=>p.cluster).filter(Boolean)).size},nodes:d,links:h}}};import{homedir as Fr}from"node:os";import{join as _r}from"node:path";import{DeleteObjectCommand as wr,GetObjectCommand as Er,HeadObjectCommand as Cr,ListObjectsV2Command as vr,PutObjectCommand as Pr,S3Client as Rr}from"@aws-sdk/client-s3";import{getSignedUrl as Tr}from"@aws-sdk/s3-request-presigner";var be=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Rr({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 Pr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Tr(this.client,new Er({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 Cr({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 wr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new vr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let i of s.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as Xe,mkdir as kr,readFile as Lr,readdir as jr,rm as Ar,stat as et,writeFile as Nr}from"node:fs/promises";import{dirname as Mr,join as Ir,relative as tt,resolve as Or}from"node:path";var W=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Or(this.root,t)}async put(e,t){let r=this.path(e);await kr(Mr(r),{recursive:!0}),await Nr(r,t)}async get(e){try{return await Lr(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 Xe(this.path(e)),!0}catch{return!1}}async delete(e){await Ar(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Xe(t)}catch{return r}let s=async o=>{let a=await jr(o,{withFileTypes:!0});for(let m of a){let c=Ir(o,m.name);if(m.isDirectory()){await s(c);continue}let l=await et(c);r.push({key:tt(this.root,c),size:l.size,updatedAt:l.mtime.toISOString()})}},i=await et(t);return i.isDirectory()?await s(t):r.push({key:tt(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),r}};function rt(n){let e=n.localRoot??_r(Fr(),".toolnet-memory","storage");if(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new be({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new W(e))}return new W(e)}function $r(n){return new Promise(e=>setTimeout(e,n))}async function st(n,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,i;for(let o=1;o<=t;o++)try{return await n()}catch(a){if(i=a,o>=t)break;let m=Math.min(s,r*2**(o-1)),c=Math.floor(Math.random()*Math.max(1,m*.2));await $r(m+c)}throw i}var Dr=new Set(["put","get","getText","delete","list"]);function ot(n,e={}){return new Proxy(n,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Dr.has(r)?(...i)=>st(()=>Promise.resolve(s.apply(t,i)),e):s.bind(t)}})}function nt(n){let e=n.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 it(n){let e=n.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 xe=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=nt(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 o;try{o=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof o.id=="string"&&o.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${o.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof o.createdAt=="string"&&(r=o.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
7
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=it(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))}};var we=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","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;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,r(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,r(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,r(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,r(e.clusters),"application/json")])}};var Ce=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,r(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,r(e.dependencies),"application/json")])}};var ve=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.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,null,2),"application/json")}};async function at(n,e={}){let t=Date.now();async function r(p,b,g){await e.onStage?.({id:p,title:b,state:"start"});let x=Date.now(),y=await g();return await e.onStage?.({id:p,title:b,state:"complete",durationMs:Date.now()-x}),y}let s=ze(),i=ot(rt({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:3}),o=new xe(i,n.id,n.name,n.remote??n.name),a=new G(o),c=(await r("source-index","Source Index",async()=>{let p=await new ee().index(n.id,n.rootPath);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:p.files,symbols:p.graph.allSymbols(n.id),edges:p.graph.allEdges(n.id)}),p})).graph,l=await r("type-resolution","Type Resolution",async()=>{let p=await new ce(c).resolveProject(n.id,n.rootPath);return await new we(o).save(p),p});await r("rich-graph","Rich Graph",async()=>{let p=new le(c).enrich(n.id,n.rootPath,l),b=c.allSymbols(n.id),g=c.allEdges(n.id);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:b.filter(x=>x.type==="file").length,symbols:b,edges:g}),p});let u=await r("semantic-index","Semantic Code Index",async()=>new ne({projectId:n.id,rootPath:n.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:o,embeddings:Ve(),graph:c}).initialize()),d=await r("architecture","Architecture Intelligence",async()=>{let p=new fe(c).analyze(n.id);return await new Ee(o).save(p),p}),f=await r("analysis","Graph Analysis",async()=>{let p=new ye(c).analyze(n.id);return await new Ce(o).save(p),p}),h=await r("visualization","3D Visualization Dataset",async()=>{let p=new Se(c).build(n.id,d,f);return await new ve(o).save(p),p});return{project:{id:n.id,name:n.name,remote:n.remote??n.name},storage:o.name,durationMs:Date.now()-t,graph:{symbols:c.allSymbols(n.id).length,edges:c.allEdges(n.id).length},resolution:{total:l.total,exact:l.exact,high:l.high,fallback:l.fallback},semantic:u,architecture:d.summary,analysis:f.summary,visualization:h.summary}}var A=new q().detect(),Ge=De(A.rootPath,".toolnet"),_e=De(Ge,"index.lock"),Wr=De(Ge,"last-index.json");zr(Ge,{recursive:!0});function Pe(n){Kr(Wr,JSON.stringify(n,null,2)+`
8
- `,{encoding:"utf8",mode:384})}var $e;try{$e=Br(_e,"wx",384)}catch{console.error("\u274C Index already running for this project."),console.error(`Lock: ${_e}`),process.exit(2)}var Re=new Date().toISOString(),V=[];try{console.log(),console.log("=============================================="),console.log(" ToolNet Production Index"),console.log("=============================================="),console.log(`Project : ${A.name}`),console.log(`Remote : projects/${A.remote??A.name}/`),console.log("Runtime : production/dist"),console.log("Snapshot: disabled"),Pe({version:2,state:"running",startedAt:Re,completedStages:V,project:A});let n=await at(A,{onStage:async e=>{e.state==="start"?(console.log(),console.log(`===== ${e.title} =====`)):(V.push(e.id),console.log(`\u2705 ${e.title} (${((e.durationMs??0)/1e3).toFixed(1)}s)`)),Pe({version:2,state:"running",startedAt:Re,currentStage:e.id,completedStages:[...V],project:A})}});Pe({version:2,state:"complete",startedAt:Re,finishedAt:new Date().toISOString(),completedStages:V,result:n}),console.log(),console.log("=============================================="),console.log(" FULL INDEX COMPLETE \u2705"),console.log("=============================================="),console.log(JSON.stringify(n,null,2))}catch(n){Pe({version:2,state:"failed",startedAt:Re,failedAt:new Date().toISOString(),completedStages:V,error:n instanceof Error?n.message:String(n)}),console.error("FULL INDEX FAILED \u274C"),console.error(n),process.exitCode=1}finally{$e!==void 0&&Gr($e),Hr(_e,{force:!0})}
1
+ import{closeSync as Yr,mkdirSync as qr,openSync as Qr,rmSync as Zr,writeFileSync as Xr}from"node:fs";import{join as ze}from"node:path";import{existsSync as mt,readFileSync as ut}from"node:fs";import{homedir as ft}from"node:os";import{join as gt}from"node:path";function ht(n){let e=n.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 yt(){let n=process.env.TOOLNET_GLOBAL_ENV??gt(ft(),".config","toolnet-memory",".env");if(!mt(n))return;let e=ut(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let i=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=ht(r.slice(s+1)))}}yt();function O(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function _(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function Be(){return{memory:{autoCapture:O(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:O(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:O(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:O(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:_(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:_(process.env.MEMORY_RERANK_TOP,10),finalContext:_(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:_(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:O(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:_(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as St}from"node:crypto";import{existsSync as Re,mkdirSync as bt,readFileSync as xt,renameSync as wt,writeFileSync as Et}from"node:fs";import{basename as Ct,dirname as Y,join as Q,parse as Ue,resolve as F}from"node:path";var Ve=".toolnet",vt="project.json";function Pt(n){return St("sha256").update(n).digest("hex").slice(0,16)}function Ae(n){return Q(n,Ve,vt)}function kt(n){return Re(Ae(n))}function Tt(n,e){let t=F(n),r=Ue(t).root;for(;;){if(kt(t))return t;if(t===r||e&&t===F(e))break;let s=Y(t);if(s===t)break;t=s}return null}function Rt(n){let e=F(n),t=Ue(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(i=>Re(Q(e,i))))return e;if(e===t)break;let s=Y(e);if(s===e)break;e=s}return F(n)}function At(n){let e;try{e=JSON.parse(xt(n,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${n}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:Y(Y(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function He(n,e){let t=Q(n,Ve);bt(t,{recursive:!0});let r=Ae(n),s=`${r}.tmp-${process.pid}`;Et(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),wt(s,r)}function We(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}var q=class{detect(e=process.cwd()){let t=F(e),r=Rt(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Re(Q(r,l))),o=Tt(t,i?r:void 0);if(o){let l=Ae(o),u=At(l);return u.rootPath!==o&&(u.rootPath=o,u.updatedAt=new Date().toISOString(),He(o,u)),We(u,o)}let a=new Date().toISOString(),m=Ct(r),c={version:1,id:Pt(r),name:m,remote:m,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return He(r,c),We(c,r)}};var Lt=[{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 r of Lt){let s=new RegExp(r.regex.source,r.regex.flags);for(let i of e.matchAll(s))t.push({type:r.type,value:i[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var $=class{scanner=new Z;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let i of r)s.add(i.type),t=t.split(i.value).join(`[REDACTED:${i.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let i=r.toLowerCase();i.includes("password")||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var X=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(i=>jt(i))}};function jt(n){if(!Array.isArray(n))throw new Error("Invalid embedding");if(n.length>0&&typeof n[0]=="number")return n;if(n.length>0&&Array.isArray(n[0])){let e=n;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let i=0;i<t;i++)r[i]+=s[i]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as It}from"node:crypto";var ee=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 o=It("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[o]+=1}return Nt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function Nt(n){let e=Math.sqrt(n.reduce((t,r)=>t+r*r,0));return e===0?n:n.map(t=>t/e)}var Le=class{constructor(e,t=new ee){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 Je(){let n=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=n?new X({token:n,model:e}):null;return new Le(t)}import{readdir as Ft}from"node:fs/promises";import{extname as $t,join as Dt,relative as Gt}from"node:path";import{basename as Mt}from"node:path";var Ot=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),_t=new Set([".pem",".key",".p12",".pfx"]);function Ye(n){let e=Mt(n).toLowerCase();if(Ot.has(e))return!0;for(let t of _t)if(e.endsWith(t))return!0;return!1}var zt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Kt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function je(n){let e=[];async function t(r){let s=await Ft(r,{withFileTypes:!0});for(let i of s){if(Kt.has(i.name))continue;let o=Dt(r,i.name);if(i.isDirectory()){await t(o);continue}zt.has($t(i.name))&&(Ye(o)||e.push(Gt(n,o)))}}return await t(n),e.sort()}import{readFile as Bt}from"node:fs/promises";import{join as Ht}from"node:path";import{createHash as Wt}from"node:crypto";import*as E from"typescript";function qe(n,e){return Wt("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function Ie(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Ne(n,e,t){let r=Ht(e,t),s=await Bt(r,"utf8"),i=E.createSourceFile(t,s,E.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?E.ScriptKind.TSX:E.ScriptKind.TS),o=[],a=[],m=[],c=[],l={id:qe(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:i.getLineAndCharacterOfPosition(i.end).line+1};o.push(l);let u=[],d=[];function f(g,x,y,w){let P=qe(n,`${t}:${y}:${w??x}:${g.pos}`);return o.push({id:P,projectId:n,name:x,qualifiedName:w??x,type:y,filePath:t,startLine:Ie(i,g),endLine:i.getLineAndCharacterOfPosition(g.end).line+1}),P}function h(g){if(!E.isStringLiteral(g.moduleSpecifier))return;let x=[],y=g.importClause;if(y?.name&&x.push({localName:y.name.text,importedName:"default",kind:"default"}),y?.namedBindings&&E.isNamedImports(y.namedBindings))for(let w of y.namedBindings.elements)x.push({localName:w.name.text,importedName:w.propertyName?.text??w.name.text,kind:"named"});y?.namedBindings&&E.isNamespaceImport(y.namedBindings)&&x.push({localName:y.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:g.moduleSpecifier.text,bindings:x})}function p(g,x){for(let y of g.heritageClauses??[])for(let w of y.types){let P=w.expression.getText(i).split(".").at(-1)??"";P&&c.push({fromId:x,targetName:P,type:y.token===E.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function b(g){let x=!1,y=!1;if(E.isImportDeclaration(g)&&h(g),E.isInterfaceDeclaration(g)&&f(g,g.name.text,"interface",g.name.text),E.isClassDeclaration(g)&&g.name){let w=f(g,g.name.text,"class",g.name.text);p(g,w),d.push({id:w,name:g.name.text}),y=!0}if(E.isFunctionDeclaration(g)&&g.name){let w=f(g,g.name.text,"function",g.name.text);u.push(w),x=!0}if(E.isMethodDeclaration(g)&&g.name){let w=g.name.getText(i),P=d.at(-1)?.name,v=f(g,w,"method",P?`${P}.${w}`:w);u.push(v),x=!0}if(E.isCallExpression(g)&&(E.isIdentifier(g.expression)&&m.push({callerId:u.at(-1),calleeName:g.expression.text,line:Ie(i,g)}),E.isPropertyAccessExpression(g.expression))){let w=g.expression;m.push({callerId:u.at(-1),qualifier:w.expression.getText(i),calleeName:w.name.text,line:Ie(i,g)})}E.forEachChild(g,b),x&&u.pop(),y&&d.pop()}return b(i),{filePath:t,symbols:o,imports:a,calls:m,heritage:c}}import{createHash as Ut}from"node:crypto";import{dirname as Vt,extname as Jt,normalize as Yt,posix as qt}from"node:path";var D=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 Qt(n,e,t,r){return Ut("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function L(n){return Yt(n).replaceAll("\\","/")}function Me(n,e,t){if(!e.startsWith("."))return;let r=L(qt.join(Vt(n),e)),s=Jt(r),i;if(s===".js"){let o=r.slice(0,-3);i=[`${o}.ts`,`${o}.tsx`,`${o}.js`,`${o}.jsx`]}else if(s===".mjs"){let o=r.slice(0,-4);i=[`${o}.mts`,`${o}.ts`,`${o}.mjs`]}else if(s===".cjs"){let o=r.slice(0,-4);i=[`${o}.cts`,`${o}.ts`,`${o}.cjs`]}else s?i=[r]:i=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return i.find(o=>t.has(L(o)))}var G=class{build(e,t){let r=new D,s=new Map;for(let o of t)for(let a of o.symbols)r.addSymbol(a),a.type==="file"&&s.set(L(o.filePath),a);let i=new Set(s.keys());for(let o of t){let a=L(o.filePath),m=s.get(a);if(m){for(let c of o.symbols)c.id!==m.id&&r.addEdge(this.edge(e,m.id,"DEFINES",c.id));for(let c of o.imports){let l=Me(a,c.source,i);if(!l)continue;let u=s.get(l);u&&r.addEdge(this.edge(e,m.id,"IMPORTS",u.id,{source:c.source}))}for(let c of o.heritage){let l=r.findByName(e,c.targetName).filter(u=>u.type==="class"||u.type==="interface");for(let u of l)r.addEdge(this.edge(e,c.fromId,c.type,u.id))}for(let c of o.calls){if(!c.callerId)continue;let l=this.resolveCallTargets(e,o,c.calleeName,c.qualifier,t,r,i);for(let u of l)u.id!==c.callerId&&r.addEdge(this.edge(e,c.callerId,"CALLS",u.id,{line:c.line,qualifier:c.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,i,o,a){let m=L(t.filePath),c=o.findByName(e,r).filter(l=>L(l.filePath)===m);if(!s&&c.length)return c;if(s)for(let l of t.imports){if(!l.bindings.find(f=>f.kind==="namespace"&&f.localName===s))continue;let d=Me(m,l.source,a);if(d)return o.findByName(e,r).filter(f=>L(f.filePath)===d)}for(let l of t.imports){let u=l.bindings.find(p=>p.localName===r);if(!u)continue;let d=Me(m,l.source,a);if(!d)continue;let f=u.importedName==="default"?r:u.importedName,h=o.findByName(e,f).filter(p=>L(p.filePath)===d);if(h.length)return h}return o.findByName(e,r).filter(l=>l.type==="function"||l.type==="method")}edge(e,t,r,s,i){return{id:Qt(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:i}}};var te=class{async index(e,t){let r=await je(t),s=[];for(let o of r)try{s.push(await Ne(e,t,o))}catch(a){console.warn(`[indexer] skipped ${o}:`,a instanceof Error?a.message:a)}let i=new G().build(e,s);return{files:s.length,symbols:i.allSymbols(e).length,edges:i.allEdges(e).length,graph:i}}};import{execFile as Zt}from"node:child_process";import{promisify as Xt}from"node:util";var xo=Xt(Zt);var z=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 er}from"node:crypto";import{readFile as tr}from"node:fs/promises";import{join as rr}from"node:path";function Qe(n){return er("sha256").update(n).digest("hex")}var re=class{sanitizer=new $;async build(e,t,r,s={}){let i=s.maxLines??80,o=s.overlapLines??10,a=new Map;for(let c of r){let l=a.get(c.filePath)??[];l.push(c),a.set(c.filePath,l)}let m=[];for(let[c,l]of a){let u;try{u=await tr(rr(t,c),"utf8")}catch{continue}let d=u.split(/\r?\n/),f=l.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(f.length>0)for(let h of f)m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:i,overlapLines:o}));else m.push(...this.chunkRange({projectId:e,filePath:c,lines:d,startLine:1,endLine:Math.max(1,d.length),maxLines:i,overlapLines:o}))}return m}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:i,maxLines:o}=e,a=Math.min(e.overlapLines,Math.max(0,o-1)),m=Math.max(1,e.startLine),c=Math.min(s.length,Math.max(m,e.endLine)),l=[],u=m,d=0;for(;u<=c;){let f=Math.min(c,u+o-1),h=s.slice(u-1,f).join(`
4
+ `).trim();if(h){let p=this.sanitizer.sanitize(h).text,b=Qe(p),g=[t,r,i?.id??"file",String(d),b].join(":");l.push({id:Qe(g).slice(0,32),projectId:t,filePath:r,symbolId:i?.id,symbolName:i?.qualifiedName??i?.name,symbolType:i?.type,startLine:u,endLine:f,content:p,contentHash:b})}if(f>=c)break;u=f-a+1,d++}return l}};var se=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 oe=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 ne=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let i of this.records.values()){if(i.projectId!==e)continue;let o=sr(t,i.vector);s.push({id:i.id,score:o,metadata:i.metadata})}return s.sort((i,o)=>o.score-i.score).slice(0,r)}size(){return this.records.size}};function sr(n,e){if(n.length===0||e.length===0||n.length!==e.length)return 0;let t=0,r=0,s=0;for(let i=0;i<n.length;i++){let o=n[i]??0,a=e[i]??0;t+=o*a,r+=o*o,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}function Oe(n){return n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function Ze(n,e){let t=n.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var ie=class{constructor(e){this.options=e}options;vectors=new ne;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:s,graph:i,model:o}=this.options,a=new se(r),m=new oe(r),c=await new re().build(e,t,i.allSymbols(e));this.chunks.clear();for(let v of c)this.chunks.set(v.id,v);let l=await a.load(e),u=!l||l.chunks.length!==c.length||l.chunks.some(v=>!this.chunks.has(v.id));u&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:c});let d=await m.load(e),f=0;d&&d.model===o&&(f=this.vectors.importRecords(d.records));let h=new Set(c.map(v=>v.id)),p=0;for(let v of this.vectors.exportProject(e))h.has(v.id)||this.vectors.remove(v.id)&&p++;let b=c.filter(v=>{let R=this.vectors.get(v.id);return R?R.metadata?.contentHash!==v.contentHash:!0}),g=0,x=8,y=this.vectors.exportProject(e)[0]?.vector.length;for(let v=0;v<b.length;v+=x){let R=b.slice(v,v+x),dt=R.map(T=>[`file: ${T.filePath}`,T.symbolName?`symbol: ${T.symbolName}`:"",T.symbolType?`type: ${T.symbolType}`:"",T.content].filter(Boolean).join(`
5
+ `)),pt=await s.embedMany(dt);for(let T=0;T<R.length;T++){let A=R[T],I=pt[T];if(!(!A||!I||I.length===0)){if(y===void 0&&(y=I.length),I.length!==y){console.warn(`[code-semantic] skip dimension mismatch: ${I.length} != ${y}`);continue}this.vectors.upsert({id:A.id,projectId:e,vector:I,metadata:{contentHash:A.contentHash,filePath:A.filePath,symbolName:A.symbolName,symbolType:A.symbolType,startLine:A.startLine,endLine:A.endLine}}),g++}}}let w=this.vectors.exportProject(e),P=g>0||p>0||!d||d.model!==o;return P&&await m.save({version:1,projectId:e,model:o,dimensions:w[0]?.vector.length??y??0,updatedAt:new Date().toISOString(),records:w}),{chunks:c.length,vectorsLoaded:f,vectorsIndexed:g,vectorsRemoved:p,totalVectors:w.length,savedChunks:u,savedVectors:P}}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)),i=new Set(Oe(e)),o=[];for(let a of s){let m=this.chunks.get(a.id);if(!m)continue;let c=new Set(Oe([m.filePath,m.symbolName??"",m.symbolType??"",m.content].join(" "))),l=0;for(let p of i)c.has(p)&&l++;let u=i.size===0?0:l/i.size,d=Math.max(0,a.score),f=Ze(m.filePath,e),h=(d*.75+u*.25)*f;o.push({chunk:m,score:h,vectorScore:d,lexicalScore:u})}return o.sort((a,m)=>m.score-a.score).slice(0,t)}size(){return this.chunks.size}};import{createHash as or}from"node:crypto";import{dirname as nr,relative as ae,resolve as ce}from"node:path";import*as C from"typescript";function N(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function Xe(n){return or("sha256").update(n).digest("hex").slice(0,24)}function K(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}function ir(n){let e=n;if(e.name&&C.isIdentifier(e.name))return e.name.text}var le=class{constructor(e){this.graph=e}graph;async resolveProject(e,t){let r=this.loadConfig(t),s=C.createProgram({rootNames:r.fileNames,options:r.options}),i=s.getTypeChecker(),o=[];for(let a of s.getSourceFiles()){if(a.isDeclarationFile)continue;let m=ce(a.fileName),c=N(ae(t,m));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=u=>{if(C.isCallExpression(u)){let d=this.resolveCall({projectId:e,rootPath:t,source:a,node:u,checker:i});d&&o.push(d)}C.isClassDeclaration(u)&&o.push(...this.resolveHeritage({projectId:e,rootPath:t,source:a,node:u,checker:i})),C.forEachChild(u,l)};l(a)}return{version:1,projectId:e,updatedAt:new Date().toISOString(),total:o.length,exact:o.filter(a=>a.confidence==="exact").length,high:o.filter(a=>a.confidence==="high").length,fallback:o.filter(a=>a.confidence==="fallback").length,resolutions:o}}resolveCall(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a;if(a=o.getResolvedSignature(i)?.declaration,!a){let c=o.getSymbolAtLocation(i.expression);a=c?.valueDeclaration??c?.declarations?.[0]}return a?this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:i,declaration:a,expression:i.expression.getText(s),kind:"CALL"}):this.fallbackCall(t,r,s,i)}resolveHeritage(e){let{projectId:t,rootPath:r,source:s,node:i,checker:o}=e,a=[];for(let m of i.heritageClauses??[])for(let c of m.types){let l=o.getSymbolAtLocation(c.expression),u=l?.valueDeclaration??l?.declarations?.[0];if(!u)continue;let d=this.fromDeclaration({projectId:t,rootPath:r,source:s,sourceNode:c,declaration:u,expression:c.getText(s),kind:m.token===C.SyntaxKind.ExtendsKeyword?"EXTENDS":"IMPLEMENTS"});d&&a.push(d)}return a}fromDeclaration(e){let t=e.declaration.getSourceFile();if(t.isDeclarationFile)return null;let r=N(ae(e.rootPath,ce(t.fileName)));if(r.startsWith("../")||r.includes("node_modules/"))return null;let s=K(t,e.declaration),i=ir(e.declaration)??e.expression.split(".").at(-1),o=this.findGraphSymbol(e.projectId,r,s,i),a=N(ae(e.rootPath,ce(e.source.fileName)));return{id:Xe([e.projectId,a,K(e.source,e.sourceNode),e.kind,r,s].join(":")),projectId:e.projectId,kind:e.kind,sourceFile:a,sourceLine:K(e.source,e.sourceNode),expression:e.expression,targetFile:r,targetLine:s,targetName:i,targetQualifiedName:o?.qualifiedName,targetSymbolId:o?.id,confidence:o?"exact":"high",resolver:"typescript-checker"}}fallbackCall(e,t,r,s){let i=s.expression.getText(r).split(".").at(-1);if(!i)return null;let o=this.graph.findByName(e,i).filter(c=>c.type==="function"||c.type==="method");if(o.length!==1)return null;let a=o[0],m=N(ae(t,ce(r.fileName)));return{id:Xe(`${e}:${m}:${K(r,s)}:${a.id}`),projectId:e,kind:"CALL",sourceFile:m,sourceLine:K(r,s),expression:s.expression.getText(r),targetFile:a.filePath,targetLine:a.startLine,targetName:a.name,targetQualifiedName:a.qualifiedName,targetSymbolId:a.id,confidence:"fallback",resolver:"graph-fallback"}}findGraphSymbol(e,t,r,s){let o=this.graph.allSymbols(e).filter(a=>N(a.filePath)===N(t)).filter(a=>typeof a.startLine=="number"&&typeof a.endLine=="number"&&a.startLine<=r&&a.endLine>=r);if(s){let a=o.find(m=>m.name===s||(m.qualifiedName?.endsWith(`.${s}`)??!1));if(a)return a}return o.sort((a,m)=>(a.endLine??0)-(a.startLine??0)-((m.endLine??0)-(m.startLine??0)))[0]}loadConfig(e){let t=C.findConfigFile(e,C.sys.fileExists,"tsconfig.json");if(t){let s=C.readConfigFile(t,C.sys.readFile);if(s.error)throw new Error(C.flattenDiagnosticMessageText(s.error.messageText,`
6
+ `));return C.parseJsonConfigFileContent(s.config,C.sys,nr(t))}return{fileNames:C.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,checkJs:!1,target:C.ScriptTarget.ES2022,module:C.ModuleKind.NodeNext,moduleResolution:C.ModuleResolutionKind.NodeNext,skipLibCheck:!0,noEmit:!0}}}};import{createHash as ar}from"node:crypto";import{dirname as cr,relative as B,resolve as H}from"node:path";import*as S from"typescript";function k(n){return n.replaceAll("\\","/").replace(/^\.\//,"")}function _e(...n){return ar("sha256").update(n.join(":")).digest("hex").slice(0,24)}function W(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}var lr=new Set(["get","post","put","patch","delete","options","head"]),dr=new Set([S.SyntaxKind.EqualsToken,S.SyntaxKind.PlusEqualsToken,S.SyntaxKind.MinusEqualsToken,S.SyntaxKind.AsteriskEqualsToken,S.SyntaxKind.SlashEqualsToken,S.SyntaxKind.PercentEqualsToken,S.SyntaxKind.QuestionQuestionEqualsToken,S.SyntaxKind.AmpersandAmpersandEqualsToken,S.SyntaxKind.BarBarEqualsToken]),de=class{constructor(e){this.graph=e}graph;enrich(e,t,r){let s={routes:0,tests:0,usesType:0,writes:0,callReferences:0,properties:0},i=this.loadConfig(t),o=S.createProgram({rootNames:i.fileNames,options:i.options}),a=o.getTypeChecker();for(let m of o.getSourceFiles()){if(m.isDeclarationFile)continue;let c=k(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))continue;let l=this.fileNode(e,c);if(!l)continue;let u=d=>{if(S.isCallExpression(d)&&this.addRoute(e,t,m,l,d,a)&&s.routes++,S.isTypeReferenceNode(d)&&this.addTypeUse(e,t,m,d,a)&&s.usesType++,S.isBinaryExpression(d)&&dr.has(d.operatorToken.kind)){let f=this.addWrite(e,t,m,d.left,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}if((S.isPrefixUnaryExpression(d)||S.isPostfixUnaryExpression(d))&&(d.operator===S.SyntaxKind.PlusPlusToken||d.operator===S.SyntaxKind.MinusMinusToken)){let f=this.addWrite(e,t,m,d.operand,a);f.added&&(s.writes++,f.propertyCreated&&s.properties++)}S.forEachChild(d,u)};u(m)}return s.tests+=this.addTestEdges(e),r&&(s.callReferences+=this.addResolvedCalls(e,r)),s}addRoute(e,t,r,s,i,o){if(!S.isPropertyAccessExpression(i.expression))return!1;let a=i.expression.name.text.toLowerCase();if(!lr.has(a))return!1;let m=i.arguments[0];if(!m||!(S.isStringLiteral(m)||S.isNoSubstitutionTemplateLiteral(m)))return!1;let c=m.text;if(!c.startsWith("/"))return!1;let l=W(r,i),u=_e(e,r.fileName,l,a,c);this.graph.getSymbol(u)||(this.graph.addSymbol({id:u,projectId:e,name:`${a.toUpperCase()} ${c}`,qualifiedName:`${a.toUpperCase()} ${c}`,type:"route",filePath:s.filePath,startLine:l,endLine:l}),this.graph.addEdge(this.edge(e,s.id,"DEFINES",u)));let d=i.arguments.at(-1);if(d){let f=this.resolveNodeSymbol(e,t,d,o);f&&this.graph.addEdge(this.edge(e,u,"ROUTE",f.id,{method:a.toUpperCase(),path:c}))}return!0}addTypeUse(e,t,r,s,i){let o=this.resolveNodeSymbol(e,t,s.typeName,i);if(!o)return!1;let a=this.containingSymbol(e,k(B(t,H(r.fileName))),W(r,s));return!a||a.id===o.id?!1:(this.graph.addEdge(this.edge(e,a.id,"USES_TYPE",o.id)),!0)}addWrite(e,t,r,s,i){let o=this.resolveTsSymbol(s,i),a=o?.valueDeclaration??o?.declarations?.[0];if(!a)return{added:!1,propertyCreated:!1};let m=a.getSourceFile();if(m.isDeclarationFile)return{added:!1,propertyCreated:!1};let c=k(B(t,H(m.fileName)));if(c.startsWith("../")||c.includes("node_modules/"))return{added:!1,propertyCreated:!1};let l=W(m,a),u=this.findSymbolAt(e,c,l),d=!1;if(!u||u.type==="file"){let p=o?.getName()??s.getText(r),b=_e(e,c,"property",p,l);if(u=this.graph.getSymbol(b),!u){u={id:b,projectId:e,name:p,qualifiedName:p,type:"property",filePath:c,startLine:l,endLine:l},this.graph.addSymbol(u);let g=this.fileNode(e,c);g&&this.graph.addEdge(this.edge(e,g.id,"DEFINES",u.id)),d=!0}}if(!u)return{added:!1,propertyCreated:d};let f=k(B(t,H(r.fileName))),h=this.containingSymbol(e,f,W(r,s));return!h||h.id===u.id?{added:!1,propertyCreated:d}:(this.graph.addEdge(this.edge(e,h.id,"WRITES",u.id,{expression:s.getText(r)})),{added:!0,propertyCreated:d})}addTestEdges(e){let t=this.graph.allEdges(e),r=0;for(let s of t){if(s.type!=="IMPORTS")continue;let i=this.graph.getSymbol(s.from),o=this.graph.getSymbol(s.to);!i||!o||!this.isTestFile(i.filePath)||this.isTestFile(o.filePath)||(this.graph.addEdge(this.edge(e,i.id,"TESTS",o.id)),r++)}return r}addResolvedCalls(e,t){let r=0;for(let s of t.resolutions){if(s.kind!=="CALL"||!s.targetSymbolId)continue;let i=this.graph.getSymbol(s.targetSymbolId);if(!i)continue;let o=this.containingSymbol(e,s.sourceFile,s.sourceLine);!o||o.id===i.id||this.graph.allEdges(e).some(m=>m.type==="CALLS"&&m.from===o.id&&m.to===i.id)||(this.graph.addEdge(this.edge(e,o.id,"CALL_REFERENCE",i.id,{expression:s.expression,confidence:s.confidence,resolver:s.resolver})),r++)}return r}resolveNodeSymbol(e,t,r,s){let i=this.resolveTsSymbol(r,s),o=i?.valueDeclaration??i?.declarations?.[0];if(!o)return;let a=o.getSourceFile();if(a.isDeclarationFile)return;let m=k(B(t,H(a.fileName)));if(!(m.startsWith("../")||m.includes("node_modules/")))return this.findSymbolAt(e,m,W(a,o),i?.getName())}resolveTsSymbol(e,t){let r=t.getSymbolAtLocation(e);if(r&&r.flags&S.SymbolFlags.Alias)try{r=t.getAliasedSymbol(r)}catch{}return r}containingSymbol(e,t,r){return this.graph.allSymbols(e).filter(s=>k(s.filePath)===k(t)&&typeof s.startLine=="number"&&typeof s.endLine=="number"&&s.startLine<=r&&s.endLine>=r).sort((s,i)=>(s.endLine??0)-(s.startLine??0)-((i.endLine??0)-(i.startLine??0)))[0]}findSymbolAt(e,t,r,s){let i=this.graph.allSymbols(e).filter(o=>k(o.filePath)===k(t)&&typeof o.startLine=="number"&&typeof o.endLine=="number"&&o.startLine<=r&&o.endLine>=r).sort((o,a)=>(o.endLine??0)-(o.startLine??0)-((a.endLine??0)-(a.startLine??0)));if(s){let o=i.find(a=>a.name===s||(a.qualifiedName?.endsWith(`.${s}`)??!1));if(o)return o}return i[0]}fileNode(e,t){return this.graph.allSymbols(e).find(r=>r.type==="file"&&k(r.filePath)===k(t))}isTestFile(e){let t=k(e).toLowerCase();return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)}edge(e,t,r,s,i){return{id:_e(e,t,r,s,JSON.stringify(i??{})),projectId:e,from:t,to:s,type:r,metadata:i}}loadConfig(e){let t=S.findConfigFile(e,S.sys.fileExists,"tsconfig.json");if(t){let r=S.readConfigFile(t,S.sys.readFile);return S.parseJsonConfigFileContent(r.config,S.sys,cr(t))}return{fileNames:S.sys.readDirectory(e,[".ts",".tsx",".js",".jsx",".mts",".cts",".mjs",".cjs"],["node_modules",".git","dist","build","coverage"]),options:{allowJs:!0,noEmit:!0,skipLibCheck:!0,target:S.ScriptTarget.ES2022,module:S.ModuleKind.NodeNext,moduleResolution:S.ModuleResolutionKind.NodeNext}}}};function pr(n){return n.replaceAll("\\","/").toLowerCase()}var M=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=[];for(let o of t){if(o.type!=="route"&&o.type!=="file")continue;let a=this.classify(o,r);a&&s.push({symbolId:o.id,filePath:o.filePath,name:o.name,kind:a.kind,score:a.score,reasons:a.reasons})}let i=new Map;for(let o of s){let a=o.kind==="route"?o.symbolId:o.filePath,m=i.get(a);(!m||o.score>m.score)&&i.set(a,o)}return[...i.values()].sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath))}classify(e,t){let r=pr(e.filePath),s=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let i=null,o=0;if(r.startsWith("bin/"))i="cli",o=100,s.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(r))i="cli",o=90,s.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(r))i="main",o=90,s.push("main/server file");else if(r.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(r))i="runtime",o=75,s.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(r)){let m=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,c=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(r.startsWith("packages/")||m===0||c>0)&&(i="package",o=r.startsWith("packages/")?70:55,s.push("package/public index"))}return i?(t.filter(m=>m.to===e.id&&m.type!=="DEFINES").length===0&&(o+=10,s.push("no incoming dependency")),{kind:i,score:o,reasons:s}):null}};var mr={CALL_REFERENCE:6,CALLS:4,IMPORTS:3,USES_TYPE:4,WRITES:5,ROUTE:4,TESTS:1,INHERITS:5,IMPLEMENTS:5,DEFINES:.25},pe=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(c=>[c.id,c])),i=new Map,o=c=>{let l=i.get(c);return l||(l={symbols:0,incoming:0,outgoing:0,weightedIncoming:0,weightedOutgoing:0,writes:0,callReferences:0,crossFile:0},i.set(c,l)),l};for(let c of t)o(c.filePath).symbols++;for(let c of r){let l=s.get(c.from),u=s.get(c.to);if(!l||!u)continue;let d=mr[c.type]??1,f=o(l.filePath),h=o(u.filePath);f.outgoing++,h.incoming++,f.weightedOutgoing+=d,h.weightedIncoming+=d,c.type==="WRITES"&&f.writes++,c.type==="CALL_REFERENCE"&&f.callReferences++,l.filePath!==u.filePath&&(f.crossFile++,h.crossFile++)}let a=[...i.entries()].map(([c,l])=>{let u=Number((l.symbols*.4+l.weightedIncoming*1.75+l.weightedOutgoing*.65+l.crossFile*1.5+l.writes*3+l.callReferences*2).toFixed(2)),d=[];return l.incoming>=10&&d.push("high incoming dependency"),l.crossFile>=10&&d.push("high cross-file coupling"),l.callReferences>=5&&d.push("many exact call references"),l.writes>0&&d.push("contains write relationships"),l.symbols>=10&&d.push("high symbol density"),{filePath:c,score:u,symbols:l.symbols,incoming:l.incoming,outgoing:l.outgoing,reasons:d}}).filter(c=>c.score>0).sort((c,l)=>l.score-c.score||c.filePath.localeCompare(l.filePath));if(a.length===0)return[];let m=Math.max(1,Math.min(30,Math.ceil(a.length*.15)));return a.slice(0,m)}};function ur(n){return n.replaceAll("\\","/").toLowerCase()}var fr={CALL_REFERENCE:6,CALLS:4,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:6,IMPLEMENTS:6,ROUTE:3,TESTS:1},me=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(a=>[a.id,a])),i=[...new Set(t.map(a=>a.filePath))].sort(),o=new Map;for(let a of i)o.set(a,this.classifyPath(a));for(let a=0;a<3;a++){let m=!1;for(let c of i){let l=o.get(c);if(!l||l.layer!=="unknown")continue;let u=new Map;for(let f of r){let h=s.get(f.from),p=s.get(f.to);if(!h||!p||h.filePath===p.filePath)continue;let b=null;if(h.filePath===c?b=p.filePath:p.filePath===c&&(b=h.filePath),!b)continue;let g=o.get(b);if(!g||g.layer==="unknown"||g.layer==="tests")continue;let x=fr[f.type]??1;u.set(g.layer,(u.get(g.layer)??0)+x)}let d=[...u.entries()].sort((f,h)=>h[1]-f[1]||f[0].localeCompare(h[0]))[0];d&&d[1]>=4&&(o.set(c,{filePath:c,layer:d[0],confidence:.65,reasons:[`graph-neighbor vote=${d[1]}`]}),m=!0)}if(!m)break}return i.map(a=>o.get(a))}classifyPath(e){let t=ur(e);return t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t)?{filePath:e,layer:"tests",confidence:1,reasons:["test path"]}:t.startsWith("bin/")||t.includes("/mcp/")||t.includes("/cli/")||t.includes("/api/")||t.includes("/routes/")||t.includes("/hooks/")?{filePath:e,layer:"interface",confidence:.9,reasons:["interface boundary"]}:t.includes("/runtime/")||t.includes("/processor/")||t.includes("/retrieval/")||t.includes("/snapshot/")||t.includes("/code-intelligence/")?{filePath:e,layer:"application",confidence:.85,reasons:["application orchestration"]}:t.includes("/core/")||t.includes("/memory/")||/(^|\/)types\.[^.]+$/.test(t)?{filePath:e,layer:"domain",confidence:.9,reasons:["domain/core logic"]}:t.includes("/storage/")||t.includes("/production/")||t.includes("/security/")||t.includes("/config/")||t.includes("/utils/")?{filePath:e,layer:"infrastructure",confidence:.85,reasons:["infrastructure boundary"]}:{filePath:e,layer:"unknown",confidence:.35,reasons:[]}}};import{createHash as gr}from"node:crypto";var hr={CALL_REFERENCE:7,CALLS:3,IMPORTS:4,USES_TYPE:4,WRITES:5,INHERITS:7,IMPLEMENTS:7,ROUTE:4,TESTS:1};function yr(n){return gr("sha256").update(n).digest("hex").slice(0,12)}function ue(n){return n.replaceAll("\\","/")}function Sr(n){let t=ue(n).split("/").filter(Boolean);return t[0]==="src"&&t[1]?`src/${t[1]}`:t[0]==="packages"&&t[1]?`packages/${t[1]}`:t[0]==="tests"?"tests":t[0]==="bin"?"bin":t[0]??"root"}function br(n){let e=n.replace(/^src\//,"").replace(/^packages\//,"");return{"code-intelligence":"Code Intelligence",memory:"Memory",storage:"Storage",retrieval:"Retrieval",runtime:"Runtime",mcp:"MCP",hooks:"Hooks",security:"Security",snapshot:"Snapshots",production:"Production",capture:"Capture",processor:"Processor",core:"Core",tests:"Tests",bin:"CLI",sdk:"SDK",cli:"CLI"}[e]??e}var fe=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Map(t.map(d=>[d.id,d])),i=[...new Set(t.map(d=>ue(d.filePath)))].sort(),o=new Map,a=(d,f)=>{let h=[d,f].sort();return`${h[0]}\0${h[1]}`};for(let d of r){let f=s.get(d.from),h=s.get(d.to);if(!f||!h)continue;let p=ue(f.filePath),b=ue(h.filePath);if(p===b)continue;let g=hr[d.type]??0;if(g<=0)continue;let x=a(p,b),y=o.get(x);y?y.weight+=g:o.set(x,{a:[p,b].sort()[0],b:[p,b].sort()[1],weight:g})}let m=new Map;for(let d of i){let f=Sr(d),h=m.get(f)??[];h.push(d),m.set(f,h)}let c=[];for(let[d,f]of m){if(f.sort(),f.length<=30){c.push({subsystem:d,files:f});continue}let h=new Set(f),p=new Map;for(let y of f)p.set(y,new Set);for(let y of o.values())!h.has(y.a)||!h.has(y.b)||y.weight>=8&&(p.get(y.a)?.add(y.b),p.get(y.b)?.add(y.a));let b=new Set,g=[];for(let y of f){if(b.has(y))continue;let w=[y],P=[];for(b.add(y);w.length>0;){let v=w.shift();P.push(v);for(let R of p.get(v)??[])b.has(R)||(b.add(R),w.push(R))}g.push(P.sort())}let x=[];for(let y of g)y.length>=2?c.push({subsystem:d,files:y}):x.push(...y);x.length>0&&c.push({subsystem:`${d}/residual`,files:x.sort()})}let l=c.map(d=>({subsystem:d.subsystem,files:[...d.files]}));for(let d=0;d<3;d++){let f=!1;e:for(let h=0;h<l.length;h++){let p=l[h];if(!(!p||p.files.length>3))for(let b=0;b<l.length;b++){if(h===b)continue;let g=l[b];if(!g)continue;let x=0,y=new Set(p.files),w=new Set(g.files);for(let P of o.values())(y.has(P.a)&&w.has(P.b)||y.has(P.b)&&w.has(P.a))&&(x+=P.weight);if(x>=20){g.files=[...new Set([...g.files,...p.files])].sort(),l.splice(h,1),f=!0;break e}}}if(!f)break}let u=[];for(let d of l){let f=new Set(d.files),h=0,p=0;for(let w of o.values()){let P=f.has(w.a),v=f.has(w.b);P&&v?h+=w.weight:(P||v)&&(p+=w.weight)}let b=h+p,g=d.subsystem.replace(/\/residual$/,""),x=br(g),y=d.subsystem.endsWith("/residual")?`${x} Misc`:x;u.push({id:`cluster-${yr(`${d.subsystem}:${d.files.join("|")}`)}`,label:y,subsystem:g,files:d.files,size:d.files.length,internalWeight:h,externalWeight:p,cohesion:b>0?Number((h/b).toFixed(4)):0})}return u.sort((d,f)=>f.size-d.size||f.cohesion-d.cohesion||d.label.localeCompare(f.label))}};var ge=class{constructor(e){this.graph=e;this.entryPoints=new M(e),this.hotspots=new pe(e),this.layers=new me(e),this.clusters=new fe(e)}graph;entryPoints;hotspots;layers;clusters;analyze(e){let t=this.entryPoints.detect(e),r=this.hotspots.analyze(e),s=this.layers.detect(e),i=this.clusters.detect(e),o=new Set(this.graph.allSymbols(e).map(a=>a.filePath));return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{files:o.size,entryPoints:t.length,hotspots:r.length,layers:s.length,clusters:i.length},entryPoints:t,hotspots:r,layers:s,clusters:i}}};var et=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Fe(n){return n.replaceAll("\\","/").toLowerCase()}function xr(n){let e=Fe(n);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function wr(n){let e=Fe(n.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var he=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e),s=new Set(new M(this.graph).detect(e).map(o=>o.symbolId)),i=[];for(let o of t){if(!["function","method","class","interface","property"].includes(o.type)||xr(o.filePath)||s.has(o.id)||wr(o)||r.filter(f=>f.to===o.id&&et.has(f.type)).length>0)continue;let m=r.filter(f=>f.from===o.id&&et.has(f.type)),c=["no incoming usage edge"],l=50;(o.type==="function"||o.type==="method")&&(l+=20,c.push("callable symbol")),o.type==="property"&&(l-=15),m.length===0&&(l+=10,c.push("no outgoing dependency")),Fe(o.filePath).includes("/internal/")&&(l+=10,c.push("internal implementation")),o.name.startsWith("_")&&(l+=5);let d=l>=75?"high":l>=55?"medium":"low";i.push({symbolId:o.id,name:o.name,qualifiedName:o.qualifiedName,type:o.type,filePath:o.filePath,startLine:o.startLine,confidence:d,score:l,reasons:c})}return i.sort((o,a)=>a.score-o.score||o.filePath.localeCompare(a.filePath)||o.name.localeCompare(a.name))}};var Er=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),ye=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),r=this.graph.allEdges(e).filter(o=>Er.has(o.type)),s=new Map(t.map(o=>[o.id,o]));return[...new Set(t.map(o=>o.filePath))].sort().map(o=>{let a=new Set,m=new Set,c=0,l=0;for(let u of r){let d=s.get(u.from),f=s.get(u.to);!d||!f||d.filePath===f.filePath||(d.filePath===o&&(a.add(f.filePath),c++),f.filePath===o&&(m.add(d.filePath),l++))}return{filePath:o,dependencies:[...a].sort(),dependents:[...m].sort(),outgoingEdges:c,incomingEdges:l}})}};var Se=class{constructor(e){this.graph=e}graph;analyze(e){let t=new he(this.graph).analyze(e),r=new ye(this.graph).analyze(e);return{version:1,projectId:e,updatedAt:new Date().toISOString(),summary:{deadCodeCandidates:t.length,highConfidenceDeadCode:t.filter(s=>s.confidence==="high").length,files:r.length},deadCode:t,dependencies:r}}};var be=class{constructor(e){this.graph=e}graph;build(e,t,r){let s=this.graph.allSymbols(e),i=this.graph.allEdges(e),o=new Map(t?.layers.map(p=>[p.filePath,p.layer])??[]),a=new Map;for(let p of t?.clusters??[])for(let b of p.files)a.set(b,{id:p.id,label:p.label});let m=new Map(t?.hotspots.map(p=>[p.filePath,p.score])??[]),c=new Map(r?.deadCode.map(p=>[p.symbolId,{confidence:p.confidence,score:p.score}])??[]),l=new Map,u=new Map;for(let p of i)u.set(p.from,(u.get(p.from)??0)+1),l.set(p.to,(l.get(p.to)??0)+1);let d=s.map(p=>{let b=a.get(p.filePath);return{id:p.id,name:p.name,qualifiedName:p.qualifiedName,type:p.type,filePath:p.filePath,layer:o.get(p.filePath),cluster:b?.id,clusterLabel:b?.label,hotspotScore:m.get(p.filePath),deadCode:c.get(p.id),incoming:l.get(p.id)??0,outgoing:u.get(p.id)??0}}),f=new Set(d.map(p=>p.id)),h=i.filter(p=>f.has(p.from)&&f.has(p.to)).map(p=>({source:p.from,target:p.to,type:p.type,confidence:typeof p.metadata?.confidence=="string"?p.metadata.confidence:void 0,resolver:typeof p.metadata?.resolver=="string"?p.metadata.resolver:void 0}));return{version:1,projectId:e,generatedAt:new Date().toISOString(),summary:{nodes:d.length,links:h.length,files:new Set(d.map(p=>p.filePath)).size,clusters:new Set(d.map(p=>p.cluster).filter(Boolean)).size},nodes:d,links:h}}};import{homedir as Wr}from"node:os";import{join as Ur}from"node:path";import{DeleteObjectCommand as Cr,GetObjectCommand as vr,HeadObjectCommand as Pr,ListObjectsV2Command as kr,PutObjectCommand as Tr,S3Client as Rr}from"@aws-sdk/client-s3";import{getSignedUrl as Ar}from"@aws-sdk/s3-request-presigner";var xe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Rr({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 Tr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Ar(this.client,new vr({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 Pr({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 Cr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new kr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let i of s.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as tt,mkdir as Lr,readFile as jr,readdir as Ir,rm as Nr,stat as rt,writeFile as Mr}from"node:fs/promises";import{dirname as Or,join as _r,relative as st,resolve as Fr}from"node:path";var U=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Fr(this.root,t)}async put(e,t){let r=this.path(e);await Lr(Or(r),{recursive:!0}),await Mr(r,t)}async get(e){try{return await jr(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 tt(this.path(e)),!0}catch{return!1}}async delete(e){await Nr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await tt(t)}catch{return r}let s=async o=>{let a=await Ir(o,{withFileTypes:!0});for(let m of a){let c=_r(o,m.name);if(m.isDirectory()){await s(c);continue}let l=await rt(c);r.push({key:st(this.root,c),size:l.size,updatedAt:l.mtime.toISOString()})}},i=await rt(t);return i.isDirectory()?await s(t):r.push({key:st(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),r}};import{DeleteObjectCommand as $r,GetObjectCommand as Dr,HeadObjectCommand as Gr,ListObjectsV2Command as zr,PutObjectCommand as Kr,S3Client as Br}from"@aws-sdk/client-s3";import{getSignedUrl as Hr}from"@aws-sdk/s3-request-presigner";var V=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Br({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 Kr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Hr(this.client,new Dr({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 Gr({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 $r({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new zr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let i of s.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};function $e(n,e){return console.warn(e),new U(n)}function ot(n){let e=n.localRoot??Ur(Wr(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new V({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):$e(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(n.provider==="s3"){let t=n.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new V({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):$e(e,"[storage] S3 credentials missing. Using local fallback.")}if(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new xe({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):$e(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new U(e)}function Vr(n){return new Promise(e=>setTimeout(e,n))}async function nt(n,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,i;for(let o=1;o<=t;o++)try{return await n()}catch(a){if(i=a,o>=t)break;let m=Math.min(s,r*2**(o-1)),c=Math.floor(Math.random()*Math.max(1,m*.2));await Vr(m+c)}throw i}var Jr=new Set(["put","get","getText","delete","list"]);function it(n,e={}){return new Proxy(n,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Jr.has(r)?(...i)=>nt(()=>Promise.resolve(s.apply(t,i)),e):s.bind(t)}})}function at(n){let e=n.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 ct(n){let e=n.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 we=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=at(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 o;try{o=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof o.id=="string"&&o.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${o.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof o.createdAt=="string"&&(r=o.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
7
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=ct(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))}};var Ee=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","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{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,r(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,r(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,r(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,r(e.clusters),"application/json")])}};var ve=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),r=s=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:s},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,r(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,r(e.dependencies),"application/json")])}};var Pe=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.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,null,2),"application/json")}};async function lt(n,e={}){let t=Date.now();async function r(p,b,g){await e.onStage?.({id:p,title:b,state:"start"});let x=Date.now(),y=await g();return await e.onStage?.({id:p,title:b,state:"complete",durationMs:Date.now()-x}),y}let s=Be(),i=it(ot({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:3}),o=new we(i,n.id,n.name,n.remote??n.name),a=new z(o),c=(await r("source-index","Source Index",async()=>{let p=await new te().index(n.id,n.rootPath);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:p.files,symbols:p.graph.allSymbols(n.id),edges:p.graph.allEdges(n.id)}),p})).graph,l=await r("type-resolution","Type Resolution",async()=>{let p=await new le(c).resolveProject(n.id,n.rootPath);return await new Ee(o).save(p),p});await r("rich-graph","Rich Graph",async()=>{let p=new de(c).enrich(n.id,n.rootPath,l),b=c.allSymbols(n.id),g=c.allEdges(n.id);return await a.save({version:1,projectId:n.id,updatedAt:new Date().toISOString(),files:b.filter(x=>x.type==="file").length,symbols:b,edges:g}),p});let u=await r("semantic-index","Semantic Code Index",async()=>new ie({projectId:n.id,rootPath:n.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:o,embeddings:Je(),graph:c}).initialize()),d=await r("architecture","Architecture Intelligence",async()=>{let p=new ge(c).analyze(n.id);return await new Ce(o).save(p),p}),f=await r("analysis","Graph Analysis",async()=>{let p=new Se(c).analyze(n.id);return await new ve(o).save(p),p}),h=await r("visualization","3D Visualization Dataset",async()=>{let p=new be(c).build(n.id,d,f);return await new Pe(o).save(p),p});return{project:{id:n.id,name:n.name,remote:n.remote??n.name},storage:o.name,durationMs:Date.now()-t,graph:{symbols:c.allSymbols(n.id).length,edges:c.allEdges(n.id).length},resolution:{total:l.total,exact:l.exact,high:l.high,fallback:l.fallback},semantic:u,architecture:d.summary,analysis:f.summary,visualization:h.summary}}var j=new q().detect(),Ke=ze(j.rootPath,".toolnet"),De=ze(Ke,"index.lock"),es=ze(Ke,"last-index.json");qr(Ke,{recursive:!0});function ke(n){Xr(es,JSON.stringify(n,null,2)+`
8
+ `,{encoding:"utf8",mode:384})}var Ge;try{Ge=Qr(De,"wx",384)}catch{console.error("\u274C Index already running for this project."),console.error(`Lock: ${De}`),process.exit(2)}var Te=new Date().toISOString(),J=[];try{console.log(),console.log("=============================================="),console.log(" ToolNet Production Index"),console.log("=============================================="),console.log(`Project : ${j.name}`),console.log(`Remote : projects/${j.remote??j.name}/`),console.log("Runtime : production/dist"),console.log("Snapshot: disabled"),ke({version:2,state:"running",startedAt:Te,completedStages:J,project:j});let n=await lt(j,{onStage:async e=>{e.state==="start"?(console.log(),console.log(`===== ${e.title} =====`)):(J.push(e.id),console.log(`\u2705 ${e.title} (${((e.durationMs??0)/1e3).toFixed(1)}s)`)),ke({version:2,state:"running",startedAt:Te,currentStage:e.id,completedStages:[...J],project:j})}});ke({version:2,state:"complete",startedAt:Te,finishedAt:new Date().toISOString(),completedStages:J,result:n}),console.log(),console.log("=============================================="),console.log(" FULL INDEX COMPLETE \u2705"),console.log("=============================================="),console.log(JSON.stringify(n,null,2))}catch(n){ke({version:2,state:"failed",startedAt:Te,failedAt:new Date().toISOString(),completedStages:J,error:n instanceof Error?n.message:String(n)}),console.error("FULL INDEX FAILED \u274C"),console.error(n),process.exitCode=1}finally{Ge!==void 0&&Yr(Ge),Zr(De,{force:!0})}
@@ -1,4 +1,4 @@
1
- import"dotenv/config";import{existsSync as ie,readFileSync as ae}from"node:fs";import{homedir as ce}from"node:os";import{join as le}from"node:path";function de(s){let e=s.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 pe(){let s=process.env.TOOLNET_GLOBAL_ENV??le(ce(),".config","toolnet-memory",".env");if(!ie(s))return;let e=ae(s,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let n=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=de(r.slice(o+1)))}}pe();function N(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function w(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function H(){return{memory:{autoCapture:N(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:N(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:N(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:N(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:w(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:w(process.env.MEMORY_RERANK_TOP,10),finalContext:w(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:w(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:w(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as me}from"node:crypto";import{existsSync as $,mkdirSync as fe,readFileSync as ue,renameSync as ge,writeFileSync as he}from"node:fs";import{basename as ye,dirname as A,join as I,parse as J,resolve as P}from"node:path";var q=".toolnet",Se="project.json";function be(s){return me("sha256").update(s).digest("hex").slice(0,16)}function G(s){return I(s,q,Se)}function xe(s){return $(G(s))}function Ce(s,e){let t=P(s),r=J(t).root;for(;;){if(xe(t))return t;if(t===r||e&&t===P(e))break;let o=A(t);if(o===t)break;t=o}return null}function Ee(s){let e=P(s),t=J(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>$(I(e,n))))return e;if(e===t)break;let o=A(e);if(o===e)break;e=o}return P(s)}function ve(s){let e;try{e=JSON.parse(ue(s,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${s}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${s}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${s}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${s}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:A(A(s)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function V(s,e){let t=I(s,q);fe(t,{recursive:!0});let r=G(s),o=`${r}.tmp-${process.pid}`;he(o,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),ge(o,r)}function U(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var M=class{detect(e=process.cwd()){let t=P(e),r=Ee(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>$(I(r,f))),i=Ce(t,n?r:void 0);if(i){let f=G(i),m=ve(f);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),V(i,m)),U(m,i)}let d=new Date().toISOString(),g=ye(r),l={version:1,id:be(r),name:g,remote:g,rootPath:r,createdAt:d,updatedAt:d,graphVersion:0,memoryVersion:0};return V(r,l),U(l,r)}};import{readdir as ke}from"node:fs/promises";import{extname as je,join as Le,relative as Ne}from"node:path";import{basename as Pe}from"node:path";var Re=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Te=new Set([".pem",".key",".p12",".pfx"]);function Y(s){let e=Pe(s).toLowerCase();if(Re.has(e))return!0;for(let t of Te)if(e.endsWith(t))return!0;return!1}var Ae=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Me=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function D(s){let e=[];async function t(r){let o=await ke(r,{withFileTypes:!0});for(let n of o){if(Me.has(n.name))continue;let i=Le(r,n.name);if(n.isDirectory()){await t(i);continue}Ae.has(je(n.name))&&(Y(i)||e.push(Ne(s,i)))}}return await t(s),e.sort()}import{readFile as Ie}from"node:fs/promises";import{join as Oe}from"node:path";import{createHash as Fe}from"node:crypto";import*as c from"typescript";function Z(s,e){return Fe("sha256").update(`${s}:${e}`).digest("hex").slice(0,24)}function z(s,e){return s.getLineAndCharacterOfPosition(e.getStart(s)).line+1}async function B(s,e,t){let r=Oe(e,t),o=await Ie(r,"utf8"),n=c.createSourceFile(t,o,c.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?c.ScriptKind.TSX:c.ScriptKind.TS),i=[],d=[],g=[],l=[],f={id:Z(s,`file:${t}`),projectId:s,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(f);let m=[],x=[];function b(a,y,h,u){let C=Z(s,`${t}:${h}:${u??y}:${a.pos}`);return i.push({id:C,projectId:s,name:y,qualifiedName:u??y,type:h,filePath:t,startLine:z(n,a),endLine:n.getLineAndCharacterOfPosition(a.end).line+1}),C}function L(a){if(!c.isStringLiteral(a.moduleSpecifier))return;let y=[],h=a.importClause;if(h?.name&&y.push({localName:h.name.text,importedName:"default",kind:"default"}),h?.namedBindings&&c.isNamedImports(h.namedBindings))for(let u of h.namedBindings.elements)y.push({localName:u.name.text,importedName:u.propertyName?.text??u.name.text,kind:"named"});h?.namedBindings&&c.isNamespaceImport(h.namedBindings)&&y.push({localName:h.namedBindings.name.text,importedName:"*",kind:"namespace"}),d.push({source:a.moduleSpecifier.text,bindings:y})}function v(a,y){for(let h of a.heritageClauses??[])for(let u of h.types){let C=u.expression.getText(n).split(".").at(-1)??"";C&&l.push({fromId:y,targetName:C,type:h.token===c.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function W(a){let y=!1,h=!1;if(c.isImportDeclaration(a)&&L(a),c.isInterfaceDeclaration(a)&&b(a,a.name.text,"interface",a.name.text),c.isClassDeclaration(a)&&a.name){let u=b(a,a.name.text,"class",a.name.text);v(a,u),x.push({id:u,name:a.name.text}),h=!0}if(c.isFunctionDeclaration(a)&&a.name){let u=b(a,a.name.text,"function",a.name.text);m.push(u),y=!0}if(c.isMethodDeclaration(a)&&a.name){let u=a.name.getText(n),C=x.at(-1)?.name,ne=b(a,u,"method",C?`${C}.${u}`:u);m.push(ne),y=!0}if(c.isCallExpression(a)&&(c.isIdentifier(a.expression)&&g.push({callerId:m.at(-1),calleeName:a.expression.text,line:z(n,a)}),c.isPropertyAccessExpression(a.expression))){let u=a.expression;g.push({callerId:m.at(-1),qualifier:u.expression.getText(n),calleeName:u.name.text,line:z(n,a)})}c.forEachChild(a,W),y&&m.pop(),h&&x.pop()}return W(n),{filePath:t,symbols:i,imports:d,calls:g,heritage:l}}import{createHash as _e}from"node:crypto";import{dirname as $e,extname as Ge,normalize as De,posix as ze}from"node:path";var R=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 Be(s,e,t,r){return _e("sha256").update(`${s}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function E(s){return De(s).replaceAll("\\","/")}function K(s,e,t){if(!e.startsWith("."))return;let r=E(ze.join($e(s),e)),o=Ge(r),n;if(o===".js"){let i=r.slice(0,-3);n=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(o===".mjs"){let i=r.slice(0,-4);n=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(o===".cjs"){let i=r.slice(0,-4);n=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else o?n=[r]:n=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return n.find(i=>t.has(E(i)))}var T=class{build(e,t){let r=new R,o=new Map;for(let i of t)for(let d of i.symbols)r.addSymbol(d),d.type==="file"&&o.set(E(i.filePath),d);let n=new Set(o.keys());for(let i of t){let d=E(i.filePath),g=o.get(d);if(g){for(let l of i.symbols)l.id!==g.id&&r.addEdge(this.edge(e,g.id,"DEFINES",l.id));for(let l of i.imports){let f=K(d,l.source,n);if(!f)continue;let m=o.get(f);m&&r.addEdge(this.edge(e,g.id,"IMPORTS",m.id,{source:l.source}))}for(let l of i.heritage){let f=r.findByName(e,l.targetName).filter(m=>m.type==="class"||m.type==="interface");for(let m of f)r.addEdge(this.edge(e,l.fromId,l.type,m.id))}for(let l of i.calls){if(!l.callerId)continue;let f=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let m of f)m.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",m.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,o,n,i,d){let g=E(t.filePath),l=i.findByName(e,r).filter(f=>E(f.filePath)===g);if(!o&&l.length)return l;if(o)for(let f of t.imports){if(!f.bindings.find(b=>b.kind==="namespace"&&b.localName===o))continue;let x=K(g,f.source,d);if(x)return i.findByName(e,r).filter(b=>E(b.filePath)===x)}for(let f of t.imports){let m=f.bindings.find(v=>v.localName===r);if(!m)continue;let x=K(g,f.source,d);if(!x)continue;let b=m.importedName==="default"?r:m.importedName,L=i.findByName(e,b).filter(v=>E(v.filePath)===x);if(L.length)return L}return i.findByName(e,r).filter(f=>f.type==="function"||f.type==="method")}edge(e,t,r,o,n){return{id:Be(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:n}}};var O=class{async index(e,t){let r=await D(t),o=[];for(let i of r)try{o.push(await B(e,t,i))}catch(d){console.warn(`[indexer] skipped ${i}:`,d instanceof Error?d.message:d)}let n=new T().build(e,o);return{files:o.length,symbols:n.allSymbols(e).length,edges:n.allEdges(e).length,graph:n}}};function Q(s,e){let t=s.allSymbols(e),r=s.allEdges(e),o=i=>t.filter(d=>d.type===i).length,n=i=>r.filter(d=>d.type===i).length;return{files:o("file"),classes:o("class"),interfaces:o("interface"),functions:o("function"),methods:o("method"),properties:o("property"),routes:o("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")}}import{execFile as Ke}from"node:child_process";import{promisify as We}from"node:util";var Sr=We(Ke);var k=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*as S from"typescript";import*as p from"typescript";var Ns=new Set([p.SyntaxKind.EqualsToken,p.SyntaxKind.PlusEqualsToken,p.SyntaxKind.MinusEqualsToken,p.SyntaxKind.AsteriskEqualsToken,p.SyntaxKind.SlashEqualsToken,p.SyntaxKind.PercentEqualsToken,p.SyntaxKind.QuestionQuestionEqualsToken,p.SyntaxKind.AmpersandAmpersandEqualsToken,p.SyntaxKind.BarBarEqualsToken]);import{homedir as at}from"node:os";import{join as ct}from"node:path";import{DeleteObjectCommand as Ve,GetObjectCommand as Ue,HeadObjectCommand as Je,ListObjectsV2Command as qe,PutObjectCommand as Ye,S3Client as Ze}from"@aws-sdk/client-s3";import{getSignedUrl as Qe}from"@aws-sdk/s3-request-presigner";var F=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ze({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ye({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Qe(this.client,new Ue({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 Je({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 Ve({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new qe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as X,mkdir as Xe,readFile as et,readdir as tt,rm as rt,stat as ee,writeFile as st}from"node:fs/promises";import{dirname as ot,join as nt,relative as te,resolve as it}from"node:path";var j=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return it(this.root,t)}async put(e,t){let r=this.path(e);await Xe(ot(r),{recursive:!0}),await st(r,t)}async get(e){try{return await et(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 X(this.path(e)),!0}catch{return!1}}async delete(e){await rt(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await X(t)}catch{return r}let o=async i=>{let d=await tt(i,{withFileTypes:!0});for(let g of d){let l=nt(i,g.name);if(g.isDirectory()){await o(l);continue}let f=await ee(l);r.push({key:te(this.root,l),size:f.size,updatedAt:f.mtime.toISOString()})}},n=await ee(t);return n.isDirectory()?await o(t):r.push({key:te(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function re(s){let e=s.localRoot??ct(at(),".toolnet-memory","storage");if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new F({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new j(e))}return new j(e)}function se(s){let e=s.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 oe(s){let e=s.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 o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var _=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=se(o??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,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(d){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${d instanceof Error?d.message:String(d)}`)}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)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=oe(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))}};async function lt(){let s=H(),e=new M().detect(),t=re({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),r=new _(t,e.id,e.name,e.remote??e.name),o=await new O().index(e.id,e.rootPath),n=Q(o.graph,e.id);await new k(r).save({version:1,projectId:e.id,updatedAt:new Date().toISOString(),files:o.files,symbols:o.graph.allSymbols(e.id),edges:o.graph.allEdges(e.id)}),console.log({ok:!0,storage:r.name,...n})}lt().catch(s=>{console.error(s),process.exit(1)});
1
+ import"dotenv/config";import{existsSync as ce,readFileSync as le}from"node:fs";import{homedir as de}from"node:os";import{join as pe}from"node:path";function me(s){let e=s.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 fe(){let s=process.env.TOOLNET_GLOBAL_ENV??pe(de(),".config","toolnet-memory",".env");if(!ce(s))return;let e=le(s,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let n=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=me(r.slice(o+1)))}}fe();function w(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function P(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function V(){return{memory:{autoCapture:w(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:w(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:w(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:w(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:P(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:P(process.env.MEMORY_RERANK_TOP,10),finalContext:P(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:P(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:w(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:P(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ue}from"node:crypto";import{existsSync as D,mkdirSync as ge,readFileSync as he,renameSync as ye,writeFileSync as Se}from"node:fs";import{basename as be,dirname as I,join as O,parse as q,resolve as k}from"node:path";var Q=".toolnet",xe="project.json";function Ce(s){return ue("sha256").update(s).digest("hex").slice(0,16)}function G(s){return O(s,Q,xe)}function Ee(s){return D(G(s))}function ve(s,e){let t=k(s),r=q(t).root;for(;;){if(Ee(t))return t;if(t===r||e&&t===k(e))break;let o=I(t);if(o===t)break;t=o}return null}function we(s){let e=k(s),t=q(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>D(O(e,n))))return e;if(e===t)break;let o=I(e);if(o===e)break;e=o}return k(s)}function Pe(s){let e;try{e=JSON.parse(he(s,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${s}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${s}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${s}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${s}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:I(I(s)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Y(s,e){let t=O(s,Q);ge(t,{recursive:!0});let r=G(s),o=`${r}.tmp-${process.pid}`;Se(o,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),ye(o,r)}function J(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var M=class{detect(e=process.cwd()){let t=k(e),r=we(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>D(O(r,f))),i=ve(t,n?r:void 0);if(i){let f=G(i),m=Pe(f);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),Y(i,m)),J(m,i)}let d=new Date().toISOString(),g=be(r),l={version:1,id:Ce(r),name:g,remote:g,rootPath:r,createdAt:d,updatedAt:d,graphVersion:0,memoryVersion:0};return Y(r,l),J(l,r)}};import{readdir as Ae}from"node:fs/promises";import{extname as Le,join as Ne,relative as Ie}from"node:path";import{basename as Re}from"node:path";var Te=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),je=new Set([".pem",".key",".p12",".pfx"]);function Z(s){let e=Re(s).toLowerCase();if(Te.has(e))return!0;for(let t of je)if(e.endsWith(t))return!0;return!1}var Me=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Oe=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function K(s){let e=[];async function t(r){let o=await Ae(r,{withFileTypes:!0});for(let n of o){if(Oe.has(n.name))continue;let i=Ne(r,n.name);if(n.isDirectory()){await t(i);continue}Me.has(Le(n.name))&&(Z(i)||e.push(Ie(s,i)))}}return await t(s),e.sort()}import{readFile as _e}from"node:fs/promises";import{join as Fe}from"node:path";import{createHash as $e}from"node:crypto";import*as c from"typescript";function X(s,e){return $e("sha256").update(`${s}:${e}`).digest("hex").slice(0,24)}function z(s,e){return s.getLineAndCharacterOfPosition(e.getStart(s)).line+1}async function B(s,e,t){let r=Fe(e,t),o=await _e(r,"utf8"),n=c.createSourceFile(t,o,c.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?c.ScriptKind.TSX:c.ScriptKind.TS),i=[],d=[],g=[],l=[],f={id:X(s,`file:${t}`),projectId:s,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(f);let m=[],x=[];function b(a,y,h,u){let C=X(s,`${t}:${h}:${u??y}:${a.pos}`);return i.push({id:C,projectId:s,name:y,qualifiedName:u??y,type:h,filePath:t,startLine:z(n,a),endLine:n.getLineAndCharacterOfPosition(a.end).line+1}),C}function N(a){if(!c.isStringLiteral(a.moduleSpecifier))return;let y=[],h=a.importClause;if(h?.name&&y.push({localName:h.name.text,importedName:"default",kind:"default"}),h?.namedBindings&&c.isNamedImports(h.namedBindings))for(let u of h.namedBindings.elements)y.push({localName:u.name.text,importedName:u.propertyName?.text??u.name.text,kind:"named"});h?.namedBindings&&c.isNamespaceImport(h.namedBindings)&&y.push({localName:h.namedBindings.name.text,importedName:"*",kind:"namespace"}),d.push({source:a.moduleSpecifier.text,bindings:y})}function v(a,y){for(let h of a.heritageClauses??[])for(let u of h.types){let C=u.expression.getText(n).split(".").at(-1)??"";C&&l.push({fromId:y,targetName:C,type:h.token===c.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function U(a){let y=!1,h=!1;if(c.isImportDeclaration(a)&&N(a),c.isInterfaceDeclaration(a)&&b(a,a.name.text,"interface",a.name.text),c.isClassDeclaration(a)&&a.name){let u=b(a,a.name.text,"class",a.name.text);v(a,u),x.push({id:u,name:a.name.text}),h=!0}if(c.isFunctionDeclaration(a)&&a.name){let u=b(a,a.name.text,"function",a.name.text);m.push(u),y=!0}if(c.isMethodDeclaration(a)&&a.name){let u=a.name.getText(n),C=x.at(-1)?.name,ae=b(a,u,"method",C?`${C}.${u}`:u);m.push(ae),y=!0}if(c.isCallExpression(a)&&(c.isIdentifier(a.expression)&&g.push({callerId:m.at(-1),calleeName:a.expression.text,line:z(n,a)}),c.isPropertyAccessExpression(a.expression))){let u=a.expression;g.push({callerId:m.at(-1),qualifier:u.expression.getText(n),calleeName:u.name.text,line:z(n,a)})}c.forEachChild(a,U),y&&m.pop(),h&&x.pop()}return U(n),{filePath:t,symbols:i,imports:d,calls:g,heritage:l}}import{createHash as De}from"node:crypto";import{dirname as Ge,extname as Ke,normalize as ze,posix as Be}from"node:path";var R=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 We(s,e,t,r){return De("sha256").update(`${s}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function E(s){return ze(s).replaceAll("\\","/")}function W(s,e,t){if(!e.startsWith("."))return;let r=E(Be.join(Ge(s),e)),o=Ke(r),n;if(o===".js"){let i=r.slice(0,-3);n=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(o===".mjs"){let i=r.slice(0,-4);n=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(o===".cjs"){let i=r.slice(0,-4);n=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else o?n=[r]:n=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return n.find(i=>t.has(E(i)))}var T=class{build(e,t){let r=new R,o=new Map;for(let i of t)for(let d of i.symbols)r.addSymbol(d),d.type==="file"&&o.set(E(i.filePath),d);let n=new Set(o.keys());for(let i of t){let d=E(i.filePath),g=o.get(d);if(g){for(let l of i.symbols)l.id!==g.id&&r.addEdge(this.edge(e,g.id,"DEFINES",l.id));for(let l of i.imports){let f=W(d,l.source,n);if(!f)continue;let m=o.get(f);m&&r.addEdge(this.edge(e,g.id,"IMPORTS",m.id,{source:l.source}))}for(let l of i.heritage){let f=r.findByName(e,l.targetName).filter(m=>m.type==="class"||m.type==="interface");for(let m of f)r.addEdge(this.edge(e,l.fromId,l.type,m.id))}for(let l of i.calls){if(!l.callerId)continue;let f=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let m of f)m.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",m.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,o,n,i,d){let g=E(t.filePath),l=i.findByName(e,r).filter(f=>E(f.filePath)===g);if(!o&&l.length)return l;if(o)for(let f of t.imports){if(!f.bindings.find(b=>b.kind==="namespace"&&b.localName===o))continue;let x=W(g,f.source,d);if(x)return i.findByName(e,r).filter(b=>E(b.filePath)===x)}for(let f of t.imports){let m=f.bindings.find(v=>v.localName===r);if(!m)continue;let x=W(g,f.source,d);if(!x)continue;let b=m.importedName==="default"?r:m.importedName,N=i.findByName(e,b).filter(v=>E(v.filePath)===x);if(N.length)return N}return i.findByName(e,r).filter(f=>f.type==="function"||f.type==="method")}edge(e,t,r,o,n){return{id:We(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:n}}};var _=class{async index(e,t){let r=await K(t),o=[];for(let i of r)try{o.push(await B(e,t,i))}catch(d){console.warn(`[indexer] skipped ${i}:`,d instanceof Error?d.message:d)}let n=new T().build(e,o);return{files:o.length,symbols:n.allSymbols(e).length,edges:n.allEdges(e).length,graph:n}}};function ee(s,e){let t=s.allSymbols(e),r=s.allEdges(e),o=i=>t.filter(d=>d.type===i).length,n=i=>r.filter(d=>d.type===i).length;return{files:o("file"),classes:o("class"),interfaces:o("interface"),functions:o("function"),methods:o("method"),properties:o("property"),routes:o("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")}}import{execFile as He}from"node:child_process";import{promisify as Ue}from"node:util";var Rr=Ue(He);var j=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*as S from"typescript";import*as p from"typescript";var Gs=new Set([p.SyntaxKind.EqualsToken,p.SyntaxKind.PlusEqualsToken,p.SyntaxKind.MinusEqualsToken,p.SyntaxKind.AsteriskEqualsToken,p.SyntaxKind.SlashEqualsToken,p.SyntaxKind.PercentEqualsToken,p.SyntaxKind.QuestionQuestionEqualsToken,p.SyntaxKind.AmpersandAmpersandEqualsToken,p.SyntaxKind.BarBarEqualsToken]);import{homedir as ht}from"node:os";import{join as yt}from"node:path";import{DeleteObjectCommand as Ye,GetObjectCommand as Je,HeadObjectCommand as qe,ListObjectsV2Command as Qe,PutObjectCommand as Ze,S3Client as Xe}from"@aws-sdk/client-s3";import{getSignedUrl as et}from"@aws-sdk/s3-request-presigner";var F=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Xe({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ze({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await et(this.client,new Je({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 qe({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 Ye({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Qe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as te,mkdir as tt,readFile as rt,readdir as st,rm as ot,stat as re,writeFile as nt}from"node:fs/promises";import{dirname as it,join as at,relative as se,resolve as ct}from"node:path";var A=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return ct(this.root,t)}async put(e,t){let r=this.path(e);await tt(it(r),{recursive:!0}),await nt(r,t)}async get(e){try{return await rt(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 te(this.path(e)),!0}catch{return!1}}async delete(e){await ot(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await te(t)}catch{return r}let o=async i=>{let d=await st(i,{withFileTypes:!0});for(let g of d){let l=at(i,g.name);if(g.isDirectory()){await o(l);continue}let f=await re(l);r.push({key:se(this.root,l),size:f.size,updatedAt:f.mtime.toISOString()})}},n=await re(t);return n.isDirectory()?await o(t):r.push({key:se(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as lt,GetObjectCommand as dt,HeadObjectCommand as pt,ListObjectsV2Command as mt,PutObjectCommand as ft,S3Client as ut}from"@aws-sdk/client-s3";import{getSignedUrl as gt}from"@aws-sdk/s3-request-presigner";var L=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ut({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ft({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await gt(this.client,new dt({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 pt({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 lt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new mt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function H(s,e){return console.warn(e),new A(s)}function oe(s){let e=s.localRoot??yt(ht(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new L({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):H(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(s.provider==="s3"){let t=s.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new L({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):H(e,"[storage] S3 credentials missing. Using local fallback.")}if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new F({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):H(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new A(e)}function ne(s){let e=s.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 ie(s){let e=s.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 o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var $=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=ne(o??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,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(d){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${d instanceof Error?d.message:String(d)}`)}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)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=ie(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))}};async function St(){let s=V(),e=new M().detect(),t=oe({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),r=new $(t,e.id,e.name,e.remote??e.name),o=await new _().index(e.id,e.rootPath),n=ee(o.graph,e.id);await new j(r).save({version:1,projectId:e.id,updatedAt:new Date().toISOString(),files:o.files,symbols:o.graph.allSymbols(e.id),edges:o.graph.allEdges(e.id)}),console.log({ok:!0,storage:r.name,...n})}St().catch(s=>{console.error(s),process.exit(1)});
package/bundle/impact.js CHANGED
@@ -1,4 +1,4 @@
1
- import"dotenv/config";import{existsSync as te,readFileSync as re}from"node:fs";import{homedir as se}from"node:os";import{join as oe}from"node:path";function ne(s){let e=s.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 ie(){let s=process.env.TOOLNET_GLOBAL_ENV??oe(se(),".config","toolnet-memory",".env");if(!te(s))return;let e=re(s,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let n=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=ne(r.slice(o+1)))}}ie();function E(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function y(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function _(){return{memory:{autoCapture:E(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:E(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:E(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:E(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:y(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:y(process.env.MEMORY_RERANK_TOP,10),finalContext:y(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:y(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:y(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ae}from"node:crypto";import{existsSync as I,mkdirSync as ce,readFileSync as le,renameSync as de,writeFileSync as pe}from"node:fs";import{basename as me,dirname as v,join as P,parse as D,resolve as S}from"node:path";var z=".toolnet",fe="project.json";function ue(s){return ae("sha256").update(s).digest("hex").slice(0,16)}function F(s){return P(s,z,fe)}function ge(s){return I(F(s))}function he(s,e){let t=S(s),r=D(t).root;for(;;){if(ge(t))return t;if(t===r||e&&t===S(e))break;let o=v(t);if(o===t)break;t=o}return null}function ye(s){let e=S(s),t=D(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>I(P(e,n))))return e;if(e===t)break;let o=v(e);if(o===e)break;e=o}return S(s)}function Se(s){let e;try{e=JSON.parse(le(s,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${s}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${s}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${s}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${s}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:v(v(s)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function $(s,e){let t=P(s,z);ce(t,{recursive:!0});let r=F(s),o=`${r}.tmp-${process.pid}`;pe(o,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),de(o,r)}function G(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var w=class{detect(e=process.cwd()){let t=S(e),r=ye(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>I(P(r,d))),i=he(t,n?r:void 0);if(i){let d=F(i),u=Se(d);return u.rootPath!==i&&(u.rootPath=i,u.updatedAt=new Date().toISOString(),$(i,u)),G(u,i)}let p=new Date().toISOString(),l=me(r),c={version:1,id:ue(r),name:l,remote:l,rootPath:r,createdAt:p,updatedAt:p,graphVersion:0,memoryVersion:0};return $(r,c),G(c,r)}};import{homedir as Fe}from"node:os";import{join as Oe}from"node:path";import{DeleteObjectCommand as xe,GetObjectCommand as Ce,HeadObjectCommand as Ee,ListObjectsV2Command as ve,PutObjectCommand as we,S3Client as Pe}from"@aws-sdk/client-s3";import{getSignedUrl as Re}from"@aws-sdk/s3-request-presigner";var R=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Pe({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new we({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Re(this.client,new Ce({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 Ee({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 xe({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new ve({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as B,mkdir as Te,readFile as ke,readdir as je,rm as Le,stat as K,writeFile as Ne}from"node:fs/promises";import{dirname as Ae,join as Me,relative as W,resolve as Ie}from"node:path";var b=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ie(this.root,t)}async put(e,t){let r=this.path(e);await Te(Ae(r),{recursive:!0}),await Ne(r,t)}async get(e){try{return await ke(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 B(this.path(e)),!0}catch{return!1}}async delete(e){await Le(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await B(t)}catch{return r}let o=async i=>{let p=await je(i,{withFileTypes:!0});for(let l of p){let c=Me(i,l.name);if(l.isDirectory()){await o(c);continue}let d=await K(c);r.push({key:W(this.root,c),size:d.size,updatedAt:d.mtime.toISOString()})}},n=await K(t);return n.isDirectory()?await o(t):r.push({key:W(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function H(s){let e=s.localRoot??Oe(Fe(),".toolnet-memory","storage");if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new R({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new b(e))}return new b(e)}var x=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")}};function _e(s){return new Promise(e=>setTimeout(e,s))}async function V(s,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await s()}catch(p){if(n=p,i>=t)break;let l=Math.min(o,r*2**(i-1)),c=Math.floor(Math.random()*Math.max(1,l*.2));await _e(l+c)}throw n}var $e=new Set(["put","get","getText","delete","list"]);function U(s,e={}){return new Proxy(s,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:$e.has(r)?(...n)=>V(()=>Promise.resolve(o.apply(t,n)),e):o.bind(t)}})}function J(s){let e=s.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 q(s){let e=s.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 o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var T=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=J(o??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,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(p){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${p instanceof Error?p.message:String(p)}`)}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)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=q(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*as m from"typescript";var h=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 Be(s,e){return e.ranges.length===0?!0:typeof s.startLine!="number"||typeof s.endLine!="number"?!1:e.ranges.some(t=>s.startLine<=t.endLine&&s.endLine>=t.startLine)}var k=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),o=[];for(let n of t){let i=r.filter(c=>c.filePath===n.filePath),l=i.filter(c=>c.type!=="file").filter(c=>Be(c,n));if(l.length===0){let c=i.find(d=>d.type==="file");c&&o.push({symbol:c,fileStatus:n.status,direct:!0});continue}for(let c of l)o.push({symbol:c,fileStatus:n.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Ke={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function We(s){return s>=30?"CRITICAL":s>=16?"HIGH":s>=6?"MEDIUM":"LOW"}function Y(s){let e=s.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var j=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let o=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 u=new Set([d.symbol.id]),N=[{id:d.symbol.id,depth:0}];for(;N.length;){let A=N.shift();if(A.depth>=r)continue;let Q=o.filter(g=>g.to===A.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(g.type));for(let g of Q){if(u.has(g.from))continue;u.add(g.from);let C=this.graph.getSymbol(g.from);if(!C)continue;let M=A.depth+1,X=`${d.symbol.id}:${C.id}`;n.set(X,{symbol:C,relation:g.type,depth:M,sourceSymbolId:d.symbol.id});let ee=Ke[g.type]??1;i+=Math.max(1,ee-(M-1)),N.push({id:C.id,depth:M})}}}let p=[...n.values()].sort((d,u)=>d.depth-u.depth),l=[...new Set(p.map(d=>d.symbol.filePath))],c=l.filter(Y);return c.length===0&&c.push(...l.filter(d=>!Y(d)).slice(0,10)),{risk:We(i),riskScore:i,changedSymbols:t,impacted:p,impactedFiles:l,suggestedTests:c}}};import{execFile as He}from"node:child_process";import{promisify as Ve}from"node:util";var O=Ve(He);function Ue(s){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of s.matchAll(t)){let o=Number(r[1]),n=Number(r[2]??1);e.push({startLine:o,endLine:Math.max(o,o+n-1)})}return e}function Je(s){return s.startsWith("A")?"added":s.startsWith("D")?"deleted":s.startsWith("R")?"renamed":"modified"}async function Z(s){let e="";try{e=(await O("git",["diff","HEAD","--name-status","--no-renames"],{cwd:s,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[o,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let p="";try{p=(await O("git",["diff","HEAD","--unified=0","--",i],{cwd:s,maxBuffer:20971520})).stdout}catch{p=""}t.push({filePath:i,status:Je(o),ranges:Ue(p)})}try{let r=await O("git",["ls-files","--others","--exclude-standard"],{cwd:s});for(let o of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}var L=class{constructor(e){this.graph=e;this.mapper=new k(e),this.blast=new j(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let o=await Z(t),n=this.mapper.map(e,o),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,r={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,r.maxDepth??4)}}};import*as f from"typescript";import*as a from"typescript";var so=new Set([a.SyntaxKind.EqualsToken,a.SyntaxKind.PlusEqualsToken,a.SyntaxKind.MinusEqualsToken,a.SyntaxKind.AsteriskEqualsToken,a.SyntaxKind.SlashEqualsToken,a.SyntaxKind.PercentEqualsToken,a.SyntaxKind.QuestionQuestionEqualsToken,a.SyntaxKind.AmpersandAmpersandEqualsToken,a.SyntaxKind.BarBarEqualsToken]);async function Ye(){let s=_(),e=new w().detect(),t=U(H({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:3}),r=new T(t,e.id,e.name,e.remote??e.name),o=await new x(r).load(e.id);if(!o)throw new Error("Code graph missing");let n=new h;n.import(o.symbols,o.edges);let i=new L(n),p=process.argv[2],l=p?i.analyzeFile(e.id,p):await i.analyzeGitDiff(e.id,e.rootPath);console.log({risk:l.risk,riskScore:l.riskScore,changedSymbols:l.changedSymbols.map(c=>({symbol:c.symbol.qualifiedName,file:c.symbol.filePath,type:c.symbol.type})),impactedFiles:l.impactedFiles,suggestedTests:l.suggestedTests,impactedCount:l.impacted.length})}Ye().catch(s=>{console.error(s),process.exit(1)});
1
+ import"dotenv/config";import{existsSync as se,readFileSync as oe}from"node:fs";import{homedir as ne}from"node:os";import{join as ie}from"node:path";function ae(s){let e=s.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 ce(){let s=process.env.TOOLNET_GLOBAL_ENV??ie(ne(),".config","toolnet-memory",".env");if(!se(s))return;let e=oe(s,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let n=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=ae(r.slice(o+1)))}}ce();function y(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function S(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function G(){return{memory:{autoCapture:y(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:y(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:y(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:y(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:S(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:S(process.env.MEMORY_RERANK_TOP,10),finalContext:S(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:S(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:y(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:S(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as le}from"node:crypto";import{existsSync as O,mkdirSync as de,readFileSync as pe,renameSync as me,writeFileSync as fe}from"node:fs";import{basename as ue,dirname as v,join as k,parse as z,resolve as b}from"node:path";var B=".toolnet",ge="project.json";function he(s){return le("sha256").update(s).digest("hex").slice(0,16)}function _(s){return k(s,B,ge)}function ye(s){return O(_(s))}function Se(s,e){let t=b(s),r=z(t).root;for(;;){if(ye(t))return t;if(t===r||e&&t===b(e))break;let o=v(t);if(o===t)break;t=o}return null}function be(s){let e=b(s),t=z(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>O(k(e,n))))return e;if(e===t)break;let o=v(e);if(o===e)break;e=o}return b(s)}function xe(s){let e;try{e=JSON.parse(pe(s,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${s}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${s}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${s}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${s}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:v(v(s)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function D(s,e){let t=k(s,B);de(t,{recursive:!0});let r=_(s),o=`${r}.tmp-${process.pid}`;fe(o,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),me(o,r)}function K(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var P=class{detect(e=process.cwd()){let t=b(e),r=be(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>O(k(r,d))),i=Se(t,n?r:void 0);if(i){let d=_(i),u=xe(d);return u.rootPath!==i&&(u.rootPath=i,u.updatedAt=new Date().toISOString(),D(i,u)),K(u,i)}let p=new Date().toISOString(),l=ue(r),c={version:1,id:he(r),name:l,remote:l,rootPath:r,createdAt:p,updatedAt:p,graphVersion:0,memoryVersion:0};return D(r,c),K(c,r)}};import{homedir as We}from"node:os";import{join as He}from"node:path";import{DeleteObjectCommand as Ee,GetObjectCommand as we,HeadObjectCommand as ve,ListObjectsV2Command as Pe,PutObjectCommand as ke,S3Client as Te}from"@aws-sdk/client-s3";import{getSignedUrl as Re}from"@aws-sdk/s3-request-presigner";var T=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Te({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ke({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Re(this.client,new we({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 ve({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 Ee({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Pe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as W,mkdir as je,readFile as Ae,readdir as Le,rm as Ne,stat as H,writeFile as Me}from"node:fs/promises";import{dirname as Ie,join as Oe,relative as U,resolve as _e}from"node:path";var x=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return _e(this.root,t)}async put(e,t){let r=this.path(e);await je(Ie(r),{recursive:!0}),await Me(r,t)}async get(e){try{return await Ae(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 W(this.path(e)),!0}catch{return!1}}async delete(e){await Ne(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await W(t)}catch{return r}let o=async i=>{let p=await Le(i,{withFileTypes:!0});for(let l of p){let c=Oe(i,l.name);if(l.isDirectory()){await o(c);continue}let d=await H(c);r.push({key:U(this.root,c),size:d.size,updatedAt:d.mtime.toISOString()})}},n=await H(t);return n.isDirectory()?await o(t):r.push({key:U(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as Fe,GetObjectCommand as $e,HeadObjectCommand as Ge,ListObjectsV2Command as De,PutObjectCommand as Ke,S3Client as ze}from"@aws-sdk/client-s3";import{getSignedUrl as Be}from"@aws-sdk/s3-request-presigner";var C=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ze({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 o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ke({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Be(this.client,new $e({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 Ge({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 Fe({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new De({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function F(s,e){return console.warn(e),new x(s)}function V(s){let e=s.localRoot??He(We(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new C({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(s.provider==="s3"){let t=s.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new C({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] S3 credentials missing. Using local fallback.")}if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new T({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new x(e)}var E=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")}};function Ue(s){return new Promise(e=>setTimeout(e,s))}async function Y(s,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await s()}catch(p){if(n=p,i>=t)break;let l=Math.min(o,r*2**(i-1)),c=Math.floor(Math.random()*Math.max(1,l*.2));await Ue(l+c)}throw n}var Ve=new Set(["put","get","getText","delete","list"]);function q(s,e={}){return new Proxy(s,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:Ve.has(r)?(...n)=>Y(()=>Promise.resolve(o.apply(t,n)),e):o.bind(t)}})}function J(s){let e=s.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 Q(s){let e=s.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 o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var R=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=J(o??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,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(p){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${p instanceof Error?p.message:String(p)}`)}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)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Q(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*as m from"typescript";var h=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 Qe(s,e){return e.ranges.length===0?!0:typeof s.startLine!="number"||typeof s.endLine!="number"?!1:e.ranges.some(t=>s.startLine<=t.endLine&&s.endLine>=t.startLine)}var j=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),o=[];for(let n of t){let i=r.filter(c=>c.filePath===n.filePath),l=i.filter(c=>c.type!=="file").filter(c=>Qe(c,n));if(l.length===0){let c=i.find(d=>d.type==="file");c&&o.push({symbol:c,fileStatus:n.status,direct:!0});continue}for(let c of l)o.push({symbol:c,fileStatus:n.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Ze={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Xe(s){return s>=30?"CRITICAL":s>=16?"HIGH":s>=6?"MEDIUM":"LOW"}function Z(s){let e=s.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var A=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let o=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 u=new Set([d.symbol.id]),N=[{id:d.symbol.id,depth:0}];for(;N.length;){let M=N.shift();if(M.depth>=r)continue;let ee=o.filter(g=>g.to===M.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(g.type));for(let g of ee){if(u.has(g.from))continue;u.add(g.from);let w=this.graph.getSymbol(g.from);if(!w)continue;let I=M.depth+1,te=`${d.symbol.id}:${w.id}`;n.set(te,{symbol:w,relation:g.type,depth:I,sourceSymbolId:d.symbol.id});let re=Ze[g.type]??1;i+=Math.max(1,re-(I-1)),N.push({id:w.id,depth:I})}}}let p=[...n.values()].sort((d,u)=>d.depth-u.depth),l=[...new Set(p.map(d=>d.symbol.filePath))],c=l.filter(Z);return c.length===0&&c.push(...l.filter(d=>!Z(d)).slice(0,10)),{risk:Xe(i),riskScore:i,changedSymbols:t,impacted:p,impactedFiles:l,suggestedTests:c}}};import{execFile as et}from"node:child_process";import{promisify as tt}from"node:util";var $=tt(et);function rt(s){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of s.matchAll(t)){let o=Number(r[1]),n=Number(r[2]??1);e.push({startLine:o,endLine:Math.max(o,o+n-1)})}return e}function st(s){return s.startsWith("A")?"added":s.startsWith("D")?"deleted":s.startsWith("R")?"renamed":"modified"}async function X(s){let e="";try{e=(await $("git",["diff","HEAD","--name-status","--no-renames"],{cwd:s,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[o,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let p="";try{p=(await $("git",["diff","HEAD","--unified=0","--",i],{cwd:s,maxBuffer:20971520})).stdout}catch{p=""}t.push({filePath:i,status:st(o),ranges:rt(p)})}try{let r=await $("git",["ls-files","--others","--exclude-standard"],{cwd:s});for(let o of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}var L=class{constructor(e){this.graph=e;this.mapper=new j(e),this.blast=new A(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let o=await X(t),n=this.mapper.map(e,o),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,r={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,r.maxDepth??4)}}};import*as f from"typescript";import*as a from"typescript";var xo=new Set([a.SyntaxKind.EqualsToken,a.SyntaxKind.PlusEqualsToken,a.SyntaxKind.MinusEqualsToken,a.SyntaxKind.AsteriskEqualsToken,a.SyntaxKind.SlashEqualsToken,a.SyntaxKind.PercentEqualsToken,a.SyntaxKind.QuestionQuestionEqualsToken,a.SyntaxKind.AmpersandAmpersandEqualsToken,a.SyntaxKind.BarBarEqualsToken]);async function nt(){let s=G(),e=new P().detect(),t=q(V({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:3}),r=new R(t,e.id,e.name,e.remote??e.name),o=await new E(r).load(e.id);if(!o)throw new Error("Code graph missing");let n=new h;n.import(o.symbols,o.edges);let i=new L(n),p=process.argv[2],l=p?i.analyzeFile(e.id,p):await i.analyzeGitDiff(e.id,e.rootPath);console.log({risk:l.risk,riskScore:l.riskScore,changedSymbols:l.changedSymbols.map(c=>({symbol:c.symbol.qualifiedName,file:c.symbol.filePath,type:c.symbol.type})),impactedFiles:l.impactedFiles,suggestedTests:l.suggestedTests,impactedCount:l.impacted.length})}nt().catch(s=>{console.error(s),process.exit(1)});