toolnet-memory 0.3.14 → 0.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +0 -1
- package/.release-target +1 -1
- package/README.md +25 -1
- package/bin/toolnet-memory +5 -0
- package/bundle/agy-hook.js +67 -67
- package/bundle/agy.js +61 -61
- package/bundle/api.js +15 -15
- package/bundle/auto-integrate.js +28 -28
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +51 -50
- package/bundle/codex-context.js +25 -24
- package/bundle/codex.js +71 -71
- package/bundle/context-runtime.js +45 -44
- package/bundle/context.js +15 -15
- package/bundle/continuity-certify.js +13 -13
- package/bundle/copilot-hook.js +87 -85
- package/bundle/copilot.js +4 -4
- package/bundle/cursor-hook.js +87 -85
- package/bundle/cursor.js +4 -4
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +20 -20
- package/bundle/gc.js +3 -0
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +60 -59
- package/bundle/grok.js +5 -5
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +4 -4
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -4
- package/bundle/init.js +37 -37
- package/bundle/integration-status.js +4 -4
- package/bundle/kiro-hook.js +82 -81
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +7 -7
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +80 -80
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +15 -15
- package/bundle/runtime.js +13 -12
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +60 -60
- package/bundle/work-continuity.js +7 -7
- package/package.json +9 -3
- package/release-manifest.json +54 -3
package/bundle/learner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),ze(n,o)}function G(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 b=class{detect(e=process.cwd()){let t=v(e),o=Ye(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>K(x(o,l))),i=Ue(t,s?o:void 0);if(i){let l=$(i),m=We(l);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),W(i,m)),G(m,i)}let a=new Date().toISOString(),c=Ve(o),u={version:1,id:Je(o),name:c,remote:c,rootPath:o,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return W(o,u),G(u,o)}};import{randomUUID as gt}from"node:crypto";var Ge=[{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}],k=class{scan(e){let t=[];for(let o of Ge){let n=new RegExp(o.regex.source,o.regex.flags);for(let s of e.matchAll(n))t.push({type:o.type,value:s[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var R=class{scanner=new k;sanitize(e){let t=e,o=this.scanner.scan(e),n=new Set;for(let s of o)n.add(s.type),t=t.split(s.value).join(`[REDACTED:${s.type}]`);return{text:t,redacted:o.length,secretTypes:[...n]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e)){let s=o.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")?t[o]="[REDACTED]":t[o]=this.sanitizeValue(n)}return t}return e}};var qe=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Qe=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 Z(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Qe.has(e)))}function Ze(r,e){let t=Z(r),o=Z(e);if(t.size===0||o.size===0)return 0;let n=0;for(let i of t)o.has(i)&&(n+=1);let s=new Set([...t,...o]).size;return s===0?0:n/s}function X(r){return new Set(r.tags.filter(e=>!qe.has(e.toLowerCase())))}function D(r){let e=r.metadata?.evidence;if(!e||typeof e!="object")return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,o=Number(t.crossSessionConfirmations);return{userExplicit:t.userExplicit===!0,sourceVerified:t.sourceVerified===!0,testVerified:t.testVerified===!0,crossSessionConfirmations:Number.isFinite(o)?Math.max(0,o):0,assistantDerived:t.assistantDerived===!0}}function Xe(r){let e=D(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function et(r){let e=Number(r.metadata?.confidence);return!Number.isFinite(e)||e<0?0:e>1?1:e}function tt(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function ee(r){let e=D(r),t=tt(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=et(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function te(r){let e=r.metadata?.topic;if(typeof e!="string")return;let t=e.normalize("NFKC").trim().toLowerCase();if(t)return t}function rt(r,e){let t=X(r),o=X(e);for(let n of t)if(o.has(n))return!0;return!1}function ot(r,e){if(e.id===r.id||e.projectId!==r.projectId||e.type!==r.type||e.metadata?.supersededBy)return!1;let t=te(r),o=te(e);return t&&o&&t===o||rt(r,e)?!0:Ze(r.content,e.content)>=.6}function re(r){return r.type!=="rule"?!1:D(r).userExplicit}function nt(r,e){return!re(r)||!re(e)?!1:r.createdAt>=e.createdAt}var I=class{resolve(e,t){if(e.type!=="rule"&&e.type!=="decision")return{superseded:[],conflicts:[]};let o=[],n=[],s=ee(e);for(let i of t){if(!ot(e,i))continue;let a=ee(i);if(s>a){o.push(i);continue}if(s<a){n.push(i);continue}if(nt(e,i)){o.push(i);continue}if(!Xe(i)&&e.createdAt>=i.createdAt){o.push(i);continue}n.push(i)}return{superseded:o,conflicts:n}}findSuperseded(e,t){return this.resolve(e,t).superseded}};var st=new Set(["code","decision","rule","todo","summary"]);function it(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function oe(r){return r.tags.includes("class:permanent")?4:r.tags.includes("class:task")?3:r.tags.includes("class:session")?2:r.tags.includes("class:transient")?1:0}function at(r,e){let t=oe(e)-oe(r);if(t!==0)return t;let o=e.importanceScore-r.importanceScore;if(o!==0)return o;let n=e.updatedAt.localeCompare(r.updatedAt);if(n!==0)return n;let s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function ne(r){let e=new Set,t=[];for(let o of r){let n=o.trim();if(!n)continue;let s=n.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(n))}return t}function se(r){let e=new Map;for(let n of r){if(!st.has(n.type)||n.metadata?.supersededBy)continue;let s=it(n.content);if(!s)continue;let i=[n.projectId,n.type,s].join("\0"),a=e.get(i)??[];a.push(n),e.set(i,a)}let t=[],o=0;for(let n of e.values()){if(n.length<2)continue;let s=[...n].sort(at),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:ne(s.flatMap(c=>c.tags)),mergedSources:ne(s.map(c=>c.source))}),o+=a.length}return{groups:t,duplicates:o}}function H(r){if(r.tags.includes("class:permanent"))return"permanent";if(r.tags.includes("class:task"))return"task";if(r.tags.includes("class:session"))return"session";if(r.tags.includes("class:transient"))return"transient"}function ct(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function ut(r){let e=H(r);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(r.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 dt(r){return H(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function pt(r){let e=r.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 ie(r,e=Date.now()){let t=50,o=[],n=H(r);switch(n==="permanent"?(t+=25,o.push("permanent project knowledge")):n==="task"?(t+=15,o.push("active task knowledge")):n==="session"?(t+=2,o.push("session-scoped knowledge")):n==="transient"&&(t-=25,o.push("transient knowledge")),r.importance){case"critical":t+=25,o.push("critical importance");break;case"high":t+=15,o.push("high importance");break;case"normal":break;case"temporary":t-=15,o.push("temporary importance");break}(r.type==="rule"||r.type==="decision")&&(t+=10,o.push("durable knowledge type"));let s=r.content.trim().length;s<12?(t-=30,o.push("very short content")):s<30?(t-=10,o.push("limited context")):s<=1200?(t+=8,o.push("useful context density")):s>5e3&&(t-=15,o.push("excessively large memory")),pt(r.content)&&(t-=35,o.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,o.push("confirmed across multiple sources"));let a=ct(r,e)>=ut(r);a&&(t-=15,o.push("stale for lifecycle class"));let c=dt(r);t=Math.max(0,Math.min(100,Math.round(t)));let u;t>=80?u="trusted":t>=55?u="useful":t>=30?u="weak":u="noise";let l=r.importance==="temporary"||r.type==="activity"||n==="transient";return{score:t,tier:u,stale:a,protected:c,pruneEligible:!c&&(u==="noise"&&l||a&&(u==="noise"||u==="weak")),reasons:o}}var lt={critical:100,high:75,normal:50,temporary:20},mt={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function ae(r,e,t=new Date){let o;if(e==="temporary"&&(o=30),r==="activity"&&(o=Math.min(o??14,14)),r==="summary"&&(o=Math.min(o??30,30)),!!o)return new Date(t.getTime()+o*864e5).toISOString()}function z(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function ft(r){return!!r.metadata?.supersededBy}function L(r,e=Date.now()){return!z(r,e)&&!ft(r)}function V(r,e=Date.now()){if(!L(r,e))return 0;let t=lt[r.importance];if(r.importance==="critical")return t;let o=mt[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/o);return t*i}var P=class{memories=new Map;sanitizer=new R;conflicts=new I;remember(e){let t=new Date().toISOString(),o=this.sanitizer.sanitize(e.content.trim()).text,n=e.importance??Y(e.type,o),s={id:gt(),projectId:e.projectId,type:e.type,content:o,importance:n,importanceScore:U(n),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??ae(e.type,n,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.resolve(s,this.list(e.projectId));if(i.superseded.length>0){s.metadata={...s.metadata??{},supersedes:i.superseded.map(a=>a.id)};for(let a of i.superseded)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}if(i.conflicts.length>0){let a=i.conflicts.map(c=>c.id);s.metadata={...s.metadata??{},conflictsWith:a};for(let c of i.conflicts){let u=Array.isArray(c.metadata?.conflictsWith)?c.metadata?.conflictsWith:[],l=new Set(u.filter(m=>typeof m=="string"));l.add(s.id),c.updatedAt=t,c.metadata={...c.metadata??{},conflictsWith:[...l]},this.memories.set(c.id,c)}}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let o of e)o?.id&&(this.memories.set(o.id,o),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,o)=>o.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>L(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(o=>o.type===t)}search(e){let t=e.query.trim().toLowerCase(),o=e.limit??10,n=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=V(s);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>s.tags.includes(c)))}).map(s=>{let i=s.content.toLowerCase(),a=n.filter(l=>i.includes(l)).length,c=n.length===0?0:a/n.length,u=V(s)/500;return{memory:s,score:c+u,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,o)}consolidate(e,t=Date.now()){let o=se(this.list(e)),n=[],s=0;for(let i of o.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),n.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:n.length,duplicatesRemoved:s,canonicalIds:n}}reviewLifecycle(e,t=Date.now()){let o={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let n of this.list(e)){let s=ie(n,t);o.reviewed+=1,o[s.tier]+=1,s.stale&&(o.stale+=1),s.protected&&(o.protected+=1),n.metadata={...n.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:s.score,tier:s.tier,stale:s.stale,protected:s.protected,reasons:s.reasons}},this.memories.set(n.id,n),s.pruneEligible&&this.memories.delete(n.id)&&(o.pruned+=1)}return o}pruneExpired(e,t=Date.now()){let o=0;for(let[n,s]of this.memories)s.projectId===e&&z(s,t)&&(this.memories.delete(n),o++);return o}pruneSuperseded(e,t=30,o=Date.now()){let n=0,s=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;o-new Date(c).getTime()>=s&&(this.memories.delete(i),n++)}return n}clearProject(e){let t=0;for(let[o,n]of this.memories)n.projectId===e&&(this.memories.delete(o),t++);return t}};import{homedir as Dt}from"node:os";import{join as Ht}from"node:path";import{DeleteObjectCommand as yt,GetObjectCommand as ht,HeadObjectCommand as St,ListObjectsV2Command as vt,PutObjectCommand as wt,S3Client as jt}from"@aws-sdk/client-s3";import{getSignedUrl as Mt}from"@aws-sdk/s3-request-presigner";var A=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new jt({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new wt({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await Mt(this.client,new ht({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`HF download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new St({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 yt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new vt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}};import{access as ce,mkdir as bt,readFile as xt,readdir as kt,rm as Rt,stat as ue,writeFile as It}from"node:fs/promises";import{dirname as Pt,join as At,relative as de,resolve as Ct}from"node:path";var w=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ct(this.root,t)}async put(e,t){let o=this.path(e);await bt(Pt(o),{recursive:!0}),await It(o,t)}async get(e){try{return await xt(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 ce(this.path(e)),!0}catch{return!1}}async delete(e){await Rt(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),o=[];try{await ce(t)}catch{return o}let n=async i=>{let a=await kt(i,{withFileTypes:!0});for(let c of a){let u=At(i,c.name);if(c.isDirectory()){await n(u);continue}let l=await ue(u);o.push({key:de(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await ue(t);return s.isDirectory()?await n(t):o.push({key:de(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),o}};import{DeleteObjectCommand as Ot,GetObjectCommand as Tt,HeadObjectCommand as Et,ListObjectsV2Command as _t,PutObjectCommand as Nt,S3Client as Kt}from"@aws-sdk/client-s3";import{getSignedUrl as $t}from"@aws-sdk/s3-request-presigner";var j=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Kt({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Nt({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await $t(this.client,new Tt({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`${this.name} download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Et({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Ot({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new _t({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}};function B(r,e){return console.warn(e),new w(r)}function pe(r){let e=r.localRoot??Ht(Dt(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new j({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):B(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 j({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):B(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 A({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):B(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new w(e)}var C=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let o=JSON.parse(t);if(!Array.isArray(o))throw new Error("Invalid memory snapshot");return o}async save(e,t){let o=JSON.stringify(t,null,2);await this.storage.put(this.key(e),o,"application/json")}};function zt(r){return new Promise(e=>setTimeout(e,r))}async function le(r,e={}){let t=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,n=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await r()}catch(a){if(s=a,i>=t)break;let c=Math.min(n,o*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await zt(c+u)}throw s}var Lt=new Set(["put","get","getText","delete","list"]);function me(r,e={}){return new Proxy(r,{get(t,o){let n=Reflect.get(t,o,t);return typeof n!="function"?n:Lt.has(o)?(...s)=>le(()=>Promise.resolve(n.apply(t,s)),e):n.bind(t)}})}function fe(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 ge(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(o)return`${o[1]}memory/records/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),o)return`${o[1]}memory/vectors/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),o)return`${o[1]}code/graph/${o[2]}`;let n=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:e))}var O=class{constructor(e,t,o,n){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=o,this.folder=fe(n??o),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),o=t,n=await this.provider.getText(e);if(n){let i;try{i=JSON.parse(n)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(o=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=
|
|
5
|
-
`,"application/json"),t}function
|
|
1
|
+
import{existsSync as De,readFileSync as ze}from"node:fs";import{homedir as He}from"node:os";import{join as Ve}from"node:path";function Le(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 Be(){let r=process.env.TOOLNET_GLOBAL_ENV??Ve(He(),".config","toolnet-memory",".env");if(!De(r))return;let e=ze(r,"utf8");for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7));let n=o.indexOf("=");if(n<=0)continue;let s=o.slice(0,n).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Le(o.slice(n+1)))}}Be();function S(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function v(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Y(){return{memory:{autoCapture:S(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:S(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:S(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:S(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:v(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:v(process.env.MEMORY_RERANK_TOP,10),finalContext:v(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:v(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:S(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:v(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Je={critical:100,high:75,normal:50,temporary:20};function W(r){return Je[r]}function Z(r,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":r==="rule"||r==="decision"?"high":r==="todo"?"normal":r==="activity"||r==="summary"?"temporary":"normal"}import{createHash as Fe}from"node:crypto";import{existsSync as j,mkdirSync as Ue,readFileSync as Ye,renameSync as We,writeFileSync as Ze}from"node:fs";import{basename as Ge,dirname as M,join as w,parse as ee,resolve as y}from"node:path";var te=".toolnet",qe="project.json";function Qe(r){return Fe("sha256").update(r).digest("hex").slice(0,16)}function k(r){return w(r,te,qe)}function Xe(r){return j(k(r))}function G(r,e){let t=y(r),o=ee(t).root;for(;;){if(Xe(t))return t;if(t===o||e&&t===y(e))break;let n=M(t);if(n===t)break;t=n}return null}function q(r){let e=y(r),t=ee(e).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(s=>j(w(e,s))))return e;if(e===t)break;let n=M(e);if(n===e)break;e=n}return y(r)}function Q(r){let e;try{e=JSON.parse(Ye(r,"utf8"))}catch(n){throw new Error(`Invalid ToolNet project manifest: ${r}: ${n instanceof Error?n.message:String(n)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let o=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:M(M(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:o,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:o,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function X(r,e){let t=w(r,te);Ue(t,{recursive:!0});let o=k(r),n=`${o}.tmp-${process.pid}`;Ze(n,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),We(n,o)}function D(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 R=class{findExisting(e=process.cwd()){let t=y(e),o=q(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>j(w(o,c))),i=G(t,s?o:void 0);if(!i)return null;let a=Q(k(i));return D(a,i)}requireExisting(e=process.cwd()){let t=this.findExisting(e);if(!t)throw new Error("PROJECT_NOT_INITIALIZED");return t}detect(e=process.cwd()){let t=y(e),o=q(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>j(w(o,l))),i=G(t,s?o:void 0);if(i){let l=k(i),m=Q(l);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),X(i,m)),D(m,i)}let a=new Date().toISOString(),c=Ge(o),u={version:1,id:Qe(o),name:c,remote:c,rootPath:o,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return X(o,u),D(u,o)}};import{randomUUID as kt}from"node:crypto";var et=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],tt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function re(r){return r.normalize("NFKC").trim().toLowerCase()}function rt(r){if(r.length===0)return 0;let e=new Map;for(let o of r)e.set(o,(e.get(o)??0)+1);let t=0;for(let o of e.values()){let n=o/r.length;t-=n*Math.log2(n)}return t}function ot(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function nt(r,e,t){let o=r.slice(Math.max(0,e-48),e),n=r.slice(t,Math.min(r.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${o} ${n}`)}function st(r,e){return r.start<e.end&&e.start<r.end}function oe(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var A=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let o=re(t);o&&this.allowValues.add(o)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of et){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of e.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||t.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let o=oe(t),n=[];for(let s of o)n.some(i=>st(i,s))||n.push(s);return oe(n)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=re(e);return tt.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],o=/[A-Za-z0-9_+/=-]{32,160}/g;for(let n of e.matchAll(o)){if(n.index===void 0||!n[0])continue;let s=n[0];this.allowed(s)||ot(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||nt(e,n.index,n.index+s.length)&&(rt(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:n.index,end:n.index+s.length,confidence:"heuristic"}))}return t}};var I=class{scanner;constructor(e={}){this.scanner=new A(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let o=e,n=[...t].sort((i,a)=>a.start-i.start),s=new Set;for(let i of n)s.add(i.type),o=o.slice(0,i.start)+`[REDACTED:${i.type}]`+o.slice(i.end);return{text:o,redacted:t.length,secretTypes:[...s].sort()}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e)){let s=o.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){t[o]="[REDACTED]";continue}t[o]=this.sanitizeValue(n)}return t}return e}};var ne=new I;function se(r){return ne.sanitize(r).text}function z(r){return ne.sanitizeValue(r)}var it=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),at=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function ie(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!at.has(e)))}function ct(r,e){let t=ie(r),o=ie(e);if(t.size===0||o.size===0)return 0;let n=0;for(let i of t)o.has(i)&&(n+=1);let s=new Set([...t,...o]).size;return s===0?0:n/s}function ae(r){return new Set(r.tags.filter(e=>!it.has(e.toLowerCase())))}function H(r){let e=r.metadata?.evidence;if(!e||typeof e!="object")return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,o=Number(t.crossSessionConfirmations);return{userExplicit:t.userExplicit===!0,sourceVerified:t.sourceVerified===!0,testVerified:t.testVerified===!0,crossSessionConfirmations:Number.isFinite(o)?Math.max(0,o):0,assistantDerived:t.assistantDerived===!0}}function ut(r){let e=H(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function dt(r){let e=Number(r.metadata?.confidence);return!Number.isFinite(e)||e<0?0:e>1?1:e}function pt(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function ce(r){let e=H(r),t=pt(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=dt(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function ue(r){let e=r.metadata?.topic;if(typeof e!="string")return;let t=e.normalize("NFKC").trim().toLowerCase();if(t)return t}function lt(r,e){let t=ae(r),o=ae(e);for(let n of t)if(o.has(n))return!0;return!1}function mt(r,e){if(e.id===r.id||e.projectId!==r.projectId||e.type!==r.type||e.metadata?.supersededBy)return!1;let t=ue(r),o=ue(e);return t&&o&&t===o||lt(r,e)?!0:ct(r.content,e.content)>=.6}function de(r){return r.type!=="rule"?!1:H(r).userExplicit}function ft(r,e){return!de(r)||!de(e)?!1:r.createdAt>=e.createdAt}var P=class{resolve(e,t){if(e.type!=="rule"&&e.type!=="decision")return{superseded:[],conflicts:[]};let o=[],n=[],s=ce(e);for(let i of t){if(!mt(e,i))continue;let a=ce(i);if(s>a){o.push(i);continue}if(s<a){n.push(i);continue}if(ft(e,i)){o.push(i);continue}if(!ut(i)&&e.createdAt>=i.createdAt){o.push(i);continue}n.push(i)}return{superseded:o,conflicts:n}}findSuperseded(e,t){return this.resolve(e,t).superseded}};var gt=new Set(["code","decision","rule","todo","summary"]);function yt(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function pe(r){return r.tags.includes("class:permanent")?4:r.tags.includes("class:task")?3:r.tags.includes("class:session")?2:r.tags.includes("class:transient")?1:0}function ht(r,e){let t=pe(e)-pe(r);if(t!==0)return t;let o=e.importanceScore-r.importanceScore;if(o!==0)return o;let n=e.updatedAt.localeCompare(r.updatedAt);if(n!==0)return n;let s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function le(r){let e=new Set,t=[];for(let o of r){let n=o.trim();if(!n)continue;let s=n.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(n))}return t}function me(r){let e=new Map;for(let n of r){if(!gt.has(n.type)||n.metadata?.supersededBy)continue;let s=yt(n.content);if(!s)continue;let i=[n.projectId,n.type,s].join("\0"),a=e.get(i)??[];a.push(n),e.set(i,a)}let t=[],o=0;for(let n of e.values()){if(n.length<2)continue;let s=[...n].sort(ht),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:le(s.flatMap(c=>c.tags)),mergedSources:le(s.map(c=>c.source))}),o+=a.length}return{groups:t,duplicates:o}}function V(r){if(r.tags.includes("class:permanent"))return"permanent";if(r.tags.includes("class:task"))return"task";if(r.tags.includes("class:session"))return"session";if(r.tags.includes("class:transient"))return"transient"}function St(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function vt(r){let e=V(r);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(r.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 wt(r){return V(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function bt(r){let e=r.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 fe(r,e=Date.now()){let t=50,o=[],n=V(r);switch(n==="permanent"?(t+=25,o.push("permanent project knowledge")):n==="task"?(t+=15,o.push("active task knowledge")):n==="session"?(t+=2,o.push("session-scoped knowledge")):n==="transient"&&(t-=25,o.push("transient knowledge")),r.importance){case"critical":t+=25,o.push("critical importance");break;case"high":t+=15,o.push("high importance");break;case"normal":break;case"temporary":t-=15,o.push("temporary importance");break}(r.type==="rule"||r.type==="decision")&&(t+=10,o.push("durable knowledge type"));let s=r.content.trim().length;s<12?(t-=30,o.push("very short content")):s<30?(t-=10,o.push("limited context")):s<=1200?(t+=8,o.push("useful context density")):s>5e3&&(t-=15,o.push("excessively large memory")),bt(r.content)&&(t-=35,o.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,o.push("confirmed across multiple sources"));let a=St(r,e)>=vt(r);a&&(t-=15,o.push("stale for lifecycle class"));let c=wt(r);t=Math.max(0,Math.min(100,Math.round(t)));let u;t>=80?u="trusted":t>=55?u="useful":t>=30?u="weak":u="noise";let l=r.importance==="temporary"||r.type==="activity"||n==="transient";return{score:t,tier:u,stale:a,protected:c,pruneEligible:!c&&(u==="noise"&&l||a&&(u==="noise"||u==="weak")),reasons:o}}var xt={critical:100,high:75,normal:50,temporary:20},jt={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function ge(r,e,t=new Date){let o;if(e==="temporary"&&(o=30),r==="activity"&&(o=Math.min(o??14,14)),r==="summary"&&(o=Math.min(o??30,30)),!!o)return new Date(t.getTime()+o*864e5).toISOString()}function L(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function Mt(r){return!!r.metadata?.supersededBy}function B(r,e=Date.now()){return!L(r,e)&&!Mt(r)}function J(r,e=Date.now()){if(!B(r,e))return 0;let t=xt[r.importance];if(r.importance==="critical")return t;let o=jt[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/o);return t*i}var C=class{memories=new Map;conflicts=new P;remember(e){let t=new Date().toISOString(),o=se(e.content.trim()),n=e.importance??Z(e.type,o),s={id:kt(),projectId:e.projectId,type:e.type,content:o,importance:n,importanceScore:W(n),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??ge(e.type,n,new Date(t)),metadata:z(e.metadata)},i=this.conflicts.resolve(s,this.list(e.projectId));if(i.superseded.length>0){s.metadata={...s.metadata??{},supersedes:i.superseded.map(a=>a.id)};for(let a of i.superseded)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}if(i.conflicts.length>0){let a=i.conflicts.map(c=>c.id);s.metadata={...s.metadata??{},conflictsWith:a};for(let c of i.conflicts){let u=Array.isArray(c.metadata?.conflictsWith)?c.metadata?.conflictsWith:[],l=new Set(u.filter(m=>typeof m=="string"));l.add(s.id),c.updatedAt=t,c.metadata={...c.metadata??{},conflictsWith:[...l]},this.memories.set(c.id,c)}}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let o of e){if(!o?.id)continue;let n=z(o);this.memories.set(n.id,n),t++}return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,o)=>o.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>B(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(o=>o.type===t)}search(e){let t=e.query.trim().toLowerCase(),o=e.limit??10,n=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=J(s);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>s.tags.includes(c)))}).map(s=>{let i=s.content.toLowerCase(),a=n.filter(l=>i.includes(l)).length,c=n.length===0?0:a/n.length,u=J(s)/500;return{memory:s,score:c+u,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,o)}consolidate(e,t=Date.now()){let o=me(this.list(e)),n=[],s=0;for(let i of o.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),n.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:n.length,duplicatesRemoved:s,canonicalIds:n}}reviewLifecycle(e,t=Date.now()){let o={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let n of this.list(e)){let s=fe(n,t);o.reviewed+=1,o[s.tier]+=1,s.stale&&(o.stale+=1),s.protected&&(o.protected+=1),n.metadata={...n.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:s.score,tier:s.tier,stale:s.stale,protected:s.protected,reasons:s.reasons}},this.memories.set(n.id,n),s.pruneEligible&&this.memories.delete(n.id)&&(o.pruned+=1)}return o}pruneExpired(e,t=Date.now()){let o=0;for(let[n,s]of this.memories)s.projectId===e&&L(s,t)&&(this.memories.delete(n),o++);return o}pruneSuperseded(e,t=30,o=Date.now()){let n=0,s=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;o-new Date(c).getTime()>=s&&(this.memories.delete(i),n++)}return n}clearProject(e){let t=0;for(let[o,n]of this.memories)n.projectId===e&&(this.memories.delete(o),t++);return t}};import{homedir as Wt}from"node:os";import{join as Zt}from"node:path";import{DeleteObjectCommand as Rt,GetObjectCommand as At,HeadObjectCommand as It,ListObjectsV2Command as Pt,PutObjectCommand as Ct,S3Client as Ot}from"@aws-sdk/client-s3";import{getSignedUrl as Tt}from"@aws-sdk/s3-request-presigner";var O=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ot({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ct({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await Tt(this.client,new At({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`HF download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new It({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 Rt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new Pt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}};import{access as ye,mkdir as Et,readFile as _t,readdir as Nt,rm as Kt,stat as he,writeFile as $t}from"node:fs/promises";import{dirname as Dt,join as zt,relative as Se,resolve as Ht}from"node:path";var b=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ht(this.root,t)}async put(e,t){let o=this.path(e);await Et(Dt(o),{recursive:!0}),await $t(o,t)}async get(e){try{return await _t(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 ye(this.path(e)),!0}catch{return!1}}async delete(e){await Kt(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),o=[];try{await ye(t)}catch{return o}let n=async i=>{let a=await Nt(i,{withFileTypes:!0});for(let c of a){let u=zt(i,c.name);if(c.isDirectory()){await n(u);continue}let l=await he(u);o.push({key:Se(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await he(t);return s.isDirectory()?await n(t):o.push({key:Se(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),o}};import{DeleteObjectCommand as Vt,GetObjectCommand as Lt,HeadObjectCommand as Bt,ListObjectsV2Command as Jt,PutObjectCommand as Ft,S3Client as Ut}from"@aws-sdk/client-s3";import{getSignedUrl as Yt}from"@aws-sdk/s3-request-presigner";var x=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ut({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ft({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await Yt(this.client,new Lt({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`${this.name} download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Bt({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 Vt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new Jt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}};function F(r,e){return console.warn(e),new b(r)}function ve(r){let e=r.localRoot??Zt(Wt(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new x({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new x({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new O({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):F(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new b(e)}var T=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let o=JSON.parse(t);if(!Array.isArray(o))throw new Error("Invalid memory snapshot");return o}async save(e,t){let o=JSON.stringify(t,null,2);await this.storage.put(this.key(e),o,"application/json")}};function Gt(r){return new Promise(e=>setTimeout(e,r))}async function we(r,e={}){let t=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,n=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await r()}catch(a){if(s=a,i>=t)break;let c=Math.min(n,o*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Gt(c+u)}throw s}var qt=new Set(["put","get","getText","delete","list"]);function be(r,e={}){return new Proxy(r,{get(t,o){let n=Reflect.get(t,o,t);return typeof n!="function"?n:qt.has(o)?(...s)=>we(()=>Promise.resolve(n.apply(t,s)),e):n.bind(t)}})}function xe(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 je(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(o)return`${o[1]}memory/records/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),o)return`${o[1]}memory/vectors/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),o)return`${o[1]}code/graph/${o[2]}`;let n=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:e))}var E=class{constructor(e,t,o,n){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=o,this.folder=xe(n??o),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),o=t,n=await this.provider.getText(e);if(n){let i;try{i=JSON.parse(n)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(o=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=je(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,o){return await this.ensureRegistered(),this.provider.put(this.key(e),t,o)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{closeSync as Qt,mkdirSync as Xt,openSync as er,readFileSync as tr,unlinkSync as Me,writeFileSync as rr}from"node:fs";import{tmpdir as or}from"node:os";import{join as ke}from"node:path";function nr(r){try{return process.kill(r,0),!0}catch(e){return e?.code==="EPERM"}}var _=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=ke(or(),"toolnet-memory-locks");Xt(t,{recursive:!0});let o=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=ke(t,`${o}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=er(this.path,"wx");rr(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Qt(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let o=!0;try{let n=JSON.parse(tr(this.path,"utf8"));Number.isInteger(n.pid)&&nr(n.pid)&&(o=!1)}catch{o=!0}if(!o)throw new Error("ToolNet Memory is already running for this project");try{Me(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{Me(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};import{createHash as pr}from"node:crypto";import{hostname as lr}from"node:os";import{createHash as sr,randomUUID as ir}from"node:crypto";function g(r,e){let t=r.trim();if(!t)throw new Error(`${e} is required`);return t}function N(r,e){return encodeURIComponent(g(r,e))}function ar(r){let e=JSON.stringify(r);if(e===void 0)throw new Error("Multi-host operation payload must be JSON serializable");return e}function Ae(r){return sr("sha256").update(r).digest("hex")}function Ie(r){return Ae(ar(r))}function Pe(r){return Number.isFinite(Date.parse(r))}function cr(r){return Ae(JSON.stringify({version:r.version,operationId:r.operationId,projectId:r.projectId,scope:r.scope,hostId:r.hostId,occurredAt:r.occurredAt,payloadSha256:r.payloadSha256,payload:r.payload}))}function Ce(r){let e=g(r.projectId,"projectId"),t=g(r.scope,"scope"),o=g(r.hostId,"hostId"),n=g(r.operationId??ir(),"operationId"),s=r.occurredAt??new Date().toISOString();if(!Pe(s))throw new Error(`Invalid operation timestamp: ${s}`);return{version:1,operationId:n,projectId:e,scope:t,hostId:o,occurredAt:s,payloadSha256:Ie(r.payload),payload:r.payload}}function Oe(r,e){let t=["projects",N(r,"projectId"),"operations"];return e?`${[...t,N(e,"scope")].join("/")}/`:`${t.join("/")}/`}function ur(r){return[Oe(r.projectId,r.scope).replace(/\/$/,""),N(r.hostId,"hostId"),`${N(r.operationId,"operationId")}-${r.payloadSha256}.json`].join("/")}async function Te(r,e){let t=ur(e);return await r.put(t,`${JSON.stringify(e,null,2)}
|
|
5
|
+
`,"application/json"),t}function dr(r){let e;try{e=JSON.parse(r)}catch{return null}return e.version!==1||typeof e.operationId!="string"||typeof e.projectId!="string"||typeof e.scope!="string"||typeof e.hostId!="string"||typeof e.occurredAt!="string"||!Pe(e.occurredAt)||typeof e.payloadSha256!="string"||Ie(e.payload)!==e.payloadSha256?null:e}function Re(r,e){let t=r.occurredAt.localeCompare(e.occurredAt);if(t!==0)return t;let o=r.hostId.localeCompare(e.hostId);if(o!==0)return o;let n=r.operationId.localeCompare(e.operationId);return n!==0?n:r.payloadSha256.localeCompare(e.payloadSha256)}async function Ee(r,e,t){let o=g(e,"projectId"),n=g(t,"scope"),s=Oe(o,n),i=await r.list(s),a=[],c=[];for(let p of i){let d=await r.getText(p.key);if(!d){a.push(p.key);continue}let f=dr(d);if(!f){a.push(p.key);continue}if(f.projectId!==o){a.push(p.key);continue}if(f.scope!==n){a.push(p.key);continue}c.push(f)}let u=new Map;for(let p of c){let d=u.get(p.operationId);if(!d){u.set(p.operationId,[p]);continue}d.push(p)}let l=[],m=[];for(let[p,d]of u){if(new Set(d.map($e=>cr($e))).size>1){m.push({operationId:p,variants:[...d].sort(Re)});continue}let h=d[0];h&&l.push(h)}return l.sort(Re),m.sort((p,d)=>p.operationId.localeCompare(d.operationId)),a.sort(),{operations:l,conflicts:m,invalidKeys:a}}function mr(r){let t=(r??process.env.TOOLNET_HOST_ID??lr()).trim();return t||`pid-${process.pid}`}function fr(r){let e=t=>{if(t===null||typeof t!="object")return t;if(Array.isArray(t))return t.map(n=>e(n));let o=t;return Object.fromEntries(Object.keys(o).sort().map(n=>[n,e(o[n])]))};return JSON.stringify(e(r))}function K(r){return pr("sha256").update(fr(r)).digest("hex")}function gr(r,e){let t=K(r).slice(0,12),o=K(e);return["memory",t,o].join("-")}function yr(r,e){let t=r.updatedAt.localeCompare(e.updatedAt);if(t!==0)return t;let o=r.createdAt.localeCompare(e.createdAt);return o!==0?o:K(r).localeCompare(K(e))}function hr(r,e){return yr(r,e)>=0?r:e}function U(r,e){let t=new Map;for(let o of r)t.set(o.id,o);for(let o of e){if(o.payload.kind!=="upsert")continue;let n=o.payload.memory,s=t.get(n.id);if(!s){t.set(n.id,n);continue}t.set(n.id,hr(s,n))}return[...t.values()].sort((o,n)=>o.id.localeCompare(n.id))}var $=class{constructor(e,t={}){this.storage=e;this.legacy=new T(e),this.hostId=mr(t.hostId)}storage;legacy;hostId;diagnostics={operationCount:0,conflicts:0,invalidKeys:0};getDiagnostics(){return{...this.diagnostics}}async operations(e){let t=await Ee(this.storage,e,"memory");return this.diagnostics={operationCount:t.operations.length,conflicts:t.conflicts.length,invalidKeys:t.invalidKeys.length},t.operations}async load(e){let t=await this.legacy.load(e),o=await this.operations(e);return U(t,o)}async appendMemory(e,t){let o=Ce({projectId:e,scope:"memory",hostId:this.hostId,operationId:gr(this.hostId,t),occurredAt:t.updatedAt,payload:{kind:"upsert",memory:t}});await Te(this.storage,o)}async refreshProjection(e){let t=await this.legacy.load(e),o=await this.operations(e),n=U(t,o);return await this.legacy.save(e,n),n}async save(e,t){let o=[...t].sort((i,a)=>i.id.localeCompare(a.id));for(let i of o)await this.appendMemory(e,i);let n=await this.operations(e),s=U(t,n);await this.legacy.save(e,s)}};function _e(r){let e=r.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}function Ne(r){return!r||typeof r!="object"?{}:r}function Sr(r){let e=r.metadata?.confirmingSessionKeys,t=new Set;if(Array.isArray(e))for(let n of e)typeof n=="string"&&t.add(n);let o=r.metadata?.sessionKey;return typeof o=="string"&&t.add(o),t}function vr(r,e){let t=Sr(r),o=t.size;t.add(e.sessionKey);let n=Ne(r.metadata?.evidence),s=Ne(e.evidence),i=t.size,a=n.userExplicit===!0||s.userExplicit===!0,c=n.sourceVerified===!0||s.sourceVerified===!0,u=n.testVerified===!0||s.testVerified===!0,l=n.assistantDerived===!0&&s.assistantDerived===!0,m=Number(n.crossSessionConfirmations??0);return o!==i||m!==i||n.userExplicit!==a||n.sourceVerified!==c||n.testVerified!==u||n.assistantDerived!==l?(r.metadata={...r.metadata??{},evidence:{userExplicit:a,sourceVerified:c,testVerified:u,crossSessionConfirmations:i,assistantDerived:l},confirmingSessionKeys:[...t].sort()},!0):!1}async function wr(r,e){let t=`projects/${r.id}/memory/learned/`,o=await e.list(t),n=[];for(let s of o.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(s.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;n.push(a)}catch{}}return n}async function Ke(r,e){let t=await wr(r,e),o=new $(e),n=await o.load(r.id),s=new C;s.importRecords(n);let i=new Set(n.map(p=>_e(p)).filter(p=>!!p)),a=new Map(n.flatMap(p=>{let d=_e(p);return d?[[d,p]]:[]})),c=0,u=0,l=0,m=0;for(let p of t)for(let d of p.candidates){if(c+=1,i.has(d.fingerprint)){l+=1;let h=a.get(d.fingerprint);m+=h&&vr(h,d)?1:0;continue}let f=s.remember({projectId:r.id,type:d.type,content:d.content,importance:d.importance,tags:d.tags,source:"session-memory-learner",metadata:{learningFingerprint:d.fingerprint,learningKind:d.kind,confidence:d.confidence,provenance:d.provenance,sourceCreatedAt:d.createdAt,sessionKey:d.sessionKey,agent:d.agent,nativeSessionId:d.nativeSessionId}});i.add(d.fingerprint),a.set(d.fingerprint,f),u+=1}return(u>0||m>0)&&await o.save(r.id,s.exportProject(r.id)),{batches:t.length,candidates:c,added:u,duplicates:l,memories:s.exportProject(r.id).length}}function br(r,e){let t=r.indexOf(e);return t>=0?r[t+1]:void 0}async function xr(){let[r="help",...e]=process.argv.slice(2);if(r!=="reconcile"){console.log(`Session Memory Learner
|
|
6
6
|
|
|
7
7
|
Commands:
|
|
8
8
|
reconcile [--project PATH]
|
|
9
|
-
`);return}let t=
|
|
9
|
+
`);return}let t=br(e,"--project")??process.cwd(),o=new R().detect(t),n=Y(),s=be(ve({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),{attempts:3}),i=new E(s,o.id,o.name,o.remote??o.name),a=new _(o.id);await a.acquire();try{let c=await Ke(o,i);console.log(JSON.stringify({project:o.name,...c},null,2))}finally{await a.release()}}xr().catch(r=>{console.error(r instanceof Error?r.message:r),process.exit(1)});
|