toolnet-memory 0.2.14 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/runtime.js CHANGED
@@ -1,11 +1,11 @@
1
- import{randomUUID as $t}from"node:crypto";var Tt={critical:100,high:75,normal:50,temporary:20};function Ue(s){return Tt[s]}function Ve(s,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":s==="rule"||s==="decision"?"high":s==="todo"?"normal":s==="activity"||s==="summary"?"temporary":"normal"}var It=[{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 It){let o=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(o))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var j=class{scanner=new z;sanitize(e){let t=e,r=this.scanner.scan(e),o=new Set;for(let n of r)o.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...o]}}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,o]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(o)}return t}return e}};var Mt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),At=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function qe(s){return new Set(s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!At.has(e)))}function Lt(s,e){let t=qe(s),r=qe(e);if(t.size===0||r.size===0)return 0;let o=0;for(let i of t)r.has(i)&&o++;let n=new Set([...t,...r]).size;return o/n}function Je(s){return new Set(s.tags.filter(e=>!Mt.has(e.toLowerCase())))}var K=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,o=Je(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=Je(n);for(let c of o)if(a.has(c))return!0;return Lt(e.content,n.content)>=.6})}};var Nt={critical:100,high:75,normal:50,temporary:20},Ot={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function Ye(s,e,t=new Date){let r;if(e==="temporary"&&(r=30),s==="activity"&&(r=Math.min(r??14,14)),s==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Re(s,e=Date.now()){return s.expiresAt?new Date(s.expiresAt).getTime()<=e:!1}function _t(s){return!!s.metadata?.supersededBy}function Te(s,e=Date.now()){return!Re(s,e)&&!_t(s)}function M(s,e=Date.now()){if(!Te(s,e))return 0;let t=Nt[s.importance];if(s.importance==="critical")return t;let r=Ot[s.type]??180,n=Math.max(0,e-new Date(s.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var R=class{memories=new Map;sanitizer=new j;conflicts=new K;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,o=e.importance??Ve(e.type,r),n={id:$t(),projectId:e.projectId,type:e.type,content:r,importance:o,importanceScore:Ue(o),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??Ye(e.type,o,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Te(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,o=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=M(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=o.filter(p=>i.includes(p)).length,c=o.length===0?0:a/o.length,l=M(n)/500;return{memory:n,score:c+l,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[o,n]of this.memories)n.projectId===e&&Re(n,t)&&(this.memories.delete(o),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let o=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),o++)}return o}clearProject(e){let t=0;for(let[r,o]of this.memories)o.projectId===e&&(this.memories.delete(r),t++);return t}};var B=class{constructor(e){this.memory=e}memory;run(e){let t=this.memory.pruneExpired(e),r=this.memory.pruneSuperseded(e,30);return{expiredRemoved:t,supersededRemoved:r,active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Ie(s){return[...new Set(s.filter(Boolean))]}var H=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,o=t.maxItems??50,n=t.retentionDays??90,i=this.memory.byType(e,"activity").slice(0,o);if(i.length<r)return{scanned:i.length,consolidated:0,summaryCreated:!1};let a=this.buildSummary(i),c=new Date,l=new Date(c.getTime()+n*864e5).toISOString(),p=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:l,metadata:{consolidatedFrom:i.map(u=>u.id),itemCount:i.length}}),d=c.toISOString();for(let u of i){let f=this.memory.get(u.id);f&&(f.updatedAt=d,f.metadata={...f.metadata??{},consolidated:!0,supersededBy:p.id,supersededAt:d})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:p.id}}buildSummary(e){let t=Ie(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Ie(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),o=Ie(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),n=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&n.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&n.push(`- Commands: ${r.slice(0,10).join("; ")}`),o.length&&n.push(`- Errors: ${o.slice(0,10).join("; ")}`),n.join(`
2
- `)}};function W(s){return s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var U=class{score(e,t){let r=W(e),o=W([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||o.length===0)return 0;let n=new Map;for(let a of o)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function Qe(s,e=Date.now()){let t=s.updatedAt??s.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let o=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*o/30)}function Ze(s){return M(s)/100}var Ft={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function Xe(s){return Ft[s]??.4}var V=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var q=class{bm25=new U;analyzer=new V;search(e,t,r={}){let o=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=Qe(c),d=Ze(c),u=Xe(c.type);i.preferredTypes.includes(c.type)&&(u=Math.min(1,u+.25));let f=l*.55+d*.2+p*.15+u*.1;l<=0||f<n||a.push({memory:c,score:f,scores:{keyword:l,recency:p,importance:d,type:u}})}return a.sort((c,l)=>l.score-c.score).slice(0,o)}};var J=class{build(e,t=6e3){let r=[],o=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(o+a.length>t)break;r.push(a),o+=a.length}return r.join(`
3
- `)}};var Y=class{constructor(e){this.memory=e}memory;searcher=new q;contextBuilder=new J;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let o=this.search(e,t,r);return this.contextBuilder.build(o)}};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 o=await r.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(n=>Dt(n))}};function Dt(s){if(!Array.isArray(s))throw new Error("Invalid embedding");if(s.length>0&&typeof s[0]=="number")return s;if(s.length>0&&Array.isArray(s[0])){let e=s;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let o of e)for(let n=0;n<t;n++)r[n]+=o[n]??0;for(let o=0;o<t;o++)r[o]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as Gt}from"node:crypto";var Z=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 o of r){let i=Gt("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return zt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function zt(s){let e=Math.sqrt(s.reduce((t,r)=>t+r*r,0));return e===0?s:s.map(t=>t/e)}var Me=class{constructor(e,t=new Z){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 Ae(){let s=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=s?new Q({token:s,model:e}):null;return new Me(t)}import{readdir as Wt}from"node:fs/promises";import{extname as Ut,join as Vt,relative as qt}from"node:path";import{basename as Kt}from"node:path";var Bt=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Ht=new Set([".pem",".key",".p12",".pfx"]);function Le(s){let e=Kt(s).toLowerCase();if(Bt.has(e))return!0;for(let t of Ht)if(e.endsWith(t))return!0;return!1}var Jt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Yt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Ne(s){let e=[];async function t(r){let o=await Wt(r,{withFileTypes:!0});for(let n of o){if(Yt.has(n.name))continue;let i=Vt(r,n.name);if(n.isDirectory()){await t(i);continue}Jt.has(Ut(n.name))&&(Le(i)||e.push(qt(s,i)))}}return await t(s),e.sort()}import{readFile as Qt}from"node:fs/promises";import{join as Zt}from"node:path";import{createHash as Xt}from"node:crypto";import*as h from"typescript";function et(s,e){return Xt("sha256").update(`${s}:${e}`).digest("hex").slice(0,24)}function Oe(s,e){return s.getLineAndCharacterOfPosition(e.getStart(s)).line+1}async function _e(s,e,t){let r=Zt(e,t),o=await Qt(r,"utf8"),n=h.createSourceFile(t,o,h.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?h.ScriptKind.TSX:h.ScriptKind.TS),i=[],a=[],c=[],l=[],p={id:et(s,`file:${t}`),projectId:s,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(p);let d=[],u=[];function f(m,v,x,b){let C=et(s,`${t}:${x}:${b??v}:${m.pos}`);return i.push({id:C,projectId:s,name:v,qualifiedName:b??v,type:x,filePath:t,startLine:Oe(n,m),endLine:n.getLineAndCharacterOfPosition(m.end).line+1}),C}function w(m){if(!h.isStringLiteral(m.moduleSpecifier))return;let v=[],x=m.importClause;if(x?.name&&v.push({localName:x.name.text,importedName:"default",kind:"default"}),x?.namedBindings&&h.isNamedImports(x.namedBindings))for(let b of x.namedBindings.elements)v.push({localName:b.name.text,importedName:b.propertyName?.text??b.name.text,kind:"named"});x?.namedBindings&&h.isNamespaceImport(x.namedBindings)&&v.push({localName:x.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:m.moduleSpecifier.text,bindings:v})}function S(m,v){for(let x of m.heritageClauses??[])for(let b of x.types){let C=b.expression.getText(n).split(".").at(-1)??"";C&&l.push({fromId:v,targetName:C,type:x.token===h.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function g(m){let v=!1,x=!1;if(h.isImportDeclaration(m)&&w(m),h.isInterfaceDeclaration(m)&&f(m,m.name.text,"interface",m.name.text),h.isClassDeclaration(m)&&m.name){let b=f(m,m.name.text,"class",m.name.text);S(m,b),u.push({id:b,name:m.name.text}),x=!0}if(h.isFunctionDeclaration(m)&&m.name){let b=f(m,m.name.text,"function",m.name.text);d.push(b),v=!0}if(h.isMethodDeclaration(m)&&m.name){let b=m.name.getText(n),C=u.at(-1)?.name,Rt=f(m,b,"method",C?`${C}.${b}`:b);d.push(Rt),v=!0}if(h.isCallExpression(m)&&(h.isIdentifier(m.expression)&&c.push({callerId:d.at(-1),calleeName:m.expression.text,line:Oe(n,m)}),h.isPropertyAccessExpression(m.expression))){let b=m.expression;c.push({callerId:d.at(-1),qualifier:b.expression.getText(n),calleeName:b.name.text,line:Oe(n,m)})}h.forEachChild(m,g),v&&d.pop(),x&&u.pop()}return g(n),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as er}from"node:crypto";import{dirname as tr,extname as rr,normalize as sr,posix as or}from"node:path";var P=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 nr(s,e,t,r){return er("sha256").update(`${s}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function k(s){return sr(s).replaceAll("\\","/")}function $e(s,e,t){if(!e.startsWith("."))return;let r=k(or.join(tr(s),e)),o=rr(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(k(i)))}var A=class{build(e,t){let r=new P,o=new Map;for(let i of t)for(let a of i.symbols)r.addSymbol(a),a.type==="file"&&o.set(k(i.filePath),a);let n=new Set(o.keys());for(let i of t){let a=k(i.filePath),c=o.get(a);if(c){for(let l of i.symbols)l.id!==c.id&&r.addEdge(this.edge(e,c.id,"DEFINES",l.id));for(let l of i.imports){let p=$e(a,l.source,n);if(!p)continue;let d=o.get(p);d&&r.addEdge(this.edge(e,c.id,"IMPORTS",d.id,{source:l.source}))}for(let l of i.heritage){let p=r.findByName(e,l.targetName).filter(d=>d.type==="class"||d.type==="interface");for(let d of p)r.addEdge(this.edge(e,l.fromId,l.type,d.id))}for(let l of i.calls){if(!l.callerId)continue;let p=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let d of p)d.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",d.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,o,n,i,a){let c=k(t.filePath),l=i.findByName(e,r).filter(p=>k(p.filePath)===c);if(!o&&l.length)return l;if(o)for(let p of t.imports){if(!p.bindings.find(f=>f.kind==="namespace"&&f.localName===o))continue;let u=$e(c,p.source,a);if(u)return i.findByName(e,r).filter(f=>k(f.filePath)===u)}for(let p of t.imports){let d=p.bindings.find(S=>S.localName===r);if(!d)continue;let u=$e(c,p.source,a);if(!u)continue;let f=d.importedName==="default"?r:d.importedName,w=i.findByName(e,f).filter(S=>k(S.filePath)===u);if(w.length)return w}return i.findByName(e,r).filter(p=>p.type==="function"||p.type==="method")}edge(e,t,r,o,n){return{id:nr(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:n}}};function tt(s,e){let t=s.allSymbols(e),r=s.allEdges(e),o=i=>t.filter(a=>a.type===i).length,n=i=>r.filter(a=>a.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")}}var X=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(o=>o.type==="CALLS"&&o.to===t).map(o=>o.from).map(o=>this.graph.getSymbol(o)).filter(o=>!!o)}};function ir(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 ee=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(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>ir(l,n));if(c.length===0){let l=i.find(p=>p.type==="file");l&&o.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)o.push({symbol:l,fileStatus:n.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var ar={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function cr(s){return s>=30?"CRITICAL":s>=16?"HIGH":s>=6?"MEDIUM":"LOW"}function rt(s){let e=s.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var te=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 p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let d=new Set([p.symbol.id]),u=[{id:p.symbol.id,depth:0}];for(;u.length;){let f=u.shift();if(f.depth>=r)continue;let w=o.filter(S=>S.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(S.type));for(let S of w){if(d.has(S.from))continue;d.add(S.from);let g=this.graph.getSymbol(S.from);if(!g)continue;let m=f.depth+1,v=`${p.symbol.id}:${g.id}`;n.set(v,{symbol:g,relation:S.type,depth:m,sourceSymbolId:p.symbol.id});let x=ar[S.type]??1;i+=Math.max(1,x-(m-1)),u.push({id:g.id,depth:m})}}}let a=[...n.values()].sort((p,d)=>p.depth-d.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(rt);return l.length===0&&l.push(...c.filter(p=>!rt(p)).slice(0,10)),{risk:cr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as lr}from"node:child_process";import{promisify as dr}from"node:util";var Fe=dr(lr);function pr(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 mr(s){return s.startsWith("A")?"added":s.startsWith("D")?"deleted":s.startsWith("R")?"renamed":"modified"}async function st(s){let e="";try{e=(await Fe("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 a="";try{a=(await Fe("git",["diff","HEAD","--unified=0","--",i],{cwd:s,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:mr(o),ranges:pr(a)})}try{let r=await Fe("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 re=class{constructor(e){this.graph=e;this.mapper=new ee(e),this.blast=new te(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let o=await st(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)}}};var ur=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,fr=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function ot(s){return s.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function gr(s){return s.length>0&&s.length<500&&!s.includes(`
4
- `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(s)}function hr(s){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let o of s.matchAll(r))o[1]&&e.push(ot(o[1]));return e}function De(s,e,t){if(typeof s=="string"){let r=t?.toLowerCase();if(r&&fr.has(r)&&gr(s)&&e.add(ot(s)),s.includes("*** Update File:")||s.includes("*** Add File:")||s.includes("*** Delete File:")||s.includes("+++ b/"))for(let o of hr(s))e.add(o);return}if(Array.isArray(s)){for(let r of s)De(r,e,t);return}if(s&&typeof s=="object")for(let[r,o]of Object.entries(s))De(o,e,r)}function yr(s){return ur.test(s.toLowerCase())}function nt(s,e){if(!yr(s))return[];let t=new Set;return De(e,t),[...t]}import{createHash as Sr}from"node:crypto";import{readFile as br}from"node:fs/promises";async function it(s){let e=await br(s);return Sr("sha256").update(e).digest("hex")}function at(s,e){let t=s?.files??{},r=e.files,o=[],n=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let p=t[c];p?p.hash!==l.hash?n.push(c):a.push(c):o.push(c)}for(let c of Object.keys(t))r[c]||i.push(c);return{added:o.sort(),modified:n.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as vr}from"node:path";async function ct(s,e){let t=await Ne(e),r={};for(let o of t)r[o]={path:o,hash:await it(vr(e,o))};return{version:1,projectId:s,updatedAt:new Date().toISOString(),files:r}}var T=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")}};var se=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.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;async index(e,t){let r=new se(this.storage),o=new T(this.storage),n=await r.load(e),i=await o.load(e),a=await ct(e,t),c=at(n,a),l=[...c.added,...c.modified];if(n&&i&&l.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let p=i?.symbols.filter(g=>c.unchanged.includes(g.filePath))??[],d=[];for(let g of l)d.push(await _e(e,t,g));let u=new A().build(e,d),f=new P;for(let g of p)f.addSymbol(g);for(let g of u.allSymbols(e))f.addSymbol(g);let w=new Set(f.allSymbols(e).map(g=>g.id));for(let g of i?.edges??[])w.has(g.from)&&w.has(g.to)&&!l.includes(i.symbols.find(m=>m.id===g.from)?.filePath??"")&&!l.includes(i.symbols.find(m=>m.id===g.to)?.filePath??"")&&f.addEdge(g);for(let g of u.allEdges(e))f.addEdge(g);let S={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(a.files).length,symbols:f.allSymbols(e),edges:f.allEdges(e)};return await o.save(S),await r.save(a),{firstRun:n===null,scanned:Object.keys(a.files).length,parsed:l.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,unchanged:c.unchanged.length,symbols:S.symbols.length,edges:S.edges.length,saved:!0}}};var L=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,o]of this.records)o.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 o=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=xr(t,n.vector);o.push({id:n.id,score:i,metadata:n.metadata})}return o.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function xr(s,e){if(s.length===0||e.length===0||s.length!==e.length)return 0;let t=0,r=0,o=0;for(let n=0;n<s.length;n++){let i=s[n]??0,a=e[n]??0;t+=i*a,r+=i*i,o+=a*a}return r===0||o===0?0:t/(Math.sqrt(r)*Math.sqrt(o))}import*as E from"typescript";import*as y from"typescript";var Xn=new Set([y.SyntaxKind.EqualsToken,y.SyntaxKind.PlusEqualsToken,y.SyntaxKind.MinusEqualsToken,y.SyntaxKind.AsteriskEqualsToken,y.SyntaxKind.SlashEqualsToken,y.SyntaxKind.PercentEqualsToken,y.SyntaxKind.QuestionQuestionEqualsToken,y.SyntaxKind.AmpersandAmpersandEqualsToken,y.SyntaxKind.BarBarEqualsToken]);var ne=class{constructor(e,t){this.embeddings=e;this.store=t}embeddings;store;async index(e){let t=e.filter(n=>!this.store.has(n.id));if(t.length===0)return 0;let r=await this.embeddings.embedMany(t.map(n=>[n.type,n.content,...n.tags??[]].join(" "))),o=0;for(let n=0;n<t.length;n++){let i=t[n],a=r[n];!i||!a||(this.store.upsert({id:i.id,projectId:i.projectId,vector:a,metadata:{type:i.type,updatedAt:i.updatedAt}}),o++)}return o}};var N=class{constructor(e,t,r,o,n){this.projectId=e;this.model=t;this.embeddings=r;this.store=o;this.persistence=n}projectId;model;embeddings;store;persistence;async initialize(e){let t=0,r=await this.persistence.load(this.projectId);r&&r.model===this.model&&(t=this.store.importRecords(r.records));let o=new Set(e.map(d=>d.id)),n=0;for(let d of this.store.exportProject(this.projectId))o.has(d.id)||this.store.remove(d.id)&&n++;let a=await new ne(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),l=c[0]?.vector.length??this.embeddings.dimensions??0,p=!1;return(a>0||n>0||!r)&&(await this.persistence.save({version:1,projectId:this.projectId,model:this.model,dimensions:l,updatedAt:new Date().toISOString(),records:c}),p=!0),{loaded:t,indexed:a,removed:n,total:c.length,saved:p}}};var ie=class{events=[];push(e){this.events.push(e)}drain(){let e=[...this.events];return this.events.length=0,e}list(){return[...this.events]}size(){return this.events.length}shouldFlush(e){return this.events.length>=e}};import{createHash as Er}from"node:crypto";var ae=class{seen=new Set;fingerprint(e){return Er("sha256").update(JSON.stringify({projectId:e.projectId,type:e.type,data:e.data})).digest("hex")}filter(e){let t=[];for(let r of e){let o=this.fingerprint(r);this.seen.has(o)||(this.seen.add(o),t.push(r))}return t}clear(){this.seen.clear()}};import{randomUUID as Cr}from"node:crypto";var ce=class{constructor(e){this.queue=e}queue;sanitizer=new j;capture(e,t,r={}){let o={id:Cr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(o),o}};import{randomUUID as Pr}from"node:crypto";var le=class{constructor(e){this.capture=e}capture;sessionId=Pr();start(e){return this.capture.capture(e,"session_start",{sessionId:this.sessionId})}end(e){return this.capture.capture(e,"session_end",{sessionId:this.sessionId})}};var de=class{extract(e){switch(e.type){case"decision":return{type:"decision",content:String(e.data.content??"Decision recorded"),tags:["decision"],source:"auto-extractor",metadata:e.data};case"todo":return{type:"todo",content:String(e.data.content??"TODO recorded"),tags:["todo"],source:"auto-extractor",metadata:e.data};case"error":return{type:"activity",content:`Error: ${String(e.data.message??"")}`,tags:["error"],source:"auto-extractor",metadata:e.data};case"file_write":return{type:"activity",content:`Modified file: ${String(e.data.filePath??"")}`,tags:["file","write"],source:"auto-extractor",metadata:e.data};case"command":return{type:"activity",content:`Command: ${String(e.data.command??"")}`,tags:["command"],source:"auto-extractor",metadata:e.data};case"session_start":case"session_end":case"file_read":case"tool_call":case"user_prompt":case"test":case"commit":case"deploy":return null;default:return null}}};function Ge(s){let e=s.toLowerCase();return["kh\xF4ng \u0111\u01B0\u1EE3c","b\u1EAFt bu\u1ED9c","ph\u1EA3i lu\xF4n","tuy\u1EC7t \u0111\u1ED1i","never ","must ","always ","do not "].some(t=>e.includes(t))}function ze(s){let e=s.toLowerCase();return["quy\u1EBFt \u0111\u1ECBnh","ch\u1ECDn ","s\u1EED d\u1EE5ng ","d\xF9ng ","decided","decision","we will use","use "].some(t=>e.includes(t))}function Ke(s){let e=s.toLowerCase();return["todo","c\u1EA7n l\xE0m","ch\u01B0a xong","c\xF2n ph\u1EA3i","next:","next step","pending"].some(t=>e.includes(t))}function pe(s,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("tuy\u1EC7t \u0111\u1ED1i")||t.includes("must not")||t.includes("never ")?"critical":s==="rule"||s==="decision"?"high":s==="todo"||t.includes("error")||t.includes("failed")||t.includes("exception")?"normal":"temporary"}function O(s){return[...new Set(s.filter(Boolean))]}function me(s,e=120){return s.length>e?`${s.slice(0,e)}\u2026`:s}var ue=class{summarize(e){if(e.length===0)return null;let t=O(e.filter(c=>c.type==="file_write").map(c=>String(c.data.filePath??""))),r=O(e.filter(c=>c.type==="command").map(c=>me(String(c.data.command??"")))),o=O(e.filter(c=>c.type==="error").map(c=>me(String(c.data.message??"")))),n=O(e.filter(c=>c.type==="decision").map(c=>me(String(c.data.content??"")))),i=O(e.filter(c=>c.type==="todo").map(c=>me(String(c.data.content??""))));if(t.length===0&&r.length===0&&o.length===0&&n.length===0&&i.length===0)return null;let a=["Session summary:"];return t.length&&a.push(`- Files changed (${t.length}): ${t.slice(0,10).join(", ")}`),r.length&&a.push(`- Commands (${r.length}): ${r.slice(0,5).join("; ")}`),o.length&&a.push(`- Errors (${o.length}): ${o.slice(0,5).join("; ")}`),n.length&&a.push(`- Decisions: ${n.slice(0,5).join("; ")}`),i.length&&a.push(`- TODO: ${i.slice(0,5).join("; ")}`),a.join(`
5
- `)}};var fe=class{constructor(e){this.memory=e}memory;extractor=new de;summarizer=new ue;process(e){let t=0;for(let o of e){let n=this.extractor.extract(o);if(n){let i=this.refineType(n.type,n.content);this.memory.remember({projectId:o.projectId,type:i,content:n.content,importance:pe(i,n.content),tags:n.tags,source:n.source,metadata:{eventId:o.id,timestamp:o.timestamp,...n.metadata}}),t++}if(o.type==="user_prompt"){let i=String(o.data.content??""),a=this.detectPromptMemoryType(i);a&&(this.memory.remember({projectId:o.projectId,type:a,content:i,importance:pe(a,i),tags:["user",a],source:"auto-prompt-extractor",metadata:{eventId:o.id,timestamp:o.timestamp}}),t++)}}let r=this.summarizer.summarize(e);if(r){let o=e[0]?.projectId;o&&(this.memory.remember({projectId:o,type:"summary",content:r,importance:"temporary",tags:["summary"],source:"auto-summary",metadata:{eventCount:e.length}}),t++)}return t}refineType(e,t){return Ge(t)?"rule":Ke(t)?"todo":ze(t)?"decision":e}detectPromptMemoryType(e){return Ge(e)?"rule":Ke(e)?"todo":ze(e)?"decision":null}};import{createHash as kr}from"node:crypto";function jr(s){return kr("sha256").update([s.projectId,s.type,s.content.trim().toLowerCase()].join("|")).digest("hex")}function lt(s){let e=new Set,t=[];for(let r of s){let o=jr(r);e.has(o)||(e.add(o),t.push(r))}return t}var ge=class{projectId;memory;memoryStore;queue=new ie;capture=new ce(this.queue);session=new le(this.capture);processor;dedup=new ae;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new fe(this.memory)}async sessionStart(){this.session.start(this.projectId),await this.flushIfNeeded()}async sessionEnd(){this.session.end(this.projectId),await this.flush()}async userPrompt(e){this.capture.capture(this.projectId,"user_prompt",{content:e}),await this.flushIfNeeded()}async beforeTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"before",tool:e,input:t}),await this.flushIfNeeded()}async afterTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"after",tool:e,output:t}),await this.flushIfNeeded()}async fileRead(e){this.capture.capture(this.projectId,"file_read",{filePath:e}),await this.flushIfNeeded()}async fileWrite(e){this.capture.capture(this.projectId,"file_write",{filePath:e}),await this.flushIfNeeded()}async command(e,t){this.capture.capture(this.projectId,"command",{command:e,exitCode:t}),await this.flushIfNeeded()}async error(e){let t=e instanceof Error?e.message:String(e);this.capture.capture(this.projectId,"error",{message:t}),await this.flushIfNeeded()}async decision(e,t={}){this.capture.capture(this.projectId,"decision",{content:e,...t}),await this.flushIfNeeded()}async todo(e,t={}){this.capture.capture(this.projectId,"todo",{content:e,...t}),await this.flushIfNeeded()}async flushIfNeeded(){this.queue.shouldFlush(this.maxEventsBeforeFlush)&&await this.flush()}async flush(){let e=this.queue.drain();if(e.length===0)return 0;let t=this.dedup.filter(e);if(t.length===0)return 0;let r=this.processor.process(t),o=lt(this.memory.exportProject(this.projectId));return this.memory.clearProject(this.projectId),this.memory.importRecords(o),await this.memoryStore.save(this.projectId,o),r}pendingEvents(){return this.queue.size()}};var he=class{constructor(e,t,r){this.memory=e;this.retrieval=t;this.graph=r}memory;retrieval;graph;build(e,t,r={}){let o=r.maxRules??3,n=r.maxTodos??3,i=r.maxDecisions??3,a=r.maxRelevant??5,c=r.maxCharacters??7e3,l=this.memory.byType(e,"rule").slice(0,o),p=this.memory.byType(e,"todo").slice(0,n),d=this.memory.byType(e,"decision").slice(0,i),u=this.retrieval.search(e,t,{topK:a}),f=tt(this.graph,e),w=[];w.push(["[PROJECT]",`files=${f.files}`,`classes=${f.classes}`,`functions=${f.functions}`,`methods=${f.methods}`,`calls=${f.calls}`].join(" "));for(let g of l)w.push(`[RULE] ${g.content}`);for(let g of d)w.push(`[DECISION] ${g.content}`);for(let g of p)w.push(`[TODO] ${g.content}`);for(let g of u){let v=`[${g.memory.type.toUpperCase()}] ${g.memory.content}`;w.includes(v)||w.push(v)}let S="";for(let g of w){let m=S.length===0?g:`${S}
6
- ${g}`;if(m.length>c)break;S=m}return S}};var ye=class{constructor(e,t,r){this.runtime=e;this.builder=t;this.projectId=r}runtime;builder;projectId;async prepare(e){await this.runtime.userPrompt(e);let t=this.builder.build(this.projectId,e);return{originalPrompt:e,context:t,augmentedPrompt:t?["<toolnet_memory>",t,"</toolnet_memory>","",e].join(`
7
- `):e}}};var dt={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},Se=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=nt(e,t);if(r.length===0)return{triggered:!1,tool:e,highestRisk:"LOW",totalRiskScore:0,files:[],impactedFiles:[],suggestedTests:[],requiresVerification:!1,context:""};let o=[];for(let d of r){let u=this.guard.analyzeFile(this.projectId,d);o.push({filePath:d,risk:u.risk,riskScore:u.riskScore,impactedFiles:u.impactedFiles,suggestedTests:u.suggestedTests,impactedCount:u.impacted.length})}let n="LOW";for(let d of o)dt[d.risk]>dt[n]&&(n=d.risk);let i=[...new Set(o.flatMap(d=>d.impactedFiles))],a=[...new Set(o.flatMap(d=>d.suggestedTests))],c=o.reduce((d,u)=>d+u.riskScore,0),l=n==="HIGH"||n==="CRITICAL",p=["[TOOLNET IMPACT GUARD]",`Risk: ${n}`,`Risk score: ${c}`,`Files being changed: ${r.join(", ")}`,`Impacted files: ${i.length}`];return i.length&&p.push("Blast radius:",...i.slice(0,20).map(d=>`- ${d}`)),a.length&&p.push("Verify/tests:",...a.slice(0,15).map(d=>`- ${d}`)),l&&p.push("IMPORTANT: High blast radius. Inspect affected dependencies and run relevant tests after the edit."),{triggered:!0,tool:e,highestRisk:n,totalRiskScore:c,files:o,impactedFiles:i,suggestedTests:a,requiresVerification:l,context:p.join(`
8
- `)}}};import{homedir as Yr}from"node:os";import{join as Qr}from"node:path";import{DeleteObjectCommand as Rr,GetObjectCommand as Tr,HeadObjectCommand as Ir,ListObjectsV2Command as Mr,PutObjectCommand as Ar,S3Client as Lr}from"@aws-sdk/client-s3";import{getSignedUrl as Nr}from"@aws-sdk/s3-request-presigner";var be=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Lr({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 Ar({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Nr(this.client,new Tr({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 Ir({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 Rr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Mr({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 pt,mkdir as Or,readFile as _r,readdir as $r,rm as Fr,stat as mt,writeFile as Dr}from"node:fs/promises";import{dirname as Gr,join as zr,relative as ut,resolve as Kr}from"node:path";var _=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Kr(this.root,t)}async put(e,t){let r=this.path(e);await Or(Gr(r),{recursive:!0}),await Dr(r,t)}async get(e){try{return await _r(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 pt(this.path(e)),!0}catch{return!1}}async delete(e){await Fr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await pt(t)}catch{return r}let o=async i=>{let a=await $r(i,{withFileTypes:!0});for(let c of a){let l=zr(i,c.name);if(c.isDirectory()){await o(l);continue}let p=await mt(l);r.push({key:ut(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await mt(t);return n.isDirectory()?await o(t):r.push({key:ut(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as Br,GetObjectCommand as Hr,HeadObjectCommand as Wr,ListObjectsV2Command as Ur,PutObjectCommand as Vr,S3Client as qr}from"@aws-sdk/client-s3";import{getSignedUrl as Jr}from"@aws-sdk/s3-request-presigner";var $=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new qr({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 Vr({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Jr(this.client,new Hr({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 Wr({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 Br({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Ur({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 Be(s,e){return console.warn(e),new _(s)}function ft(s){let e=s.localRoot??Qr(Yr(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(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 $({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(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 be({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new _(e)}var I=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};var ve=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let r=JSON.parse(t);if(r.version!==1||r.projectId!==e||!Array.isArray(r.records))throw new Error("Invalid vector snapshot");return r}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function Zr(s){return new Promise(e=>setTimeout(e,s))}async function gt(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(a){if(n=a,i>=t)break;let c=Math.min(o,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Zr(c+l)}throw n}var Xr=new Set(["put","get","getText","delete","list"]);function ht(s,e={}){return new Proxy(s,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:Xr.has(r)?(...n)=>gt(()=>Promise.resolve(o.apply(t,n)),e):o.bind(t)}})}function yt(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 St(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 xe=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=yt(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(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
9
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=St(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))}};function ts(s){let e=s.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function rs(s,e){let t=`projects/${s.id}/memory/learned/`,r=await e.list(t),o=[];for(let n of r.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(n.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;o.push(a)}catch{}}return o}async function bt(s,e){let t=await rs(s,e),r=new I(e),o=await r.load(s.id),n=new R;n.importRecords(o);let i=new Set(o.map(p=>ts(p)).filter(p=>!!p)),a=0,c=0,l=0;for(let p of t)for(let d of p.candidates){if(a+=1,i.has(d.fingerprint)){l+=1;continue}n.remember({projectId:s.id,type:d.type,content:d.content,importance:d.importance,tags:d.tags,source:"session-memory-learner",metadata:{learningFingerprint:d.fingerprint,learningKind:d.kind,confidence:d.confidence,provenance:d.provenance,sourceCreatedAt:d.createdAt,sessionKey:d.sessionKey,agent:d.agent,nativeSessionId:d.nativeSessionId}}),i.add(d.fingerprint),c+=1}return c>0&&await r.save(s.id,n.exportProject(s.id)),{batches:t.length,candidates:a,added:c,duplicates:l,memories:n.exportProject(s.id).length}}var ss=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],we=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let o=new Date().toISOString(),n=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of ss){let d=`${i}/${p}`,u=await this.storage.get(d);u&&(await this.storage.put(`${a}/${p}`,u,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:o,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.getText(`${r}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(o);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.list(r);for(let n of o)await this.storage.delete(n.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),n=0;for(let i of o)await this.remove(e,i.id),n++;return n}};import{closeSync as os,mkdirSync as ns,openSync as is,readFileSync as as,unlinkSync as vt,writeFileSync as cs}from"node:fs";import{tmpdir as ls}from"node:os";import{join as xt}from"node:path";function ds(s){try{return process.kill(s,0),!0}catch(e){return e?.code==="EPERM"}}var Ee=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=xt(ls(),"toolnet-memory-locks");ns(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=xt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=is(this.path,"wx");cs(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),os(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let o=JSON.parse(as(this.path,"utf8"));Number.isInteger(o.pid)&&ds(o.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{vt(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{vt(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var Ce=class{constructor(e){this.options=e;this.memoryStore=new I(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new ve(e.storage),this.processLock=new Ee(e.project.id),this.retrieval=new Y(this.memory),this.references=new X(this.graph),this.hooks=new ge({projectId:e.project.id,memory:this.memory,memoryStore:this.memoryStore,maxEventsBeforeFlush:100});let t=new he(this.memory,this.retrieval,this.graph);this.autoRetrieval=new ye(this.hooks,t,e.project.id),this.impactGuard=new re(this.graph),this.autoImpactGuard=new Se(this.impactGuard,e.project.id)}options;memory=new R;graph=new P;vectors=new L;retrieval;references;hooks;autoRetrieval;impactGuard;autoImpactGuard;memoryStore;graphStore;vectorStore;processLock;async start(){let{project:e}=this.options;await this.processLock.acquire(),await bt(e,this.options.storage);let t=await this.memoryStore.load(e.id);this.memory.importRecords(t);let o=new B(this.memory).run(e.id);(o.expiredRemoved>0||o.supersededRemoved>0)&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let n=await this.graphStore.load(e.id);n&&this.graph.import(n.symbols,n.edges);let i=Ae(),c=await new N(e.id,this.options.embeddingModel,i,this.vectors,this.vectorStore).initialize(this.memory.list(e.id));return await this.hooks.sessionStart(),{memories:t.length,graphSymbols:this.graph.allSymbols(e.id).length,graphEdges:this.graph.allEdges(e.id).length,vectors:c.total,vectorsIndexed:c.indexed}}async preparePrompt(e){return this.autoRetrieval.prepare(e)}async beforeTool(e,t){let r=await this.autoImpactGuard.beforeTool(e,t);return await this.hooks.beforeTool(e,t),r}async afterTool(e,t){return this.hooks.afterTool(e,t)}async stop(){let{project:e,storage:t,embeddingModel:r}=this.options,o=new we(t),n=await o.create(e.id,"session-end-auto");await o.prune(e.id,10),await this.hooks.sessionEnd();let i=new H(this.memory).consolidate(e.id);i.summaryCreated&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let a=await new oe(t).index(e.id,e.rootPath),c=await this.graphStore.load(e.id);c&&(this.graph.clearProject(e.id),this.graph.import(c.symbols,c.edges));let l=Ae(),d=await new N(e.id,r,l,this.vectors,this.vectorStore).initialize(this.memory.list(e.id)),u={code:a,vectors:d,consolidation:i,snapshot:n?.id,memories:this.memory.list(e.id).length};return await this.processLock.release(),u}};import"dotenv/config";import{existsSync as ps,readFileSync as ms}from"node:fs";import{homedir as us}from"node:os";import{join as fs}from"node:path";function gs(s){let e=s.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
10
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function hs(){let s=process.env.TOOLNET_GLOBAL_ENV??fs(us(),".config","toolnet-memory",".env");if(!ps(s))return;let e=ms(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]=gs(r.slice(o+1)))}}hs();function F(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function D(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function wt(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:D(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:D(process.env.MEMORY_RERANK_TOP,10),finalContext:D(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:D(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:F(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:D(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ys}from"node:crypto";import{existsSync as He,mkdirSync as Ss,readFileSync as bs,renameSync as vs,writeFileSync as xs}from"node:fs";import{basename as ws,dirname as Pe,join as je,parse as Pt,resolve as G}from"node:path";var kt=".toolnet",Es="project.json";function Cs(s){return ys("sha256").update(s).digest("hex").slice(0,16)}function We(s){return je(s,kt,Es)}function Ps(s){return He(We(s))}function ks(s,e){let t=G(s),r=Pt(t).root;for(;;){if(Ps(t))return t;if(t===r||e&&t===G(e))break;let o=Pe(t);if(o===t)break;t=o}return null}function js(s){let e=G(s),t=Pt(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>He(je(e,n))))return e;if(e===t)break;let o=Pe(e);if(o===e)break;e=o}return G(s)}function Rs(s){let e;try{e=JSON.parse(bs(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:Pe(Pe(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 Et(s,e){let t=je(s,kt);Ss(t,{recursive:!0});let r=We(s),o=`${r}.tmp-${process.pid}`;xs(o,JSON.stringify(e,null,2)+`
11
- `,{encoding:"utf8",mode:384}),vs(o,r)}function Ct(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 ke=class{detect(e=process.cwd()){let t=G(e),r=js(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>He(je(r,p))),i=ks(t,n?r:void 0);if(i){let p=We(i),d=Rs(p);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Et(i,d)),Ct(d,i)}let a=new Date().toISOString(),c=ws(r),l={version:1,id:Cs(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Et(r,l),Ct(l,r)}};function jt(s=process.cwd()){let e=wt(),t=new ke().detect(s),r=ft({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),o=ht(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),n=new xe(o,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new Ce({project:t,storage:n,embeddingModel:i})}async function Ts(){let s=jt(),e=await s.start(),t=await s.preparePrompt("Ti\u1EBFp t\u1EE5c c\xF4ng vi\u1EC7c hi\u1EC7n t\u1EA1i");console.log({started:!0,...e,contextCharacters:t.context.length});let r=await s.stop();console.log({stopped:!0,memories:r.memories,codeParsed:r.code.parsed,vectorsIndexed:r.vectors.indexed})}Ts().catch(s=>{console.error(s),process.exit(1)});
1
+ import{randomUUID as Vt}from"node:crypto";var Ft={critical:100,high:75,normal:50,temporary:20};function Ze(o){return Ft[o]}function Xe(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":o==="rule"||o==="decision"?"high":o==="todo"?"normal":o==="activity"||o==="summary"?"temporary":"normal"}var $t=[{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}],U=class{scan(e){let t=[];for(let r of $t){let s=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(s))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var k=class{scanner=new U;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let n of r)s.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[r,s]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Kt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Gt=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function et(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Gt.has(e)))}function Bt(o,e){let t=et(o),r=et(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let n=new Set([...t,...r]).size;return s/n}function tt(o){return new Set(o.tags.filter(e=>!Kt.has(e.toLowerCase())))}var z=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=tt(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=tt(n);for(let c of s)if(a.has(c))return!0;return Bt(e.content,n.content)>=.6})}};var Ut={critical:100,high:75,normal:50,temporary:20},zt={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function rt(o,e,t=new Date){let r;if(e==="temporary"&&(r=30),o==="activity"&&(r=Math.min(r??14,14)),o==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Le(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function Ht(o){return!!o.metadata?.supersededBy}function _e(o,e=Date.now()){return!Le(o,e)&&!Ht(o)}function L(o,e=Date.now()){if(!_e(o,e))return 0;let t=Ut[o.importance];if(o.importance==="critical")return t;let r=zt[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var j=class{memories=new Map;sanitizer=new k;conflicts=new z;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??Xe(e.type,r),n={id:Vt(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:Ze(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??rt(e.type,s,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>_e(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,s=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=L(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=s.filter(m=>i.includes(m)).length,c=s.length===0?0:a/s.length,d=L(n)/500;return{memory:n,score:c+d,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[s,n]of this.memories)n.projectId===e&&Le(n,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),s++)}return s}clearProject(e){let t=0;for(let[r,s]of this.memories)s.projectId===e&&(this.memories.delete(r),t++);return t}};var H=class{constructor(e){this.memory=e}memory;run(e){let t=this.memory.pruneExpired(e),r=this.memory.pruneSuperseded(e,30);return{expiredRemoved:t,supersededRemoved:r,active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Ne(o){return[...new Set(o.filter(Boolean))]}var V=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,s=t.maxItems??50,n=t.retentionDays??90,i=this.memory.byType(e,"activity").slice(0,s);if(i.length<r)return{scanned:i.length,consolidated:0,summaryCreated:!1};let a=this.buildSummary(i),c=new Date,d=new Date(c.getTime()+n*864e5).toISOString(),m=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:d,metadata:{consolidatedFrom:i.map(f=>f.id),itemCount:i.length}}),p=c.toISOString();for(let f of i){let g=this.memory.get(f.id);g&&(g.updatedAt=p,g.metadata={...g.metadata??{},consolidated:!0,supersededBy:m.id,supersededAt:p})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:m.id}}buildSummary(e){let t=Ne(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Ne(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=Ne(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),n=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&n.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&n.push(`- Commands: ${r.slice(0,10).join("; ")}`),s.length&&n.push(`- Errors: ${s.slice(0,10).join("; ")}`),n.join(`
2
+ `)}};function q(o){return o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var W=class{score(e,t){let r=q(e),s=q([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function ot(o,e=Date.now()){let t=o.updatedAt??o.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let s=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*s/30)}function st(o){return L(o)/100}var qt={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function nt(o){return qt[o]??.4}var Y=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var J=class{bm25=new W;analyzer=new Y;search(e,t,r={}){let s=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let d=this.bm25.score(e,c),m=ot(c),p=st(c),f=nt(c.type);i.preferredTypes.includes(c.type)&&(f=Math.min(1,f+.25));let g=d*.55+p*.2+m*.15+f*.1;d<=0||g<n||a.push({memory:c,score:g,scores:{keyword:d,recency:m,importance:p,type:f}})}return a.sort((c,d)=>d.score-c.score).slice(0,s)}};var Q=class{build(e,t=6e3){let r=[],s=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(s+a.length>t)break;r.push(a),s+=a.length}return r.join(`
3
+ `)}};var Z=class{constructor(e){this.memory=e}memory;searcher=new J;contextBuilder=new Q;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let s=this.search(e,t,r);return this.contextBuilder.build(s)}};var it=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function X(o){let e=it.find(t=>t.id===o);if(!e)throw new Error(`Unsupported AI provider: ${o}`);return e}function ee(o){return it.some(e=>e.id===o)}function l(o){return process.env[o]?.trim()||void 0}function b(...o){return o.find(e=>!!e?.trim())}function at(){if(l("GROQ_API_KEY"))return"groq";if(l("DEEPSEEK_API_KEY"))return"deepseek";if(l("NVIDIA_API_KEY")||l("NVIDIA_NIM_API_KEY"))return"nvidia";if(l("OPENROUTER_API_KEY"))return"openrouter";if(l("ALIBABA_API_KEY")||l("DASHSCOPE_API_KEY"))return"alibaba";if(l("GEMINI_API_KEY")||l("GOOGLE_API_KEY"))return"gemini";if(l("CLOUDFLARE_API_TOKEN")&&l("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(l("HF_TOKEN"))return"huggingface";if(l("OLLAMA_MODEL")||l("OLLAMA_BASE_URL"))return"ollama"}function Wt(){let o=l("TOOLNET_LLM_PROVIDER");return o&&ee(o)?o:at()??"openai-compatible"}function Oe(o){let e=X(o);switch(o){case"alibaba":return{provider:o,apiKey:b(l("ALIBABA_API_KEY"),l("DASHSCOPE_API_KEY")),baseUrl:b(l("ALIBABA_BASE_URL"),l("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:b(l("ALIBABA_MODEL"),l("DASHSCOPE_MODEL"))};case"openrouter":return{provider:o,apiKey:l("OPENROUTER_API_KEY"),baseUrl:b(l("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:l("OPENROUTER_MODEL")};case"groq":return{provider:o,apiKey:l("GROQ_API_KEY"),baseUrl:b(l("GROQ_BASE_URL"),e.defaultBaseUrl),model:l("GROQ_MODEL")};case"deepseek":return{provider:o,apiKey:l("DEEPSEEK_API_KEY"),baseUrl:b(l("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:b(l("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:o,apiKey:b(l("NVIDIA_API_KEY"),l("NVIDIA_NIM_API_KEY")),baseUrl:b(l("NVIDIA_BASE_URL"),l("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:b(l("NVIDIA_MODEL"),l("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:o,apiKey:b(l("GEMINI_API_KEY"),l("GOOGLE_API_KEY")),baseUrl:b(l("GEMINI_BASE_URL"),e.defaultBaseUrl),model:l("GEMINI_MODEL")};case"huggingface":return{provider:o,apiKey:l("HF_TOKEN"),baseUrl:b(l("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:b(l("HF_LLM_MODEL"),l("HF_MODEL"))};case"ollama":return{provider:o,apiKey:l("OLLAMA_API_KEY"),baseUrl:b(l("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:l("OLLAMA_MODEL")};case"cloudflare":return{provider:o,accountId:l("CLOUDFLARE_ACCOUNT_ID"),apiKey:l("CLOUDFLARE_API_TOKEN"),baseUrl:l("CLOUDFLARE_AI_BASE_URL"),model:l("CLOUDFLARE_MODEL")};case"custom":return{provider:o,apiKey:l("CUSTOM_AI_API_KEY"),baseUrl:l("CUSTOM_AI_BASE_URL"),model:l("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:b(l("OPENAI_API_KEY"),l("MODEL_API_KEY")),baseUrl:b(l("OPENAI_BASE_URL"),l("MODEL_BASE_URL")),model:b(l("OPENAI_MODEL"),l("MODEL_NAME"))}}}function Yt(){let o=l("TOOLNET_LLM_PROVIDER"),e=o&&ee(o)?o:Wt(),t=X(e),r=Oe(e);return{provider:e,apiKey:b(l("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:b(l("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:b(l("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:b(l("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function Jt(){let o=l("TOOLNET_EMBEDDING_PROVIDER");return o==="local"?"local":o&&ee(o)?o:l("HF_TOKEN")||l("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Qt(){let o=Jt();if(o==="local")return{provider:"local",model:b(l("TOOLNET_EMBEDDING_MODEL"),l("LOCAL_EMBEDDING_MODEL"))};let e=X(o),t,r,s,n;switch(o){case"huggingface":t=l("HF_TOKEN"),r=l("HF_INFERENCE_BASE_URL"),s=l("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=l("OPENAI_API_KEY"),r=l("OPENAI_BASE_URL"),s=l("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=l("CLOUDFLARE_API_TOKEN"),r=l("CLOUDFLARE_AI_BASE_URL"),s=l("CLOUDFLARE_EMBEDDING_MODEL"),n=l("CLOUDFLARE_ACCOUNT_ID");break;default:t=Oe(o).apiKey,r=Oe(o).baseUrl,s=l(`${o.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}return{provider:o,apiKey:b(l("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:b(l("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),model:b(l("TOOLNET_EMBEDDING_MODEL"),s),accountId:b(l("TOOLNET_EMBEDDING_ACCOUNT_ID"),n)}}function ct(){let o=Yt(),e=Qt();return{llm:o,embedding:e,legacy:{llm:!l("TOOLNET_LLM_PROVIDER")&&!!at(),embedding:!l("TOOLNET_EMBEDDING_PROVIDER")&&!!(l("HF_TOKEN")||l("HF_EMBEDDING_MODEL"))}}}var te=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>Zt(n))}};function Zt(o){if(!Array.isArray(o))throw new Error("Invalid embedding");if(o.length>0&&typeof o[0]=="number")return o;if(o.length>0&&Array.isArray(o[0])){let e=o;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let n=0;n<t;n++)r[n]+=s[n]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as Xt}from"node:crypto";var re=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of r){let i=Xt("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return er(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function er(o){let e=Math.sqrt(o.reduce((t,r)=>t+r*r,0));return e===0?o:o.map(t=>t/e)}var oe=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),r=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:e})});if(!r.ok)throw new Error(`Embedding failed: ${r.status} ${await r.text()}`);let n=(await r.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!n||n.length!==e.length||n.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return n}};var De=class{constructor(e,t=new re){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function tr(){let o=ct().embedding;return o.provider==="local"?null:o.provider==="huggingface"?!o.apiKey||!o.model?null:new te({token:o.apiKey,model:o.model}):o.baseUrl&&o.model?new oe({apiKey:o.apiKey,baseUrl:o.baseUrl,model:o.model}):null}function Fe(){return new De(tr())}import{readdir as nr}from"node:fs/promises";import{extname as ir,join as ar,relative as cr}from"node:path";import{basename as rr}from"node:path";var or=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),sr=new Set([".pem",".key",".p12",".pfx"]);function $e(o){let e=rr(o).toLowerCase();if(or.has(e))return!0;for(let t of sr)if(e.endsWith(t))return!0;return!1}var lr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),dr=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Ke(o){let e=[];async function t(r){let s=await nr(r,{withFileTypes:!0});for(let n of s){if(dr.has(n.name))continue;let i=ar(r,n.name);if(n.isDirectory()){await t(i);continue}lr.has(ir(n.name))&&($e(i)||e.push(cr(o,i)))}}return await t(o),e.sort()}import{readFile as pr}from"node:fs/promises";import{join as mr}from"node:path";import{createHash as ur}from"node:crypto";import*as y from"typescript";function lt(o,e){return ur("sha256").update(`${o}:${e}`).digest("hex").slice(0,24)}function Ge(o,e){return o.getLineAndCharacterOfPosition(e.getStart(o)).line+1}async function Be(o,e,t){let r=mr(e,t),s=await pr(r,"utf8"),n=y.createSourceFile(t,s,y.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?y.ScriptKind.TSX:y.ScriptKind.TS),i=[],a=[],c=[],d=[],m={id:lt(o,`file:${t}`),projectId:o,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(m);let p=[],f=[];function g(u,x,w,E){let R=lt(o,`${t}:${w}:${E??x}:${u.pos}`);return i.push({id:R,projectId:o,name:x,qualifiedName:E??x,type:w,filePath:t,startLine:Ge(n,u),endLine:n.getLineAndCharacterOfPosition(u.end).line+1}),R}function C(u){if(!y.isStringLiteral(u.moduleSpecifier))return;let x=[],w=u.importClause;if(w?.name&&x.push({localName:w.name.text,importedName:"default",kind:"default"}),w?.namedBindings&&y.isNamedImports(w.namedBindings))for(let E of w.namedBindings.elements)x.push({localName:E.name.text,importedName:E.propertyName?.text??E.name.text,kind:"named"});w?.namedBindings&&y.isNamespaceImport(w.namedBindings)&&x.push({localName:w.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:u.moduleSpecifier.text,bindings:x})}function v(u,x){for(let w of u.heritageClauses??[])for(let E of w.types){let R=E.expression.getText(n).split(".").at(-1)??"";R&&d.push({fromId:x,targetName:R,type:w.token===y.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function h(u){let x=!1,w=!1;if(y.isImportDeclaration(u)&&C(u),y.isInterfaceDeclaration(u)&&g(u,u.name.text,"interface",u.name.text),y.isClassDeclaration(u)&&u.name){let E=g(u,u.name.text,"class",u.name.text);v(u,E),f.push({id:E,name:u.name.text}),w=!0}if(y.isFunctionDeclaration(u)&&u.name){let E=g(u,u.name.text,"function",u.name.text);p.push(E),x=!0}if(y.isMethodDeclaration(u)&&u.name){let E=u.name.getText(n),R=f.at(-1)?.name,Dt=g(u,E,"method",R?`${R}.${E}`:E);p.push(Dt),x=!0}if(y.isCallExpression(u)&&(y.isIdentifier(u.expression)&&c.push({callerId:p.at(-1),calleeName:u.expression.text,line:Ge(n,u)}),y.isPropertyAccessExpression(u.expression))){let E=u.expression;c.push({callerId:p.at(-1),qualifier:E.expression.getText(n),calleeName:E.name.text,line:Ge(n,u)})}y.forEachChild(u,h),x&&p.pop(),w&&f.pop()}return h(n),{filePath:t,symbols:i,imports:a,calls:c,heritage:d}}import{createHash as fr}from"node:crypto";import{dirname as gr,extname as hr,normalize as yr,posix as Sr}from"node:path";var A=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 br(o,e,t,r){return fr("sha256").update(`${o}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function I(o){return yr(o).replaceAll("\\","/")}function Ue(o,e,t){if(!e.startsWith("."))return;let r=I(Sr.join(gr(o),e)),s=hr(r),n;if(s===".js"){let i=r.slice(0,-3);n=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(s===".mjs"){let i=r.slice(0,-4);n=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(s===".cjs"){let i=r.slice(0,-4);n=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else s?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(I(i)))}var _=class{build(e,t){let r=new A,s=new Map;for(let i of t)for(let a of i.symbols)r.addSymbol(a),a.type==="file"&&s.set(I(i.filePath),a);let n=new Set(s.keys());for(let i of t){let a=I(i.filePath),c=s.get(a);if(c){for(let d of i.symbols)d.id!==c.id&&r.addEdge(this.edge(e,c.id,"DEFINES",d.id));for(let d of i.imports){let m=Ue(a,d.source,n);if(!m)continue;let p=s.get(m);p&&r.addEdge(this.edge(e,c.id,"IMPORTS",p.id,{source:d.source}))}for(let d of i.heritage){let m=r.findByName(e,d.targetName).filter(p=>p.type==="class"||p.type==="interface");for(let p of m)r.addEdge(this.edge(e,d.fromId,d.type,p.id))}for(let d of i.calls){if(!d.callerId)continue;let m=this.resolveCallTargets(e,i,d.calleeName,d.qualifier,t,r,n);for(let p of m)p.id!==d.callerId&&r.addEdge(this.edge(e,d.callerId,"CALLS",p.id,{line:d.line,qualifier:d.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,n,i,a){let c=I(t.filePath),d=i.findByName(e,r).filter(m=>I(m.filePath)===c);if(!s&&d.length)return d;if(s)for(let m of t.imports){if(!m.bindings.find(g=>g.kind==="namespace"&&g.localName===s))continue;let f=Ue(c,m.source,a);if(f)return i.findByName(e,r).filter(g=>I(g.filePath)===f)}for(let m of t.imports){let p=m.bindings.find(v=>v.localName===r);if(!p)continue;let f=Ue(c,m.source,a);if(!f)continue;let g=p.importedName==="default"?r:p.importedName,C=i.findByName(e,g).filter(v=>I(v.filePath)===f);if(C.length)return C}return i.findByName(e,r).filter(m=>m.type==="function"||m.type==="method")}edge(e,t,r,s,n){return{id:br(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:n}}};function dt(o,e){let t=o.allSymbols(e),r=o.allEdges(e),s=i=>t.filter(a=>a.type===i).length,n=i=>r.filter(a=>a.type===i).length;return{files:s("file"),classes:s("class"),interfaces:s("interface"),functions:s("function"),methods:s("method"),properties:s("property"),routes:s("route"),symbols:t.length,edges:r.length,calls:n("CALLS"),callReferences:n("CALL_REFERENCE"),imports:n("IMPORTS"),inherits:n("INHERITS"),implements:n("IMPLEMENTS"),usesType:n("USES_TYPE"),tests:n("TESTS"),routeEdges:n("ROUTE"),writes:n("WRITES")}}var se=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function vr(o,e){return e.ranges.length===0?!0:typeof o.startLine!="number"||typeof o.endLine!="number"?!1:e.ranges.some(t=>o.startLine<=t.endLine&&o.endLine>=t.startLine)}var ne=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let n of t){let i=r.filter(d=>d.filePath===n.filePath),c=i.filter(d=>d.type!=="file").filter(d=>vr(d,n));if(c.length===0){let d=i.find(m=>m.type==="file");d&&s.push({symbol:d,fileStatus:n.status,direct:!0});continue}for(let d of c)s.push({symbol:d,fileStatus:n.status,direct:!0})}return s}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Er={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function xr(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function pt(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var ie=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Map,i=0;for(let m of t){m.fileStatus==="deleted"?i+=8:m.fileStatus==="renamed"?i+=5:i+=2,m.symbol.type==="interface"&&(i+=5),m.symbol.type==="class"&&(i+=3);let p=new Set([m.symbol.id]),f=[{id:m.symbol.id,depth:0}];for(;f.length;){let g=f.shift();if(g.depth>=r)continue;let C=s.filter(v=>v.to===g.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(v.type));for(let v of C){if(p.has(v.from))continue;p.add(v.from);let h=this.graph.getSymbol(v.from);if(!h)continue;let u=g.depth+1,x=`${m.symbol.id}:${h.id}`;n.set(x,{symbol:h,relation:v.type,depth:u,sourceSymbolId:m.symbol.id});let w=Er[v.type]??1;i+=Math.max(1,w-(u-1)),f.push({id:h.id,depth:u})}}}let a=[...n.values()].sort((m,p)=>m.depth-p.depth),c=[...new Set(a.map(m=>m.symbol.filePath))],d=c.filter(pt);return d.length===0&&d.push(...c.filter(m=>!pt(m)).slice(0,10)),{risk:xr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:d}}};import{execFile as wr}from"node:child_process";import{promisify as Cr}from"node:util";var ze=Cr(wr);function Pr(o){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of o.matchAll(t)){let s=Number(r[1]),n=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function Rr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function mt(o){let e="";try{e=(await ze("git",["diff","HEAD","--name-status","--no-renames"],{cwd:o,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await ze("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Rr(s),ranges:Pr(a)})}try{let r=await ze("git",["ls-files","--others","--exclude-standard"],{cwd:o});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===s)||t.push({filePath:s,status:"added",ranges:[]})}catch{}return t}var ae=class{constructor(e){this.graph=e;this.mapper=new ne(e),this.blast=new ie(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await mt(t),n=this.mapper.map(e,s),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:s,...i}}analyzeFile(e,t,r={}){let s=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,s,r.maxDepth??4)}}};var Ar=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,Ir=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function ut(o){return o.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function kr(o){return o.length>0&&o.length<500&&!o.includes(`
4
+ `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(o)}function jr(o){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let s of o.matchAll(r))s[1]&&e.push(ut(s[1]));return e}function He(o,e,t){if(typeof o=="string"){let r=t?.toLowerCase();if(r&&Ir.has(r)&&kr(o)&&e.add(ut(o)),o.includes("*** Update File:")||o.includes("*** Add File:")||o.includes("*** Delete File:")||o.includes("+++ b/"))for(let s of jr(o))e.add(s);return}if(Array.isArray(o)){for(let r of o)He(r,e,t);return}if(o&&typeof o=="object")for(let[r,s]of Object.entries(o))He(s,e,r)}function Tr(o){return Ar.test(o.toLowerCase())}function ft(o,e){if(!Tr(o))return[];let t=new Set;return He(e,t),[...t]}import{createHash as Mr}from"node:crypto";import{readFile as Lr}from"node:fs/promises";async function gt(o){let e=await Lr(o);return Mr("sha256").update(e).digest("hex")}function ht(o,e){let t=o?.files??{},r=e.files,s=[],n=[],i=[],a=[];for(let[c,d]of Object.entries(r)){let m=t[c];m?m.hash!==d.hash?n.push(c):a.push(c):s.push(c)}for(let c of Object.keys(t))r[c]||i.push(c);return{added:s.sort(),modified:n.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as _r}from"node:path";async function yt(o,e){let t=await Ke(e),r={};for(let s of t)r[s]={path:s,hash:await gt(_r(e,s))};return{version:1,projectId:o,updatedAt:new Date().toISOString(),files:r}}var T=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")}};var ce=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.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 le=class{constructor(e){this.storage=e}storage;async index(e,t){let r=new ce(this.storage),s=new T(this.storage),n=await r.load(e),i=await s.load(e),a=await yt(e,t),c=ht(n,a),d=[...c.added,...c.modified];if(n&&i&&d.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let m=i?.symbols.filter(h=>c.unchanged.includes(h.filePath))??[],p=[];for(let h of d)p.push(await Be(e,t,h));let f=new _().build(e,p),g=new A;for(let h of m)g.addSymbol(h);for(let h of f.allSymbols(e))g.addSymbol(h);let C=new Set(g.allSymbols(e).map(h=>h.id));for(let h of i?.edges??[])C.has(h.from)&&C.has(h.to)&&!d.includes(i.symbols.find(u=>u.id===h.from)?.filePath??"")&&!d.includes(i.symbols.find(u=>u.id===h.to)?.filePath??"")&&g.addEdge(h);for(let h of f.allEdges(e))g.addEdge(h);let v={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(a.files).length,symbols:g.allSymbols(e),edges:g.allEdges(e)};return await s.save(v),await r.save(a),{firstRun:n===null,scanned:Object.keys(a.files).length,parsed:d.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,unchanged:c.unchanged.length,symbols:v.symbols.length,edges:v.edges.length,saved:!0}}};var N=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=Nr(t,n.vector);s.push({id:n.id,score:i,metadata:n.metadata})}return s.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function Nr(o,e){if(o.length===0||e.length===0||o.length!==e.length)return 0;let t=0,r=0,s=0;for(let n=0;n<o.length;n++){let i=o[n]??0,a=e[n]??0;t+=i*a,r+=i*i,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}import*as P from"typescript";import*as S from"typescript";var vi=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]);var de=class{constructor(e,t){this.embeddings=e;this.store=t}embeddings;store;async index(e){let t=e.filter(n=>!this.store.has(n.id));if(t.length===0)return 0;let r=await this.embeddings.embedMany(t.map(n=>[n.type,n.content,...n.tags??[]].join(" "))),s=0;for(let n=0;n<t.length;n++){let i=t[n],a=r[n];!i||!a||(this.store.upsert({id:i.id,projectId:i.projectId,vector:a,metadata:{type:i.type,updatedAt:i.updatedAt}}),s++)}return s}};var O=class{constructor(e,t,r,s,n){this.projectId=e;this.model=t;this.embeddings=r;this.store=s;this.persistence=n}projectId;model;embeddings;store;persistence;async initialize(e){let t=0,r=await this.persistence.load(this.projectId);r&&r.model===this.model&&(t=this.store.importRecords(r.records));let s=new Set(e.map(p=>p.id)),n=0;for(let p of this.store.exportProject(this.projectId))s.has(p.id)||this.store.remove(p.id)&&n++;let a=await new de(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),d=c[0]?.vector.length??this.embeddings.dimensions??0,m=!1;return(a>0||n>0||!r)&&(await this.persistence.save({version:1,projectId:this.projectId,model:this.model,dimensions:d,updatedAt:new Date().toISOString(),records:c}),m=!0),{loaded:t,indexed:a,removed:n,total:c.length,saved:m}}};var pe=class{events=[];push(e){this.events.push(e)}drain(){let e=[...this.events];return this.events.length=0,e}list(){return[...this.events]}size(){return this.events.length}shouldFlush(e){return this.events.length>=e}};import{createHash as Dr}from"node:crypto";var me=class{seen=new Set;fingerprint(e){return Dr("sha256").update(JSON.stringify({projectId:e.projectId,type:e.type,data:e.data})).digest("hex")}filter(e){let t=[];for(let r of e){let s=this.fingerprint(r);this.seen.has(s)||(this.seen.add(s),t.push(r))}return t}clear(){this.seen.clear()}};import{randomUUID as Fr}from"node:crypto";var ue=class{constructor(e){this.queue=e}queue;sanitizer=new k;capture(e,t,r={}){let s={id:Fr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(s),s}};import{randomUUID as $r}from"node:crypto";var fe=class{constructor(e){this.capture=e}capture;sessionId=$r();start(e){return this.capture.capture(e,"session_start",{sessionId:this.sessionId})}end(e){return this.capture.capture(e,"session_end",{sessionId:this.sessionId})}};var ge=class{extract(e){switch(e.type){case"decision":return{type:"decision",content:String(e.data.content??"Decision recorded"),tags:["decision"],source:"auto-extractor",metadata:e.data};case"todo":return{type:"todo",content:String(e.data.content??"TODO recorded"),tags:["todo"],source:"auto-extractor",metadata:e.data};case"error":return{type:"activity",content:`Error: ${String(e.data.message??"")}`,tags:["error"],source:"auto-extractor",metadata:e.data};case"file_write":return{type:"activity",content:`Modified file: ${String(e.data.filePath??"")}`,tags:["file","write"],source:"auto-extractor",metadata:e.data};case"command":return{type:"activity",content:`Command: ${String(e.data.command??"")}`,tags:["command"],source:"auto-extractor",metadata:e.data};case"session_start":case"session_end":case"file_read":case"tool_call":case"user_prompt":case"test":case"commit":case"deploy":return null;default:return null}}};function Ve(o){let e=o.toLowerCase();return["kh\xF4ng \u0111\u01B0\u1EE3c","b\u1EAFt bu\u1ED9c","ph\u1EA3i lu\xF4n","tuy\u1EC7t \u0111\u1ED1i","never ","must ","always ","do not "].some(t=>e.includes(t))}function qe(o){let e=o.toLowerCase();return["quy\u1EBFt \u0111\u1ECBnh","ch\u1ECDn ","s\u1EED d\u1EE5ng ","d\xF9ng ","decided","decision","we will use","use "].some(t=>e.includes(t))}function We(o){let e=o.toLowerCase();return["todo","c\u1EA7n l\xE0m","ch\u01B0a xong","c\xF2n ph\u1EA3i","next:","next step","pending"].some(t=>e.includes(t))}function he(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("tuy\u1EC7t \u0111\u1ED1i")||t.includes("must not")||t.includes("never ")?"critical":o==="rule"||o==="decision"?"high":o==="todo"||t.includes("error")||t.includes("failed")||t.includes("exception")?"normal":"temporary"}function D(o){return[...new Set(o.filter(Boolean))]}function ye(o,e=120){return o.length>e?`${o.slice(0,e)}\u2026`:o}var Se=class{summarize(e){if(e.length===0)return null;let t=D(e.filter(c=>c.type==="file_write").map(c=>String(c.data.filePath??""))),r=D(e.filter(c=>c.type==="command").map(c=>ye(String(c.data.command??"")))),s=D(e.filter(c=>c.type==="error").map(c=>ye(String(c.data.message??"")))),n=D(e.filter(c=>c.type==="decision").map(c=>ye(String(c.data.content??"")))),i=D(e.filter(c=>c.type==="todo").map(c=>ye(String(c.data.content??""))));if(t.length===0&&r.length===0&&s.length===0&&n.length===0&&i.length===0)return null;let a=["Session summary:"];return t.length&&a.push(`- Files changed (${t.length}): ${t.slice(0,10).join(", ")}`),r.length&&a.push(`- Commands (${r.length}): ${r.slice(0,5).join("; ")}`),s.length&&a.push(`- Errors (${s.length}): ${s.slice(0,5).join("; ")}`),n.length&&a.push(`- Decisions: ${n.slice(0,5).join("; ")}`),i.length&&a.push(`- TODO: ${i.slice(0,5).join("; ")}`),a.join(`
5
+ `)}};var be=class{constructor(e){this.memory=e}memory;extractor=new ge;summarizer=new Se;process(e){let t=0;for(let s of e){let n=this.extractor.extract(s);if(n){let i=this.refineType(n.type,n.content);this.memory.remember({projectId:s.projectId,type:i,content:n.content,importance:he(i,n.content),tags:n.tags,source:n.source,metadata:{eventId:s.id,timestamp:s.timestamp,...n.metadata}}),t++}if(s.type==="user_prompt"){let i=String(s.data.content??""),a=this.detectPromptMemoryType(i);a&&(this.memory.remember({projectId:s.projectId,type:a,content:i,importance:he(a,i),tags:["user",a],source:"auto-prompt-extractor",metadata:{eventId:s.id,timestamp:s.timestamp}}),t++)}}let r=this.summarizer.summarize(e);if(r){let s=e[0]?.projectId;s&&(this.memory.remember({projectId:s,type:"summary",content:r,importance:"temporary",tags:["summary"],source:"auto-summary",metadata:{eventCount:e.length}}),t++)}return t}refineType(e,t){return Ve(t)?"rule":We(t)?"todo":qe(t)?"decision":e}detectPromptMemoryType(e){return Ve(e)?"rule":We(e)?"todo":qe(e)?"decision":null}};import{createHash as Kr}from"node:crypto";function Gr(o){return Kr("sha256").update([o.projectId,o.type,o.content.trim().toLowerCase()].join("|")).digest("hex")}function St(o){let e=new Set,t=[];for(let r of o){let s=Gr(r);e.has(s)||(e.add(s),t.push(r))}return t}var ve=class{projectId;memory;memoryStore;queue=new pe;capture=new ue(this.queue);session=new fe(this.capture);processor;dedup=new me;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new be(this.memory)}async sessionStart(){this.session.start(this.projectId),await this.flushIfNeeded()}async sessionEnd(){this.session.end(this.projectId),await this.flush()}async userPrompt(e){this.capture.capture(this.projectId,"user_prompt",{content:e}),await this.flushIfNeeded()}async beforeTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"before",tool:e,input:t}),await this.flushIfNeeded()}async afterTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"after",tool:e,output:t}),await this.flushIfNeeded()}async fileRead(e){this.capture.capture(this.projectId,"file_read",{filePath:e}),await this.flushIfNeeded()}async fileWrite(e){this.capture.capture(this.projectId,"file_write",{filePath:e}),await this.flushIfNeeded()}async command(e,t){this.capture.capture(this.projectId,"command",{command:e,exitCode:t}),await this.flushIfNeeded()}async error(e){let t=e instanceof Error?e.message:String(e);this.capture.capture(this.projectId,"error",{message:t}),await this.flushIfNeeded()}async decision(e,t={}){this.capture.capture(this.projectId,"decision",{content:e,...t}),await this.flushIfNeeded()}async todo(e,t={}){this.capture.capture(this.projectId,"todo",{content:e,...t}),await this.flushIfNeeded()}async flushIfNeeded(){this.queue.shouldFlush(this.maxEventsBeforeFlush)&&await this.flush()}async flush(){let e=this.queue.drain();if(e.length===0)return 0;let t=this.dedup.filter(e);if(t.length===0)return 0;let r=this.processor.process(t),s=St(this.memory.exportProject(this.projectId));return this.memory.clearProject(this.projectId),this.memory.importRecords(s),await this.memoryStore.save(this.projectId,s),r}pendingEvents(){return this.queue.size()}};var Ee=class{constructor(e,t,r){this.memory=e;this.retrieval=t;this.graph=r}memory;retrieval;graph;build(e,t,r={}){let s=r.maxRules??3,n=r.maxTodos??3,i=r.maxDecisions??3,a=r.maxRelevant??5,c=r.maxCharacters??7e3,d=this.memory.byType(e,"rule").slice(0,s),m=this.memory.byType(e,"todo").slice(0,n),p=this.memory.byType(e,"decision").slice(0,i),f=this.retrieval.search(e,t,{topK:a}),g=dt(this.graph,e),C=[];C.push(["[PROJECT]",`files=${g.files}`,`classes=${g.classes}`,`functions=${g.functions}`,`methods=${g.methods}`,`calls=${g.calls}`].join(" "));for(let h of d)C.push(`[RULE] ${h.content}`);for(let h of p)C.push(`[DECISION] ${h.content}`);for(let h of m)C.push(`[TODO] ${h.content}`);for(let h of f){let x=`[${h.memory.type.toUpperCase()}] ${h.memory.content}`;C.includes(x)||C.push(x)}let v="";for(let h of C){let u=v.length===0?h:`${v}
6
+ ${h}`;if(u.length>c)break;v=u}return v}};var xe=class{constructor(e,t,r){this.runtime=e;this.builder=t;this.projectId=r}runtime;builder;projectId;async prepare(e){await this.runtime.userPrompt(e);let t=this.builder.build(this.projectId,e);return{originalPrompt:e,context:t,augmentedPrompt:t?["<toolnet_memory>",t,"</toolnet_memory>","",e].join(`
7
+ `):e}}};var bt={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},we=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=ft(e,t);if(r.length===0)return{triggered:!1,tool:e,highestRisk:"LOW",totalRiskScore:0,files:[],impactedFiles:[],suggestedTests:[],requiresVerification:!1,context:""};let s=[];for(let p of r){let f=this.guard.analyzeFile(this.projectId,p);s.push({filePath:p,risk:f.risk,riskScore:f.riskScore,impactedFiles:f.impactedFiles,suggestedTests:f.suggestedTests,impactedCount:f.impacted.length})}let n="LOW";for(let p of s)bt[p.risk]>bt[n]&&(n=p.risk);let i=[...new Set(s.flatMap(p=>p.impactedFiles))],a=[...new Set(s.flatMap(p=>p.suggestedTests))],c=s.reduce((p,f)=>p+f.riskScore,0),d=n==="HIGH"||n==="CRITICAL",m=["[TOOLNET IMPACT GUARD]",`Risk: ${n}`,`Risk score: ${c}`,`Files being changed: ${r.join(", ")}`,`Impacted files: ${i.length}`];return i.length&&m.push("Blast radius:",...i.slice(0,20).map(p=>`- ${p}`)),a.length&&m.push("Verify/tests:",...a.slice(0,15).map(p=>`- ${p}`)),d&&m.push("IMPORTANT: High blast radius. Inspect affected dependencies and run relevant tests after the edit."),{triggered:!0,tool:e,highestRisk:n,totalRiskScore:c,files:s,impactedFiles:i,suggestedTests:a,requiresVerification:d,context:m.join(`
8
+ `)}}};import{homedir as po}from"node:os";import{join as mo}from"node:path";import{DeleteObjectCommand as Br,GetObjectCommand as Ur,HeadObjectCommand as zr,ListObjectsV2Command as Hr,PutObjectCommand as Vr,S3Client as qr}from"@aws-sdk/client-s3";import{getSignedUrl as Wr}from"@aws-sdk/s3-request-presigner";var Ce=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new qr({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 Vr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Wr(this.client,new Ur({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 zr({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 Br({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new Hr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as vt,mkdir as Yr,readFile as Jr,readdir as Qr,rm as Zr,stat as Et,writeFile as Xr}from"node:fs/promises";import{dirname as eo,join as to,relative as xt,resolve as ro}from"node:path";var F=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return ro(this.root,t)}async put(e,t){let r=this.path(e);await Yr(eo(r),{recursive:!0}),await Xr(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 vt(this.path(e)),!0}catch{return!1}}async delete(e){await Zr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await vt(t)}catch{return r}let s=async i=>{let a=await Qr(i,{withFileTypes:!0});for(let c of a){let d=to(i,c.name);if(c.isDirectory()){await s(d);continue}let m=await Et(d);r.push({key:xt(this.root,d),size:m.size,updatedAt:m.mtime.toISOString()})}},n=await Et(t);return n.isDirectory()?await s(t):r.push({key:xt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as oo,GetObjectCommand as so,HeadObjectCommand as no,ListObjectsV2Command as io,PutObjectCommand as ao,S3Client as co}from"@aws-sdk/client-s3";import{getSignedUrl as lo}from"@aws-sdk/s3-request-presigner";var $=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new co({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 ao({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await lo(this.client,new so({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${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 no({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new oo({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new io({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};function Ye(o,e){return console.warn(e),new F(o)}function wt(o){let e=o.localRoot??mo(po(),".toolnet-memory","storage");if(o.provider==="r2"){let t=o.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ye(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(o.provider==="s3"){let t=o.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ye(e,"[storage] S3 credentials missing. Using local fallback.")}if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new Ce({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Ye(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new F(e)}var M=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};var Pe=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let r=JSON.parse(t);if(r.version!==1||r.projectId!==e||!Array.isArray(r.records))throw new Error("Invalid vector snapshot");return r}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function uo(o){return new Promise(e=>setTimeout(e,o))}async function Ct(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),d=Math.floor(Math.random()*Math.max(1,c*.2));await uo(c+d)}throw n}var fo=new Set(["put","get","getText","delete","list"]);function Pt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:fo.has(r)?(...n)=>Ct(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function Rt(o){let e=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function At(o){let e=o.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var Re=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=Rt(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
9
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=At(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};function ho(o){let e=o.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function yo(o,e){let t=`projects/${o.id}/memory/learned/`,r=await e.list(t),s=[];for(let n of r.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(n.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;s.push(a)}catch{}}return s}async function It(o,e){let t=await yo(o,e),r=new M(e),s=await r.load(o.id),n=new j;n.importRecords(s);let i=new Set(s.map(m=>ho(m)).filter(m=>!!m)),a=0,c=0,d=0;for(let m of t)for(let p of m.candidates){if(a+=1,i.has(p.fingerprint)){d+=1;continue}n.remember({projectId:o.id,type:p.type,content:p.content,importance:p.importance,tags:p.tags,source:"session-memory-learner",metadata:{learningFingerprint:p.fingerprint,learningKind:p.kind,confidence:p.confidence,provenance:p.provenance,sourceCreatedAt:p.createdAt,sessionKey:p.sessionKey,agent:p.agent,nativeSessionId:p.nativeSessionId}}),i.add(p.fingerprint),c+=1}return c>0&&await r.save(o.id,n.exportProject(o.id)),{batches:t.length,candidates:a,added:c,duplicates:d,memories:n.exportProject(o.id).length}}var So=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],Ae=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let m of So){let p=`${i}/${m}`,f=await this.storage.get(p);f&&(await this.storage.put(`${a}/${m}`,f,"application/json"),c.push(m))}if(c.length===0)return null;let d={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(d,null,2),"application/json"),d}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let d=await this.storage.get(`${r}/${c}`);d&&(await this.storage.put(`${i}/${c}`,d,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};import{closeSync as bo,mkdirSync as vo,openSync as Eo,readFileSync as xo,unlinkSync as kt,writeFileSync as wo}from"node:fs";import{tmpdir as Co}from"node:os";import{join as jt}from"node:path";function Po(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var Ie=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=jt(Co(),"toolnet-memory-locks");vo(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=jt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Eo(this.path,"wx");wo(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),bo(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let s=JSON.parse(xo(this.path,"utf8"));Number.isInteger(s.pid)&&Po(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{kt(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{kt(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var ke=class{constructor(e){this.options=e;this.memoryStore=new M(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new Pe(e.storage),this.processLock=new Ie(e.project.id),this.retrieval=new Z(this.memory),this.references=new se(this.graph),this.hooks=new ve({projectId:e.project.id,memory:this.memory,memoryStore:this.memoryStore,maxEventsBeforeFlush:100});let t=new Ee(this.memory,this.retrieval,this.graph);this.autoRetrieval=new xe(this.hooks,t,e.project.id),this.impactGuard=new ae(this.graph),this.autoImpactGuard=new we(this.impactGuard,e.project.id)}options;memory=new j;graph=new A;vectors=new N;retrieval;references;hooks;autoRetrieval;impactGuard;autoImpactGuard;memoryStore;graphStore;vectorStore;processLock;async start(){let{project:e}=this.options;await this.processLock.acquire(),await It(e,this.options.storage);let t=await this.memoryStore.load(e.id);this.memory.importRecords(t);let s=new H(this.memory).run(e.id);(s.expiredRemoved>0||s.supersededRemoved>0)&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let n=await this.graphStore.load(e.id);n&&this.graph.import(n.symbols,n.edges);let i=Fe(),c=await new O(e.id,this.options.embeddingModel,i,this.vectors,this.vectorStore).initialize(this.memory.list(e.id));return await this.hooks.sessionStart(),{memories:t.length,graphSymbols:this.graph.allSymbols(e.id).length,graphEdges:this.graph.allEdges(e.id).length,vectors:c.total,vectorsIndexed:c.indexed}}async preparePrompt(e){return this.autoRetrieval.prepare(e)}async beforeTool(e,t){let r=await this.autoImpactGuard.beforeTool(e,t);return await this.hooks.beforeTool(e,t),r}async afterTool(e,t){return this.hooks.afterTool(e,t)}async stop(){let{project:e,storage:t,embeddingModel:r}=this.options,s=new Ae(t),n=await s.create(e.id,"session-end-auto");await s.prune(e.id,10),await this.hooks.sessionEnd();let i=new V(this.memory).consolidate(e.id);i.summaryCreated&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let a=await new le(t).index(e.id,e.rootPath),c=await this.graphStore.load(e.id);c&&(this.graph.clearProject(e.id),this.graph.import(c.symbols,c.edges));let d=Fe(),p=await new O(e.id,r,d,this.vectors,this.vectorStore).initialize(this.memory.list(e.id)),f={code:a,vectors:p,consolidation:i,snapshot:n?.id,memories:this.memory.list(e.id).length};return await this.processLock.release(),f}};import"dotenv/config";import{existsSync as Ro,readFileSync as Ao}from"node:fs";import{homedir as Io}from"node:os";import{join as ko}from"node:path";function jo(o){let e=o.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
10
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function To(){let o=process.env.TOOLNET_GLOBAL_ENV??ko(Io(),".config","toolnet-memory",".env");if(!Ro(o))return;let e=Ao(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let n=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=jo(r.slice(s+1)))}}To();function K(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function G(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function Tt(){return{memory:{autoCapture:K(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:K(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:K(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:K(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:G(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:G(process.env.MEMORY_RERANK_TOP,10),finalContext:G(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:G(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:K(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:G(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Mo}from"node:crypto";import{existsSync as Je,mkdirSync as Lo,readFileSync as _o,renameSync as No,writeFileSync as Oo}from"node:fs";import{basename as Do,dirname as je,join as Me,parse as _t,resolve as B}from"node:path";var Nt=".toolnet",Fo="project.json";function $o(o){return Mo("sha256").update(o).digest("hex").slice(0,16)}function Qe(o){return Me(o,Nt,Fo)}function Ko(o){return Je(Qe(o))}function Go(o,e){let t=B(o),r=_t(t).root;for(;;){if(Ko(t))return t;if(t===r||e&&t===B(e))break;let s=je(t);if(s===t)break;t=s}return null}function Bo(o){let e=B(o),t=_t(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Je(Me(e,n))))return e;if(e===t)break;let s=je(e);if(s===e)break;e=s}return B(o)}function Uo(o){let e;try{e=JSON.parse(_o(o,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${o}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:je(je(o)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Mt(o,e){let t=Me(o,Nt);Lo(t,{recursive:!0});let r=Qe(o),s=`${r}.tmp-${process.pid}`;Oo(s,JSON.stringify(e,null,2)+`
11
+ `,{encoding:"utf8",mode:384}),No(s,r)}function Lt(o,e){return{id:o.id,name:o.name,remote:o.remote,rootPath:e,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var Te=class{detect(e=process.cwd()){let t=B(e),r=Bo(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>Je(Me(r,m))),i=Go(t,n?r:void 0);if(i){let m=Qe(i),p=Uo(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Mt(i,p)),Lt(p,i)}let a=new Date().toISOString(),c=Do(r),d={version:1,id:$o(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Mt(r,d),Lt(d,r)}};function Ot(o=process.cwd()){let e=Tt(),t=new Te().detect(o),r=wt({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),s=Pt(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),n=new Re(s,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new ke({project:t,storage:n,embeddingModel:i})}async function zo(){let o=Ot(),e=await o.start(),t=await o.preparePrompt("Ti\u1EBFp t\u1EE5c c\xF4ng vi\u1EC7c hi\u1EC7n t\u1EA1i");console.log({started:!0,...e,contextCharacters:t.context.length});let r=await o.stop();console.log({stopped:!0,memories:r.memories,codeParsed:r.code.parsed,vectorsIndexed:r.vectors.indexed})}zo().catch(o=>{console.error(o),process.exit(1)});
@@ -1,6 +1,6 @@
1
- import"dotenv/config";import{existsSync as Se,readFileSync as be}from"node:fs";import{homedir as xe}from"node:os";import{join as Ee}from"node:path";function Ce(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 we(){let s=process.env.TOOLNET_GLOBAL_ENV??Ee(xe(),".config","toolnet-memory",".env");if(!Se(s))return;let e=be(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]=Ce(r.slice(o+1)))}}we();function R(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function j(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function re(){return{memory:{autoCapture:R(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:R(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:R(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:R(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:j(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:j(process.env.MEMORY_RERANK_TOP,10),finalContext:j(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:j(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:R(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:j(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ve}from"node:crypto";import{existsSync as q,mkdirSync as Pe,readFileSync as ke,renameSync as Te,writeFileSync as Re}from"node:fs";import{basename as je,dirname as O,join as F,parse as ne,resolve as A}from"node:path";var ie=".toolnet",Ae="project.json";function Le(s){return ve("sha256").update(s).digest("hex").slice(0,16)}function J(s){return F(s,ie,Ae)}function Ne(s){return q(J(s))}function Me(s,e){let t=A(s),r=ne(t).root;for(;;){if(Ne(t))return t;if(t===r||e&&t===A(e))break;let o=O(t);if(o===t)break;t=o}return null}function Ie(s){let e=A(s),t=ne(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>q(F(e,n))))return e;if(e===t)break;let o=O(e);if(o===e)break;e=o}return A(s)}function Oe(s){let e;try{e=JSON.parse(ke(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:O(O(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 se(s,e){let t=F(s,ie);Pe(t,{recursive:!0});let r=J(s),o=`${r}.tmp-${process.pid}`;Re(o,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Te(o,r)}function oe(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 _=class{detect(e=process.cwd()){let t=A(e),r=Ie(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>q(F(r,d))),i=Me(t,n?r:void 0);if(i){let d=J(i),m=Oe(d);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),se(i,m)),oe(m,i)}let c=new Date().toISOString(),l=je(r),a={version:1,id:Le(r),name:l,remote:l,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return se(r,a),oe(a,r)}};var _e=[{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}],$=class{scan(e){let t=[];for(let r of _e){let o=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(o))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var L=class{scanner=new $;sanitize(e){let t=e,r=this.scanner.scan(e),o=new Set;for(let n of r)o.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...o]}}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,o]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(o)}return t}return e}};import{homedir as nt}from"node:os";import{join as it}from"node:path";import{DeleteObjectCommand as Fe,GetObjectCommand as $e,HeadObjectCommand as De,ListObjectsV2Command as Ge,PutObjectCommand as Ke,S3Client as ze}from"@aws-sdk/client-s3";import{getSignedUrl as Be}from"@aws-sdk/s3-request-presigner";var D=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 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(`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 De({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 Ge({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 ae,mkdir as He,readFile as We,readdir as Ue,rm as Ve,stat as ce,writeFile as Ye}from"node:fs/promises";import{dirname as qe,join as Je,relative as le,resolve as Qe}from"node:path";var N=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Qe(this.root,t)}async put(e,t){let r=this.path(e);await He(qe(r),{recursive:!0}),await Ye(r,t)}async get(e){try{return await We(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 ae(this.path(e)),!0}catch{return!1}}async delete(e){await Ve(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await ae(t)}catch{return r}let o=async i=>{let c=await Ue(i,{withFileTypes:!0});for(let l of c){let a=Je(i,l.name);if(l.isDirectory()){await o(a);continue}let d=await ce(a);r.push({key:le(this.root,a),size:d.size,updatedAt:d.mtime.toISOString()})}},n=await ce(t);return n.isDirectory()?await o(t):r.push({key:le(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as Ze,GetObjectCommand as Xe,HeadObjectCommand as et,ListObjectsV2Command as tt,PutObjectCommand as rt,S3Client as st}from"@aws-sdk/client-s3";import{getSignedUrl as ot}from"@aws-sdk/s3-request-presigner";var M=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new st({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 rt({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await ot(this.client,new Xe({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 et({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 Ze({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new tt({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 Q(s,e){return console.warn(e),new N(s)}function de(s){let e=s.localRoot??it(nt(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new M({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Q(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 M({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Q(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 D({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Q(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new N(e)}var I=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")}};var G=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 K=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")}};function pe(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 me(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 z=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=pe(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(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}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=me(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 u from"typescript";var v=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)}};import{execFile as dt}from"node:child_process";import{promisify as pt}from"node:util";var js=pt(dt);import{createHash as mt}from"node:crypto";import{readFile as ft}from"node:fs/promises";import{join as ut}from"node:path";function fe(s){return mt("sha256").update(s).digest("hex")}var B=class{sanitizer=new L;async build(e,t,r,o={}){let n=o.maxLines??80,i=o.overlapLines??10,c=new Map;for(let a of r){let d=c.get(a.filePath)??[];d.push(a),c.set(a.filePath,d)}let l=[];for(let[a,d]of c){let m;try{m=await ft(ut(t,a),"utf8")}catch{continue}let g=m.split(/\r?\n/),S=d.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(S.length>0)for(let h of S)l.push(...this.chunkRange({projectId:e,filePath:a,lines:g,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:n,overlapLines:i}));else l.push(...this.chunkRange({projectId:e,filePath:a,lines:g,startLine:1,endLine:Math.max(1,g.length),maxLines:n,overlapLines:i}))}return l}chunkRange(e){let{projectId:t,filePath:r,lines:o,symbol:n,maxLines:i}=e,c=Math.min(e.overlapLines,Math.max(0,i-1)),l=Math.max(1,e.startLine),a=Math.min(o.length,Math.max(l,e.endLine)),d=[],m=l,g=0;for(;m<=a;){let S=Math.min(a,m+i-1),h=o.slice(m-1,S).join(`
5
- `).trim();if(h){let x=this.sanitizer.sanitize(h).text,P=fe(x),k=[t,r,n?.id??"file",String(g),P].join(":");d.push({id:fe(k).slice(0,32),projectId:t,filePath:r,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:m,endLine:S,content:x,contentHash:P})}if(S>=a)break;m=S-c+1,g++}return d}};var H=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,o]of this.records)o.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 o=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=gt(t,n.vector);o.push({id:n.id,score:i,metadata:n.metadata})}return o.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function gt(s,e){if(s.length===0||e.length===0||s.length!==e.length)return 0;let t=0,r=0,o=0;for(let n=0;n<s.length;n++){let i=s[n]??0,c=e[n]??0;t+=i*c,r+=i*i,o+=c*c}return r===0||o===0?0:t/(Math.sqrt(r)*Math.sqrt(o))}function Z(s){return s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function ue(s,e){let t=s.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var W=class{constructor(e){this.options=e}options;vectors=new H;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:o,graph:n,model:i}=this.options,c=new G(r),l=new K(r),a=await new B().build(e,t,n.allSymbols(e));this.chunks.clear();for(let f of a)this.chunks.set(f.id,f);let d=await c.load(e),m=!d||d.chunks.length!==a.length||d.chunks.some(f=>!this.chunks.has(f.id));m&&await c.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:a});let g=await l.load(e),S=0;g&&g.model===i&&(S=this.vectors.importRecords(g.records));let h=new Set(a.map(f=>f.id)),x=0;for(let f of this.vectors.exportProject(e))h.has(f.id)||this.vectors.remove(f.id)&&x++;let P=a.filter(f=>{let C=this.vectors.get(f.id);return C?C.metadata?.contentHash!==f.contentHash:!0}),k=0,ee=8,T=this.vectors.exportProject(e)[0]?.vector.length;for(let f=0;f<P.length;f+=ee){let C=P.slice(f,f+ee),he=C.map(b=>[`file: ${b.filePath}`,b.symbolName?`symbol: ${b.symbolName}`:"",b.symbolType?`type: ${b.symbolType}`:"",b.content].filter(Boolean).join(`
6
- `)),ye=await o.embedMany(he);for(let b=0;b<C.length;b++){let E=C[b],w=ye[b];if(!(!E||!w||w.length===0)){if(T===void 0&&(T=w.length),w.length!==T){console.warn(`[code-semantic] skip dimension mismatch: ${w.length} != ${T}`);continue}this.vectors.upsert({id:E.id,projectId:e,vector:w,metadata:{contentHash:E.contentHash,filePath:E.filePath,symbolName:E.symbolName,symbolType:E.symbolType,startLine:E.startLine,endLine:E.endLine}}),k++}}}let Y=this.vectors.exportProject(e),te=k>0||x>0||!g||g.model!==i;return te&&await l.save({version:1,projectId:e,model:i,dimensions:Y[0]?.vector.length??T??0,updatedAt:new Date().toISOString(),records:Y}),{chunks:a.length,vectorsLoaded:S,vectorsIndexed:k,vectorsRemoved:x,totalVectors:Y.length,savedChunks:m,savedVectors:te}}async search(e,t=8){let r=await this.options.embeddings.embed(e),o=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),n=new Set(Z(e)),i=[];for(let c of o){let l=this.chunks.get(c.id);if(!l)continue;let a=new Set(Z([l.filePath,l.symbolName??"",l.symbolType??"",l.content].join(" "))),d=0;for(let x of n)a.has(x)&&d++;let m=n.size===0?0:d/n.size,g=Math.max(0,c.score),S=ue(l.filePath,e),h=(g*.75+m*.25)*S;i.push({chunk:l,score:h,vectorScore:g,lexicalScore:m})}return i.sort((c,l)=>l.score-c.score).slice(0,t)}size(){return this.chunks.size}};import*as y from"typescript";import*as p from"typescript";var _o=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]);var U=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 o=await r.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(n=>yt(n))}};function yt(s){if(!Array.isArray(s))throw new Error("Invalid embedding");if(s.length>0&&typeof s[0]=="number")return s;if(s.length>0&&Array.isArray(s[0])){let e=s;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let o of e)for(let n=0;n<t;n++)r[n]+=o[n]??0;for(let o=0;o<t;o++)r[o]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as St}from"node:crypto";var V=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 o of r){let i=St("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return bt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function bt(s){let e=Math.sqrt(s.reduce((t,r)=>t+r*r,0));return e===0?s:s.map(t=>t/e)}var X=class{constructor(e,t=new V){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 ge(){let s=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=s?new U({token:s,model:e}):null;return new X(t)}async function xt(){let s=re(),e=new _().detect(),t=de({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),r=new z(t,e.id,e.name,e.remote??e.name),o=new v,n=await new I(r).load(e.id);if(!n)throw new Error("Code graph missing. Run npm run code:index:test first.");o.import(n.symbols,n.edges);let i=new W({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:r,embeddings:ge(),graph:o}),c=await i.initialize(),l=process.argv.slice(2).join(" ")||"memory storage hugging face",a=await i.search(l,5);console.log({ok:!0,query:l,...c,results:a.map(d=>({score:Number(d.score.toFixed(4)),file:d.chunk.filePath,symbol:d.chunk.symbolName,lines:`${d.chunk.startLine}-${d.chunk.endLine}`,preview:d.chunk.content.replace(/\s+/g," ").slice(0,140)}))})}xt().catch(s=>{console.error(s),process.exit(1)});
1
+ import"dotenv/config";import{existsSync as Le,readFileSync as Re}from"node:fs";import{homedir as Te}from"node:os";import{join as Ie}from"node:path";function _e(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 ke(){let s=process.env.TOOLNET_GLOBAL_ENV??Ie(Te(),".config","toolnet-memory",".env");if(!Le(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 i=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=_e(r.slice(o+1)))}}ke();function I(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function _(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function ce(){return{memory:{autoCapture:I(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:I(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:I(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:I(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:I(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 Ne}from"node:crypto";import{existsSync as ee,mkdirSync as Me,readFileSync as Oe,renameSync as je,writeFileSync as De}from"node:fs";import{basename as Fe,dirname as D,join as K,parse as pe,resolve as k}from"node:path";var me=".toolnet",Ke="project.json";function Ge(s){return Ne("sha256").update(s).digest("hex").slice(0,16)}function te(s){return K(s,me,Ke)}function $e(s){return ee(te(s))}function Be(s,e){let t=k(s),r=pe(t).root;for(;;){if($e(t))return t;if(t===r||e&&t===k(e))break;let o=D(t);if(o===t)break;t=o}return null}function Ue(s){let e=k(s),t=pe(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(i=>ee(K(e,i))))return e;if(e===t)break;let o=D(e);if(o===e)break;e=o}return k(s)}function ze(s){let e;try{e=JSON.parse(Oe(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:D(D(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 le(s,e){let t=K(s,me);Me(t,{recursive:!0});let r=te(s),o=`${r}.tmp-${process.pid}`;De(o,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),je(o,r)}function de(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 F=class{detect(e=process.cwd()){let t=k(e),r=Ue(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>ee(K(r,p))),a=Be(t,i?r:void 0);if(a){let p=te(a),f=ze(p);return f.rootPath!==a&&(f.rootPath=a,f.updatedAt=new Date().toISOString(),le(a,f)),de(f,a)}let c=new Date().toISOString(),d=Fe(r),l={version:1,id:Ge(r),name:d,remote:d,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return le(r,l),de(l,r)}};var He=[{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}],G=class{scan(e){let t=[];for(let r of He){let o=new RegExp(r.regex.source,r.regex.flags);for(let i of e.matchAll(o))t.push({type:r.type,value:i[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var N=class{scanner=new G;sanitize(e){let t=e,r=this.scanner.scan(e),o=new Set;for(let i of r)o.add(i.type),t=t.split(i.value).join(`[REDACTED:${i.type}]`);return{text:t,redacted:r.length,secretTypes:[...o]}}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,o]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(o)}return t}return e}};import{homedir as ft}from"node:os";import{join as gt}from"node:path";import{DeleteObjectCommand as Ve,GetObjectCommand as We,HeadObjectCommand as Ye,ListObjectsV2Command as qe,PutObjectCommand as Je,S3Client as Qe}from"@aws-sdk/client-s3";import{getSignedUrl as Ze}from"@aws-sdk/s3-request-presigner";var $=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Qe({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 Je({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Ze(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 Ye({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 i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as ue,mkdir as Xe,readFile as et,readdir as tt,rm as rt,stat as fe,writeFile as st}from"node:fs/promises";import{dirname as ot,join as nt,relative as ge,resolve as it}from"node:path";var M=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 ue(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 ue(t)}catch{return r}let o=async a=>{let c=await tt(a,{withFileTypes:!0});for(let d of c){let l=nt(a,d.name);if(d.isDirectory()){await o(l);continue}let p=await fe(l);r.push({key:ge(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},i=await fe(t);return i.isDirectory()?await o(t):r.push({key:ge(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),r}};import{DeleteObjectCommand as at,GetObjectCommand as ct,HeadObjectCommand as lt,ListObjectsV2Command as dt,PutObjectCommand as pt,S3Client as mt}from"@aws-sdk/client-s3";import{getSignedUrl as ut}from"@aws-sdk/s3-request-presigner";var O=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new mt({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 pt({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await ut(this.client,new ct({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 lt({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 at({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new dt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function re(s,e){return console.warn(e),new M(s)}function he(s){let e=s.localRoot??gt(ft(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):re(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 O({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):re(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 $({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):re(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new M(e)}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")}};var B=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 U=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")}};function ye(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 Se(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 z=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=ye(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 a;try{a=JSON.parse(o)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(r=a.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)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Se(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 h from"typescript";var A=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)}};import{execFile as bt}from"node:child_process";import{promisify as Et}from"node:util";var Us=Et(bt);import{createHash as Ct}from"node:crypto";import{readFile as vt}from"node:fs/promises";import{join as xt}from"node:path";function be(s){return Ct("sha256").update(s).digest("hex")}var H=class{sanitizer=new N;async build(e,t,r,o={}){let i=o.maxLines??80,a=o.overlapLines??10,c=new Map;for(let l of r){let p=c.get(l.filePath)??[];p.push(l),c.set(l.filePath,p)}let d=[];for(let[l,p]of c){let f;try{f=await vt(xt(t,l),"utf8")}catch{continue}let y=f.split(/\r?\n/),E=p.filter(S=>S.type!=="file"&&typeof S.startLine=="number"&&typeof S.endLine=="number");if(E.length>0)for(let S of E)d.push(...this.chunkRange({projectId:e,filePath:l,lines:y,symbol:S,startLine:S.startLine,endLine:S.endLine,maxLines:i,overlapLines:a}));else d.push(...this.chunkRange({projectId:e,filePath:l,lines:y,startLine:1,endLine:Math.max(1,y.length),maxLines:i,overlapLines:a}))}return d}chunkRange(e){let{projectId:t,filePath:r,lines:o,symbol:i,maxLines:a}=e,c=Math.min(e.overlapLines,Math.max(0,a-1)),d=Math.max(1,e.startLine),l=Math.min(o.length,Math.max(d,e.endLine)),p=[],f=d,y=0;for(;f<=l;){let E=Math.min(l,f+a-1),S=o.slice(f-1,E).join(`
5
+ `).trim();if(S){let v=this.sanitizer.sanitize(S).text,L=be(v),R=[t,r,i?.id??"file",String(y),L].join(":");p.push({id:be(R).slice(0,32),projectId:t,filePath:r,symbolId:i?.id,symbolName:i?.qualifiedName??i?.name,symbolType:i?.type,startLine:f,endLine:E,content:v,contentHash:L})}if(E>=l)break;f=E-c+1,y++}return p}};var V=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,o]of this.records)o.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 o=[];for(let i of this.records.values()){if(i.projectId!==e)continue;let a=wt(t,i.vector);o.push({id:i.id,score:a,metadata:i.metadata})}return o.sort((i,a)=>a.score-i.score).slice(0,r)}size(){return this.records.size}};function wt(s,e){if(s.length===0||e.length===0||s.length!==e.length)return 0;let t=0,r=0,o=0;for(let i=0;i<s.length;i++){let a=s[i]??0,c=e[i]??0;t+=a*c,r+=a*a,o+=c*c}return r===0||o===0?0:t/(Math.sqrt(r)*Math.sqrt(o))}function se(s){return s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function Ee(s,e){let t=s.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var W=class{constructor(e){this.options=e}options;vectors=new V;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:r,embeddings:o,graph:i,model:a}=this.options,c=new B(r),d=new U(r),l=await new H().build(e,t,i.allSymbols(e));this.chunks.clear();for(let g of l)this.chunks.set(g.id,g);let p=await c.load(e),f=!p||p.chunks.length!==l.length||p.chunks.some(g=>!this.chunks.has(g.id));f&&await c.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:l});let y=await d.load(e),E=0;y&&y.model===a&&(E=this.vectors.importRecords(y.records));let S=new Set(l.map(g=>g.id)),v=0;for(let g of this.vectors.exportProject(e))S.has(g.id)||this.vectors.remove(g.id)&&v++;let L=l.filter(g=>{let w=this.vectors.get(g.id);return w?w.metadata?.contentHash!==g.contentHash:!0}),R=0,ie=8,T=this.vectors.exportProject(e)[0]?.vector.length;for(let g=0;g<L.length;g+=ie){let w=L.slice(g,g+ie),Pe=w.map(C=>[`file: ${C.filePath}`,C.symbolName?`symbol: ${C.symbolName}`:"",C.symbolType?`type: ${C.symbolType}`:"",C.content].filter(Boolean).join(`
6
+ `)),Ae=await o.embedMany(Pe);for(let C=0;C<w.length;C++){let x=w[C],P=Ae[C];if(!(!x||!P||P.length===0)){if(T===void 0&&(T=P.length),P.length!==T){console.warn(`[code-semantic] skip dimension mismatch: ${P.length} != ${T}`);continue}this.vectors.upsert({id:x.id,projectId:e,vector:P,metadata:{contentHash:x.contentHash,filePath:x.filePath,symbolName:x.symbolName,symbolType:x.symbolType,startLine:x.startLine,endLine:x.endLine}}),R++}}}let X=this.vectors.exportProject(e),ae=R>0||v>0||!y||y.model!==a;return ae&&await d.save({version:1,projectId:e,model:a,dimensions:X[0]?.vector.length??T??0,updatedAt:new Date().toISOString(),records:X}),{chunks:l.length,vectorsLoaded:E,vectorsIndexed:R,vectorsRemoved:v,totalVectors:X.length,savedChunks:f,savedVectors:ae}}async search(e,t=8){let r=await this.options.embeddings.embed(e),o=this.vectors.search(this.options.projectId,r,Math.max(t*4,20)),i=new Set(se(e)),a=[];for(let c of o){let d=this.chunks.get(c.id);if(!d)continue;let l=new Set(se([d.filePath,d.symbolName??"",d.symbolType??"",d.content].join(" "))),p=0;for(let v of i)l.has(v)&&p++;let f=i.size===0?0:p/i.size,y=Math.max(0,c.score),E=Ee(d.filePath,e),S=(y*.75+f*.25)*E;a.push({chunk:d,score:S,vectorScore:y,lexicalScore:f})}return a.sort((c,d)=>d.score-c.score).slice(0,t)}size(){return this.chunks.size}};import*as b from"typescript";import*as m from"typescript";var Jo=new Set([m.SyntaxKind.EqualsToken,m.SyntaxKind.PlusEqualsToken,m.SyntaxKind.MinusEqualsToken,m.SyntaxKind.AsteriskEqualsToken,m.SyntaxKind.SlashEqualsToken,m.SyntaxKind.PercentEqualsToken,m.SyntaxKind.QuestionQuestionEqualsToken,m.SyntaxKind.AmpersandAmpersandEqualsToken,m.SyntaxKind.BarBarEqualsToken]);var Ce=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function Y(s){let e=Ce.find(t=>t.id===s);if(!e)throw new Error(`Unsupported AI provider: ${s}`);return e}function q(s){return Ce.some(e=>e.id===s)}function n(s){return process.env[s]?.trim()||void 0}function u(...s){return s.find(e=>!!e?.trim())}function ve(){if(n("GROQ_API_KEY"))return"groq";if(n("DEEPSEEK_API_KEY"))return"deepseek";if(n("NVIDIA_API_KEY")||n("NVIDIA_NIM_API_KEY"))return"nvidia";if(n("OPENROUTER_API_KEY"))return"openrouter";if(n("ALIBABA_API_KEY")||n("DASHSCOPE_API_KEY"))return"alibaba";if(n("GEMINI_API_KEY")||n("GOOGLE_API_KEY"))return"gemini";if(n("CLOUDFLARE_API_TOKEN")&&n("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(n("HF_TOKEN"))return"huggingface";if(n("OLLAMA_MODEL")||n("OLLAMA_BASE_URL"))return"ollama"}function At(){let s=n("TOOLNET_LLM_PROVIDER");return s&&q(s)?s:ve()??"openai-compatible"}function oe(s){let e=Y(s);switch(s){case"alibaba":return{provider:s,apiKey:u(n("ALIBABA_API_KEY"),n("DASHSCOPE_API_KEY")),baseUrl:u(n("ALIBABA_BASE_URL"),n("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:u(n("ALIBABA_MODEL"),n("DASHSCOPE_MODEL"))};case"openrouter":return{provider:s,apiKey:n("OPENROUTER_API_KEY"),baseUrl:u(n("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:n("OPENROUTER_MODEL")};case"groq":return{provider:s,apiKey:n("GROQ_API_KEY"),baseUrl:u(n("GROQ_BASE_URL"),e.defaultBaseUrl),model:n("GROQ_MODEL")};case"deepseek":return{provider:s,apiKey:n("DEEPSEEK_API_KEY"),baseUrl:u(n("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:u(n("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:s,apiKey:u(n("NVIDIA_API_KEY"),n("NVIDIA_NIM_API_KEY")),baseUrl:u(n("NVIDIA_BASE_URL"),n("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:u(n("NVIDIA_MODEL"),n("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:s,apiKey:u(n("GEMINI_API_KEY"),n("GOOGLE_API_KEY")),baseUrl:u(n("GEMINI_BASE_URL"),e.defaultBaseUrl),model:n("GEMINI_MODEL")};case"huggingface":return{provider:s,apiKey:n("HF_TOKEN"),baseUrl:u(n("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:u(n("HF_LLM_MODEL"),n("HF_MODEL"))};case"ollama":return{provider:s,apiKey:n("OLLAMA_API_KEY"),baseUrl:u(n("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:n("OLLAMA_MODEL")};case"cloudflare":return{provider:s,accountId:n("CLOUDFLARE_ACCOUNT_ID"),apiKey:n("CLOUDFLARE_API_TOKEN"),baseUrl:n("CLOUDFLARE_AI_BASE_URL"),model:n("CLOUDFLARE_MODEL")};case"custom":return{provider:s,apiKey:n("CUSTOM_AI_API_KEY"),baseUrl:n("CUSTOM_AI_BASE_URL"),model:n("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:u(n("OPENAI_API_KEY"),n("MODEL_API_KEY")),baseUrl:u(n("OPENAI_BASE_URL"),n("MODEL_BASE_URL")),model:u(n("OPENAI_MODEL"),n("MODEL_NAME"))}}}function Lt(){let s=n("TOOLNET_LLM_PROVIDER"),e=s&&q(s)?s:At(),t=Y(e),r=oe(e);return{provider:e,apiKey:u(n("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:u(n("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:u(n("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:u(n("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function Rt(){let s=n("TOOLNET_EMBEDDING_PROVIDER");return s==="local"?"local":s&&q(s)?s:n("HF_TOKEN")||n("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Tt(){let s=Rt();if(s==="local")return{provider:"local",model:u(n("TOOLNET_EMBEDDING_MODEL"),n("LOCAL_EMBEDDING_MODEL"))};let e=Y(s),t,r,o,i;switch(s){case"huggingface":t=n("HF_TOKEN"),r=n("HF_INFERENCE_BASE_URL"),o=n("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=n("OPENAI_API_KEY"),r=n("OPENAI_BASE_URL"),o=n("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=n("CLOUDFLARE_API_TOKEN"),r=n("CLOUDFLARE_AI_BASE_URL"),o=n("CLOUDFLARE_EMBEDDING_MODEL"),i=n("CLOUDFLARE_ACCOUNT_ID");break;default:t=oe(s).apiKey,r=oe(s).baseUrl,o=n(`${s.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}return{provider:s,apiKey:u(n("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:u(n("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),model:u(n("TOOLNET_EMBEDDING_MODEL"),o),accountId:u(n("TOOLNET_EMBEDDING_ACCOUNT_ID"),i)}}function xe(){let s=Lt(),e=Tt();return{llm:s,embedding:e,legacy:{llm:!n("TOOLNET_LLM_PROVIDER")&&!!ve(),embedding:!n("TOOLNET_EMBEDDING_PROVIDER")&&!!(n("HF_TOKEN")||n("HF_EMBEDDING_MODEL"))}}}var J=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 o=await r.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(i=>It(i))}};function It(s){if(!Array.isArray(s))throw new Error("Invalid embedding");if(s.length>0&&typeof s[0]=="number")return s;if(s.length>0&&Array.isArray(s[0])){let e=s;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let o of e)for(let i=0;i<t;i++)r[i]+=o[i]??0;for(let o=0;o<t;o++)r[o]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as _t}from"node:crypto";var Q=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 o of r){let a=_t("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[a]+=1}return kt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function kt(s){let e=Math.sqrt(s.reduce((t,r)=>t+r*r,0));return e===0?s:s.map(t=>t/e)}var Z=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),r=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:e})});if(!r.ok)throw new Error(`Embedding failed: ${r.status} ${await r.text()}`);let i=(await r.json()).data?.sort((a,c)=>(a.index??0)-(c.index??0)).map(a=>a.embedding);if(!i||i.length!==e.length||i.some(a=>!Array.isArray(a)))throw new Error("Embedding provider returned invalid response");return i}};var ne=class{constructor(e,t=new Q){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 Nt(){let s=xe().embedding;return s.provider==="local"?null:s.provider==="huggingface"?!s.apiKey||!s.model?null:new J({token:s.apiKey,model:s.model}):s.baseUrl&&s.model?new Z({apiKey:s.apiKey,baseUrl:s.baseUrl,model:s.model}):null}function we(){return new ne(Nt())}async function Mt(){let s=ce(),e=new F().detect(),t=he({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),r=new z(t,e.id,e.name,e.remote??e.name),o=new A,i=await new j(r).load(e.id);if(!i)throw new Error("Code graph missing. Run npm run code:index:test first.");o.import(i.symbols,i.edges);let a=new W({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:r,embeddings:we(),graph:o}),c=await a.initialize(),d=process.argv.slice(2).join(" ")||"memory storage hugging face",l=await a.search(d,5);console.log({ok:!0,query:d,...c,results:l.map(p=>({score:Number(p.score.toFixed(4)),file:p.chunk.filePath,symbol:p.chunk.symbolName,lines:`${p.chunk.startLine}-${p.chunk.endLine}`,preview:p.chunk.content.replace(/\s+/g," ").slice(0,140)}))})}Mt().catch(s=>{console.error(s),process.exit(1)});