toolnet-memory 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/agy-hook.js +79 -69
- package/bundle/agy.js +71 -61
- package/bundle/api.js +16 -16
- package/bundle/auto-integrate.js +377 -71
- package/bundle/claude-hook.js +102 -36
- package/bundle/codex-context.js +10 -10
- package/bundle/codex.js +67 -65
- package/bundle/context-runtime.js +30 -30
- package/bundle/context.js +15 -15
- package/bundle/continuity-certify.js +14 -13
- package/bundle/doctor.js +5 -5
- package/bundle/full-index.js +22 -18
- package/bundle/graph-index.js +2 -2
- package/bundle/handoff-refresh.js +7 -7
- package/bundle/init.js +386 -80
- package/bundle/learner.js +1 -1
- package/bundle/mcp.js +19 -19
- package/bundle/memory-agent.js +11 -11
- package/bundle/memory-query.js +5 -5
- package/bundle/opencode.js +442 -121
- package/bundle/project-manual.js +3 -3
- package/bundle/provider.js +5 -2
- package/bundle/recovery-certify.js +21 -20
- package/bundle/runtime.js +4 -4
- package/bundle/semantic.js +5 -5
- package/bundle/service-cli.js +2 -2
- package/bundle/setup.js +376 -70
- package/bundle/snapshot.js +4 -4
- package/bundle/update.js +4 -4
- package/bundle/work-continuity.js +7 -7
- package/package.json +1 -1
package/bundle/runtime.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{randomUUID as or}from"node:crypto";var Ut={critical:100,high:75,normal:50,temporary:20};function tt(n){return Ut[n]}function rt(n,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":n==="rule"||n==="decision"?"high":n==="todo"?"normal":n==="activity"||n==="summary"?"temporary":"normal"}var Wt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],z=class{scan(e){let t=[];for(let r of Wt){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))t.push({type:r.type,value:o[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var I=class{scanner=new z;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),t=t.split(o.value).join(`[REDACTED:${o.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 o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Ht=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Vt=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 nt(n){return new Set(n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Vt.has(e)))}function qt(n,e){let t=nt(n),r=nt(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let o=new Set([...t,...r]).size;return s/o}function st(n){return new Set(n.tags.filter(e=>!Ht.has(e.toLowerCase())))}var U=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=st(e);return t.filter(o=>{if(o.id===e.id||o.projectId!==e.projectId||o.type!==e.type||o.metadata?.supersededBy)return!1;let i=typeof o.metadata?.topic=="string"?o.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=st(o);for(let c of s)if(a.has(c))return!0;return qt(e.content,o.content)>=.6})}};var Jt=new Set(["code","decision","rule","todo","summary"]);function Yt(n){return n.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function ot(n){return n.tags.includes("class:permanent")?4:n.tags.includes("class:task")?3:n.tags.includes("class:session")?2:n.tags.includes("class:transient")?1:0}function Qt(n,e){let t=ot(e)-ot(n);if(t!==0)return t;let r=e.importanceScore-n.importanceScore;if(r!==0)return r;let s=e.updatedAt.localeCompare(n.updatedAt);if(s!==0)return s;let o=e.createdAt.localeCompare(n.createdAt);return o!==0?o:n.id.localeCompare(e.id)}function it(n){let e=new Set,t=[];for(let r of n){let s=r.trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),t.push(s))}return t}function at(n){let e=new Map;for(let s of n){if(!Jt.has(s.type)||s.metadata?.supersededBy)continue;let o=Yt(s.content);if(!o)continue;let i=[s.projectId,s.type,o].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 o=[...s].sort(Qt),i=o[0];if(!i)continue;let a=o.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:it(o.flatMap(c=>c.tags)),mergedSources:it(o.map(c=>c.source))}),r+=a.length}return{groups:t,duplicates:r}}function _e(n){if(n.tags.includes("class:permanent"))return"permanent";if(n.tags.includes("class:task"))return"task";if(n.tags.includes("class:session"))return"session";if(n.tags.includes("class:transient"))return"transient"}function Xt(n,e){let t=new Date(n.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Zt(n){let e=_e(n);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(n.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(n){return _e(n)==="permanent"||n.type==="rule"||n.type==="decision"||n.importance==="critical"}function tr(n){let e=n.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(n,e=Date.now()){let t=50,r=[],s=_e(n);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")),n.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}(n.type==="rule"||n.type==="decision")&&(t+=10,r.push("durable knowledge type"));let o=n.content.trim().length;o<12?(t-=30,r.push("very short content")):o<30?(t-=10,r.push("limited context")):o<=1200?(t+=8,r.push("useful context density")):o>5e3&&(t-=15,r.push("excessively large memory")),tr(n.content)&&(t-=35,r.push("matches transient/noise pattern"));let i=n.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,r.push("confirmed across multiple sources"));let a=Xt(n,e)>=Zt(n);a&&(t-=15,r.push("stale for lifecycle class"));let c=er(n);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 p=n.importance==="temporary"||n.type==="activity"||s==="transient";return{score:t,tier:l,stale:a,protected:c,pruneEligible:!c&&(l==="noise"&&p||a&&(l==="noise"||l==="weak")),reasons:r}}var rr={critical:100,high:75,normal:50,temporary:20},nr={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function lt(n,e,t=new Date){let r;if(e==="temporary"&&(r=30),n==="activity"&&(r=Math.min(r??14,14)),n==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Ne(n,e=Date.now()){return n.expiresAt?new Date(n.expiresAt).getTime()<=e:!1}function sr(n){return!!n.metadata?.supersededBy}function Oe(n,e=Date.now()){return!Ne(n,e)&&!sr(n)}function L(n,e=Date.now()){if(!Oe(n,e))return 0;let t=rr[n.importance];if(n.importance==="critical")return t;let r=nr[n.type]??180,o=Math.max(0,e-new Date(n.updatedAt).getTime())/864e5,i=Math.pow(.5,o/r);return t*i}var R=class{memories=new Map;sanitizer=new I;conflicts=new U;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??rt(e.type,r),o={id:or(),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(o,this.list(e.projectId));if(i.length){o.metadata={...o.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:o.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(o.id,o),o}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(o=>{if(e.types&&!e.types.includes(o.type))return!1;let i=L(o);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>o.tags.includes(c)))}).map(o=>{let i=o.content.toLowerCase(),a=s.filter(p=>i.includes(p)).length,c=s.length===0?0:a/s.length,l=L(o)/500;return{memory:o,score:c+l,source:"memory"}}).filter(o=>t.length===0||o.score>0).sort((o,i)=>i.score-o.score).slice(0,r)}consolidate(e,t=Date.now()){let r=at(this.list(e)),s=[],o=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)&&(o+=1)}}return{groupsConsolidated:s.length,duplicatesRemoved:o,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 o=ct(s,t);r.reviewed+=1,r[o.tier]+=1,o.stale&&(r.stale+=1),o.protected&&(r.protected+=1),s.metadata={...s.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:o.score,tier:o.tier,stale:o.stale,protected:o.protected,reasons:o.reasons}},this.memories.set(s.id,s),o.pruneEligible&&this.memories.delete(s.id)&&(r.pruned+=1)}return r}pruneExpired(e,t=Date.now()){let r=0;for(let[s,o]of this.memories)o.projectId===e&&Ne(o,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,o=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()>=o&&(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 W=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),o=this.memory.reviewLifecycle(e);return{expiredRemoved:t,supersededRemoved:s,groupsConsolidated:r.groupsConsolidated,duplicatesRemoved:r.duplicatesRemoved,lifecycleReviewed:o.reviewed,lifecyclePruned:o.pruned,quality:{trusted:o.trusted,useful:o.useful,weak:o.weak,noise:o.noise,stale:o.stale,protected:o.protected},active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Ke(n){return[...new Set(n.filter(Boolean))]}var H=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,s=t.maxItems??50,o=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()+o*864e5).toISOString(),p=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:l,metadata:{consolidatedFrom:i.map(f=>f.id),itemCount:i.length}}),u=c.toISOString();for(let f of i){let g=this.memory.get(f.id);g&&(g.updatedAt=u,g.metadata={...g.metadata??{},consolidated:!0,supersededBy:p.id,supersededAt:u})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:p.id}}buildSummary(e){let t=Ke(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Ke(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=Ke(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),o=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&o.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&o.push(`- Commands: ${r.slice(0,10).join("; ")}`),s.length&&o.push(`- Errors: ${s.slice(0,10).join("; ")}`),o.join(`
|
|
1
|
+
import{randomUUID as or}from"node:crypto";var Ut={critical:100,high:75,normal:50,temporary:20};function tt(n){return Ut[n]}function rt(n,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":n==="rule"||n==="decision"?"high":n==="todo"?"normal":n==="activity"||n==="summary"?"temporary":"normal"}var Wt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],z=class{scan(e){let t=[];for(let r of Wt){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))t.push({type:r.type,value:o[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var A=class{scanner=new z;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),t=t.split(o.value).join(`[REDACTED:${o.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 o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Ht=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Vt=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 nt(n){return new Set(n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Vt.has(e)))}function qt(n,e){let t=nt(n),r=nt(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let o=new Set([...t,...r]).size;return s/o}function st(n){return new Set(n.tags.filter(e=>!Ht.has(e.toLowerCase())))}var U=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=st(e);return t.filter(o=>{if(o.id===e.id||o.projectId!==e.projectId||o.type!==e.type||o.metadata?.supersededBy)return!1;let i=typeof o.metadata?.topic=="string"?o.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=st(o);for(let c of s)if(a.has(c))return!0;return qt(e.content,o.content)>=.6})}};var Jt=new Set(["code","decision","rule","todo","summary"]);function Yt(n){return n.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function ot(n){return n.tags.includes("class:permanent")?4:n.tags.includes("class:task")?3:n.tags.includes("class:session")?2:n.tags.includes("class:transient")?1:0}function Qt(n,e){let t=ot(e)-ot(n);if(t!==0)return t;let r=e.importanceScore-n.importanceScore;if(r!==0)return r;let s=e.updatedAt.localeCompare(n.updatedAt);if(s!==0)return s;let o=e.createdAt.localeCompare(n.createdAt);return o!==0?o:n.id.localeCompare(e.id)}function it(n){let e=new Set,t=[];for(let r of n){let s=r.trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),t.push(s))}return t}function at(n){let e=new Map;for(let s of n){if(!Jt.has(s.type)||s.metadata?.supersededBy)continue;let o=Yt(s.content);if(!o)continue;let i=[s.projectId,s.type,o].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 o=[...s].sort(Qt),i=o[0];if(!i)continue;let a=o.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:it(o.flatMap(c=>c.tags)),mergedSources:it(o.map(c=>c.source))}),r+=a.length}return{groups:t,duplicates:r}}function _e(n){if(n.tags.includes("class:permanent"))return"permanent";if(n.tags.includes("class:task"))return"task";if(n.tags.includes("class:session"))return"session";if(n.tags.includes("class:transient"))return"transient"}function Xt(n,e){let t=new Date(n.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Zt(n){let e=_e(n);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(n.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(n){return _e(n)==="permanent"||n.type==="rule"||n.type==="decision"||n.importance==="critical"}function tr(n){let e=n.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(n,e=Date.now()){let t=50,r=[],s=_e(n);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")),n.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}(n.type==="rule"||n.type==="decision")&&(t+=10,r.push("durable knowledge type"));let o=n.content.trim().length;o<12?(t-=30,r.push("very short content")):o<30?(t-=10,r.push("limited context")):o<=1200?(t+=8,r.push("useful context density")):o>5e3&&(t-=15,r.push("excessively large memory")),tr(n.content)&&(t-=35,r.push("matches transient/noise pattern"));let i=n.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,r.push("confirmed across multiple sources"));let a=Xt(n,e)>=Zt(n);a&&(t-=15,r.push("stale for lifecycle class"));let c=er(n);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 p=n.importance==="temporary"||n.type==="activity"||s==="transient";return{score:t,tier:l,stale:a,protected:c,pruneEligible:!c&&(l==="noise"&&p||a&&(l==="noise"||l==="weak")),reasons:r}}var rr={critical:100,high:75,normal:50,temporary:20},nr={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function lt(n,e,t=new Date){let r;if(e==="temporary"&&(r=30),n==="activity"&&(r=Math.min(r??14,14)),n==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Ne(n,e=Date.now()){return n.expiresAt?new Date(n.expiresAt).getTime()<=e:!1}function sr(n){return!!n.metadata?.supersededBy}function Oe(n,e=Date.now()){return!Ne(n,e)&&!sr(n)}function L(n,e=Date.now()){if(!Oe(n,e))return 0;let t=rr[n.importance];if(n.importance==="critical")return t;let r=nr[n.type]??180,o=Math.max(0,e-new Date(n.updatedAt).getTime())/864e5,i=Math.pow(.5,o/r);return t*i}var R=class{memories=new Map;sanitizer=new A;conflicts=new U;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??rt(e.type,r),o={id:or(),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(o,this.list(e.projectId));if(i.length){o.metadata={...o.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:o.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(o.id,o),o}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(o=>{if(e.types&&!e.types.includes(o.type))return!1;let i=L(o);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>o.tags.includes(c)))}).map(o=>{let i=o.content.toLowerCase(),a=s.filter(p=>i.includes(p)).length,c=s.length===0?0:a/s.length,l=L(o)/500;return{memory:o,score:c+l,source:"memory"}}).filter(o=>t.length===0||o.score>0).sort((o,i)=>i.score-o.score).slice(0,r)}consolidate(e,t=Date.now()){let r=at(this.list(e)),s=[],o=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)&&(o+=1)}}return{groupsConsolidated:s.length,duplicatesRemoved:o,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 o=ct(s,t);r.reviewed+=1,r[o.tier]+=1,o.stale&&(r.stale+=1),o.protected&&(r.protected+=1),s.metadata={...s.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:o.score,tier:o.tier,stale:o.stale,protected:o.protected,reasons:o.reasons}},this.memories.set(s.id,s),o.pruneEligible&&this.memories.delete(s.id)&&(r.pruned+=1)}return r}pruneExpired(e,t=Date.now()){let r=0;for(let[s,o]of this.memories)o.projectId===e&&Ne(o,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,o=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()>=o&&(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 W=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),o=this.memory.reviewLifecycle(e);return{expiredRemoved:t,supersededRemoved:s,groupsConsolidated:r.groupsConsolidated,duplicatesRemoved:r.duplicatesRemoved,lifecycleReviewed:o.reviewed,lifecyclePruned:o.pruned,quality:{trusted:o.trusted,useful:o.useful,weak:o.weak,noise:o.noise,stale:o.stale,protected:o.protected},active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Ke(n){return[...new Set(n.filter(Boolean))]}var H=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,s=t.maxItems??50,o=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()+o*864e5).toISOString(),p=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:l,metadata:{consolidatedFrom:i.map(f=>f.id),itemCount:i.length}}),u=c.toISOString();for(let f of i){let g=this.memory.get(f.id);g&&(g.updatedAt=u,g.metadata={...g.metadata??{},consolidated:!0,supersededBy:p.id,supersededAt:u})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:p.id}}buildSummary(e){let t=Ke(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Ke(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=Ke(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),o=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&o.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&o.push(`- Commands: ${r.slice(0,10).join("; ")}`),s.length&&o.push(`- Errors: ${s.slice(0,10).join("; ")}`),o.join(`
|
|
2
2
|
`)}};function V(n){return n.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var q=class{score(e,t){let r=V(e),s=V([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||s.length===0)return 0;let o=new Map;for(let a of s)o.set(a,(o.get(a)??0)+1);let i=0;for(let a of r){let c=o.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function dt(n,e=Date.now()){let t=n.updatedAt??n.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 ut(n){return L(n)/100}var ir={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function pt(n){return ir[n]??.4}var J=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 Y=class{bm25=new q;analyzer=new J;search(e,t,r={}){let s=r.topK??8,o=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=dt(c),u=ut(c),f=pt(c.type);i.preferredTypes.includes(c.type)&&(f=Math.min(1,f+.25));let g=l*.55+u*.2+p*.15+f*.1;l<=0||g<o||a.push({memory:c,score:g,scores:{keyword:l,recency:p,importance:u,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 o of e){let i=o.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 X=class{constructor(e){this.memory=e}memory;searcher=new Y;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 mt=[{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 Z(n){let e=mt.find(t=>t.id===n);if(!e)throw new Error(`Unsupported AI provider: ${n}`);return e}function ee(n){return mt.some(e=>e.id===n)}function d(n){return process.env[n]?.trim()||void 0}function b(...n){return n.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 n=d("TOOLNET_LLM_PROVIDER");return n&&ee(n)?n:ft()??"openai-compatible"}function De(n){let e=Z(n);switch(n){case"alibaba":return{provider:n,apiKey:b(d("ALIBABA_API_KEY"),d("DASHSCOPE_API_KEY")),baseUrl:b(d("ALIBABA_BASE_URL"),d("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:b(d("ALIBABA_MODEL"),d("DASHSCOPE_MODEL"))};case"openrouter":return{provider:n,apiKey:d("OPENROUTER_API_KEY"),baseUrl:b(d("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:d("OPENROUTER_MODEL")};case"groq":return{provider:n,apiKey:d("GROQ_API_KEY"),baseUrl:b(d("GROQ_BASE_URL"),e.defaultBaseUrl),model:d("GROQ_MODEL")};case"deepseek":return{provider:n,apiKey:d("DEEPSEEK_API_KEY"),baseUrl:b(d("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:b(d("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:n,apiKey:b(d("NVIDIA_API_KEY"),d("NVIDIA_NIM_API_KEY")),baseUrl:b(d("NVIDIA_BASE_URL"),d("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:b(d("NVIDIA_MODEL"),d("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:n,apiKey:b(d("GEMINI_API_KEY"),d("GOOGLE_API_KEY")),baseUrl:b(d("GEMINI_BASE_URL"),e.defaultBaseUrl),model:d("GEMINI_MODEL")};case"huggingface":return{provider:n,apiKey:d("HF_TOKEN"),baseUrl:b(d("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:b(d("HF_LLM_MODEL"),d("HF_MODEL"))};case"ollama":return{provider:n,apiKey:d("OLLAMA_API_KEY"),baseUrl:b(d("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:d("OLLAMA_MODEL")};case"cloudflare":return{provider:n,accountId:d("CLOUDFLARE_ACCOUNT_ID"),apiKey:d("CLOUDFLARE_API_TOKEN"),baseUrl:d("CLOUDFLARE_AI_BASE_URL"),model:d("CLOUDFLARE_MODEL")};case"custom":return{provider:n,apiKey:d("CUSTOM_AI_API_KEY"),baseUrl:d("CUSTOM_AI_BASE_URL"),model:d("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:b(d("OPENAI_API_KEY"),d("MODEL_API_KEY")),baseUrl:b(d("OPENAI_BASE_URL"),d("MODEL_BASE_URL")),model:b(d("OPENAI_MODEL"),d("MODEL_NAME"))}}}function cr(){let n=d("TOOLNET_LLM_PROVIDER"),e=n&&ee(n)?n:ar(),t=Z(e),r=De(e);return{provider:e,apiKey:b(d("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:b(d("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:b(d("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:b(d("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function lr(){let n=d("TOOLNET_EMBEDDING_PROVIDER");return n==="local"?"local":n&&ee(n)?n:d("HF_TOKEN")||d("HF_EMBEDDING_MODEL")?"huggingface":"local"}function dr(){let n=lr();if(n==="local")return{provider:"local",model:b(d("TOOLNET_EMBEDDING_MODEL"),d("LOCAL_EMBEDDING_MODEL"))};let e=Z(n),t,r,s,o;switch(n){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"),o=d("CLOUDFLARE_ACCOUNT_ID");break;default:t=De(n).apiKey,r=De(n).baseUrl,s=d(`${n.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=b(d("TOOLNET_EMBEDDING_ACCOUNT_ID"),o),a=b(d("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),c=n==="cloudflare"&&!a&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:a;return{provider:n,apiKey:b(d("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:c,model:b(d("TOOLNET_EMBEDDING_MODEL"),s),accountId:i}}function gt(){let n=cr(),e=dr();return{llm:n,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)}`,o=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!o.ok)throw new Error(`Gemini embedding failed: ${o.status} ${await o.text()}`);let a=(await o.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 ur}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=ur("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return pr(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function pr(n){let e=Math.sqrt(n.reduce((t,r)=>t+r*r,0));return e===0?n:n.map(t=>t/e)}var ne=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 o=(await r.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!o||o.length!==e.length||o.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return o}};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(o=>mr(o))}};function mr(n){if(!Array.isArray(n))throw new Error("Invalid embedding");if(n.length>0&&typeof n[0]=="number")return n;if(n.length>0&&Array.isArray(n[0])){let e=n;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let o=0;o<t;o++)r[o]+=s[o]??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(n){return`https://api.cloudflare.com/client/v4/accounts/${n}/ai/v1`}function gr(){let n=gt().embedding;if(n.provider==="local")return null;if(n.provider==="huggingface")return!n.apiKey||!n.model?null:new se({token:n.apiKey,model:n.model});if(n.provider==="gemini")return!n.apiKey||!n.model?null:new te({apiKey:n.apiKey,model:n.model,baseUrl:n.baseUrl});let e=n.baseUrl;return n.provider==="cloudflare"&&!e&&n.accountId&&(e=fr(n.accountId)),e&&n.model?new ne({apiKey:n.apiKey,baseUrl:e,model:n.model}):null}function Fe(){return new $e(gr())}import{readdir as br}from"node:fs/promises";import{extname as vr,join as wr,relative as xr}from"node:path";import{basename as yr}from"node:path";var hr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Sr=new Set([".pem",".key",".p12",".pfx"]);function Ge(n){let e=yr(n).toLowerCase();if(hr.has(e))return!0;for(let t of Sr)if(e.endsWith(t))return!0;return!1}var kr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Er=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Be(n){let e=[];async function t(r){let s=await br(r,{withFileTypes:!0});for(let o of s){if(Er.has(o.name))continue;let i=wr(r,o.name);if(o.isDirectory()){await t(i);continue}kr.has(vr(o.name))&&(Ge(i)||e.push(xr(n,i)))}}return await t(n),e.sort()}import{readFile as Cr}from"node:fs/promises";import{join as Ar}from"node:path";import{createHash as Pr}from"node:crypto";import*as h from"typescript";function yt(n,e){return Pr("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function ze(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Ue(n,e,t){let r=Ar(e,t),s=await Cr(r,"utf8"),o=h.createSourceFile(t,s,h.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?h.ScriptKind.TSX:h.ScriptKind.TS),i=[],a=[],c=[],l=[],p={id:yt(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:o.getLineAndCharacterOfPosition(o.end).line+1};i.push(p);let u=[],f=[];function g(m,x,k,w){let A=yt(n,`${t}:${k}:${w??x}:${m.pos}`);return i.push({id:A,projectId:n,name:x,qualifiedName:w??x,type:k,filePath:t,startLine:ze(o,m),endLine:o.getLineAndCharacterOfPosition(m.end).line+1}),A}function E(m){if(!h.isStringLiteral(m.moduleSpecifier))return;let x=[],k=m.importClause;if(k?.name&&x.push({localName:k.name.text,importedName:"default",kind:"default"}),k?.namedBindings&&h.isNamedImports(k.namedBindings))for(let w of k.namedBindings.elements)x.push({localName:w.name.text,importedName:w.propertyName?.text??w.name.text,kind:"named"});k?.namedBindings&&h.isNamespaceImport(k.namedBindings)&&x.push({localName:k.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:m.moduleSpecifier.text,bindings:x})}function v(m,x){for(let k of m.heritageClauses??[])for(let w of k.types){let A=w.expression.getText(o).split(".").at(-1)??"";A&&l.push({fromId:x,targetName:A,type:k.token===h.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function y(m){let x=!1,k=!1;if(h.isImportDeclaration(m)&&E(m),h.isInterfaceDeclaration(m)&&g(m,m.name.text,"interface",m.name.text),h.isClassDeclaration(m)&&m.name){let w=g(m,m.name.text,"class",m.name.text);v(m,w),f.push({id:w,name:m.name.text}),k=!0}if(h.isFunctionDeclaration(m)&&m.name){let w=g(m,m.name.text,"function",m.name.text);u.push(w),x=!0}if(h.isMethodDeclaration(m)&&m.name){let w=m.name.getText(o),A=f.at(-1)?.name,zt=g(m,w,"method",A?`${A}.${w}`:w);u.push(zt),x=!0}if(h.isCallExpression(m)&&(h.isIdentifier(m.expression)&&c.push({callerId:u.at(-1),calleeName:m.expression.text,line:ze(o,m)}),h.isPropertyAccessExpression(m.expression))){let w=m.expression;c.push({callerId:u.at(-1),qualifier:w.expression.getText(o),calleeName:w.name.text,line:ze(o,m)})}h.forEachChild(m,y),x&&u.pop(),k&&f.pop()}return y(o),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as Mr}from"node:crypto";import{dirname as Ir,extname as Rr,normalize as Tr,posix as jr}from"node:path";var P=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function Lr(n,e,t,r){return Mr("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function M(n){return Tr(n).replaceAll("\\","/")}function We(n,e,t){if(!e.startsWith("."))return;let r=M(jr.join(Ir(n),e)),s=Rr(r),o;if(s===".js"){let i=r.slice(0,-3);o=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(s===".mjs"){let i=r.slice(0,-4);o=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(s===".cjs"){let i=r.slice(0,-4);o=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else s?o=[r]:o=[`${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 o.find(i=>t.has(M(i)))}var _=class{build(e,t){let r=new P,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 o=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 p=We(a,l.source,o);if(!p)continue;let u=s.get(p);u&&r.addEdge(this.edge(e,c.id,"IMPORTS",u.id,{source:l.source}))}for(let l of i.heritage){let p=r.findByName(e,l.targetName).filter(u=>u.type==="class"||u.type==="interface");for(let u of p)r.addEdge(this.edge(e,l.fromId,l.type,u.id))}for(let l of i.calls){if(!l.callerId)continue;let p=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,o);for(let u of p)u.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",u.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,o,i,a){let c=M(t.filePath),l=i.findByName(e,r).filter(p=>M(p.filePath)===c);if(!s&&l.length)return l;if(s)for(let p of t.imports){if(!p.bindings.find(g=>g.kind==="namespace"&&g.localName===s))continue;let f=We(c,p.source,a);if(f)return i.findByName(e,r).filter(g=>M(g.filePath)===f)}for(let p of t.imports){let u=p.bindings.find(v=>v.localName===r);if(!u)continue;let f=We(c,p.source,a);if(!f)continue;let g=u.importedName==="default"?r:u.importedName,E=i.findByName(e,g).filter(v=>M(v.filePath)===f);if(E.length)return E}return i.findByName(e,r).filter(p=>p.type==="function"||p.type==="method")}edge(e,t,r,s,o){return{id:Lr(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:o}}};function ht(n,e){let t=n.allSymbols(e),r=n.allEdges(e),s=i=>t.filter(a=>a.type===i).length,o=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:o("CALLS"),callReferences:o("CALL_REFERENCE"),imports:o("IMPORTS"),inherits:o("INHERITS"),implements:o("IMPLEMENTS"),usesType:o("USES_TYPE"),tests:o("TESTS"),routeEdges:o("ROUTE"),writes:o("WRITES")}}var oe=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(n,e){return e.ranges.length===0?!0:typeof n.startLine!="number"||typeof n.endLine!="number"?!1:e.ranges.some(t=>n.startLine<=t.endLine&&n.endLine>=t.startLine)}var ie=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let o of t){let i=r.filter(l=>l.filePath===o.filePath),c=i.filter(l=>l.type!=="file").filter(l=>_r(l,o));if(c.length===0){let l=i.find(p=>p.type==="file");l&&s.push({symbol:l,fileStatus:o.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:o.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(n){return n>=30?"CRITICAL":n>=16?"HIGH":n>=6?"MEDIUM":"LOW"}function St(n){let e=n.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),o=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let u=new Set([p.symbol.id]),f=[{id:p.symbol.id,depth:0}];for(;f.length;){let g=f.shift();if(g.depth>=r)continue;let E=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 E){if(u.has(v.from))continue;u.add(v.from);let y=this.graph.getSymbol(v.from);if(!y)continue;let m=g.depth+1,x=`${p.symbol.id}:${y.id}`;o.set(x,{symbol:y,relation:v.type,depth:m,sourceSymbolId:p.symbol.id});let k=Nr[v.type]??1;i+=Math.max(1,k-(m-1)),f.push({id:y.id,depth:m})}}}let a=[...o.values()].sort((p,u)=>p.depth-u.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(St);return l.length===0&&l.push(...c.filter(p=>!St(p)).slice(0,10)),{risk:Or(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as Kr}from"node:child_process";import{promisify as Dr}from"node:util";var He=Dr(Kr);function $r(n){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of n.matchAll(t)){let s=Number(r[1]),o=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+o-1)})}return e}function Fr(n){return n.startsWith("A")?"added":n.startsWith("D")?"deleted":n.startsWith("R")?"renamed":"modified"}async function bt(n){let e="";try{e=(await He("git",["diff","HEAD","--name-status","--no-renames"],{cwd:n,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...o]=r.split(" "),i=o.at(-1);if(!i)continue;let a="";try{a=(await He("git",["diff","HEAD","--unified=0","--",i],{cwd:n,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Fr(s),ranges:$r(a)})}try{let r=await He("git",["ls-files","--others","--exclude-standard"],{cwd:n});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(o=>o.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 bt(t),o=this.mapper.map(e,s),i=this.blast.analyze(e,o,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 Gr=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,Br=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function vt(n){return n.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function zr(n){return n.length>0&&n.length<500&&!n.includes(`
|
|
4
|
-
`)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(n)}function Ur(n){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let s of n.matchAll(r))s[1]&&e.push(vt(s[1]));return e}function Ve(n,e,t){if(typeof n=="string"){let r=t?.toLowerCase();if(r&&Br.has(r)&&zr(n)&&e.add(vt(n)),n.includes("*** Update File:")||n.includes("*** Add File:")||n.includes("*** Delete File:")||n.includes("+++ b/"))for(let s of Ur(n))e.add(s);return}if(Array.isArray(n)){for(let r of n)Ve(r,e,t);return}if(n&&typeof n=="object")for(let[r,s]of Object.entries(n))Ve(s,e,r)}function Wr(n){return Gr.test(n.toLowerCase())}function wt(n,e){if(!Wr(n))return[];let t=new Set;return Ve(e,t),[...t]}import{createHash as Hr}from"node:crypto";import{readFile as Vr}from"node:fs/promises";async function xt(n){let e=await Vr(n);return Hr("sha256").update(e).digest("hex")}function kt(n,e){let t=n?.files??{},r=e.files,s=[],o=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let p=t[c];p?p.hash!==l.hash?o.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:o.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as qr}from"node:path";async function Et(n,e){let t=await Be(e),r={};for(let s of t)r[s]={path:s,hash:await xt(qr(e,s))};return{version:1,projectId:n,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),o=await r.load(e),i=await s.load(e),a=await Et(e,t),c=kt(o,a),l=[...c.added,...c.modified];if(o&&i&&l.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let p=i?.symbols.filter(y=>c.unchanged.includes(y.filePath))??[],u=[];for(let y of l)u.push(await Ue(e,t,y));let f=new _().build(e,u),g=new
|
|
3
|
+
`)}};var X=class{constructor(e){this.memory=e}memory;searcher=new Y;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 mt=[{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 Z(n){let e=mt.find(t=>t.id===n);if(!e)throw new Error(`Unsupported AI provider: ${n}`);return e}function ee(n){return mt.some(e=>e.id===n)}function d(n){return process.env[n]?.trim()||void 0}function b(...n){return n.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 n=d("TOOLNET_LLM_PROVIDER");return n&&ee(n)?n:ft()??"openai-compatible"}function De(n){let e=Z(n);switch(n){case"alibaba":return{provider:n,apiKey:b(d("ALIBABA_API_KEY"),d("DASHSCOPE_API_KEY")),baseUrl:b(d("ALIBABA_BASE_URL"),d("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:b(d("ALIBABA_MODEL"),d("DASHSCOPE_MODEL"))};case"openrouter":return{provider:n,apiKey:d("OPENROUTER_API_KEY"),baseUrl:b(d("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:d("OPENROUTER_MODEL")};case"groq":return{provider:n,apiKey:d("GROQ_API_KEY"),baseUrl:b(d("GROQ_BASE_URL"),e.defaultBaseUrl),model:d("GROQ_MODEL")};case"deepseek":return{provider:n,apiKey:d("DEEPSEEK_API_KEY"),baseUrl:b(d("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:b(d("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:n,apiKey:b(d("NVIDIA_API_KEY"),d("NVIDIA_NIM_API_KEY")),baseUrl:b(d("NVIDIA_BASE_URL"),d("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:b(d("NVIDIA_MODEL"),d("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:n,apiKey:b(d("GEMINI_API_KEY"),d("GOOGLE_API_KEY")),baseUrl:b(d("GEMINI_BASE_URL"),e.defaultBaseUrl),model:d("GEMINI_MODEL")};case"huggingface":return{provider:n,apiKey:d("HF_TOKEN"),baseUrl:b(d("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:b(d("HF_LLM_MODEL"),d("HF_MODEL"))};case"ollama":return{provider:n,apiKey:d("OLLAMA_API_KEY"),baseUrl:b(d("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:d("OLLAMA_MODEL")};case"cloudflare":return{provider:n,accountId:d("CLOUDFLARE_ACCOUNT_ID"),apiKey:d("CLOUDFLARE_API_TOKEN"),baseUrl:d("CLOUDFLARE_AI_BASE_URL"),model:d("CLOUDFLARE_MODEL")};case"custom":return{provider:n,apiKey:d("CUSTOM_AI_API_KEY"),baseUrl:d("CUSTOM_AI_BASE_URL"),model:d("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:b(d("OPENAI_API_KEY"),d("MODEL_API_KEY")),baseUrl:b(d("OPENAI_BASE_URL"),d("MODEL_BASE_URL")),model:b(d("OPENAI_MODEL"),d("MODEL_NAME"))}}}function cr(){let n=d("TOOLNET_LLM_PROVIDER"),e=n&&ee(n)?n:ar(),t=Z(e),r=De(e);return{provider:e,apiKey:b(d("TOOLNET_LLM_API_KEY"),r.apiKey),baseUrl:b(d("TOOLNET_LLM_BASE_URL"),r.baseUrl,t.defaultBaseUrl),model:b(d("TOOLNET_LLM_MODEL"),r.model,t.defaultModel),accountId:b(d("TOOLNET_LLM_ACCOUNT_ID"),r.accountId)}}function lr(){let n=d("TOOLNET_EMBEDDING_PROVIDER");return n==="local"?"local":n&&ee(n)?n:d("HF_TOKEN")||d("HF_EMBEDDING_MODEL")?"huggingface":"local"}function dr(){let n=lr();if(n==="local")return{provider:"local",model:b(d("TOOLNET_EMBEDDING_MODEL"),d("LOCAL_EMBEDDING_MODEL"))};let e=Z(n),t,r,s,o;switch(n){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"),o=d("CLOUDFLARE_ACCOUNT_ID");break;default:t=De(n).apiKey,r=De(n).baseUrl,s=d(`${n.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=b(d("TOOLNET_EMBEDDING_ACCOUNT_ID"),o),a=b(d("TOOLNET_EMBEDDING_BASE_URL"),r,e.defaultBaseUrl),c=n==="cloudflare"&&!a&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:a;return{provider:n,apiKey:b(d("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:c,model:b(d("TOOLNET_EMBEDDING_MODEL"),s),accountId:i}}function gt(){let n=cr(),e=dr();return{llm:n,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)}`,o=await fetch(s,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!o.ok)throw new Error(`Gemini embedding failed: ${o.status} ${await o.text()}`);let a=(await o.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 ur}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=ur("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return pr(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function pr(n){let e=Math.sqrt(n.reduce((t,r)=>t+r*r,0));return e===0?n:n.map(t=>t/e)}var ne=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 o=(await r.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!o||o.length!==e.length||o.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return o}};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(o=>mr(o))}};function mr(n){if(!Array.isArray(n))throw new Error("Invalid embedding");if(n.length>0&&typeof n[0]=="number")return n;if(n.length>0&&Array.isArray(n[0])){let e=n;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let o=0;o<t;o++)r[o]+=s[o]??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(n){return`https://api.cloudflare.com/client/v4/accounts/${n}/ai/v1`}function gr(){let n=gt().embedding;if(n.provider==="local")return null;if(n.provider==="huggingface")return!n.apiKey||!n.model?null:new se({token:n.apiKey,model:n.model});if(n.provider==="gemini")return!n.apiKey||!n.model?null:new te({apiKey:n.apiKey,model:n.model,baseUrl:n.baseUrl});let e=n.baseUrl;return n.provider==="cloudflare"&&!e&&n.accountId&&(e=fr(n.accountId)),e&&n.model?new ne({apiKey:n.apiKey,baseUrl:e,model:n.model}):null}function Fe(){return new $e(gr())}import{readdir as br}from"node:fs/promises";import{extname as vr,join as wr,relative as xr}from"node:path";import{basename as yr}from"node:path";var hr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Sr=new Set([".pem",".key",".p12",".pfx"]);function Ge(n){let e=yr(n).toLowerCase();if(hr.has(e))return!0;for(let t of Sr)if(e.endsWith(t))return!0;return!1}var kr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Er=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Be(n){let e=[];async function t(r){let s=await br(r,{withFileTypes:!0});for(let o of s){if(Er.has(o.name))continue;let i=wr(r,o.name);if(o.isDirectory()){await t(i);continue}kr.has(vr(o.name))&&(Ge(i)||e.push(xr(n,i)))}}return await t(n),e.sort()}import{readFile as Cr}from"node:fs/promises";import{join as Ar}from"node:path";import{createHash as Pr}from"node:crypto";import*as h from"typescript";function yt(n,e){return Pr("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function ze(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Ue(n,e,t){let r=Ar(e,t),s=await Cr(r,"utf8"),o=h.createSourceFile(t,s,h.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?h.ScriptKind.TSX:h.ScriptKind.TS),i=[],a=[],c=[],l=[],p={id:yt(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:o.getLineAndCharacterOfPosition(o.end).line+1};i.push(p);let u=[],f=[];function g(m,x,k,w){let P=yt(n,`${t}:${k}:${w??x}:${m.pos}`);return i.push({id:P,projectId:n,name:x,qualifiedName:w??x,type:k,filePath:t,startLine:ze(o,m),endLine:o.getLineAndCharacterOfPosition(m.end).line+1}),P}function E(m){if(!h.isStringLiteral(m.moduleSpecifier))return;let x=[],k=m.importClause;if(k?.name&&x.push({localName:k.name.text,importedName:"default",kind:"default"}),k?.namedBindings&&h.isNamedImports(k.namedBindings))for(let w of k.namedBindings.elements)x.push({localName:w.name.text,importedName:w.propertyName?.text??w.name.text,kind:"named"});k?.namedBindings&&h.isNamespaceImport(k.namedBindings)&&x.push({localName:k.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:m.moduleSpecifier.text,bindings:x})}function v(m,x){for(let k of m.heritageClauses??[])for(let w of k.types){let P=w.expression.getText(o).split(".").at(-1)??"";P&&l.push({fromId:x,targetName:P,type:k.token===h.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function y(m){let x=!1,k=!1;if(h.isImportDeclaration(m)&&E(m),h.isInterfaceDeclaration(m)&&g(m,m.name.text,"interface",m.name.text),h.isClassDeclaration(m)&&m.name){let w=g(m,m.name.text,"class",m.name.text);v(m,w),f.push({id:w,name:m.name.text}),k=!0}if(h.isFunctionDeclaration(m)&&m.name){let w=g(m,m.name.text,"function",m.name.text);u.push(w),x=!0}if(h.isMethodDeclaration(m)&&m.name){let w=m.name.getText(o),P=f.at(-1)?.name,zt=g(m,w,"method",P?`${P}.${w}`:w);u.push(zt),x=!0}if(h.isCallExpression(m)&&(h.isIdentifier(m.expression)&&c.push({callerId:u.at(-1),calleeName:m.expression.text,line:ze(o,m)}),h.isPropertyAccessExpression(m.expression))){let w=m.expression;c.push({callerId:u.at(-1),qualifier:w.expression.getText(o),calleeName:w.name.text,line:ze(o,m)})}h.forEachChild(m,y),x&&u.pop(),k&&f.pop()}return y(o),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as Mr}from"node:crypto";import{dirname as Ir,extname as Rr,normalize as Tr,posix as jr}from"node:path";var M=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 Lr(n,e,t,r){return Mr("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function I(n){return Tr(n).replaceAll("\\","/")}function We(n,e,t){if(!e.startsWith("."))return;let r=I(jr.join(Ir(n),e)),s=Rr(r),o;if(s===".js"){let i=r.slice(0,-3);o=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(s===".mjs"){let i=r.slice(0,-4);o=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(s===".cjs"){let i=r.slice(0,-4);o=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else s?o=[r]:o=[`${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 o.find(i=>t.has(I(i)))}var _=class{build(e,t){let r=new M,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 o=new Set(s.keys());for(let i of t){let a=I(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 p=We(a,l.source,o);if(!p)continue;let u=s.get(p);u&&r.addEdge(this.edge(e,c.id,"IMPORTS",u.id,{source:l.source}))}for(let l of i.heritage){let p=r.findByName(e,l.targetName).filter(u=>u.type==="class"||u.type==="interface");for(let u of p)r.addEdge(this.edge(e,l.fromId,l.type,u.id))}for(let l of i.calls){if(!l.callerId)continue;let p=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,o);for(let u of p)u.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",u.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,o,i,a){let c=I(t.filePath),l=i.findByName(e,r).filter(p=>I(p.filePath)===c);if(!s&&l.length)return l;if(s)for(let p of t.imports){if(!p.bindings.find(g=>g.kind==="namespace"&&g.localName===s))continue;let f=We(c,p.source,a);if(f)return i.findByName(e,r).filter(g=>I(g.filePath)===f)}for(let p of t.imports){let u=p.bindings.find(v=>v.localName===r);if(!u)continue;let f=We(c,p.source,a);if(!f)continue;let g=u.importedName==="default"?r:u.importedName,E=i.findByName(e,g).filter(v=>I(v.filePath)===f);if(E.length)return E}return i.findByName(e,r).filter(p=>p.type==="function"||p.type==="method")}edge(e,t,r,s,o){return{id:Lr(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:o}}};function ht(n,e){let t=n.allSymbols(e),r=n.allEdges(e),s=i=>t.filter(a=>a.type===i).length,o=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:o("CALLS"),callReferences:o("CALL_REFERENCE"),imports:o("IMPORTS"),inherits:o("INHERITS"),implements:o("IMPLEMENTS"),usesType:o("USES_TYPE"),tests:o("TESTS"),routeEdges:o("ROUTE"),writes:o("WRITES")}}var oe=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(n,e){return e.ranges.length===0?!0:typeof n.startLine!="number"||typeof n.endLine!="number"?!1:e.ranges.some(t=>n.startLine<=t.endLine&&n.endLine>=t.startLine)}var ie=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let o of t){let i=r.filter(l=>l.filePath===o.filePath),c=i.filter(l=>l.type!=="file").filter(l=>_r(l,o));if(c.length===0){let l=i.find(p=>p.type==="file");l&&s.push({symbol:l,fileStatus:o.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:o.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(n){return n>=30?"CRITICAL":n>=16?"HIGH":n>=6?"MEDIUM":"LOW"}function St(n){let e=n.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),o=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let u=new Set([p.symbol.id]),f=[{id:p.symbol.id,depth:0}];for(;f.length;){let g=f.shift();if(g.depth>=r)continue;let E=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 E){if(u.has(v.from))continue;u.add(v.from);let y=this.graph.getSymbol(v.from);if(!y)continue;let m=g.depth+1,x=`${p.symbol.id}:${y.id}`;o.set(x,{symbol:y,relation:v.type,depth:m,sourceSymbolId:p.symbol.id});let k=Nr[v.type]??1;i+=Math.max(1,k-(m-1)),f.push({id:y.id,depth:m})}}}let a=[...o.values()].sort((p,u)=>p.depth-u.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(St);return l.length===0&&l.push(...c.filter(p=>!St(p)).slice(0,10)),{risk:Or(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as Kr}from"node:child_process";import{promisify as Dr}from"node:util";var He=Dr(Kr);function $r(n){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of n.matchAll(t)){let s=Number(r[1]),o=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+o-1)})}return e}function Fr(n){return n.startsWith("A")?"added":n.startsWith("D")?"deleted":n.startsWith("R")?"renamed":"modified"}async function bt(n){let e="";try{e=(await He("git",["diff","HEAD","--name-status","--no-renames"],{cwd:n,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...o]=r.split(" "),i=o.at(-1);if(!i)continue;let a="";try{a=(await He("git",["diff","HEAD","--unified=0","--",i],{cwd:n,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:Fr(s),ranges:$r(a)})}try{let r=await He("git",["ls-files","--others","--exclude-standard"],{cwd:n});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(o=>o.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 bt(t),o=this.mapper.map(e,s),i=this.blast.analyze(e,o,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 Gr=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,Br=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function vt(n){return n.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function zr(n){return n.length>0&&n.length<500&&!n.includes(`
|
|
4
|
+
`)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(n)}function Ur(n){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let s of n.matchAll(r))s[1]&&e.push(vt(s[1]));return e}function Ve(n,e,t){if(typeof n=="string"){let r=t?.toLowerCase();if(r&&Br.has(r)&&zr(n)&&e.add(vt(n)),n.includes("*** Update File:")||n.includes("*** Add File:")||n.includes("*** Delete File:")||n.includes("+++ b/"))for(let s of Ur(n))e.add(s);return}if(Array.isArray(n)){for(let r of n)Ve(r,e,t);return}if(n&&typeof n=="object")for(let[r,s]of Object.entries(n))Ve(s,e,r)}function Wr(n){return Gr.test(n.toLowerCase())}function wt(n,e){if(!Wr(n))return[];let t=new Set;return Ve(e,t),[...t]}import{createHash as Hr}from"node:crypto";import{readFile as Vr}from"node:fs/promises";async function xt(n){let e=await Vr(n);return Hr("sha256").update(e).digest("hex")}function kt(n,e){let t=n?.files??{},r=e.files,s=[],o=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let p=t[c];p?p.hash!==l.hash?o.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:o.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as qr}from"node:path";async function Et(n,e){let t=await Be(e),r={};for(let s of t)r[s]={path:s,hash:await xt(qr(e,s))};return{version:1,projectId:n,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),o=await r.load(e),i=await s.load(e),a=await Et(e,t),c=kt(o,a),l=[...c.added,...c.modified];if(o&&i&&l.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let p=i?.symbols.filter(y=>c.unchanged.includes(y.filePath))??[],u=[];for(let y of l)u.push(await Ue(e,t,y));let f=new _().build(e,u),g=new M;for(let y of p)g.addSymbol(y);for(let y of f.allSymbols(e))g.addSymbol(y);let E=new Set(g.allSymbols(e).map(y=>y.id));for(let y of i?.edges??[])E.has(y.from)&&E.has(y.to)&&!l.includes(i.symbols.find(m=>m.id===y.from)?.filePath??"")&&!l.includes(i.symbols.find(m=>m.id===y.to)?.filePath??"")&&g.addEdge(y);for(let y of f.allEdges(e))g.addEdge(y);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:o===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 o of this.records.values()){if(o.projectId!==e)continue;let i=Jr(t,o.vector);s.push({id:o.id,score:i,metadata:o.metadata})}return s.sort((o,i)=>i.score-o.score).slice(0,r)}size(){return this.records.size}};function Jr(n,e){if(n.length===0||e.length===0||n.length!==e.length)return 0;let t=0,r=0,s=0;for(let o=0;o<n.length;o++){let i=n[o]??0,a=e[o]??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 C from"typescript";import*as S from"typescript";var Bi=new Set([S.SyntaxKind.EqualsToken,S.SyntaxKind.PlusEqualsToken,S.SyntaxKind.MinusEqualsToken,S.SyntaxKind.AsteriskEqualsToken,S.SyntaxKind.SlashEqualsToken,S.SyntaxKind.PercentEqualsToken,S.SyntaxKind.QuestionQuestionEqualsToken,S.SyntaxKind.AmpersandAmpersandEqualsToken,S.SyntaxKind.BarBarEqualsToken]);var ue=class{constructor(e,t){this.embeddings=e;this.store=t}embeddings;store;async index(e){let t=e.filter(o=>!this.store.has(o.id));if(t.length===0)return 0;let r=await this.embeddings.embedMany(t.map(o=>[o.type,o.content,...o.tags??[]].join(" "))),s=0;for(let o=0;o<t.length;o++){let i=t[o],a=r[o];!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,o){this.projectId=e;this.model=t;this.embeddings=r;this.store=s;this.persistence=o}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(u=>u.id)),o=0;for(let u of this.store.exportProject(this.projectId))s.has(u.id)||this.store.remove(u.id)&&o++;let a=await new ue(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),l=c[0]?.vector.length??this.embeddings.dimensions??0,p=!1;return(a>0||o>0||!r)&&(await this.persistence.save({version:1,projectId:this.projectId,model:this.model,dimensions:l,updatedAt:new Date().toISOString(),records:c}),p=!0),{loaded:t,indexed:a,removed:o,total:c.length,saved:p}}};var pe=class{events=[];push(e){this.events.push(e)}drain(){let e=[...this.events];return this.events.length=0,e}list(){return[...this.events]}size(){return this.events.length}shouldFlush(e){return this.events.length>=e}};import{createHash as Qr}from"node:crypto";var me=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 Xr}from"node:crypto";var fe=class{constructor(e){this.queue=e}queue;sanitizer=new A;capture(e,t,r={}){let s={id:Xr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(s),s}};import{randomUUID as Zr}from"node:crypto";var ge=class{constructor(e){this.capture=e}capture;sessionId=Zr();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 ye=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(n){let e=n.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 Je(n){let e=n.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(n){let e=n.toLowerCase();return["todo","c\u1EA7n l\xE0m","ch\u01B0a xong","c\xF2n ph\u1EA3i","next:","next step","pending"].some(t=>e.includes(t))}function he(n,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":n==="rule"||n==="decision"?"high":n==="todo"||t.includes("error")||t.includes("failed")||t.includes("exception")?"normal":"temporary"}function K(n){return[...new Set(n.filter(Boolean))]}function Se(n,e=120){return n.length>e?`${n.slice(0,e)}\u2026`:n}var be=class{summarize(e){if(e.length===0)return null;let t=K(e.filter(c=>c.type==="file_write").map(c=>String(c.data.filePath??""))),r=K(e.filter(c=>c.type==="command").map(c=>Se(String(c.data.command??"")))),s=K(e.filter(c=>c.type==="error").map(c=>Se(String(c.data.message??"")))),o=K(e.filter(c=>c.type==="decision").map(c=>Se(String(c.data.content??"")))),i=K(e.filter(c=>c.type==="todo").map(c=>Se(String(c.data.content??""))));if(t.length===0&&r.length===0&&s.length===0&&o.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("; ")}`),o.length&&a.push(`- Decisions: ${o.slice(0,5).join("; ")}`),i.length&&a.push(`- TODO: ${i.slice(0,5).join("; ")}`),a.join(`
|
|
5
5
|
`)}};var ve=class{constructor(e){this.memory=e}memory;extractor=new ye;summarizer=new be;process(e){let t=0;for(let s of e){let o=this.extractor.extract(s);if(o){let i=this.refineType(o.type,o.content);this.memory.remember({projectId:s.projectId,type:i,content:o.content,importance:he(i,o.content),tags:o.tags,source:o.source,metadata:{eventId:s.id,timestamp:s.timestamp,...o.metadata}}),t++}if(s.type==="user_prompt"){let i=String(s.data.content??""),a=this.detectPromptMemoryType(i);a&&(this.memory.remember({projectId:s.projectId,type:a,content:i,importance:he(a,i),tags:["user",a],source:"auto-prompt-extractor",metadata:{eventId:s.id,timestamp:s.timestamp}}),t++)}}let r=this.summarizer.summarize(e);if(r){let s=e[0]?.projectId;s&&(this.memory.remember({projectId:s,type:"summary",content:r,importance:"temporary",tags:["summary"],source:"auto-summary",metadata:{eventCount:e.length}}),t++)}return t}refineType(e,t){return qe(t)?"rule":Ye(t)?"todo":Je(t)?"decision":e}detectPromptMemoryType(e){return qe(e)?"rule":Ye(e)?"todo":Je(e)?"decision":null}};import{createHash as en}from"node:crypto";function tn(n){return en("sha256").update([n.projectId,n.type,n.content.trim().toLowerCase()].join("|")).digest("hex")}function Ct(n){let e=new Set,t=[];for(let r of n){let s=tn(r);e.has(s)||(e.add(s),t.push(r))}return t}var we=class{projectId;memory;memoryStore;queue=new pe;capture=new fe(this.queue);session=new ge(this.capture);processor;dedup=new me;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new 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=Ct(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,o=r.maxTodos??3,i=r.maxDecisions??3,a=r.maxRelevant??5,c=r.maxCharacters??7e3,l=this.memory.byType(e,"rule").slice(0,s),p=this.memory.byType(e,"todo").slice(0,o),u=this.memory.byType(e,"decision").slice(0,i),f=this.retrieval.search(e,t,{topK:a}),g=ht(this.graph,e),E=[];E.push(["[PROJECT]",`files=${g.files}`,`classes=${g.classes}`,`functions=${g.functions}`,`methods=${g.methods}`,`calls=${g.calls}`].join(" "));for(let y of l)E.push(`[RULE] ${y.content}`);for(let y of u)E.push(`[DECISION] ${y.content}`);for(let y of p)E.push(`[TODO] ${y.content}`);for(let y of f){let x=`[${y.memory.type.toUpperCase()}] ${y.memory.content}`;E.includes(x)||E.push(x)}let v="";for(let y of E){let m=v.length===0?y:`${v}
|
|
6
6
|
${y}`;if(m.length>c)break;v=m}return v}};var ke=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
7
|
`):e}}};var At={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},Ee=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=wt(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 u of r){let f=this.guard.analyzeFile(this.projectId,u);s.push({filePath:u,risk:f.risk,riskScore:f.riskScore,impactedFiles:f.impactedFiles,suggestedTests:f.suggestedTests,impactedCount:f.impacted.length})}let o="LOW";for(let u of s)At[u.risk]>At[o]&&(o=u.risk);let i=[...new Set(s.flatMap(u=>u.impactedFiles))],a=[...new Set(s.flatMap(u=>u.suggestedTests))],c=s.reduce((u,f)=>u+f.riskScore,0),l=o==="HIGH"||o==="CRITICAL",p=["[TOOLNET IMPACT GUARD]",`Risk: ${o}`,`Risk score: ${c}`,`Files being changed: ${r.join(", ")}`,`Impacted files: ${i.length}`];return i.length&&p.push("Blast radius:",...i.slice(0,20).map(u=>`- ${u}`)),a.length&&p.push("Verify/tests:",...a.slice(0,15).map(u=>`- ${u}`)),l&&p.push("IMPORTANT: High blast radius. Inspect affected dependencies and run relevant tests after the edit."),{triggered:!0,tool:e,highestRisk:o,totalRiskScore:c,files:s,impactedFiles:i,suggestedTests:a,requiresVerification:l,context:p.join(`
|
|
8
8
|
`)}}};import{homedir as Cn}from"node:os";import{join as An}from"node:path";import{DeleteObjectCommand as rn,GetObjectCommand as nn,HeadObjectCommand as sn,ListObjectsV2Command as on,PutObjectCommand as an,S3Client as cn}from"@aws-sdk/client-s3";import{getSignedUrl as ln}from"@aws-sdk/s3-request-presigner";var Ce=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new cn({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 an({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await ln(this.client,new nn({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 sn({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 rn({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new on({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&t.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as Pt,mkdir as dn,readFile as un,readdir as pn,rm as mn,stat as Mt,writeFile as fn}from"node:fs/promises";import{dirname as gn,join as yn,relative as It,resolve as hn}from"node:path";var D=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return hn(this.root,t)}async put(e,t){let r=this.path(e);await dn(gn(r),{recursive:!0}),await fn(r,t)}async get(e){try{return await un(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await Pt(this.path(e)),!0}catch{return!1}}async delete(e){await mn(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Pt(t)}catch{return r}let s=async i=>{let a=await pn(i,{withFileTypes:!0});for(let c of a){let l=yn(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await Mt(l);r.push({key:It(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await Mt(t);return o.isDirectory()?await s(t):r.push({key:It(this.root,t),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Sn,GetObjectCommand as bn,HeadObjectCommand as vn,ListObjectsV2Command as wn,PutObjectCommand as xn,S3Client as kn}from"@aws-sdk/client-s3";import{getSignedUrl as En}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 kn({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 xn({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await En(this.client,new bn({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 vn({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 Sn({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new wn({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&t.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};function Qe(n,e){return console.warn(e),new D(n)}function Rt(n){let e=n.localRoot??An(Cn(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.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(n.provider==="s3"){let t=n.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(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new Ce({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Qe(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new D(e)}var j=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 Ae=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 Pn(n){return new Promise(e=>setTimeout(e,n))}async function Tt(n,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=t;i++)try{return await n()}catch(a){if(o=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Pn(c+l)}throw o}var Mn=new Set(["put","get","getText","delete","list"]);function jt(n,e={}){return new Proxy(n,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Mn.has(r)?(...o)=>Tt(()=>Promise.resolve(s.apply(t,o)),e):s.bind(t)}})}function Lt(n){let e=n.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function _t(n){let e=n.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var Pe=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=Lt(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 o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
9
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 Rn(n){let e=n.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function Tn(n,e){let t=`projects/${n.id}/memory/learned/`,r=await e.list(t),s=[];for(let o 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(o.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(n,e){let t=await Tn(n,e),r=new j(e),s=await r.load(n.id),o=new R;o.importRecords(s);let i=new Set(s.map(p=>Rn(p)).filter(p=>!!p)),a=0,c=0,l=0;for(let p of t)for(let u of p.candidates){if(a+=1,i.has(u.fingerprint)){l+=1;continue}o.remember({projectId:n.id,type:u.type,content:u.content,importance:u.importance,tags:u.tags,source:"session-memory-learner",metadata:{learningFingerprint:u.fingerprint,learningKind:u.kind,confidence:u.confidence,provenance:u.provenance,sourceCreatedAt:u.createdAt,sessionKey:u.sessionKey,agent:u.agent,nativeSessionId:u.nativeSessionId}}),i.add(u.fingerprint),c+=1}return c>0&&await r.save(n.id,o.exportProject(n.id)),{batches:t.length,candidates:a,added:c,duplicates:l,memories:o.exportProject(n.id).length}}import{existsSync as jn,readFileSync as Ln}from"node:fs";import{homedir as _n}from"node:os";import{join as Nn}from"node:path";function On(n){let e=n.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 Kn(){let n=process.env.TOOLNET_GLOBAL_ENV??Nn(_n(),".config","toolnet-memory",".env");if(!jn(n))return;let e=Ln(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=On(r.slice(s+1)))}}Kn();function F(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function G(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function Xe(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates: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:F(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:G(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var $n=["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(),o=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,o),c=[];for(let p of $n){let u=`${i}/${p}`,f=await this.storage.get(u);f&&(await this.storage.put(`${a}/${p}`,f,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:o,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")),o=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{o.push(JSON.parse(a))}catch{}}return o.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 o=JSON.parse(s);if(o.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of o.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 o of s)await this.storage.delete(o.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),o=0;for(let i of s)await this.remove(e,i.id),o++;return o}};import{closeSync as Fn,mkdirSync as Gn,openSync as Bn,readFileSync as zn,unlinkSync as Ot,writeFileSync as Un}from"node:fs";import{tmpdir as Wn}from"node:os";import{join as Kt}from"node:path";function Hn(n){try{return process.kill(n,0),!0}catch(e){return e?.code==="EPERM"}}var Ie=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=Kt(Wn(),"toolnet-memory-locks");Gn(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=Kt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Bn(this.path,"wx");Un(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Fn(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(zn(this.path,"utf8"));Number.isInteger(s.pid)&&Hn(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 Re=class{constructor(e){this.options=e;this.memoryStore=new j(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new Ae(e.storage),this.processLock=new Ie(e.project.id),this.retrieval=new X(this.memory),this.references=new oe(this.graph),this.hooks=new we({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 ke(this.hooks,t,e.project.id),this.impactGuard=new ce(this.graph),this.autoImpactGuard=new Ee(this.impactGuard,e.project.id)}options;memory=new R;graph=new
|
|
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 Kn(){let n=process.env.TOOLNET_GLOBAL_ENV??Nn(_n(),".config","toolnet-memory",".env");if(!jn(n))return;let e=Ln(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=On(r.slice(s+1)))}}Kn();function F(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function G(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function Xe(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates: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:F(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:G(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Qd=new A;var $n=["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(),o=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,o),c=[];for(let p of $n){let u=`${i}/${p}`,f=await this.storage.get(u);f&&(await this.storage.put(`${a}/${p}`,f,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:o,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")),o=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{o.push(JSON.parse(a))}catch{}}return o.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 o=JSON.parse(s);if(o.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of o.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 o of s)await this.storage.delete(o.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),o=0;for(let i of s)await this.remove(e,i.id),o++;return o}};import{closeSync as Fn,mkdirSync as Gn,openSync as Bn,readFileSync as zn,unlinkSync as Ot,writeFileSync as Un}from"node:fs";import{tmpdir as Wn}from"node:os";import{join as Kt}from"node:path";function Hn(n){try{return process.kill(n,0),!0}catch(e){return e?.code==="EPERM"}}var Ie=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=Kt(Wn(),"toolnet-memory-locks");Gn(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=Kt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Bn(this.path,"wx");Un(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Fn(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(zn(this.path,"utf8"));Number.isInteger(s.pid)&&Hn(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 Re=class{constructor(e){this.options=e;this.memoryStore=new j(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new Ae(e.storage),this.processLock=new Ie(e.project.id),this.retrieval=new X(this.memory),this.references=new oe(this.graph),this.hooks=new we({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 ke(this.hooks,t,e.project.id),this.impactGuard=new ce(this.graph),this.autoImpactGuard=new Ee(this.impactGuard,e.project.id)}options;memory=new R;graph=new M;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 W(this.memory).run(e.id);(s.expiredRemoved>0||s.supersededRemoved>0)&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let o=await this.graphStore.load(e.id);o&&this.graph.import(o.symbols,o.edges);let i=Fe(),c=await new O(e.id,this.options.embeddingModel,i,this.vectors,this.vectorStore).initialize(this.memory.list(e.id));return await this.hooks.sessionStart(),{memories:t.length,graphSymbols:this.graph.allSymbols(e.id).length,graphEdges:this.graph.allEdges(e.id).length,vectors:c.total,vectorsIndexed:c.indexed}}async preparePrompt(e){return this.autoRetrieval.prepare(e)}async beforeTool(e,t){let r=await this.autoImpactGuard.beforeTool(e,t);return await this.hooks.beforeTool(e,t),r}async afterTool(e,t){return this.hooks.afterTool(e,t)}async stop(){let{project:e,storage:t,embeddingModel:r}=this.options,s=new Me(t),o=await s.create(e.id,"session-end-auto");await s.prune(e.id,10),await this.hooks.sessionEnd();let i=new H(this.memory).consolidate(e.id);i.summaryCreated&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let a=await new 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=Fe(),u=await new O(e.id,r,l,this.vectors,this.vectorStore).initialize(this.memory.list(e.id)),f={code:a,vectors:u,consolidation:i,snapshot:o?.id,memories:this.memory.list(e.id).length};return await this.processLock.release(),f}};import"dotenv/config";import{createHash as Vn}from"node:crypto";import{existsSync as Ze,mkdirSync as qn,readFileSync as Jn,renameSync as Yn,writeFileSync as Qn}from"node:fs";import{basename as Xn,dirname as Te,join as Le,parse as Ft,resolve as B}from"node:path";var Gt=".toolnet",Zn="project.json";function es(n){return Vn("sha256").update(n).digest("hex").slice(0,16)}function et(n){return Le(n,Gt,Zn)}function ts(n){return Ze(et(n))}function rs(n,e){let t=B(n),r=Ft(t).root;for(;;){if(ts(t))return t;if(t===r||e&&t===B(e))break;let s=Te(t);if(s===t)break;t=s}return null}function ns(n){let e=B(n),t=Ft(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>Ze(Le(e,o))))return e;if(e===t)break;let s=Te(e);if(s===e)break;e=s}return B(n)}function ss(n){let e;try{e=JSON.parse(Jn(n,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${n}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:Te(Te(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function Dt(n,e){let t=Le(n,Gt);qn(t,{recursive:!0});let r=et(n),s=`${r}.tmp-${process.pid}`;Qn(s,JSON.stringify(e,null,2)+`
|
|
11
11
|
`,{encoding:"utf8",mode:384}),Yn(s,r)}function $t(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}var je=class{detect(e=process.cwd()){let t=B(e),r=ns(t),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Ze(Le(r,p))),i=rs(t,o?r:void 0);if(i){let p=et(i),u=ss(p);return u.rootPath!==i&&(u.rootPath=i,u.updatedAt=new Date().toISOString(),Dt(i,u)),$t(u,i)}let a=new Date().toISOString(),c=Xn(r),l={version:1,id:es(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Dt(r,l),$t(l,r)}};function Bt(n=process.cwd()){let e=Xe(),t=new je().detect(n),r=Rt({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),s=jt(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),o=new Pe(s,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new Re({project:t,storage:o,embeddingModel:i})}async function os(){let n=Bt(),e=await n.start(),t=await n.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 n.stop();console.log({stopped:!0,memories:r.memories,codeParsed:r.code.parsed,vectorsIndexed:r.vectors.indexed})}os().catch(n=>{console.error(n),process.exit(1)});
|
package/bundle/semantic.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import"dotenv/config";import{existsSync as Re,readFileSync as ke}from"node:fs";import{homedir as Ie}from"node:os";import{join as Te}from"node:path";function _e(r){let e=r.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Me(){let r=process.env.TOOLNET_GLOBAL_ENV??Te(Ie(),".config","toolnet-memory",".env");if(!Re(r))return;let e=ke(r,"utf8");for(let t of e.split(/\r?\n/)){let s=t.trim();if(!s||s.startsWith("#"))continue;s.startsWith("export ")&&(s=s.slice(7));let o=s.indexOf("=");if(o<=0)continue;let
|
|
3
|
-
`,{encoding:"utf8",mode:384}),De(o,s)}function pe(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}var F=class{detect(e=process.cwd()){let t=_(e),s=ze(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>te(K(s,p))),a=Be(t,i?s:void 0);if(a){let p=re(a),f=He(p);return f.rootPath!==a&&(f.rootPath=a,f.updatedAt=new Date().toISOString(),de(a,f)),pe(f,a)}let c=new Date().toISOString(),l=Ke(s),d={version:1,id:Ge(s),name:l,remote:l,rootPath:s,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return de(s,d),pe(d,s)}};var Ve=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],$=class{scan(e){let t=[];for(let s of Ve){let o=new RegExp(s.regex.source,s.regex.flags);for(let i of e.matchAll(o))t.push({type:s.type,value:i[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var M=class{scanner=new $;sanitize(e){let t=e,s=this.scanner.scan(e),o=new Set;for(let i of s)o.add(i.type),t=t.split(i.value).join(`[REDACTED:${i.type}]`);return{text:t,redacted:s.length,secretTypes:[...o]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[s,o]of Object.entries(e)){let i=s.toLowerCase();i.includes("password")||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")?t[s]="[REDACTED]":t[s]=this.sanitizeValue(o)}return t}return e}};import{homedir as gt}from"node:os";import{join as ht}from"node:path";import{DeleteObjectCommand as We,GetObjectCommand as Ye,HeadObjectCommand as qe,ListObjectsV2Command as Je,PutObjectCommand as Qe,S3Client as Ze}from"@aws-sdk/client-s3";import{getSignedUrl as Xe}from"@aws-sdk/s3-request-presigner";var G=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ze({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,s="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Qe({Bucket:this.bucket,Key:e,Body:o,ContentType:s}))}async get(e){let t=await Xe(this.client,new Ye({Bucket:this.bucket,Key:e}),{expiresIn:60}),s=await fetch(t,{redirect:"follow"});if(s.status===404)return null;if(!s.ok)throw new Error(`HF download failed: ${s.status} ${s.statusText}`);return new Uint8Array(await s.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new qe({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new We({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],s;do{let o=await this.client.send(new Je({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:s}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});s=o.IsTruncated?o.NextContinuationToken:void 0}while(s);return t}};import{access as fe,mkdir as et,readFile as tt,readdir as rt,rm as st,stat as ge,writeFile as ot}from"node:fs/promises";import{dirname as nt,join as it,relative as he,resolve as at}from"node:path";var N=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return at(this.root,t)}async put(e,t){let s=this.path(e);await et(nt(s),{recursive:!0}),await ot(s,t)}async get(e){try{return await tt(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 fe(this.path(e)),!0}catch{return!1}}async delete(e){await st(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),s=[];try{await fe(t)}catch{return s}let o=async a=>{let c=await rt(a,{withFileTypes:!0});for(let l of c){let d=it(a,l.name);if(l.isDirectory()){await o(d);continue}let p=await ge(d);s.push({key:he(this.root,d),size:p.size,updatedAt:p.mtime.toISOString()})}},i=await ge(t);return i.isDirectory()?await o(t):s.push({key:he(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),s}};import{DeleteObjectCommand as ct,GetObjectCommand as lt,HeadObjectCommand as dt,ListObjectsV2Command as pt,PutObjectCommand as ut,S3Client as mt}from"@aws-sdk/client-s3";import{getSignedUrl as ft}from"@aws-sdk/s3-request-presigner";var O=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new mt({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,s="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ut({Bucket:this.bucket,Key:e,Body:o,ContentType:s}))}async get(e){let t=await ft(this.client,new lt({Bucket:this.bucket,Key:e}),{expiresIn:60}),s=await fetch(t,{redirect:"follow"});if(s.status===404)return null;if(!s.ok)throw new Error(`${this.name} download failed: ${s.status} ${s.statusText}`);return new Uint8Array(await s.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 dt({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 ct({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],s;do{let o=await this.client.send(new pt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:s}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});s=o.IsTruncated?o.NextContinuationToken:void 0}while(s);return t}};function se(r,e){return console.warn(e),new N(r)}function ye(r){let e=r.localRoot??ht(gt(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new G({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new N(e)}var j=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var U=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var B=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function be(r){let e=r.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function Se(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(s)return`${s[1]}memory/records/${s[2]}`;if(s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),s)return`${s[1]}memory/vectors/${s[2]}`;if(s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),s)return`${s[1]}code/graph/${s[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var z=class{constructor(e,t,s,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=s,this.folder=be(o??s),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(),s=t,o=await this.provider.getText(e);if(o){let a;try{a=JSON.parse(o)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(s=a.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:s,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Se(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,s){return await this.ensureRegistered(),this.provider.put(this.key(e),t,s)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import*as h from"typescript";var A=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(s=>s.projectId===e&&(s.name===t||s.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 s of e)this.addSymbol(s);for(let s of t)this.addEdge(s)}clearProject(e){for(let[t,s]of this.symbols)s.projectId===e&&this.symbols.delete(t);for(let[t,s]of this.edges)s.projectId===e&&this.edges.delete(t)}};import{execFile as Et}from"node:child_process";import{promisify as Ct}from"node:util";var Qs=Ct(Et);import{createHash as vt}from"node:crypto";import{readFile as xt}from"node:fs/promises";import{join as wt}from"node:path";function Ee(r){return vt("sha256").update(r).digest("hex")}var H=class{sanitizer=new M;async build(e,t,s,o={}){let
|
|
5
|
-
`).trim();if(b){let v=this.sanitizer.sanitize(b).text,L=Ee(v),R=[t,s,
|
|
6
|
-
`)),Le=await o.embedMany(Ae);for(let C=0;C<w.length;C++){let x=w[C],P=Le[C];if(!(!x||!P||P.length===0)){if(k===void 0&&(k=P.length),P.length!==k){console.warn(`[code-semantic] skip dimension mismatch: ${P.length} != ${k}`);continue}this.vectors.upsert({id:x.id,projectId:e,vector:P,metadata:{contentHash:x.contentHash,filePath:x.filePath,symbolName:x.symbolName,symbolType:x.symbolType,startLine:x.startLine,endLine:x.endLine}}),R++}}}let ee=this.vectors.exportProject(e),ce=R>0||v>0||!y||y.model!==a;return ce&&await l.save({version:1,projectId:e,model:a,dimensions:ee[0]?.vector.length??k??0,updatedAt:new Date().toISOString(),records:ee}),{chunks:d.length,vectorsLoaded:E,vectorsIndexed:R,vectorsRemoved:v,totalVectors:ee.length,savedChunks:f,savedVectors:ce}}async search(e,t=8){let s=await this.options.embeddings.embed(e),o=this.vectors.search(this.options.projectId,s,Math.max(t*4,20)),i=new Set(oe(e)),a=[];for(let c of o){let l=this.chunks.get(c.id);if(!l)continue;let d=new Set(oe([l.filePath,l.symbolName??"",l.symbolType??"",l.content].join(" "))),p=0;for(let v of i)d.has(v)&&p++;let f=i.size===0?0:p/i.size,y=Math.max(0,c.score),E=Ce(l.filePath,e),b=(y*.75+f*.25)*E;a.push({chunk:l,score:b,vectorScore:y,lexicalScore:f})}return a.sort((c,l)=>l.score-c.score).slice(0,t)}size(){return this.chunks.size}};import*as S from"typescript";import*as u from"typescript";var on=new Set([u.SyntaxKind.EqualsToken,u.SyntaxKind.PlusEqualsToken,u.SyntaxKind.MinusEqualsToken,u.SyntaxKind.AsteriskEqualsToken,u.SyntaxKind.SlashEqualsToken,u.SyntaxKind.PercentEqualsToken,u.SyntaxKind.QuestionQuestionEqualsToken,u.SyntaxKind.AmpersandAmpersandEqualsToken,u.SyntaxKind.BarBarEqualsToken]);var ve=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function Y(r){let e=ve.find(t=>t.id===r);if(!e)throw new Error(`Unsupported AI provider: ${r}`);return e}function q(r){return ve.some(e=>e.id===r)}function n(r){return process.env[r]?.trim()||void 0}function m(...r){return r.find(e=>!!e?.trim())}function xe(){if(n("GROQ_API_KEY"))return"groq";if(n("DEEPSEEK_API_KEY"))return"deepseek";if(n("NVIDIA_API_KEY")||n("NVIDIA_NIM_API_KEY"))return"nvidia";if(n("OPENROUTER_API_KEY"))return"openrouter";if(n("ALIBABA_API_KEY")||n("DASHSCOPE_API_KEY"))return"alibaba";if(n("GEMINI_API_KEY")||n("GOOGLE_API_KEY"))return"gemini";if(n("CLOUDFLARE_API_TOKEN")&&n("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(n("HF_TOKEN"))return"huggingface";if(n("OLLAMA_MODEL")||n("OLLAMA_BASE_URL"))return"ollama"}function Lt(){let r=n("TOOLNET_LLM_PROVIDER");return r&&q(r)?r:xe()??"openai-compatible"}function ne(r){let e=Y(r);switch(r){case"alibaba":return{provider:r,apiKey:m(n("ALIBABA_API_KEY"),n("DASHSCOPE_API_KEY")),baseUrl:m(n("ALIBABA_BASE_URL"),n("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:m(n("ALIBABA_MODEL"),n("DASHSCOPE_MODEL"))};case"openrouter":return{provider:r,apiKey:n("OPENROUTER_API_KEY"),baseUrl:m(n("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:n("OPENROUTER_MODEL")};case"groq":return{provider:r,apiKey:n("GROQ_API_KEY"),baseUrl:m(n("GROQ_BASE_URL"),e.defaultBaseUrl),model:n("GROQ_MODEL")};case"deepseek":return{provider:r,apiKey:n("DEEPSEEK_API_KEY"),baseUrl:m(n("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:m(n("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:r,apiKey:m(n("NVIDIA_API_KEY"),n("NVIDIA_NIM_API_KEY")),baseUrl:m(n("NVIDIA_BASE_URL"),n("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:m(n("NVIDIA_MODEL"),n("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:r,apiKey:m(n("GEMINI_API_KEY"),n("GOOGLE_API_KEY")),baseUrl:m(n("GEMINI_BASE_URL"),e.defaultBaseUrl),model:n("GEMINI_MODEL")};case"huggingface":return{provider:r,apiKey:n("HF_TOKEN"),baseUrl:m(n("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:m(n("HF_LLM_MODEL"),n("HF_MODEL"))};case"ollama":return{provider:r,apiKey:n("OLLAMA_API_KEY"),baseUrl:m(n("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:n("OLLAMA_MODEL")};case"cloudflare":return{provider:r,accountId:n("CLOUDFLARE_ACCOUNT_ID"),apiKey:n("CLOUDFLARE_API_TOKEN"),baseUrl:n("CLOUDFLARE_AI_BASE_URL"),model:n("CLOUDFLARE_MODEL")};case"custom":return{provider:r,apiKey:n("CUSTOM_AI_API_KEY"),baseUrl:n("CUSTOM_AI_BASE_URL"),model:n("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:m(n("OPENAI_API_KEY"),n("MODEL_API_KEY")),baseUrl:m(n("OPENAI_BASE_URL"),n("MODEL_BASE_URL")),model:m(n("OPENAI_MODEL"),n("MODEL_NAME"))}}}function Rt(){let r=n("TOOLNET_LLM_PROVIDER"),e=r&&q(r)?r:Lt(),t=Y(e),s=ne(e);return{provider:e,apiKey:m(n("TOOLNET_LLM_API_KEY"),s.apiKey),baseUrl:m(n("TOOLNET_LLM_BASE_URL"),s.baseUrl,t.defaultBaseUrl),model:m(n("TOOLNET_LLM_MODEL"),s.model,t.defaultModel),accountId:m(n("TOOLNET_LLM_ACCOUNT_ID"),s.accountId)}}function kt(){let r=n("TOOLNET_EMBEDDING_PROVIDER");return r==="local"?"local":r&&q(r)?r:n("HF_TOKEN")||n("HF_EMBEDDING_MODEL")?"huggingface":"local"}function It(){let r=kt();if(r==="local")return{provider:"local",model:m(n("TOOLNET_EMBEDDING_MODEL"),n("LOCAL_EMBEDDING_MODEL"))};let e=Y(r),t,s,o,i;switch(r){case"huggingface":t=n("HF_TOKEN"),s=n("HF_INFERENCE_BASE_URL"),o=n("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=n("OPENAI_API_KEY"),s=n("OPENAI_BASE_URL"),o=n("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=n("CLOUDFLARE_API_TOKEN"),s=n("CLOUDFLARE_AI_BASE_URL"),o=n("CLOUDFLARE_EMBEDDING_MODEL"),i=n("CLOUDFLARE_ACCOUNT_ID");break;default:t=ne(r).apiKey,s=ne(r).baseUrl,o=n(`${r.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let a=m(n("TOOLNET_EMBEDDING_ACCOUNT_ID"),i),c=m(n("TOOLNET_EMBEDDING_BASE_URL"),s,e.defaultBaseUrl),l=r==="cloudflare"&&!c&&a?`https://api.cloudflare.com/client/v4/accounts/${a}/ai/v1`:c;return{provider:r,apiKey:m(n("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:l,model:m(n("TOOLNET_EMBEDDING_MODEL"),o),accountId:a}}function we(){let r=Rt(),e=It();return{llm:r,embedding:e,legacy:{llm:!n("TOOLNET_LLM_PROVIDER")&&!!xe(),embedding:!n("TOOLNET_EMBEDDING_PROVIDER")&&!!(n("HF_TOKEN")||n("HF_EMBEDDING_MODEL"))}}}var J=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),o=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,i=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!i.ok)throw new Error(`Gemini embedding failed: ${i.status} ${await i.text()}`);let c=(await i.json()).embedding?.values;if(!Array.isArray(c)||c.length===0)throw new Error("Gemini embedding returned invalid response");return c}async embedMany(e){let t=[];for(let s of e)t.push(await this.embed(s));return t}};import{createHash as Tt}from"node:crypto";var Q=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),s=e.toLowerCase().split(/\s+/).filter(Boolean);for(let o of s){let a=Tt("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[a]+=1}return _t(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function _t(r){let e=Math.sqrt(r.reduce((t,s)=>t+s*s,0));return e===0?r:r.map(t=>t/e)}var Z=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),s=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(!s.ok)throw new Error(`Embedding failed: ${s.status} ${await s.text()}`);let i=(await s.json()).data?.sort((a,c)=>(a.index??0)-(c.index??0)).map(a=>a.embedding);if(!i||i.length!==e.length||i.some(a=>!Array.isArray(a)))throw new Error("Embedding provider returned invalid response");return i}};var X=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,s=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(!s.ok)throw new Error(`HF embedding failed: ${s.status} ${await s.text()}`);let o=await s.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(i=>Mt(i))}};function Mt(r){if(!Array.isArray(r))throw new Error("Invalid embedding");if(r.length>0&&typeof r[0]=="number")return r;if(r.length>0&&Array.isArray(r[0])){let e=r;if(e.length===0)return[];let t=e[0].length,s=new Array(t).fill(0);for(let o of e)for(let i=0;i<t;i++)s[i]+=o[i]??0;for(let o=0;o<t;o++)s[o]/=e.length;return s}throw new Error("Unsupported embedding shape")}var ie=class{constructor(e,t=new Q){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Nt(r){return`https://api.cloudflare.com/client/v4/accounts/${r}/ai/v1`}function Ot(){let r=we().embedding;if(r.provider==="local")return null;if(r.provider==="huggingface")return!r.apiKey||!r.model?null:new X({token:r.apiKey,model:r.model});if(r.provider==="gemini")return!r.apiKey||!r.model?null:new J({apiKey:r.apiKey,model:r.model,baseUrl:r.baseUrl});let e=r.baseUrl;return r.provider==="cloudflare"&&!e&&r.accountId&&(e=Nt(r.accountId)),e&&r.model?new Z({apiKey:r.apiKey,baseUrl:e,model:r.model}):null}function Pe(){return new ie(Ot())}async function jt(){let r=le(),e=new F().detect(),t=ye({provider:r.storage.provider,huggingface:r.storage.huggingface,localRoot:r.storage.localRoot}),s=new z(t,e.id,e.name,e.remote??e.name),o=new A,i=await new j(s).load(e.id);if(!i)throw new Error("Code graph missing. Run npm run code:index:test first.");o.import(i.symbols,i.edges);let a=new W({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Pe(),graph:o}),c=await a.initialize(),l=process.argv.slice(2).join(" ")||"memory storage hugging face",d=await a.search(l,5);console.log({ok:!0,query:l,...c,results:d.map(p=>({score:Number(p.score.toFixed(4)),file:p.chunk.filePath,symbol:p.chunk.symbolName,lines:`${p.chunk.startLine}-${p.chunk.endLine}`,preview:p.chunk.content.replace(/\s+/g," ").slice(0,140)}))})}jt().catch(r=>{console.error(r),process.exit(1)});
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Me(){let r=process.env.TOOLNET_GLOBAL_ENV??Te(Ie(),".config","toolnet-memory",".env");if(!Re(r))return;let e=ke(r,"utf8");for(let t of e.split(/\r?\n/)){let s=t.trim();if(!s||s.startsWith("#"))continue;s.startsWith("export ")&&(s=s.slice(7));let o=s.indexOf("=");if(o<=0)continue;let n=s.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=_e(s.slice(o+1)))}}Me();function I(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function T(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function le(){return{memory:{autoCapture:I(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:I(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:I(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:I(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:T(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:T(process.env.MEMORY_RERANK_TOP,10),finalContext:T(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:T(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:I(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:T(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Ne}from"node:crypto";import{existsSync as te,mkdirSync as Oe,readFileSync as je,renameSync as De,writeFileSync as Fe}from"node:fs";import{basename as Ke,dirname as D,join as K,parse as ue,resolve as _}from"node:path";var me=".toolnet",$e="project.json";function Ge(r){return Ne("sha256").update(r).digest("hex").slice(0,16)}function re(r){return K(r,me,$e)}function Ue(r){return te(re(r))}function Be(r,e){let t=_(r),s=ue(t).root;for(;;){if(Ue(t))return t;if(t===s||e&&t===_(e))break;let o=D(t);if(o===t)break;t=o}return null}function ze(r){let e=_(r),t=ue(e).root,s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(s.some(n=>te(K(e,n))))return e;if(e===t)break;let o=D(e);if(o===e)break;e=o}return _(r)}function He(r){let e;try{e=JSON.parse(je(r,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${r}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let s=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:D(D(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:s,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:s,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 de(r,e){let t=K(r,me);Oe(t,{recursive:!0});let s=re(r),o=`${s}.tmp-${process.pid}`;Fe(o,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),De(o,s)}function pe(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}var F=class{detect(e=process.cwd()){let t=_(e),s=ze(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>te(K(s,p))),a=Be(t,n?s:void 0);if(a){let p=re(a),f=He(p);return f.rootPath!==a&&(f.rootPath=a,f.updatedAt=new Date().toISOString(),de(a,f)),pe(f,a)}let c=new Date().toISOString(),l=Ke(s),d={version:1,id:Ge(s),name:l,remote:l,rootPath:s,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return de(s,d),pe(d,s)}};var Ve=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],$=class{scan(e){let t=[];for(let s of Ve){let o=new RegExp(s.regex.source,s.regex.flags);for(let n of e.matchAll(o))t.push({type:s.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var M=class{scanner=new $;sanitize(e){let t=e,s=this.scanner.scan(e),o=new Set;for(let n of s)o.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:s.length,secretTypes:[...o]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[s,o]of Object.entries(e)){let n=s.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");n.includes("password")||n.includes("passwd")||n==="pwd"||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")||n.includes("apikey")||n.includes("accesskey")||n.includes("privatekey")||n.includes("clientsecret")||n.includes("credential")?t[s]="[REDACTED]":t[s]=this.sanitizeValue(o)}return t}return e}};import{homedir as gt}from"node:os";import{join as ht}from"node:path";import{DeleteObjectCommand as We,GetObjectCommand as Ye,HeadObjectCommand as qe,ListObjectsV2Command as Je,PutObjectCommand as Qe,S3Client as Ze}from"@aws-sdk/client-s3";import{getSignedUrl as Xe}from"@aws-sdk/s3-request-presigner";var G=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ze({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,s="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Qe({Bucket:this.bucket,Key:e,Body:o,ContentType:s}))}async get(e){let t=await Xe(this.client,new Ye({Bucket:this.bucket,Key:e}),{expiresIn:60}),s=await fetch(t,{redirect:"follow"});if(s.status===404)return null;if(!s.ok)throw new Error(`HF download failed: ${s.status} ${s.statusText}`);return new Uint8Array(await s.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new qe({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new We({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],s;do{let o=await this.client.send(new Je({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:s}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});s=o.IsTruncated?o.NextContinuationToken:void 0}while(s);return t}};import{access as fe,mkdir as et,readFile as tt,readdir as rt,rm as st,stat as ge,writeFile as ot}from"node:fs/promises";import{dirname as nt,join as it,relative as he,resolve as at}from"node:path";var N=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return at(this.root,t)}async put(e,t){let s=this.path(e);await et(nt(s),{recursive:!0}),await ot(s,t)}async get(e){try{return await tt(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 fe(this.path(e)),!0}catch{return!1}}async delete(e){await st(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),s=[];try{await fe(t)}catch{return s}let o=async a=>{let c=await rt(a,{withFileTypes:!0});for(let l of c){let d=it(a,l.name);if(l.isDirectory()){await o(d);continue}let p=await ge(d);s.push({key:he(this.root,d),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await ge(t);return n.isDirectory()?await o(t):s.push({key:he(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),s}};import{DeleteObjectCommand as ct,GetObjectCommand as lt,HeadObjectCommand as dt,ListObjectsV2Command as pt,PutObjectCommand as ut,S3Client as mt}from"@aws-sdk/client-s3";import{getSignedUrl as ft}from"@aws-sdk/s3-request-presigner";var O=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new mt({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,s="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ut({Bucket:this.bucket,Key:e,Body:o,ContentType:s}))}async get(e){let t=await ft(this.client,new lt({Bucket:this.bucket,Key:e}),{expiresIn:60}),s=await fetch(t,{redirect:"follow"});if(s.status===404)return null;if(!s.ok)throw new Error(`${this.name} download failed: ${s.status} ${s.statusText}`);return new Uint8Array(await s.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 dt({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 ct({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],s;do{let o=await this.client.send(new pt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:s}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});s=o.IsTruncated?o.NextContinuationToken:void 0}while(s);return t}};function se(r,e){return console.warn(e),new N(r)}function ye(r){let e=r.localRoot??ht(gt(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new G({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):se(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new N(e)}var j=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var U=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var B=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function be(r){let e=r.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function Se(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(s)return`${s[1]}memory/records/${s[2]}`;if(s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),s)return`${s[1]}memory/vectors/${s[2]}`;if(s=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),s)return`${s[1]}code/graph/${s[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var z=class{constructor(e,t,s,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=s,this.folder=be(o??s),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(),s=t,o=await this.provider.getText(e);if(o){let a;try{a=JSON.parse(o)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(s=a.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:s,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Se(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,s){return await this.ensureRegistered(),this.provider.put(this.key(e),t,s)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import*as h from"typescript";var A=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(s=>s.projectId===e&&(s.name===t||s.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 s of e)this.addSymbol(s);for(let s of t)this.addEdge(s)}clearProject(e){for(let[t,s]of this.symbols)s.projectId===e&&this.symbols.delete(t);for(let[t,s]of this.edges)s.projectId===e&&this.edges.delete(t)}};import{execFile as Et}from"node:child_process";import{promisify as Ct}from"node:util";var Qs=Ct(Et);import{createHash as vt}from"node:crypto";import{readFile as xt}from"node:fs/promises";import{join as wt}from"node:path";function Ee(r){return vt("sha256").update(r).digest("hex")}var H=class{sanitizer=new M;async build(e,t,s,o={}){let n=o.maxLines??80,a=o.overlapLines??10,c=new Map;for(let d of s){let p=c.get(d.filePath)??[];p.push(d),c.set(d.filePath,p)}let l=[];for(let[d,p]of c){let f;try{f=await xt(wt(t,d),"utf8")}catch{continue}let y=f.split(/\r?\n/),E=p.filter(b=>b.type!=="file"&&typeof b.startLine=="number"&&typeof b.endLine=="number");if(E.length>0)for(let b of E)l.push(...this.chunkRange({projectId:e,filePath:d,lines:y,symbol:b,startLine:b.startLine,endLine:b.endLine,maxLines:n,overlapLines:a}));else l.push(...this.chunkRange({projectId:e,filePath:d,lines:y,startLine:1,endLine:Math.max(1,y.length),maxLines:n,overlapLines:a}))}return l}chunkRange(e){let{projectId:t,filePath:s,lines:o,symbol:n,maxLines:a}=e,c=Math.min(e.overlapLines,Math.max(0,a-1)),l=Math.max(1,e.startLine),d=Math.min(o.length,Math.max(l,e.endLine)),p=[],f=l,y=0;for(;f<=d;){let E=Math.min(d,f+a-1),b=o.slice(f-1,E).join(`
|
|
5
|
+
`).trim();if(b){let v=this.sanitizer.sanitize(b).text,L=Ee(v),R=[t,s,n?.id??"file",String(y),L].join(":");p.push({id:Ee(R).slice(0,32),projectId:t,filePath:s,symbolId:n?.id,symbolName:n?.qualifiedName??n?.name,symbolType:n?.type,startLine:f,endLine:E,content:v,contentHash:L})}if(E>=d)break;f=E-c+1,y++}return p}};var V=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[s,o]of this.records)o.projectId===e&&(this.records.delete(s),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let s of e)!s?.id||!s?.projectId||!Array.isArray(s.vector)||(this.records.set(s.id,s),t++);return t}search(e,t,s=10){let o=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let a=Pt(t,n.vector);o.push({id:n.id,score:a,metadata:n.metadata})}return o.sort((n,a)=>a.score-n.score).slice(0,s)}size(){return this.records.size}};function Pt(r,e){if(r.length===0||e.length===0||r.length!==e.length)return 0;let t=0,s=0,o=0;for(let n=0;n<r.length;n++){let a=r[n]??0,c=e[n]??0;t+=a*c,s+=a*a,o+=c*c}return s===0||o===0?0:t/(Math.sqrt(s)*Math.sqrt(o))}function oe(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}function Ce(r,e){let t=r.toLowerCase().replaceAll("\\","/"),s=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(s);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var W=class{constructor(e){this.options=e}options;vectors=new V;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:s,embeddings:o,graph:n,model:a}=this.options,c=new U(s),l=new B(s),d=await new H().build(e,t,n.allSymbols(e));this.chunks.clear();for(let g of d)this.chunks.set(g.id,g);let p=await c.load(e),f=!p||p.chunks.length!==d.length||p.chunks.some(g=>!this.chunks.has(g.id));f&&await c.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:d});let y=await l.load(e),E=0;y&&y.model===a&&(E=this.vectors.importRecords(y.records));let b=new Set(d.map(g=>g.id)),v=0;for(let g of this.vectors.exportProject(e))b.has(g.id)||this.vectors.remove(g.id)&&v++;let L=d.filter(g=>{let w=this.vectors.get(g.id);return w?w.metadata?.contentHash!==g.contentHash:!0}),R=0,ae=8,k=this.vectors.exportProject(e)[0]?.vector.length;for(let g=0;g<L.length;g+=ae){let w=L.slice(g,g+ae),Ae=w.map(C=>[`file: ${C.filePath}`,C.symbolName?`symbol: ${C.symbolName}`:"",C.symbolType?`type: ${C.symbolType}`:"",C.content].filter(Boolean).join(`
|
|
6
|
+
`)),Le=await o.embedMany(Ae);for(let C=0;C<w.length;C++){let x=w[C],P=Le[C];if(!(!x||!P||P.length===0)){if(k===void 0&&(k=P.length),P.length!==k){console.warn(`[code-semantic] skip dimension mismatch: ${P.length} != ${k}`);continue}this.vectors.upsert({id:x.id,projectId:e,vector:P,metadata:{contentHash:x.contentHash,filePath:x.filePath,symbolName:x.symbolName,symbolType:x.symbolType,startLine:x.startLine,endLine:x.endLine}}),R++}}}let ee=this.vectors.exportProject(e),ce=R>0||v>0||!y||y.model!==a;return ce&&await l.save({version:1,projectId:e,model:a,dimensions:ee[0]?.vector.length??k??0,updatedAt:new Date().toISOString(),records:ee}),{chunks:d.length,vectorsLoaded:E,vectorsIndexed:R,vectorsRemoved:v,totalVectors:ee.length,savedChunks:f,savedVectors:ce}}async search(e,t=8){let s=await this.options.embeddings.embed(e),o=this.vectors.search(this.options.projectId,s,Math.max(t*4,20)),n=new Set(oe(e)),a=[];for(let c of o){let l=this.chunks.get(c.id);if(!l)continue;let d=new Set(oe([l.filePath,l.symbolName??"",l.symbolType??"",l.content].join(" "))),p=0;for(let v of n)d.has(v)&&p++;let f=n.size===0?0:p/n.size,y=Math.max(0,c.score),E=Ce(l.filePath,e),b=(y*.75+f*.25)*E;a.push({chunk:l,score:b,vectorScore:y,lexicalScore:f})}return a.sort((c,l)=>l.score-c.score).slice(0,t)}size(){return this.chunks.size}};import*as S from"typescript";import*as u from"typescript";var on=new Set([u.SyntaxKind.EqualsToken,u.SyntaxKind.PlusEqualsToken,u.SyntaxKind.MinusEqualsToken,u.SyntaxKind.AsteriskEqualsToken,u.SyntaxKind.SlashEqualsToken,u.SyntaxKind.PercentEqualsToken,u.SyntaxKind.QuestionQuestionEqualsToken,u.SyntaxKind.AmpersandAmpersandEqualsToken,u.SyntaxKind.BarBarEqualsToken]);var ve=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function Y(r){let e=ve.find(t=>t.id===r);if(!e)throw new Error(`Unsupported AI provider: ${r}`);return e}function q(r){return ve.some(e=>e.id===r)}function i(r){return process.env[r]?.trim()||void 0}function m(...r){return r.find(e=>!!e?.trim())}function xe(){if(i("GROQ_API_KEY"))return"groq";if(i("DEEPSEEK_API_KEY"))return"deepseek";if(i("NVIDIA_API_KEY")||i("NVIDIA_NIM_API_KEY"))return"nvidia";if(i("OPENROUTER_API_KEY"))return"openrouter";if(i("ALIBABA_API_KEY")||i("DASHSCOPE_API_KEY"))return"alibaba";if(i("GEMINI_API_KEY")||i("GOOGLE_API_KEY"))return"gemini";if(i("CLOUDFLARE_API_TOKEN")&&i("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(i("HF_TOKEN"))return"huggingface";if(i("OLLAMA_MODEL")||i("OLLAMA_BASE_URL"))return"ollama"}function Lt(){let r=i("TOOLNET_LLM_PROVIDER");return r&&q(r)?r:xe()??"openai-compatible"}function ne(r){let e=Y(r);switch(r){case"alibaba":return{provider:r,apiKey:m(i("ALIBABA_API_KEY"),i("DASHSCOPE_API_KEY")),baseUrl:m(i("ALIBABA_BASE_URL"),i("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:m(i("ALIBABA_MODEL"),i("DASHSCOPE_MODEL"))};case"openrouter":return{provider:r,apiKey:i("OPENROUTER_API_KEY"),baseUrl:m(i("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:i("OPENROUTER_MODEL")};case"groq":return{provider:r,apiKey:i("GROQ_API_KEY"),baseUrl:m(i("GROQ_BASE_URL"),e.defaultBaseUrl),model:i("GROQ_MODEL")};case"deepseek":return{provider:r,apiKey:i("DEEPSEEK_API_KEY"),baseUrl:m(i("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:m(i("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:r,apiKey:m(i("NVIDIA_API_KEY"),i("NVIDIA_NIM_API_KEY")),baseUrl:m(i("NVIDIA_BASE_URL"),i("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:m(i("NVIDIA_MODEL"),i("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:r,apiKey:m(i("GEMINI_API_KEY"),i("GOOGLE_API_KEY")),baseUrl:m(i("GEMINI_BASE_URL"),e.defaultBaseUrl),model:i("GEMINI_MODEL")};case"huggingface":return{provider:r,apiKey:i("HF_TOKEN"),baseUrl:m(i("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:m(i("HF_LLM_MODEL"),i("HF_MODEL"))};case"ollama":return{provider:r,apiKey:i("OLLAMA_API_KEY"),baseUrl:m(i("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:i("OLLAMA_MODEL")};case"cloudflare":return{provider:r,accountId:i("CLOUDFLARE_ACCOUNT_ID"),apiKey:i("CLOUDFLARE_API_TOKEN"),baseUrl:i("CLOUDFLARE_AI_BASE_URL"),model:i("CLOUDFLARE_MODEL")};case"custom":return{provider:r,apiKey:i("CUSTOM_AI_API_KEY"),baseUrl:i("CUSTOM_AI_BASE_URL"),model:i("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:m(i("OPENAI_API_KEY"),i("MODEL_API_KEY")),baseUrl:m(i("OPENAI_BASE_URL"),i("MODEL_BASE_URL")),model:m(i("OPENAI_MODEL"),i("MODEL_NAME"))}}}function Rt(){let r=i("TOOLNET_LLM_PROVIDER"),e=r&&q(r)?r:Lt(),t=Y(e),s=ne(e);return{provider:e,apiKey:m(i("TOOLNET_LLM_API_KEY"),s.apiKey),baseUrl:m(i("TOOLNET_LLM_BASE_URL"),s.baseUrl,t.defaultBaseUrl),model:m(i("TOOLNET_LLM_MODEL"),s.model,t.defaultModel),accountId:m(i("TOOLNET_LLM_ACCOUNT_ID"),s.accountId)}}function kt(){let r=i("TOOLNET_EMBEDDING_PROVIDER");return r==="local"?"local":r&&q(r)?r:i("HF_TOKEN")||i("HF_EMBEDDING_MODEL")?"huggingface":"local"}function It(){let r=kt();if(r==="local")return{provider:"local",model:m(i("TOOLNET_EMBEDDING_MODEL"),i("LOCAL_EMBEDDING_MODEL"))};let e=Y(r),t,s,o,n;switch(r){case"huggingface":t=i("HF_TOKEN"),s=i("HF_INFERENCE_BASE_URL"),o=i("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=i("OPENAI_API_KEY"),s=i("OPENAI_BASE_URL"),o=i("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=i("CLOUDFLARE_API_TOKEN"),s=i("CLOUDFLARE_AI_BASE_URL"),o=i("CLOUDFLARE_EMBEDDING_MODEL"),n=i("CLOUDFLARE_ACCOUNT_ID");break;default:t=ne(r).apiKey,s=ne(r).baseUrl,o=i(`${r.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let a=m(i("TOOLNET_EMBEDDING_ACCOUNT_ID"),n),c=m(i("TOOLNET_EMBEDDING_BASE_URL"),s,e.defaultBaseUrl),l=r==="cloudflare"&&!c&&a?`https://api.cloudflare.com/client/v4/accounts/${a}/ai/v1`:c;return{provider:r,apiKey:m(i("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:l,model:m(i("TOOLNET_EMBEDDING_MODEL"),o),accountId:a}}function we(){let r=Rt(),e=It();return{llm:r,embedding:e,legacy:{llm:!i("TOOLNET_LLM_PROVIDER")&&!!xe(),embedding:!i("TOOLNET_EMBEDDING_PROVIDER")&&!!(i("HF_TOKEN")||i("HF_EMBEDDING_MODEL"))}}}var J=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),o=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,n=await fetch(o,{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 c=(await n.json()).embedding?.values;if(!Array.isArray(c)||c.length===0)throw new Error("Gemini embedding returned invalid response");return c}async embedMany(e){let t=[];for(let s of e)t.push(await this.embed(s));return t}};import{createHash as Tt}from"node:crypto";var Q=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),s=e.toLowerCase().split(/\s+/).filter(Boolean);for(let o of s){let a=Tt("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[a]+=1}return _t(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function _t(r){let e=Math.sqrt(r.reduce((t,s)=>t+s*s,0));return e===0?r:r.map(t=>t/e)}var Z=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),s=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(!s.ok)throw new Error(`Embedding failed: ${s.status} ${await s.text()}`);let n=(await s.json()).data?.sort((a,c)=>(a.index??0)-(c.index??0)).map(a=>a.embedding);if(!n||n.length!==e.length||n.some(a=>!Array.isArray(a)))throw new Error("Embedding provider returned invalid response");return n}};var X=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,s=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(!s.ok)throw new Error(`HF embedding failed: ${s.status} ${await s.text()}`);let o=await s.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(n=>Mt(n))}};function Mt(r){if(!Array.isArray(r))throw new Error("Invalid embedding");if(r.length>0&&typeof r[0]=="number")return r;if(r.length>0&&Array.isArray(r[0])){let e=r;if(e.length===0)return[];let t=e[0].length,s=new Array(t).fill(0);for(let o of e)for(let n=0;n<t;n++)s[n]+=o[n]??0;for(let o=0;o<t;o++)s[o]/=e.length;return s}throw new Error("Unsupported embedding shape")}var ie=class{constructor(e,t=new Q){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}};function Nt(r){return`https://api.cloudflare.com/client/v4/accounts/${r}/ai/v1`}function Ot(){let r=we().embedding;if(r.provider==="local")return null;if(r.provider==="huggingface")return!r.apiKey||!r.model?null:new X({token:r.apiKey,model:r.model});if(r.provider==="gemini")return!r.apiKey||!r.model?null:new J({apiKey:r.apiKey,model:r.model,baseUrl:r.baseUrl});let e=r.baseUrl;return r.provider==="cloudflare"&&!e&&r.accountId&&(e=Nt(r.accountId)),e&&r.model?new Z({apiKey:r.apiKey,baseUrl:e,model:r.model}):null}function Pe(){return new ie(Ot())}async function jt(){let r=le(),e=new F().detect(),t=ye({provider:r.storage.provider,huggingface:r.storage.huggingface,localRoot:r.storage.localRoot}),s=new z(t,e.id,e.name,e.remote??e.name),o=new A,n=await new j(s).load(e.id);if(!n)throw new Error("Code graph missing. Run npm run code:index:test first.");o.import(n.symbols,n.edges);let a=new W({projectId:e.id,rootPath:e.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:s,embeddings:Pe(),graph:o}),c=await a.initialize(),l=process.argv.slice(2).join(" ")||"memory storage hugging face",d=await a.search(l,5);console.log({ok:!0,query:l,...c,results:d.map(p=>({score:Number(p.score.toFixed(4)),file:p.chunk.filePath,symbol:p.chunk.symbolName,lines:`${p.chunk.startLine}-${p.chunk.endLine}`,preview:p.chunk.content.replace(/\s+/g," ").slice(0,140)}))})}jt().catch(r=>{console.error(r),process.exit(1)});
|
package/bundle/service-cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{existsSync as E}from"node:fs";import{dirname as M,join as O}from"node:path";import{fileURLToPath as k}from"node:url";import{spawnSync as C}from"node:child_process";import{createConnection as T}from"node:net";import{homedir as y}from"node:os";import{join as N}from"node:path";function v(){return process.env.TOOLNET_SERVICE_SOCKET??N(y(),".toolnet","run","service.sock")}function P(e,t={}){let o=t.socketPath??v(),f=t.timeoutMs??1e3;return new Promise((
|
|
1
|
+
import{existsSync as E}from"node:fs";import{dirname as M,join as O}from"node:path";import{fileURLToPath as k}from"node:url";import{spawnSync as C}from"node:child_process";import{createConnection as T}from"node:net";import{homedir as y}from"node:os";import{join as N}from"node:path";function v(){return process.env.TOOLNET_SERVICE_SOCKET??N(y(),".toolnet","run","service.sock")}function P(e,t={}){let o=t.socketPath??v(),f=t.timeoutMs??1e3;return new Promise((h,c)=>{let n=T({path:o}),a="",u=!1,l=i=>{u||(u=!0,clearTimeout(S),n.destroy(),i())},S=setTimeout(()=>{l(()=>{c(new Error(`ToolNet service timeout after ${f}ms`))})},f);n.setEncoding("utf8"),n.once("connect",()=>{n.write(`${JSON.stringify(e)}
|
|
2
2
|
`)}),n.on("data",i=>{a+=i;let m=a.indexOf(`
|
|
3
|
-
`);if(m===-1)return;let w=a.slice(0,m).trim();l(()=>{try{
|
|
3
|
+
`);if(m===-1)return;let w=a.slice(0,m).trim();l(()=>{try{h(JSON.parse(w))}catch(p){c(p instanceof Error?p:new Error(String(p)))}})}),n.once("error",i=>{l(()=>{c(i)})}),n.once("end",()=>{u||l(()=>{c(new Error("ToolNet service closed without response"))})})})}async function d(e={}){let t=await P({type:"ping"},e);if(!t.ok||t.type!=="ping")throw new Error(t.ok?"Invalid ToolNet service ping response":t.error);return t}var s=process.env.TOOLNET_PM2_NAME??"toolnet-memory-service";function r(e,t=!1){let o=C("pm2",e,{encoding:"utf8",stdio:t?"pipe":"inherit"});if(o.error)throw o.error;return o}function x(){if(r(["--version"],!0).status!==0)throw new Error("PM2 is not installed. Install it with: npm install -g pm2")}function R(){let e=M(k(import.meta.url)),t=O(e,"service.js");if(!E(t))throw new Error(`Production service bundle missing: ${t}`);return t}function $(){return r(["describe",s],!0).status===0}async function g(e){try{let t=await d({timeoutMs:500});if(e){console.log(JSON.stringify({running:!0,...t.stats},null,2));return}console.log(""),console.log("\u25C7 ToolNet Memory Service"),console.log(""),console.log("\u25C6 Daemon"),console.log("\u2502"),console.log("\u251C \u25C6 Status \u2014 running"),console.log(`\u251C \u25C6 PID \u2014 ${t.stats.pid}`),console.log(`\u251C \u25C6 Cache entries \u2014 ${t.stats.cacheEntries}`),console.log(`\u251C \u25C6 Cache hits \u2014 ${t.stats.cacheHits}`),console.log(`\u251C \u25C6 Cache misses \u2014 ${t.stats.cacheMisses}`),console.log("\u2502"),console.log("\u2514 \u25C6 Service healthy"),console.log("")}catch{if(e){console.log(JSON.stringify({running:!1},null,2));return}console.log(""),console.log("\u25C7 ToolNet Memory Service"),console.log(""),console.log("\u25C6 Daemon"),console.log("\u2502"),console.log("\u2514 \u25C7 Status \u2014 stopped"),console.log("")}}async function b(){let e=process.argv[2]??"status",t=process.argv.includes("--json");if(e==="status"){await g(t);return}if(x(),e==="install"){if($()){if(r(["restart",s,"--update-env"],!0).status!==0)throw new Error("PM2 restart failed")}else if(r(["start",R(),"--name",s,"--interpreter",process.execPath,"--time"],!0).status!==0)throw new Error("PM2 install failed");r(["save"],!0),await g(!1);return}if(e==="start"){if(r(["start",s],!0).status!==0)throw new Error("Service is not installed. Run toolnet-memory service:install");return}if(e==="stop"){if(r(["stop",s],!0).status!==0)throw new Error("PM2 stop failed");return}if(e==="restart"){if(r(["restart",s,"--update-env"],!0).status!==0)throw new Error("PM2 restart failed");return}if(e==="remove"){if(r(["delete",s],!0).status!==0)throw new Error("PM2 delete failed");r(["save"],!0);return}throw new Error(`Unknown service command: ${e}`)}b().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});
|