toolnet-memory 0.2.19 → 0.2.21

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 qt}from"node:crypto";var $t={critical:100,high:75,normal:50,temporary:20};function Xe(o){return $t[o]}function et(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 Kt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],U=class{scan(e){let t=[];for(let r of Kt){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 Gt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Bt=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 tt(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Bt.has(e)))}function Ut(o,e){let t=tt(o),r=tt(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 rt(o){return new Set(o.tags.filter(e=>!Gt.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=rt(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=rt(n);for(let c of s)if(a.has(c))return!0;return Ut(e.content,n.content)>=.6})}};var zt={critical:100,high:75,normal:50,temporary:20},Ht={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function ot(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 _e(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function Vt(o){return!!o.metadata?.supersededBy}function Ne(o,e=Date.now()){return!_e(o,e)&&!Vt(o)}function L(o,e=Date.now()){if(!Ne(o,e))return 0;let t=zt[o.importance];if(o.importance==="critical")return t;let r=Ht[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var T=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??et(e.type,r),n={id:qt(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:Xe(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??ot(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=>Ne(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&&_e(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 Oe(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=Oe(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Oe(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=Oe(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 st(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 nt(o){return L(o)/100}var Wt={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function it(o){return Wt[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=st(c),p=nt(c),f=it(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 at=[{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=at.find(t=>t.id===o);if(!e)throw new Error(`Unsupported AI provider: ${o}`);return e}function ee(o){return at.some(e=>e.id===o)}function l(o){return process.env[o]?.trim()||void 0}function S(...o){return o.find(e=>!!e?.trim())}function ct(){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 Yt(){let o=l("TOOLNET_LLM_PROVIDER");return o&&ee(o)?o:ct()??"openai-compatible"}function De(o){let e=X(o);switch(o){case"alibaba":return{provider:o,apiKey:S(l("ALIBABA_API_KEY"),l("DASHSCOPE_API_KEY")),baseUrl:S(l("ALIBABA_BASE_URL"),l("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:S(l("ALIBABA_MODEL"),l("DASHSCOPE_MODEL"))};case"openrouter":return{provider:o,apiKey:l("OPENROUTER_API_KEY"),baseUrl:S(l("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:l("OPENROUTER_MODEL")};case"groq":return{provider:o,apiKey:l("GROQ_API_KEY"),baseUrl:S(l("GROQ_BASE_URL"),e.defaultBaseUrl),model:l("GROQ_MODEL")};case"deepseek":return{provider:o,apiKey:l("DEEPSEEK_API_KEY"),baseUrl:S(l("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:S(l("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:o,apiKey:S(l("NVIDIA_API_KEY"),l("NVIDIA_NIM_API_KEY")),baseUrl:S(l("NVIDIA_BASE_URL"),l("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:S(l("NVIDIA_MODEL"),l("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:o,apiKey:S(l("GEMINI_API_KEY"),l("GOOGLE_API_KEY")),baseUrl:S(l("GEMINI_BASE_URL"),e.defaultBaseUrl),model:l("GEMINI_MODEL")};case"huggingface":return{provider:o,apiKey:l("HF_TOKEN"),baseUrl:S(l("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:S(l("HF_LLM_MODEL"),l("HF_MODEL"))};case"ollama":return{provider:o,apiKey:l("OLLAMA_API_KEY"),baseUrl:S(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:S(l("OPENAI_API_KEY"),l("MODEL_API_KEY")),baseUrl:S(l("OPENAI_BASE_URL"),l("MODEL_BASE_URL")),model:S(l("OPENAI_MODEL"),l("MODEL_NAME"))}}}function Jt(){let o=l("TOOLNET_LLM_PROVIDER"),e=o&&ee(o)?o:Yt(),t=X(e),r=De(e);return{provider:e,apiKey:S(l("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:S(l("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:S(l("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:S(l("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function Qt(){let o=l("TOOLNET_EMBEDDING_PROVIDER");return o==="local"?"local":o&&ee(o)?o:l("HF_TOKEN")||l("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Zt(){let o=Qt();if(o==="local")return{provider:"local",model:S(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=De(o).apiKey,r=De(o).baseUrl,s=l(`${o.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=S(l("TOOLNET_EMBEDDING_ACCOUNT_ID"),n),a=S(l("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),c=o==="cloudflare"&&!a&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:a;return{provider:o,apiKey:S(l("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:c,model:S(l("TOOLNET_EMBEDDING_MODEL"),s),accountId:i}}function lt(){let o=Jt(),e=Zt();return{llm:o,embedding:e,legacy:{llm:!l("TOOLNET_LLM_PROVIDER")&&!!ct(),embedding:!l("TOOLNET_EMBEDDING_PROVIDER")&&!!(l("HF_TOKEN")||l("HF_EMBEDDING_MODEL"))}}}var te=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),s=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,n=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!n.ok)throw new Error(`Gemini embedding failed: ${n.status} ${await n.text()}`);let a=(await n.json()).embedding?.values;if(!Array.isArray(a)||a.length===0)throw new Error("Gemini embedding returned invalid response");return a}async embedMany(e){let t=[];for(let r of e)t.push(await this.embed(r));return t}};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 se=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>tr(n))}};function tr(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")}var Fe=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 rr(o){return`https://api.cloudflare.com/client/v4/accounts/${o}/ai/v1`}function or(){let o=lt().embedding;if(o.provider==="local")return null;if(o.provider==="huggingface")return!o.apiKey||!o.model?null:new se({token:o.apiKey,model:o.model});if(o.provider==="gemini")return!o.apiKey||!o.model?null:new te({apiKey:o.apiKey,model:o.model,baseUrl:o.baseUrl});let e=o.baseUrl;return o.provider==="cloudflare"&&!e&&o.accountId&&(e=rr(o.accountId)),e&&o.model?new oe({apiKey:o.apiKey,baseUrl:e,model:o.model}):null}function $e(){return new Fe(or())}import{readdir as ar}from"node:fs/promises";import{extname as cr,join as lr,relative as dr}from"node:path";import{basename as sr}from"node:path";var nr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),ir=new Set([".pem",".key",".p12",".pfx"]);function Ke(o){let e=sr(o).toLowerCase();if(nr.has(e))return!0;for(let t of ir)if(e.endsWith(t))return!0;return!1}var pr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),mr=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Ge(o){let e=[];async function t(r){let s=await ar(r,{withFileTypes:!0});for(let n of s){if(mr.has(n.name))continue;let i=lr(r,n.name);if(n.isDirectory()){await t(i);continue}pr.has(cr(n.name))&&(Ke(i)||e.push(dr(o,i)))}}return await t(o),e.sort()}import{readFile as ur}from"node:fs/promises";import{join as fr}from"node:path";import{createHash as gr}from"node:crypto";import*as y from"typescript";function dt(o,e){return gr("sha256").update(`${o}:${e}`).digest("hex").slice(0,24)}function Be(o,e){return o.getLineAndCharacterOfPosition(e.getStart(o)).line+1}async function Ue(o,e,t){let r=fr(e,t),s=await ur(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:dt(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=dt(o,`${t}:${w}:${E??x}:${u.pos}`);return i.push({id:R,projectId:o,name:x,qualifiedName:E??x,type:w,filePath:t,startLine:Be(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,Ft=g(u,E,"method",R?`${R}.${E}`:E);p.push(Ft),x=!0}if(y.isCallExpression(u)&&(y.isIdentifier(u.expression)&&c.push({callerId:p.at(-1),calleeName:u.expression.text,line:Be(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:Be(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 hr}from"node:crypto";import{dirname as yr,extname as br,normalize as Sr,posix as vr}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 Er(o,e,t,r){return hr("sha256").update(`${o}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function I(o){return Sr(o).replaceAll("\\","/")}function ze(o,e,t){if(!e.startsWith("."))return;let r=I(vr.join(yr(o),e)),s=br(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=ze(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=ze(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=ze(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:Er(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:n}}};function pt(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 ne=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function xr(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 ie=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=>xr(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 wr={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Cr(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function mt(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var ae=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=wr[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(mt);return d.length===0&&d.push(...c.filter(m=>!mt(m)).slice(0,10)),{risk:Cr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:d}}};import{execFile as Pr}from"node:child_process";import{promisify as Rr}from"node:util";var He=Rr(Pr);function Ar(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 Ir(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function ut(o){let e="";try{e=(await He("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 He("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Ir(s),ranges:Ar(a)})}try{let r=await He("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 ce=class{constructor(e){this.graph=e;this.mapper=new ie(e),this.blast=new ae(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await ut(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 kr=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,Tr=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function ft(o){return o.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function jr(o){return o.length>0&&o.length<500&&!o.includes(`
4
- `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(o)}function Mr(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(ft(s[1]));return e}function Ve(o,e,t){if(typeof o=="string"){let r=t?.toLowerCase();if(r&&Tr.has(r)&&jr(o)&&e.add(ft(o)),o.includes("*** Update File:")||o.includes("*** Add File:")||o.includes("*** Delete File:")||o.includes("+++ b/"))for(let s of Mr(o))e.add(s);return}if(Array.isArray(o)){for(let r of o)Ve(r,e,t);return}if(o&&typeof o=="object")for(let[r,s]of Object.entries(o))Ve(s,e,r)}function Lr(o){return kr.test(o.toLowerCase())}function gt(o,e){if(!Lr(o))return[];let t=new Set;return Ve(e,t),[...t]}import{createHash as _r}from"node:crypto";import{readFile as Nr}from"node:fs/promises";async function ht(o){let e=await Nr(o);return _r("sha256").update(e).digest("hex")}function yt(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 Or}from"node:path";async function bt(o,e){let t=await Ge(e),r={};for(let s of t)r[s]={path:s,hash:await ht(Or(e,s))};return{version:1,projectId:o,updatedAt:new Date().toISOString(),files:r}}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 le=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 de=class{constructor(e){this.storage=e}storage;async index(e,t){let r=new le(this.storage),s=new j(this.storage),n=await r.load(e),i=await s.load(e),a=await bt(e,t),c=yt(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 Ue(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=Dr(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 Dr(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 b from"typescript";var Pi=new Set([b.SyntaxKind.EqualsToken,b.SyntaxKind.PlusEqualsToken,b.SyntaxKind.MinusEqualsToken,b.SyntaxKind.AsteriskEqualsToken,b.SyntaxKind.SlashEqualsToken,b.SyntaxKind.PercentEqualsToken,b.SyntaxKind.QuestionQuestionEqualsToken,b.SyntaxKind.AmpersandAmpersandEqualsToken,b.SyntaxKind.BarBarEqualsToken]);var pe=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 pe(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 me=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 $r}from"node:crypto";var ue=class{seen=new Set;fingerprint(e){return $r("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 Kr}from"node:crypto";var fe=class{constructor(e){this.queue=e}queue;sanitizer=new k;capture(e,t,r={}){let s={id:Kr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(s),s}};import{randomUUID as Gr}from"node:crypto";var ge=class{constructor(e){this.capture=e}capture;sessionId=Gr();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 he=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 qe(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 We(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 Ye(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 ye(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 be(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=>be(String(c.data.command??"")))),s=D(e.filter(c=>c.type==="error").map(c=>be(String(c.data.message??"")))),n=D(e.filter(c=>c.type==="decision").map(c=>be(String(c.data.content??"")))),i=D(e.filter(c=>c.type==="todo").map(c=>be(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 ve=class{constructor(e){this.memory=e}memory;extractor=new he;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:ye(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:ye(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 qe(t)?"rule":Ye(t)?"todo":We(t)?"decision":e}detectPromptMemoryType(e){return qe(e)?"rule":Ye(e)?"todo":We(e)?"decision":null}};import{createHash as Br}from"node:crypto";function Ur(o){return Br("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=Ur(r);e.has(s)||(e.add(s),t.push(r))}return t}var Ee=class{projectId;memory;memoryStore;queue=new me;capture=new fe(this.queue);session=new ge(this.capture);processor;dedup=new ue;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new ve(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 xe=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=pt(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}
1
+ import{randomUUID as nr}from"node:crypto";var zt={critical:100,high:75,normal:50,temporary:20};function tt(o){return zt[o]}function rt(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 Ht=[{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 Ht){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 I=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 Vt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),qt=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 ot(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!qt.has(e)))}function Wt(o,e){let t=ot(o),r=ot(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 st(o){return new Set(o.tags.filter(e=>!Vt.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=st(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=st(n);for(let c of s)if(a.has(c))return!0;return Wt(e.content,n.content)>=.6})}};var Yt=new Set(["code","decision","rule","todo","summary"]);function Jt(o){return o.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function nt(o){return o.tags.includes("class:permanent")?4:o.tags.includes("class:task")?3:o.tags.includes("class:session")?2:o.tags.includes("class:transient")?1:0}function Qt(o,e){let t=nt(e)-nt(o);if(t!==0)return t;let r=e.importanceScore-o.importanceScore;if(r!==0)return r;let s=e.updatedAt.localeCompare(o.updatedAt);if(s!==0)return s;let n=e.createdAt.localeCompare(o.createdAt);return n!==0?n:o.id.localeCompare(e.id)}function it(o){let e=new Set,t=[];for(let r of o){let s=r.trim();if(!s)continue;let n=s.normalize("NFKC").toLowerCase();e.has(n)||(e.add(n),t.push(s))}return t}function at(o){let e=new Map;for(let s of o){if(!Yt.has(s.type)||s.metadata?.supersededBy)continue;let n=Jt(s.content);if(!n)continue;let i=[s.projectId,s.type,n].join("\0"),a=e.get(i)??[];a.push(s),e.set(i,a)}let t=[],r=0;for(let s of e.values()){if(s.length<2)continue;let n=[...s].sort(Qt),i=n[0];if(!i)continue;let a=n.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:it(n.flatMap(c=>c.tags)),mergedSources:it(n.map(c=>c.source))}),r+=a.length}return{groups:t,duplicates:r}}function _e(o){if(o.tags.includes("class:permanent"))return"permanent";if(o.tags.includes("class:task"))return"task";if(o.tags.includes("class:session"))return"session";if(o.tags.includes("class:transient"))return"transient"}function Zt(o,e){let t=new Date(o.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Xt(o){let e=_e(o);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(o.type){case"rule":return 730;case"decision":return 365;case"code":return 180;case"todo":return 120;case"summary":return 45;case"activity":return 14}}function er(o){return _e(o)==="permanent"||o.type==="rule"||o.type==="decision"||o.importance==="critical"}function tr(o){let e=o.normalize("NFKC").toLowerCase().trim();return e.length<8?!0:[/^ok(?:ay)?[.!]?$/u,/^done[.!]?$/u,/^thanks?[.!]?$/u,/^test(?:ing)?[.!]?$/u,/^npm notice\b/u,/^changed \d+ packages?/u,/^packages? are looking for funding/u].some(t=>t.test(e))}function ct(o,e=Date.now()){let t=50,r=[],s=_e(o);switch(s==="permanent"?(t+=25,r.push("permanent project knowledge")):s==="task"?(t+=15,r.push("active task knowledge")):s==="session"?(t+=2,r.push("session-scoped knowledge")):s==="transient"&&(t-=25,r.push("transient knowledge")),o.importance){case"critical":t+=25,r.push("critical importance");break;case"high":t+=15,r.push("high importance");break;case"normal":break;case"temporary":t-=15,r.push("temporary importance");break}(o.type==="rule"||o.type==="decision")&&(t+=10,r.push("durable knowledge type"));let n=o.content.trim().length;n<12?(t-=30,r.push("very short content")):n<30?(t-=10,r.push("limited context")):n<=1200?(t+=8,r.push("useful context density")):n>5e3&&(t-=15,r.push("excessively large memory")),tr(o.content)&&(t-=35,r.push("matches transient/noise pattern"));let i=o.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,r.push("confirmed across multiple sources"));let a=Zt(o,e)>=Xt(o);a&&(t-=15,r.push("stale for lifecycle class"));let c=er(o);t=Math.max(0,Math.min(100,Math.round(t)));let l;t>=80?l="trusted":t>=55?l="useful":t>=30?l="weak":l="noise";let m=o.importance==="temporary"||o.type==="activity"||s==="transient";return{score:t,tier:l,stale:a,protected:c,pruneEligible:!c&&(l==="noise"&&m||a&&(l==="noise"||l==="weak")),reasons:r}}var rr={critical:100,high:75,normal:50,temporary:20},or={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function lt(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 Ne(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function sr(o){return!!o.metadata?.supersededBy}function Oe(o,e=Date.now()){return!Ne(o,e)&&!sr(o)}function j(o,e=Date.now()){if(!Oe(o,e))return 0;let t=rr[o.importance];if(o.importance==="critical")return t;let r=or[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var A=class{memories=new Map;sanitizer=new I;conflicts=new z;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??rt(e.type,r),n={id:nr(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:tt(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??lt(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=>Oe(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=j(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,l=j(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)}consolidate(e,t=Date.now()){let r=at(this.list(e)),s=[],n=0;for(let i of r.groups){let a=this.memories.get(i.canonicalId);if(a){a.tags=i.mergedTags,a.metadata={...a.metadata??{},consolidation:{version:1,consolidatedAt:new Date(t).toISOString(),mergedIds:i.duplicateIds,sources:i.mergedSources}},this.memories.set(a.id,a),s.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(n+=1)}}return{groupsConsolidated:s.length,duplicatesRemoved:n,canonicalIds:s}}reviewLifecycle(e,t=Date.now()){let r={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let s of this.list(e)){let n=ct(s,t);r.reviewed+=1,r[n.tier]+=1,n.stale&&(r.stale+=1),n.protected&&(r.protected+=1),s.metadata={...s.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:n.score,tier:n.tier,stale:n.stale,protected:n.protected,reasons:n.reasons}},this.memories.set(s.id,s),n.pruneEligible&&this.memories.delete(s.id)&&(r.pruned+=1)}return r}pruneExpired(e,t=Date.now()){let r=0;for(let[s,n]of this.memories)n.projectId===e&&Ne(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.consolidate(e),s=this.memory.pruneSuperseded(e,30),n=this.memory.reviewLifecycle(e);return{expiredRemoved:t,supersededRemoved:s,groupsConsolidated:r.groupsConsolidated,duplicatesRemoved:r.duplicatesRemoved,lifecycleReviewed:n.reviewed,lifecyclePruned:n.pruned,quality:{trusted:n.trusted,useful:n.useful,weak:n.weak,noise:n.noise,stale:n.stale,protected:n.protected},active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function De(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,l=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:l,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=De(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=De(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=De(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 dt(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 pt(o){return j(o)/100}var ir={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function mt(o){return ir[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 l=this.bm25.score(e,c),m=dt(c),p=pt(c),f=mt(c.type);i.preferredTypes.includes(c.type)&&(f=Math.min(1,f+.25));let g=l*.55+p*.2+m*.15+f*.1;l<=0||g<n||a.push({memory:c,score:g,scores:{keyword:l,recency:m,importance:p,type:f}})}return a.sort((c,l)=>l.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 ut=[{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=ut.find(t=>t.id===o);if(!e)throw new Error(`Unsupported AI provider: ${o}`);return e}function ee(o){return ut.some(e=>e.id===o)}function d(o){return process.env[o]?.trim()||void 0}function S(...o){return o.find(e=>!!e?.trim())}function ft(){if(d("GROQ_API_KEY"))return"groq";if(d("DEEPSEEK_API_KEY"))return"deepseek";if(d("NVIDIA_API_KEY")||d("NVIDIA_NIM_API_KEY"))return"nvidia";if(d("OPENROUTER_API_KEY"))return"openrouter";if(d("ALIBABA_API_KEY")||d("DASHSCOPE_API_KEY"))return"alibaba";if(d("GEMINI_API_KEY")||d("GOOGLE_API_KEY"))return"gemini";if(d("CLOUDFLARE_API_TOKEN")&&d("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(d("HF_TOKEN"))return"huggingface";if(d("OLLAMA_MODEL")||d("OLLAMA_BASE_URL"))return"ollama"}function ar(){let o=d("TOOLNET_LLM_PROVIDER");return o&&ee(o)?o:ft()??"openai-compatible"}function Fe(o){let e=X(o);switch(o){case"alibaba":return{provider:o,apiKey:S(d("ALIBABA_API_KEY"),d("DASHSCOPE_API_KEY")),baseUrl:S(d("ALIBABA_BASE_URL"),d("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:S(d("ALIBABA_MODEL"),d("DASHSCOPE_MODEL"))};case"openrouter":return{provider:o,apiKey:d("OPENROUTER_API_KEY"),baseUrl:S(d("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:d("OPENROUTER_MODEL")};case"groq":return{provider:o,apiKey:d("GROQ_API_KEY"),baseUrl:S(d("GROQ_BASE_URL"),e.defaultBaseUrl),model:d("GROQ_MODEL")};case"deepseek":return{provider:o,apiKey:d("DEEPSEEK_API_KEY"),baseUrl:S(d("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:S(d("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:o,apiKey:S(d("NVIDIA_API_KEY"),d("NVIDIA_NIM_API_KEY")),baseUrl:S(d("NVIDIA_BASE_URL"),d("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:S(d("NVIDIA_MODEL"),d("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:o,apiKey:S(d("GEMINI_API_KEY"),d("GOOGLE_API_KEY")),baseUrl:S(d("GEMINI_BASE_URL"),e.defaultBaseUrl),model:d("GEMINI_MODEL")};case"huggingface":return{provider:o,apiKey:d("HF_TOKEN"),baseUrl:S(d("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:S(d("HF_LLM_MODEL"),d("HF_MODEL"))};case"ollama":return{provider:o,apiKey:d("OLLAMA_API_KEY"),baseUrl:S(d("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:d("OLLAMA_MODEL")};case"cloudflare":return{provider:o,accountId:d("CLOUDFLARE_ACCOUNT_ID"),apiKey:d("CLOUDFLARE_API_TOKEN"),baseUrl:d("CLOUDFLARE_AI_BASE_URL"),model:d("CLOUDFLARE_MODEL")};case"custom":return{provider:o,apiKey:d("CUSTOM_AI_API_KEY"),baseUrl:d("CUSTOM_AI_BASE_URL"),model:d("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:S(d("OPENAI_API_KEY"),d("MODEL_API_KEY")),baseUrl:S(d("OPENAI_BASE_URL"),d("MODEL_BASE_URL")),model:S(d("OPENAI_MODEL"),d("MODEL_NAME"))}}}function cr(){let o=d("TOOLNET_LLM_PROVIDER"),e=o&&ee(o)?o:ar(),t=X(e),r=Fe(e);return{provider:e,apiKey:S(d("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:S(d("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:S(d("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:S(d("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function lr(){let o=d("TOOLNET_EMBEDDING_PROVIDER");return o==="local"?"local":o&&ee(o)?o:d("HF_TOKEN")||d("HF_EMBEDDING_MODEL")?"huggingface":"local"}function dr(){let o=lr();if(o==="local")return{provider:"local",model:S(d("TOOLNET_EMBEDDING_MODEL"),d("LOCAL_EMBEDDING_MODEL"))};let e=X(o),t,r,s,n;switch(o){case"huggingface":t=d("HF_TOKEN"),r=d("HF_INFERENCE_BASE_URL"),s=d("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=d("OPENAI_API_KEY"),r=d("OPENAI_BASE_URL"),s=d("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=d("CLOUDFLARE_API_TOKEN"),r=d("CLOUDFLARE_AI_BASE_URL"),s=d("CLOUDFLARE_EMBEDDING_MODEL"),n=d("CLOUDFLARE_ACCOUNT_ID");break;default:t=Fe(o).apiKey,r=Fe(o).baseUrl,s=d(`${o.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=S(d("TOOLNET_EMBEDDING_ACCOUNT_ID"),n),a=S(d("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),c=o==="cloudflare"&&!a&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:a;return{provider:o,apiKey:S(d("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:c,model:S(d("TOOLNET_EMBEDDING_MODEL"),s),accountId:i}}function gt(){let o=cr(),e=dr();return{llm:o,embedding:e,legacy:{llm:!d("TOOLNET_LLM_PROVIDER")&&!!ft(),embedding:!d("TOOLNET_EMBEDDING_PROVIDER")&&!!(d("HF_TOKEN")||d("HF_EMBEDDING_MODEL"))}}}var te=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),s=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,n=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!n.ok)throw new Error(`Gemini embedding failed: ${n.status} ${await n.text()}`);let a=(await n.json()).embedding?.values;if(!Array.isArray(a)||a.length===0)throw new Error("Gemini embedding returned invalid response");return a}async embedMany(e){let t=[];for(let r of e)t.push(await this.embed(r));return t}};import{createHash as pr}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=pr("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return mr(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function mr(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 se=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,r=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>ur(n))}};function ur(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")}var $e=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 fr(o){return`https://api.cloudflare.com/client/v4/accounts/${o}/ai/v1`}function gr(){let o=gt().embedding;if(o.provider==="local")return null;if(o.provider==="huggingface")return!o.apiKey||!o.model?null:new se({token:o.apiKey,model:o.model});if(o.provider==="gemini")return!o.apiKey||!o.model?null:new te({apiKey:o.apiKey,model:o.model,baseUrl:o.baseUrl});let e=o.baseUrl;return o.provider==="cloudflare"&&!e&&o.accountId&&(e=fr(o.accountId)),e&&o.model?new oe({apiKey:o.apiKey,baseUrl:e,model:o.model}):null}function Ke(){return new $e(gr())}import{readdir as Sr}from"node:fs/promises";import{extname as vr,join as xr,relative as Er}from"node:path";import{basename as hr}from"node:path";var yr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),br=new Set([".pem",".key",".p12",".pfx"]);function Be(o){let e=hr(o).toLowerCase();if(yr.has(e))return!0;for(let t of br)if(e.endsWith(t))return!0;return!1}var wr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Cr=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Ge(o){let e=[];async function t(r){let s=await Sr(r,{withFileTypes:!0});for(let n of s){if(Cr.has(n.name))continue;let i=xr(r,n.name);if(n.isDirectory()){await t(i);continue}wr.has(vr(n.name))&&(Be(i)||e.push(Er(o,i)))}}return await t(o),e.sort()}import{readFile as Pr}from"node:fs/promises";import{join as kr}from"node:path";import{createHash as Rr}from"node:crypto";import*as y from"typescript";function ht(o,e){return Rr("sha256").update(`${o}:${e}`).digest("hex").slice(0,24)}function Ue(o,e){return o.getLineAndCharacterOfPosition(e.getStart(o)).line+1}async function ze(o,e,t){let r=kr(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=[],l=[],m={id:ht(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,E,w,x){let k=ht(o,`${t}:${w}:${x??E}:${u.pos}`);return i.push({id:k,projectId:o,name:E,qualifiedName:x??E,type:w,filePath:t,startLine:Ue(n,u),endLine:n.getLineAndCharacterOfPosition(u.end).line+1}),k}function C(u){if(!y.isStringLiteral(u.moduleSpecifier))return;let E=[],w=u.importClause;if(w?.name&&E.push({localName:w.name.text,importedName:"default",kind:"default"}),w?.namedBindings&&y.isNamedImports(w.namedBindings))for(let x of w.namedBindings.elements)E.push({localName:x.name.text,importedName:x.propertyName?.text??x.name.text,kind:"named"});w?.namedBindings&&y.isNamespaceImport(w.namedBindings)&&E.push({localName:w.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:u.moduleSpecifier.text,bindings:E})}function v(u,E){for(let w of u.heritageClauses??[])for(let x of w.types){let k=x.expression.getText(n).split(".").at(-1)??"";k&&l.push({fromId:E,targetName:k,type:w.token===y.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function h(u){let E=!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 x=g(u,u.name.text,"class",u.name.text);v(u,x),f.push({id:x,name:u.name.text}),w=!0}if(y.isFunctionDeclaration(u)&&u.name){let x=g(u,u.name.text,"function",u.name.text);p.push(x),E=!0}if(y.isMethodDeclaration(u)&&u.name){let x=u.name.getText(n),k=f.at(-1)?.name,Ut=g(u,x,"method",k?`${k}.${x}`:x);p.push(Ut),E=!0}if(y.isCallExpression(u)&&(y.isIdentifier(u.expression)&&c.push({callerId:p.at(-1),calleeName:u.expression.text,line:Ue(n,u)}),y.isPropertyAccessExpression(u.expression))){let x=u.expression;c.push({callerId:p.at(-1),qualifier:x.expression.getText(n),calleeName:x.name.text,line:Ue(n,u)})}y.forEachChild(u,h),E&&p.pop(),w&&f.pop()}return h(n),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as Mr}from"node:crypto";import{dirname as Ir,extname as Ar,normalize as Tr,posix as Lr}from"node:path";var R=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function jr(o,e,t,r){return Mr("sha256").update(`${o}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function M(o){return Tr(o).replaceAll("\\","/")}function He(o,e,t){if(!e.startsWith("."))return;let r=M(Lr.join(Ir(o),e)),s=Ar(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(M(i)))}var _=class{build(e,t){let r=new R,s=new Map;for(let i of t)for(let a of i.symbols)r.addSymbol(a),a.type==="file"&&s.set(M(i.filePath),a);let n=new Set(s.keys());for(let i of t){let a=M(i.filePath),c=s.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 m=He(a,l.source,n);if(!m)continue;let p=s.get(m);p&&r.addEdge(this.edge(e,c.id,"IMPORTS",p.id,{source:l.source}))}for(let l of i.heritage){let m=r.findByName(e,l.targetName).filter(p=>p.type==="class"||p.type==="interface");for(let p of m)r.addEdge(this.edge(e,l.fromId,l.type,p.id))}for(let l of i.calls){if(!l.callerId)continue;let m=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let p of m)p.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",p.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,n,i,a){let c=M(t.filePath),l=i.findByName(e,r).filter(m=>M(m.filePath)===c);if(!s&&l.length)return l;if(s)for(let m of t.imports){if(!m.bindings.find(g=>g.kind==="namespace"&&g.localName===s))continue;let f=He(c,m.source,a);if(f)return i.findByName(e,r).filter(g=>M(g.filePath)===f)}for(let m of t.imports){let p=m.bindings.find(v=>v.localName===r);if(!p)continue;let f=He(c,m.source,a);if(!f)continue;let g=p.importedName==="default"?r:p.importedName,C=i.findByName(e,g).filter(v=>M(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:jr(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:n}}};function yt(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 ne=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function _r(o,e){return e.ranges.length===0?!0:typeof o.startLine!="number"||typeof o.endLine!="number"?!1:e.ranges.some(t=>o.startLine<=t.endLine&&o.endLine>=t.startLine)}var ie=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let n of t){let i=r.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>_r(l,n));if(c.length===0){let l=i.find(m=>m.type==="file");l&&s.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:n.status,direct:!0})}return s}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Nr={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Or(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function bt(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var ae=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,E=`${m.symbol.id}:${h.id}`;n.set(E,{symbol:h,relation:v.type,depth:u,sourceSymbolId:m.symbol.id});let w=Nr[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))],l=c.filter(bt);return l.length===0&&l.push(...c.filter(m=>!bt(m)).slice(0,10)),{risk:Or(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as Dr}from"node:child_process";import{promisify as Fr}from"node:util";var Ve=Fr(Dr);function $r(o){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of o.matchAll(t)){let s=Number(r[1]),n=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function Kr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function St(o){let e="";try{e=(await Ve("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 Ve("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Kr(s),ranges:$r(a)})}try{let r=await Ve("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 ce=class{constructor(e){this.graph=e;this.mapper=new ie(e),this.blast=new ae(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await St(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 Br=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,Gr=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function vt(o){return o.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function Ur(o){return o.length>0&&o.length<500&&!o.includes(`
4
+ `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(o)}function zr(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(vt(s[1]));return e}function qe(o,e,t){if(typeof o=="string"){let r=t?.toLowerCase();if(r&&Gr.has(r)&&Ur(o)&&e.add(vt(o)),o.includes("*** Update File:")||o.includes("*** Add File:")||o.includes("*** Delete File:")||o.includes("+++ b/"))for(let s of zr(o))e.add(s);return}if(Array.isArray(o)){for(let r of o)qe(r,e,t);return}if(o&&typeof o=="object")for(let[r,s]of Object.entries(o))qe(s,e,r)}function Hr(o){return Br.test(o.toLowerCase())}function xt(o,e){if(!Hr(o))return[];let t=new Set;return qe(e,t),[...t]}import{createHash as Vr}from"node:crypto";import{readFile as qr}from"node:fs/promises";async function Et(o){let e=await qr(o);return Vr("sha256").update(e).digest("hex")}function wt(o,e){let t=o?.files??{},r=e.files,s=[],n=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let m=t[c];m?m.hash!==l.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 Wr}from"node:path";async function Ct(o,e){let t=await Ge(e),r={};for(let s of t)r[s]={path:s,hash:await Et(Wr(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 le=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 de=class{constructor(e){this.storage=e}storage;async index(e,t){let r=new le(this.storage),s=new T(this.storage),n=await r.load(e),i=await s.load(e),a=await Ct(e,t),c=wt(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 m=i?.symbols.filter(h=>c.unchanged.includes(h.filePath))??[],p=[];for(let h of l)p.push(await ze(e,t,h));let f=new _().build(e,p),g=new R;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)&&!l.includes(i.symbols.find(u=>u.id===h.from)?.filePath??"")&&!l.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:l.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=Yr(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 Yr(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 b from"typescript";var Bi=new Set([b.SyntaxKind.EqualsToken,b.SyntaxKind.PlusEqualsToken,b.SyntaxKind.MinusEqualsToken,b.SyntaxKind.AsteriskEqualsToken,b.SyntaxKind.SlashEqualsToken,b.SyntaxKind.PercentEqualsToken,b.SyntaxKind.QuestionQuestionEqualsToken,b.SyntaxKind.AmpersandAmpersandEqualsToken,b.SyntaxKind.BarBarEqualsToken]);var pe=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 pe(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),l=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:l,updatedAt:new Date().toISOString(),records:c}),m=!0),{loaded:t,indexed:a,removed:n,total:c.length,saved:m}}};var me=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 Qr}from"node:crypto";var ue=class{seen=new Set;fingerprint(e){return Qr("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 Zr}from"node:crypto";var fe=class{constructor(e){this.queue=e}queue;sanitizer=new I;capture(e,t,r={}){let s={id:Zr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(s),s}};import{randomUUID as Xr}from"node:crypto";var ge=class{constructor(e){this.capture=e}capture;sessionId=Xr();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 he=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 We(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 Ye(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 Je(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 ye(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 be(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=>be(String(c.data.command??"")))),s=D(e.filter(c=>c.type==="error").map(c=>be(String(c.data.message??"")))),n=D(e.filter(c=>c.type==="decision").map(c=>be(String(c.data.content??"")))),i=D(e.filter(c=>c.type==="todo").map(c=>be(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 ve=class{constructor(e){this.memory=e}memory;extractor=new he;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:ye(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:ye(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 We(t)?"rule":Je(t)?"todo":Ye(t)?"decision":e}detectPromptMemoryType(e){return We(e)?"rule":Je(e)?"todo":Ye(e)?"decision":null}};import{createHash as eo}from"node:crypto";function to(o){return eo("sha256").update([o.projectId,o.type,o.content.trim().toLowerCase()].join("|")).digest("hex")}function Pt(o){let e=new Set,t=[];for(let r of o){let s=to(r);e.has(s)||(e.add(s),t.push(r))}return t}var xe=class{projectId;memory;memoryStore;queue=new me;capture=new fe(this.queue);session=new ge(this.capture);processor;dedup=new ue;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new ve(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=Pt(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,l=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=yt(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 l)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 E=`[${h.memory.type.toUpperCase()}] ${h.memory.content}`;C.includes(E)||C.push(E)}let v="";for(let h of C){let u=v.length===0?h:`${v}
6
6
  ${h}`;if(u.length>c)break;v=u}return v}};var we=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 vt={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},Ce=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=gt(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)vt[p.risk]>vt[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 uo}from"node:os";import{join as fo}from"node:path";import{DeleteObjectCommand as zr,GetObjectCommand as Hr,HeadObjectCommand as Vr,ListObjectsV2Command as qr,PutObjectCommand as Wr,S3Client as Yr}from"@aws-sdk/client-s3";import{getSignedUrl as Jr}from"@aws-sdk/s3-request-presigner";var Pe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Yr({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 Wr({Bucket:this.bucket,Key:e,Body:s,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(`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 Vr({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 zr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new qr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as Et,mkdir as Qr,readFile as Zr,readdir as Xr,rm as eo,stat as xt,writeFile as to}from"node:fs/promises";import{dirname as ro,join as oo,relative as wt,resolve as so}from"node:path";var F=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return so(this.root,t)}async put(e,t){let r=this.path(e);await Qr(ro(r),{recursive:!0}),await to(r,t)}async get(e){try{return await Zr(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await Et(this.path(e)),!0}catch{return!1}}async delete(e){await eo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Et(t)}catch{return r}let s=async i=>{let a=await Xr(i,{withFileTypes:!0});for(let c of a){let d=oo(i,c.name);if(c.isDirectory()){await s(d);continue}let m=await xt(d);r.push({key:wt(this.root,d),size:m.size,updatedAt:m.mtime.toISOString()})}},n=await xt(t);return n.isDirectory()?await s(t):r.push({key:wt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as no,GetObjectCommand as io,HeadObjectCommand as ao,ListObjectsV2Command as co,PutObjectCommand as lo,S3Client as po}from"@aws-sdk/client-s3";import{getSignedUrl as mo}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 po({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 lo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await mo(this.client,new io({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 ao({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 no({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new co({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 Je(o,e){return console.warn(e),new F(o)}function Ct(o){let e=o.localRoot??fo(uo(),".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}):Je(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}):Je(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 Pe({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Je(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 Re=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 go(o){return new Promise(e=>setTimeout(e,o))}async function Pt(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 go(c+d)}throw n}var ho=new Set(["put","get","getText","delete","list"]);function Rt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:ho.has(r)?(...n)=>Pt(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function At(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 It(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 Ae=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=At(s??r),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),r=t,s=await this.provider.getText(e);if(s){let 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=It(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};function bo(o){let e=o.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function So(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 kt(o,e){let t=await So(o,e),r=new M(e),s=await r.load(o.id),n=new T;n.importRecords(s);let i=new Set(s.map(m=>bo(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 vo=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],Ie=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 vo){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 Eo,mkdirSync as xo,openSync as wo,readFileSync as Co,unlinkSync as Tt,writeFileSync as Po}from"node:fs";import{tmpdir as Ro}from"node:os";import{join as jt}from"node:path";function Ao(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var ke=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=jt(Ro(),"toolnet-memory-locks");xo(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=wo(this.path,"wx");Po(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Eo(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(Co(this.path,"utf8"));Number.isInteger(s.pid)&&Ao(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{Tt(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{Tt(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var Te=class{constructor(e){this.options=e;this.memoryStore=new M(e.storage),this.graphStore=new j(e.storage),this.vectorStore=new Re(e.storage),this.processLock=new ke(e.project.id),this.retrieval=new Z(this.memory),this.references=new ne(this.graph),this.hooks=new Ee({projectId:e.project.id,memory:this.memory,memoryStore:this.memoryStore,maxEventsBeforeFlush:100});let t=new xe(this.memory,this.retrieval,this.graph);this.autoRetrieval=new we(this.hooks,t,e.project.id),this.impactGuard=new ce(this.graph),this.autoImpactGuard=new Ce(this.impactGuard,e.project.id)}options;memory=new T;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 kt(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=$e(),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 Ie(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 de(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=$e(),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 Io,readFileSync as ko}from"node:fs";import{homedir as To}from"node:os";import{join as jo}from"node:path";function Mo(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 Lo(){let o=process.env.TOOLNET_GLOBAL_ENV??jo(To(),".config","toolnet-memory",".env");if(!Io(o))return;let e=ko(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]=Mo(r.slice(s+1)))}}Lo();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 Mt(){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 _o}from"node:crypto";import{existsSync as Qe,mkdirSync as No,readFileSync as Oo,renameSync as Do,writeFileSync as Fo}from"node:fs";import{basename as $o,dirname as je,join as Le,parse as Nt,resolve as B}from"node:path";var Ot=".toolnet",Ko="project.json";function Go(o){return _o("sha256").update(o).digest("hex").slice(0,16)}function Ze(o){return Le(o,Ot,Ko)}function Bo(o){return Qe(Ze(o))}function Uo(o,e){let t=B(o),r=Nt(t).root;for(;;){if(Bo(t))return t;if(t===r||e&&t===B(e))break;let s=je(t);if(s===t)break;t=s}return null}function zo(o){let e=B(o),t=Nt(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Qe(Le(e,n))))return e;if(e===t)break;let s=je(e);if(s===e)break;e=s}return B(o)}function Ho(o){let e;try{e=JSON.parse(Oo(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 Lt(o,e){let t=Le(o,Ot);No(t,{recursive:!0});let r=Ze(o),s=`${r}.tmp-${process.pid}`;Fo(s,JSON.stringify(e,null,2)+`
11
- `,{encoding:"utf8",mode:384}),Do(s,r)}function _t(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 Me=class{detect(e=process.cwd()){let t=B(e),r=zo(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>Qe(Le(r,m))),i=Uo(t,n?r:void 0);if(i){let m=Ze(i),p=Ho(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Lt(i,p)),_t(p,i)}let a=new Date().toISOString(),c=$o(r),d={version:1,id:Go(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Lt(r,d),_t(d,r)}};function Dt(o=process.cwd()){let e=Mt(),t=new Me().detect(o),r=Ct({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),s=Rt(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),n=new Ae(s,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new Te({project:t,storage:n,embeddingModel:i})}async function Vo(){let o=Dt(),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})}Vo().catch(o=>{console.error(o),process.exit(1)});
7
+ `):e}}};var kt={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},Ce=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=xt(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)kt[p.risk]>kt[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),l=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}`)),l&&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:l,context:m.join(`
8
+ `)}}};import{homedir as Po}from"node:os";import{join as ko}from"node:path";import{DeleteObjectCommand as ro,GetObjectCommand as oo,HeadObjectCommand as so,ListObjectsV2Command as no,PutObjectCommand as io,S3Client as ao}from"@aws-sdk/client-s3";import{getSignedUrl as co}from"@aws-sdk/s3-request-presigner";var Pe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new ao({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 io({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await co(this.client,new oo({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 so({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 ro({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new no({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 Rt,mkdir as lo,readFile as po,readdir as mo,rm as uo,stat as Mt,writeFile as fo}from"node:fs/promises";import{dirname as go,join as ho,relative as It,resolve as yo}from"node:path";var F=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return yo(this.root,t)}async put(e,t){let r=this.path(e);await lo(go(r),{recursive:!0}),await fo(r,t)}async get(e){try{return await po(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 Rt(this.path(e)),!0}catch{return!1}}async delete(e){await uo(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Rt(t)}catch{return r}let s=async i=>{let a=await mo(i,{withFileTypes:!0});for(let c of a){let l=ho(i,c.name);if(c.isDirectory()){await s(l);continue}let m=await Mt(l);r.push({key:It(this.root,l),size:m.size,updatedAt:m.mtime.toISOString()})}},n=await Mt(t);return n.isDirectory()?await s(t):r.push({key:It(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as bo,GetObjectCommand as So,HeadObjectCommand as vo,ListObjectsV2Command as xo,PutObjectCommand as Eo,S3Client as wo}from"@aws-sdk/client-s3";import{getSignedUrl as Co}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 wo({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 Eo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Co(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 vo({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new bo({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new xo({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 Qe(o,e){return console.warn(e),new F(o)}function At(o){let e=o.localRoot??ko(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}):Qe(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}):Qe(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 Pe({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Qe(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new F(e)}var L=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 ke=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 Ro(o){return new Promise(e=>setTimeout(e,o))}async function Tt(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Ro(c+l)}throw n}var Mo=new Set(["put","get","getText","delete","list"]);function Lt(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Mo.has(r)?(...n)=>Tt(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function jt(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 _t(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=jt(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=_t(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 Ao(o){let e=o.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function To(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 Nt(o,e){let t=await To(o,e),r=new L(e),s=await r.load(o.id),n=new A;n.importRecords(s);let i=new Set(s.map(m=>Ao(m)).filter(m=>!!m)),a=0,c=0,l=0;for(let m of t)for(let p of m.candidates){if(a+=1,i.has(p.fingerprint)){l+=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:l,memories:n.exportProject(o.id).length}}import{existsSync as Lo,readFileSync as jo}from"node:fs";import{homedir as _o}from"node:os";import{join as No}from"node:path";function Oo(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 Do(){let o=process.env.TOOLNET_GLOBAL_ENV??No(_o(),".config","toolnet-memory",".env");if(!Lo(o))return;let e=jo(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]=Oo(r.slice(s+1)))}}Do();function K(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function B(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function Ze(){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:B(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:B(process.env.MEMORY_RERANK_TOP,10),finalContext:B(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:B(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:B(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Fo=["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"],Me=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 Fo){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 l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};import{closeSync as $o,mkdirSync as Ko,openSync as Bo,readFileSync as Go,unlinkSync as Ot,writeFileSync as Uo}from"node:fs";import{tmpdir as zo}from"node:os";import{join as Dt}from"node:path";function Ho(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=Dt(zo(),"toolnet-memory-locks");Ko(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=Dt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Bo(this.path,"wx");Uo(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),$o(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(Go(this.path,"utf8"));Number.isInteger(s.pid)&&Ho(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{Ot(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{Ot(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var Ae=class{constructor(e){this.options=e;this.memoryStore=new L(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new ke(e.storage),this.processLock=new Ie(e.project.id),this.retrieval=new Z(this.memory),this.references=new ne(this.graph),this.hooks=new xe({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 we(this.hooks,t,e.project.id),this.impactGuard=new ce(this.graph),this.autoImpactGuard=new Ce(this.impactGuard,e.project.id)}options;memory=new A;graph=new R;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 Nt(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=Ke(),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 Me(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 de(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=Ke(),p=await new O(e.id,r,l,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{createHash as Vo}from"node:crypto";import{existsSync as Xe,mkdirSync as qo,readFileSync as Wo,renameSync as Yo,writeFileSync as Jo}from"node:fs";import{basename as Qo,dirname as Te,join as je,parse as Kt,resolve as G}from"node:path";var Bt=".toolnet",Zo="project.json";function Xo(o){return Vo("sha256").update(o).digest("hex").slice(0,16)}function et(o){return je(o,Bt,Zo)}function es(o){return Xe(et(o))}function ts(o,e){let t=G(o),r=Kt(t).root;for(;;){if(es(t))return t;if(t===r||e&&t===G(e))break;let s=Te(t);if(s===t)break;t=s}return null}function rs(o){let e=G(o),t=Kt(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Xe(je(e,n))))return e;if(e===t)break;let s=Te(e);if(s===e)break;e=s}return G(o)}function os(o){let e;try{e=JSON.parse(Wo(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:Te(Te(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 Ft(o,e){let t=je(o,Bt);qo(t,{recursive:!0});let r=et(o),s=`${r}.tmp-${process.pid}`;Jo(s,JSON.stringify(e,null,2)+`
11
+ `,{encoding:"utf8",mode:384}),Yo(s,r)}function $t(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 Le=class{detect(e=process.cwd()){let t=G(e),r=rs(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>Xe(je(r,m))),i=ts(t,n?r:void 0);if(i){let m=et(i),p=os(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Ft(i,p)),$t(p,i)}let a=new Date().toISOString(),c=Qo(r),l={version:1,id:Xo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Ft(r,l),$t(l,r)}};function Gt(o=process.cwd()){let e=Ze(),t=new Le().detect(o),r=At({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),s=Lt(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 Ae({project:t,storage:n,embeddingModel:i})}async function ss(){let o=Gt(),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})}ss().catch(o=>{console.error(o),process.exit(1)});