toolnet-memory 0.3.15 → 0.3.16
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/.release-target +1 -1
- package/README.md +158 -6
- package/bundle/agy-hook.js +66 -66
- package/bundle/agy.js +59 -59
- package/bundle/api.js +15 -15
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +49 -49
- package/bundle/codex-context.js +29 -29
- package/bundle/codex.js +71 -71
- package/bundle/context-runtime.js +44 -44
- package/bundle/context.js +14 -14
- package/bundle/copilot-hook.js +77 -77
- package/bundle/cursor-hook.js +78 -78
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +19 -19
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +55 -55
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +3 -3
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -5
- package/bundle/init.js +36 -35
- package/bundle/kiro-hook.js +86 -86
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +6 -6
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +73 -73
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +9 -9
- package/bundle/runtime.js +13 -13
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +48 -48
- package/bundle/work-continuity.js +7 -7
- package/package.json +14 -2
- package/release-manifest.json +51 -1
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}),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=
|
|
5
|
-
`,"application/json"),t}function
|
|
1
|
+
import{existsSync as st,readFileSync as at}from"node:fs";import{homedir as ct}from"node:os";import{join as dt}from"node:path";function ut(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 pt(){let r=process.env.TOOLNET_GLOBAL_ENV??dt(ct(),".config","toolnet-memory",".env");if(!st(r))return;let e=at(r,"utf8");for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let o=n.indexOf("=");if(o<=0)continue;let i=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=ut(n.slice(o+1)))}}pt();function x(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function M(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function ie(){return{memory:{autoCapture:x(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:x(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:x(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:x(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:M(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:M(process.env.MEMORY_RERANK_TOP,10),finalContext:M(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:M(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:x(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:M(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var lt={critical:100,high:75,normal:50,temporary:20};function se(r){return lt[r]}function ae(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 vt}from"node:crypto";import{existsSync as E,mkdirSync as wt,readFileSync as bt,renameSync as xt,writeFileSync as Mt}from"node:fs";import{basename as jt,dirname as T,join as k,parse as ge,resolve as h}from"node:path";import{createHash as ue}from"node:crypto";import{spawnSync as mt}from"node:child_process";var j="git-remote-v1",ft=new Set(["github.com","gitlab.com","bitbucket.org"]);function pe(r,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(n=>!n||n==="."||n==="..")?null:(ft.has(r)&&(t=t.toLowerCase()),t)}function gt(r){let e;try{e=new URL(r)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let n=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!n?`${t}:${e.port}`:t,i=pe(t,e.pathname);return i?`${o}/${i}`:null}function yt(r){let e=r.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let n=pe(t,e[2]??"");return n?`${t}/${n}`:null}function ce(r){let e=r.trim();return e?e.includes("://")?gt(e):yt(e):null}function ht(r){return ue("sha256").update(`${j}:${r}`).digest("hex")}function le(r){return ue("sha256").update(`toolnet-project:${j}:${r}`).digest("hex").slice(0,16)}function St(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function U(r,e){let t=mt("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function de(r,e){let t=St(r);return t?{scheme:j,canonicalRemote:r,fingerprint:ht(r),repositoryName:t,source:e}:null}function me(r){let e=U(r,["remote","get-url","origin"]);if(e){let o=ce(e);if(o)return de(o,"origin")}let t=U(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(i=>i.trim()).filter(Boolean)){let i=U(r,["remote","get-url",o]);if(!i)continue;let s=ce(i);s&&n.add(s)}return n.size!==1?null:de([...n][0],"unique-remote")}var ye=".toolnet",kt="project.json";function Rt(r){return vt("sha256").update(r).digest("hex").slice(0,16)}function w(r){return k(r,ye,kt)}function he(r){return E(w(r))}function fe(r,e){let t=h(r),n=ge(t).root;for(;;){if(he(t))return t;if(t===n||e&&t===h(e))break;let o=T(t);if(o===t)break;t=o}return null}function Y(r){let e=h(r),t=ge(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(i=>E(k(e,i))))return e;if(e===t)break;let o=T(e);if(o===e)break;e=o}return h(r)}function P(r){let e;try{e=JSON.parse(bt(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 n=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:T(T(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:n,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:n,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 C(r,e){let t=k(r,ye);wt(t,{recursive:!0});let n=w(r),o=`${n}.tmp-${process.pid}`;Mt(o,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),xt(o,n)}function y(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}}function q(r){return{version:1,scheme:j,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function It(r){let e=r.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var O=class{adopt(e,t){let n=Y(h(e));if(!t.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!t.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!t.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(he(n)){let a=P(w(n));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return y(a,n)}let o=new Date().toISOString(),i={...t.metadata};t.gitIdentity&&(i.toolnetIdentity=q(t.gitIdentity));let s={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:n,createdAt:t.createdAt??o,updatedAt:o,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(i).length?i:void 0};return C(n,s),y(s,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),i=w(o.rootPath),s=P(i),a=It(s);if(a&&a!==t.fingerprint&&!n.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=s.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(s.metadata={...s.metadata,toolnetIdentity:q(t)},s.updatedAt=new Date().toISOString(),C(o.rootPath,s)),y(s,o.rootPath)}findExisting(e=process.cwd()){let t=h(e),n=Y(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>E(k(n,c))),s=fe(t,i?n:void 0);if(!s)return null;let a=P(w(s));return y(a,s)}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=h(e),n=Y(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>E(k(n,m))),s=fe(t,i?n:void 0);if(s){let m=w(s),p=P(m);return p.rootPath!==s&&(p.rootPath=s,p.updatedAt=new Date().toISOString(),C(s,p)),y(p,s)}let a=new Date().toISOString(),c=jt(n),d=me(n),l={version:1,id:d?le(d.canonicalRemote):Rt(n),name:c,remote:d?.repositoryName??c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:d?{toolnetIdentity:q(d)}:void 0};return C(n,l),y(l,n)}};import{randomUUID as sr}from"node:crypto";var At=[{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"}],Pt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function Se(r){return r.normalize("NFKC").trim().toLowerCase()}function Ct(r){if(r.length===0)return 0;let e=new Map;for(let n of r)e.set(n,(e.get(n)??0)+1);let t=0;for(let n of e.values()){let o=n/r.length;t-=o*Math.log2(o)}return t}function Et(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function Tt(r,e,t){let n=r.slice(Math.max(0,e-48),e),o=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(`${n} ${o}`)}function Ot(r,e){return r.start<e.end&&e.start<r.end}function ve(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var _=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=Se(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let i of At){let s=new RegExp(i.regex.source,i.regex.flags);for(let a of e.matchAll(s))a.index===void 0||!a[0]||this.allowed(a[0])||t.push({type:i.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:i.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let n=ve(t),o=[];for(let i of n)o.some(s=>Ot(s,i))||o.push(i);return ve(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=Se(e);return Pt.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],n=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(n)){if(o.index===void 0||!o[0])continue;let i=o[0];this.allowed(i)||Et(i)||!/[A-Za-z]/u.test(i)||!/[0-9]/u.test(i)||Tt(e,o.index,o.index+i.length)&&(Ct(i)<3.7||t.push({type:"high_entropy_secret",value:i,start:o.index,end:o.index+i.length,confidence:"heuristic"}))}return t}};var N=class{scanner;constructor(e={}){this.scanner=new _(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let n=e,o=[...t].sort((s,a)=>a.start-s.start),i=new Set;for(let s of o)i.add(s.type),n=n.slice(0,s.start)+`[REDACTED:${s.type}]`+n.slice(s.end);return{text:n,redacted:t.length,secretTypes:[...i].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[n,o]of Object.entries(e)){let i=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(i.includes("password")||i.includes("passwd")||i==="pwd"||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")||i.includes("apikey")||i.includes("accesskey")||i.includes("privatekey")||i.includes("clientsecret")||i.includes("credential")){t[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}};var we=new N;function be(r){return we.sanitize(r).text}function W(r){return we.sanitizeValue(r)}var _t=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","next_action","next-action","opencode","agy","codex","claude","kiro","cursor","copilot","grok","toolnet","kilo"]),Nt=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","cho","v\xE0","l\xE0","c\u1EE7a","v\u1EDBi","m\u1ED9t","c\xE1c","use","using","the","a","an","to","for","with","and","of","quy\u1EBFt","\u0111\u1ECBnh"]),Kt=new Set(["todo","task","next","step","action","need","needs","needed","remaining","fix","fixed","fixing","resolve","resolved","implemented","complete","completed","done","pass","passed","passing","tests","test","c\u1EA7n","l\xE0m","s\u1EEDa","\u0111\xE3","x\u1EED","l\xFD","ho\xE0n","t\u1EA5t","th\xE0nh","ti\u1EBFp","theo","b\u01B0\u1EDBc"]),Dt=new Set(["rule","decision","todo","next_action","fix","context","architecture"]);function f(r){return r.normalize("NFKC").trim().toLowerCase()}function Ce(r,e){for(let t of e){let n=r.metadata?.[t];if(typeof n!="string")continue;let o=f(n);if(o)return o}}function Ee(r,e){for(let t of r.tags){let n=f(t);for(let o of e){if(!n.startsWith(o))continue;let i=n.slice(o.length).trim();if(i)return i}}}function K(r){if(typeof r!="string")return;let e=f(r).replaceAll("-","_");if(e==="nextaction")return"next_action";if(Dt.has(e))return e}function S(r){let e=K(r.metadata?.conflictKind);if(e)return e;let t=K(r.metadata?.learningKind);if(t)return t;let n=K(r.metadata?.lifecycleKind);if(n)return n;for(let o of r.tags){let i=f(o);if(!i.startsWith("kind:"))continue;let s=K(i.slice(5));if(s)return s}return r.tags.some(o=>f(o)==="next_action")?"next_action":r.type==="rule"?"rule":r.type==="decision"?"decision":r.type==="todo"?"todo":"other"}function $t(r){let e=r.metadata?.lifecycleState;return typeof e=="string"&&["active","conflicting","superseded","resolved","completed","stale"].includes(e)?e:r.metadata?.supersededBy?"superseded":"active"}function Q(r){return new Set(f(r).replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/u).filter(e=>e.length>2&&!Nt.has(e)))}function xe(r){return new Set([...Q(r)].filter(e=>!Kt.has(e)))}function Te(r,e){if(r.size===0||e.size===0)return 0;let t=0;for(let o of r)e.has(o)&&(t+=1);let n=new Set([...r,...e]).size;return n===0?0:t/n}function zt(r,e){return Te(Q(r),Q(e))}function Lt(r,e){return Te(xe(r),xe(e))}function Me(r){return new Set(r.tags.map(f).filter(e=>!(_t.has(e)||e.startsWith("class:")||e.startsWith("kind:")||e.startsWith("level:"))))}function Ht(r,e){let t=Me(r),n=Me(e);for(let o of t)if(n.has(o))return!0;return!1}function je(r){return Ce(r,["topic","topicKey"])??Ee(r,["topic:"])}function ke(r){return Ce(r,["entity","entityKey","subject","taskId","taskKey"])??Ee(r,["entity:","subject:","task:"])}function Re(r){let e=r.metadata?.provenance;if(!e||typeof e!="object"||Array.isArray(e))return new Set;let t=e.sourcePaths;return Array.isArray(t)?new Set(t.filter(n=>typeof n=="string").map(f).filter(Boolean)):new Set}function Vt(r,e){let t=Re(r);if(t.size===0)return!1;let n=Re(e);for(let o of t)if(n.has(o))return!0;return!1}function R(r){let e=r.metadata?.evidence;if(!e||typeof e!="object"||Array.isArray(e))return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,n=Number(t.crossSessionConfirmations);return{userExplicit:t.userExplicit===!0,sourceVerified:t.sourceVerified===!0,testVerified:t.testVerified===!0,crossSessionConfirmations:Number.isFinite(n)?Math.max(0,n):0,assistantDerived:t.assistantDerived===!0}}function Ft(r){let e=R(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function Bt(r){let e=Number(r.metadata?.confidence);return Number.isFinite(e)?Math.max(0,Math.min(1,e)):0}function Jt(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function Ie(r){let e=R(r),t=Jt(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=Bt(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function Gt(r,e){if(r==="other"||e==="other")return!1;if(r===e)return!0;let t=new Set(["todo","next_action"]);return!!(t.has(r)&&t.has(e)||r==="fix"&&t.has(e)||e==="fix"&&t.has(r)||r==="fix"&&e==="context"||e==="fix"&&r==="context")}function Ut(r,e){if(r==="fix"&&e==="context"||e==="fix"&&r==="context")return .65;let t=new Set(["todo","next_action","fix"]);return t.has(r)&&t.has(e)?.38:r==="rule"||r==="decision"?.6:.5}function Yt(r,e){if(e.id===r.id||e.projectId!==r.projectId)return!1;let t=$t(e);if(["superseded","resolved","completed","stale"].includes(t))return!1;let n=S(r),o=S(e);if(!Gt(n,o))return!1;let i=je(r),s=je(e);if(i&&s&&i===s)return!0;let a=ke(r),c=ke(e);if(a&&c&&a===c||Ht(r,e))return!0;let d=Ut(n,o),l=Lt(r.content,e.content);return!!(l>=d||zt(r.content,e.content)>=d||Vt(r,e)&&l>=Math.max(.3,d-.2))}function Ae(r){return S(r)==="rule"&&R(r).userExplicit}function qt(r,e){return!Ae(r)||!Ae(e)?!1:r.createdAt>=e.createdAt}function Pe(r){let e=R(r);return e.userExplicit||e.sourceVerified||e.testVerified}function D(r){return r==="todo"||r==="next_action"}function Z(r,e){return r.createdAt>=e.createdAt}var $=class{resolve(e,t){let n=S(e),o={kind:n,superseded:[],conflicts:[],completed:[],resolved:[]};if(n==="other")return o;let i=Ie(e);for(let s of t){if(!Yt(e,s))continue;let a=S(s),c=Ie(s);if(n==="fix"&&D(a)){if(Pe(e)){o.completed.push(s);continue}o.conflicts.push(s);continue}if(n==="fix"&&a==="context"){if(Pe(e)&&i>=c){o.resolved.push(s);continue}o.conflicts.push(s);continue}if(D(n)&&a==="fix"){if(R(e).userExplicit||i>c){o.superseded.push(s);continue}o.conflicts.push(s);continue}if(D(n)&&D(a)){if(i>c||i===c&&Z(e,s)){o.superseded.push(s);continue}o.conflicts.push(s);continue}if(i>c){o.superseded.push(s);continue}if(i<c){o.conflicts.push(s);continue}if(qt(e,s)){o.superseded.push(s);continue}if(["context","fix","architecture","decision"].includes(n)&&Z(e,s)){o.superseded.push(s);continue}if(!Ft(s)&&Z(e,s)){o.superseded.push(s);continue}o.conflicts.push(s)}return o}findSuperseded(e,t){return this.resolve(e,t).superseded}};var Wt=new Set(["code","decision","rule","todo","summary"]);function Zt(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 Qt(r,e){let t=Oe(e)-Oe(r);if(t!==0)return t;let n=e.importanceScore-r.importanceScore;if(n!==0)return n;let o=e.updatedAt.localeCompare(r.updatedAt);if(o!==0)return o;let i=e.createdAt.localeCompare(r.createdAt);return i!==0?i:r.id.localeCompare(e.id)}function _e(r){let e=new Set,t=[];for(let n of r){let o=n.trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();e.has(i)||(e.add(i),t.push(o))}return t}function Ne(r){let e=new Map;for(let o of r){if(!Wt.has(o.type)||o.metadata?.supersededBy)continue;let i=Zt(o.content);if(!i)continue;let s=[o.projectId,o.type,i].join("\0"),a=e.get(s)??[];a.push(o),e.set(s,a)}let t=[],n=0;for(let o of e.values()){if(o.length<2)continue;let i=[...o].sort(Qt),s=i[0];if(!s)continue;let a=i.slice(1);t.push({canonicalId:s.id,duplicateIds:a.map(c=>c.id),mergedTags:_e(i.flatMap(c=>c.tags)),mergedSources:_e(i.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function X(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 Xt(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function er(r){let e=X(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 tr(r){return X(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function rr(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 Ke(r,e=Date.now()){let t=50,n=[],o=X(r);switch(o==="permanent"?(t+=25,n.push("permanent project knowledge")):o==="task"?(t+=15,n.push("active task knowledge")):o==="session"?(t+=2,n.push("session-scoped knowledge")):o==="transient"&&(t-=25,n.push("transient knowledge")),r.importance){case"critical":t+=25,n.push("critical importance");break;case"high":t+=15,n.push("high importance");break;case"normal":break;case"temporary":t-=15,n.push("temporary importance");break}(r.type==="rule"||r.type==="decision")&&(t+=10,n.push("durable knowledge type"));let i=r.content.trim().length;i<12?(t-=30,n.push("very short content")):i<30?(t-=10,n.push("limited context")):i<=1200?(t+=8,n.push("useful context density")):i>5e3&&(t-=15,n.push("excessively large memory")),rr(r.content)&&(t-=35,n.push("matches transient/noise pattern"));let s=r.metadata?.consolidation;s&&typeof s=="object"&&Array.isArray(s.sources)&&s.sources.length>1&&(t+=10,n.push("confirmed across multiple sources"));let a=Xt(r,e)>=er(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=tr(r);t=Math.max(0,Math.min(100,Math.round(t)));let d;t>=80?d="trusted":t>=55?d="useful":t>=30?d="weak":d="noise";let l=r.importance==="temporary"||r.type==="activity"||o==="transient";return{score:t,tier:d,stale:a,protected:c,pruneEligible:!c&&(d==="noise"&&l||a&&(d==="noise"||d==="weak")),reasons:n}}var nr={critical:100,high:75,normal:50,temporary:20},or={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function De(r,e,t=new Date){let n;if(e==="temporary"&&(n=30),r==="activity"&&(n=Math.min(n??14,14)),r==="summary"&&(n=Math.min(n??30,30)),!!n)return new Date(t.getTime()+n*864e5).toISOString()}function ee(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function ir(r){return!!r.metadata?.supersededBy||r.metadata?.lifecycleState==="superseded"}function te(r,e=Date.now()){if(ee(r,e)||ir(r))return!1;let t=r.metadata?.lifecycleState;return!(t==="completed"||t==="resolved"||t==="conflicting"||t==="stale")}function re(r,e=Date.now()){if(!te(r,e))return 0;let t=nr[r.importance];if(r.importance==="critical")return t;let n=or[r.type]??180,i=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,s=Math.pow(.5,i/n);return t*s}var z=class{memories=new Map;conflicts=new $;remember(e){let n=(e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?new Date(e.createdAt).toISOString():void 0)??new Date().toISOString(),o=be(e.content.trim()),i=e.importance??ae(e.type,o),s={id:sr(),projectId:e.projectId,type:e.type,content:o,importance:i,importanceScore:se(i),tags:e.tags??[],source:e.source??"agent",createdAt:n,updatedAt:n,expiresAt:e.expiresAt??De(e.type,i,new Date(n)),metadata:W(e.metadata)};s.metadata={...s.metadata??{},lifecycleState:"active"},s.metadata={...s.metadata,conflictKind:S(s)};let a=this.conflicts.resolve(s,this.list(e.projectId));if(a.superseded.length>0){s.metadata={...s.metadata??{},supersedes:a.superseded.map(c=>c.id)};for(let c of a.superseded)c.updatedAt=n,c.metadata={...c.metadata??{},supersededBy:s.id,supersededAt:n,lifecycleState:"superseded"},this.memories.set(c.id,c)}if(a.completed.length>0){s.metadata={...s.metadata??{},completes:a.completed.map(c=>c.id)};for(let c of a.completed)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"completed",completedBy:s.id,completedAt:n},this.memories.set(c.id,c)}if(a.resolved.length>0){s.metadata={...s.metadata??{},resolves:a.resolved.map(c=>c.id)};for(let c of a.resolved)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"resolved",resolvedBy:s.id,resolvedAt:n},this.memories.set(c.id,c)}if(a.conflicts.length>0){let c=a.conflicts.map(d=>d.id);s.metadata={...s.metadata??{},conflictsWith:c,lifecycleState:"conflicting"};for(let d of a.conflicts){let l=Array.isArray(d.metadata?.conflictsWith)?d.metadata?.conflictsWith:[],m=new Set(l.filter(p=>typeof p=="string"));m.add(s.id),d.updatedAt=n,d.metadata={...d.metadata??{},conflictsWith:[...m]},this.memories.set(d.id,d)}}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let n of e){if(!n?.id)continue;let o=W(n);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,n)=>n.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>te(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(n=>n.type===t)}search(e){let t=e.query.trim().toLowerCase(),n=e.limit??10,o=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(i=>{if(e.types&&!e.types.includes(i.type))return!1;let s=re(i);return!(e.minImportanceScore&&s<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>i.tags.includes(c)))}).map(i=>{let s=i.content.toLowerCase(),a=o.filter(l=>s.includes(l)).length,c=o.length===0?0:a/o.length,d=re(i)/500;return{memory:i,score:c+d,source:"memory"}}).filter(i=>t.length===0||i.score>0).sort((i,s)=>s.score-i.score).slice(0,n)}consolidate(e,t=Date.now()){let n=Ne(this.list(e)),o=[],i=0;for(let s of n.groups){let a=this.memories.get(s.canonicalId);if(a){a.tags=s.mergedTags,a.metadata={...a.metadata??{},consolidation:{version:1,consolidatedAt:new Date(t).toISOString(),mergedIds:s.duplicateIds,sources:s.mergedSources}},this.memories.set(a.id,a),o.push(a.id);for(let c of s.duplicateIds)this.memories.delete(c)&&(i+=1)}}return{groupsConsolidated:o.length,duplicatesRemoved:i,canonicalIds:o}}reviewLifecycle(e,t=Date.now()){let n={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let o of this.list(e)){let i=Ke(o,t);n.reviewed+=1,n[i.tier]+=1,i.stale&&(n.stale+=1),i.protected&&(n.protected+=1),o.metadata={...o.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:i.score,tier:i.tier,stale:i.stale,protected:i.protected,reasons:i.reasons}},this.memories.set(o.id,o),i.pruneEligible&&this.memories.delete(o.id)&&(n.pruned+=1)}return n}pruneExpired(e,t=Date.now()){let n=0;for(let[o,i]of this.memories)i.projectId===e&&ee(i,t)&&(this.memories.delete(o),n++);return n}pruneSuperseded(e,t=30,n=Date.now()){let o=0,i=t*864e5;for(let[s,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;n-new Date(c).getTime()>=i&&(this.memories.delete(s),o++)}return o}clearProject(e){let t=0;for(let[n,o]of this.memories)o.projectId===e&&(this.memories.delete(n),t++);return t}};import{homedir as Pr}from"node:os";import{join as Cr}from"node:path";import{DeleteObjectCommand as ar,GetObjectCommand as cr,HeadObjectCommand as dr,ListObjectsV2Command as ur,PutObjectCommand as pr,S3Client as lr}from"@aws-sdk/client-s3";import{getSignedUrl as mr}from"@aws-sdk/s3-request-presigner";var L=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new lr({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new pr({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await mr(this.client,new cr({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.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 dr({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 ar({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new ur({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};import{access as $e,mkdir as fr,readFile as gr,readdir as yr,rm as hr,stat as ze,writeFile as Sr}from"node:fs/promises";import{dirname as vr,join as wr,relative as Le,resolve as br}from"node:path";var I=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return br(this.root,t)}async put(e,t){let n=this.path(e);await fr(vr(n),{recursive:!0}),await Sr(n,t)}async get(e){try{return await gr(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 $e(this.path(e)),!0}catch{return!1}}async delete(e){await hr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await $e(t)}catch{return n}let o=async s=>{let a=await yr(s,{withFileTypes:!0});for(let c of a){let d=wr(s,c.name);if(c.isDirectory()){await o(d);continue}let l=await ze(d);n.push({key:Le(this.root,d),size:l.size,updatedAt:l.mtime.toISOString()})}},i=await ze(t);return i.isDirectory()?await o(t):n.push({key:Le(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),n}};import{DeleteObjectCommand as xr,GetObjectCommand as Mr,HeadObjectCommand as jr,ListObjectsV2Command as kr,PutObjectCommand as Rr,S3Client as Ir}from"@aws-sdk/client-s3";import{getSignedUrl as Ar}from"@aws-sdk/s3-request-presigner";var A=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ir({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,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Rr({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Ar(this.client,new Mr({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.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 jr({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 xr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new kr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};function ne(r,e){return console.warn(e),new I(r)}function He(r){let e=r.localRoot??Cr(Pr(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new A({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):ne(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 A({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):ne(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 L({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):ne(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new I(e)}var H=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 n=JSON.parse(t);if(!Array.isArray(n))throw new Error("Invalid memory snapshot");return n}async save(e,t){let n=JSON.stringify(t,null,2);await this.storage.put(this.key(e),n,"application/json")}};function Er(r){return new Promise(e=>setTimeout(e,r))}async function Ve(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=e.maxDelayMs??2e3,i;for(let s=1;s<=t;s++)try{return await r()}catch(a){if(i=a,s>=t)break;let c=Math.min(o,n*2**(s-1)),d=Math.floor(Math.random()*Math.max(1,c*.2));await Er(c+d)}throw i}var Tr=new Set(["put","get","getText","delete","list"]);function Fe(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:Tr.has(n)?(...i)=>Ve(()=>Promise.resolve(o.apply(t,i)),e):o.bind(t)}})}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 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 n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[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 V=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=Be(o??n),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(),n=t,o=await this.provider.getText(e);if(o){let s;try{s=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof s.id=="string"&&s.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${s.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof s.createdAt=="string"&&(n=s.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,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=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,n){return await this.ensureRegistered(),this.provider.put(this.key(e),t,n)}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 Or,mkdirSync as _r,openSync as Nr,readFileSync as Kr,unlinkSync as Ge,writeFileSync as Dr}from"node:fs";import{tmpdir as $r}from"node:os";import{join as Ue}from"node:path";function zr(r){try{return process.kill(r,0),!0}catch(e){return e?.code==="EPERM"}}var F=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=Ue($r(),"toolnet-memory-locks");_r(t,{recursive:!0});let n=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=Ue(t,`${n}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Nr(this.path,"wx");Dr(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Or(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let n=!0;try{let o=JSON.parse(Kr(this.path,"utf8"));Number.isInteger(o.pid)&&zr(o.pid)&&(n=!1)}catch{n=!0}if(!n)throw new Error("ToolNet Memory is already running for this project");try{Ge(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{Ge(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};import{createHash as Gr}from"node:crypto";import{hostname as Ur}from"node:os";import{createHash as Lr,randomUUID as Hr}from"node:crypto";function v(r,e){let t=r.trim();if(!t)throw new Error(`${e} is required`);return t}function B(r,e){return encodeURIComponent(v(r,e))}function Vr(r){let e=JSON.stringify(r);if(e===void 0)throw new Error("Multi-host operation payload must be JSON serializable");return e}function qe(r){return Lr("sha256").update(r).digest("hex")}function We(r){return qe(Vr(r))}function Ze(r){return Number.isFinite(Date.parse(r))}function Fr(r){return qe(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 Qe(r){let e=v(r.projectId,"projectId"),t=v(r.scope,"scope"),n=v(r.hostId,"hostId"),o=v(r.operationId??Hr(),"operationId"),i=r.occurredAt??new Date().toISOString();if(!Ze(i))throw new Error(`Invalid operation timestamp: ${i}`);return{version:1,operationId:o,projectId:e,scope:t,hostId:n,occurredAt:i,payloadSha256:We(r.payload),payload:r.payload}}function Xe(r,e){let t=["projects",B(r,"projectId"),"operations"];return e?`${[...t,B(e,"scope")].join("/")}/`:`${t.join("/")}/`}function Br(r){return[Xe(r.projectId,r.scope).replace(/\/$/,""),B(r.hostId,"hostId"),`${B(r.operationId,"operationId")}-${r.payloadSha256}.json`].join("/")}async function et(r,e){let t=Br(e);return await r.put(t,`${JSON.stringify(e,null,2)}
|
|
5
|
+
`,"application/json"),t}function Jr(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"||!Ze(e.occurredAt)||typeof e.payloadSha256!="string"||We(e.payload)!==e.payloadSha256?null:e}function Ye(r,e){let t=r.occurredAt.localeCompare(e.occurredAt);if(t!==0)return t;let n=r.hostId.localeCompare(e.hostId);if(n!==0)return n;let o=r.operationId.localeCompare(e.operationId);return o!==0?o:r.payloadSha256.localeCompare(e.payloadSha256)}async function tt(r,e,t){let n=v(e,"projectId"),o=v(t,"scope"),i=Xe(n,o),s=await r.list(i),a=[],c=[];for(let p of s){let u=await r.getText(p.key);if(!u){a.push(p.key);continue}let g=Jr(u);if(!g){a.push(p.key);continue}if(g.projectId!==n){a.push(p.key);continue}if(g.scope!==o){a.push(p.key);continue}c.push(g)}let d=new Map;for(let p of c){let u=d.get(p.operationId);if(!u){d.set(p.operationId,[p]);continue}u.push(p)}let l=[],m=[];for(let[p,u]of d){if(new Set(u.map(it=>Fr(it))).size>1){m.push({operationId:p,variants:[...u].sort(Ye)});continue}let b=u[0];b&&l.push(b)}return l.sort(Ye),m.sort((p,u)=>p.operationId.localeCompare(u.operationId)),a.sort(),{operations:l,conflicts:m,invalidKeys:a}}function Yr(r){let t=(r??process.env.TOOLNET_HOST_ID??Ur()).trim();return t||`pid-${process.pid}`}function qr(r){let e=t=>{if(t===null||typeof t!="object")return t;if(Array.isArray(t))return t.map(o=>e(o));let n=t;return Object.fromEntries(Object.keys(n).sort().map(o=>[o,e(n[o])]))};return JSON.stringify(e(r))}function J(r){return Gr("sha256").update(qr(r)).digest("hex")}function Wr(r,e){let t=J(r).slice(0,12),n=J(e);return["memory",t,n].join("-")}function Zr(r,e){let t=r.updatedAt.localeCompare(e.updatedAt);if(t!==0)return t;let n=r.createdAt.localeCompare(e.createdAt);return n!==0?n:J(r).localeCompare(J(e))}function Qr(r,e){return Zr(r,e)>=0?r:e}function oe(r,e){let t=new Map;for(let n of r)t.set(n.id,n);for(let n of e){if(n.payload.kind!=="upsert")continue;let o=n.payload.memory,i=t.get(o.id);if(!i){t.set(o.id,o);continue}t.set(o.id,Qr(i,o))}return[...t.values()].sort((n,o)=>n.id.localeCompare(o.id))}var G=class{constructor(e,t={}){this.storage=e;this.legacy=new H(e),this.hostId=Yr(t.hostId)}storage;legacy;hostId;diagnostics={operationCount:0,conflicts:0,invalidKeys:0};getDiagnostics(){return{...this.diagnostics}}async operations(e){let t=await tt(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),n=await this.operations(e);return oe(t,n)}async appendMemory(e,t){let n=Qe({projectId:e,scope:"memory",hostId:this.hostId,operationId:Wr(this.hostId,t),occurredAt:t.updatedAt,payload:{kind:"upsert",memory:t}});await et(this.storage,n)}async refreshProjection(e){let t=await this.legacy.load(e),n=await this.operations(e),o=oe(t,n);return await this.legacy.save(e,o),o}async save(e,t){let n=[...t].sort((s,a)=>s.id.localeCompare(a.id));for(let s of n)await this.appendMemory(e,s);let o=await this.operations(e),i=oe(t,o);await this.legacy.save(e,i)}};function rt(r){let e=r.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}function nt(r){return!r||typeof r!="object"?{}:r}function Xr(r){let e=r.metadata?.confirmingSessionKeys,t=new Set;if(Array.isArray(e))for(let o of e)typeof o=="string"&&t.add(o);let n=r.metadata?.sessionKey;return typeof n=="string"&&t.add(n),t}function en(r,e){let t=Xr(r),n=t.size;t.add(e.sessionKey);let o=nt(r.metadata?.evidence),i=nt(e.evidence),s=t.size,a=o.userExplicit===!0||i.userExplicit===!0,c=o.sourceVerified===!0||i.sourceVerified===!0,d=o.testVerified===!0||i.testVerified===!0,l=o.assistantDerived===!0&&i.assistantDerived===!0,m=Number(o.crossSessionConfirmations??0);return n!==s||m!==s||o.userExplicit!==a||o.sourceVerified!==c||o.testVerified!==d||o.assistantDerived!==l?(r.metadata={...r.metadata??{},evidence:{userExplicit:a,sourceVerified:c,testVerified:d,crossSessionConfirmations:s,assistantDerived:l},confirmingSessionKeys:[...t].sort()},!0):!1}async function tn(r,e){let t=`projects/${r.id}/memory/learned/`,n=await e.list(t),o=[];for(let i of n.filter(s=>s.key.includes("/batches/")&&s.key.endsWith(".json")).sort((s,a)=>s.key.localeCompare(a.key))){let s=await e.getText(i.key);if(s)try{let a=JSON.parse(s);if(a.version!==1||!Array.isArray(a.candidates))continue;o.push(a)}catch{}}return o}async function ot(r,e){let t=await tn(r,e),n=new G(e),o=await n.load(r.id),i=new z;i.importRecords(o);let s=new Set(o.map(p=>rt(p)).filter(p=>!!p)),a=new Map(o.flatMap(p=>{let u=rt(p);return u?[[u,p]]:[]})),c=0,d=0,l=0,m=0;for(let p of t)for(let u of p.candidates){if(c+=1,s.has(u.fingerprint)){l+=1;let b=a.get(u.fingerprint);m+=b&&en(b,u)?1:0;continue}let g=i.remember({projectId:r.id,type:u.type,content:u.content,importance:u.importance,tags:u.tags,source:"session-memory-learner",createdAt:u.createdAt,metadata:{learningFingerprint:u.fingerprint,learningKind:u.kind,conflictKind:u.kind,lifecycleState:"active",confidence:u.confidence,evidence:u.evidence,provenance:u.provenance,sourceCreatedAt:u.createdAt,sessionKey:u.sessionKey,agent:u.agent,nativeSessionId:u.nativeSessionId}});s.add(u.fingerprint),a.set(u.fingerprint,g),d+=1}return(d>0||m>0)&&await n.save(r.id,i.exportProject(r.id)),{batches:t.length,candidates:c,added:d,duplicates:l,memories:i.exportProject(r.id).length}}function rn(r,e){let t=r.indexOf(e);return t>=0?r[t+1]:void 0}async function nn(){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=rn(e,"--project")??process.cwd(),n=new O().detect(t),o=ie(),i=Fe(He({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),{attempts:3}),s=new V(i,n.id,n.name,n.remote??n.name),a=new F(n.id);await a.acquire();try{let c=await ot(n,s);console.log(JSON.stringify({project:n.name,...c},null,2))}finally{await a.release()}}nn().catch(r=>{console.error(r instanceof Error?r.message:r),process.exit(1)});
|