toolnet-memory 0.3.16 → 0.3.18

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.
Files changed (45) hide show
  1. package/.env.example +74 -0
  2. package/.release-target +1 -1
  3. package/README.md +157 -7
  4. package/bin/toolnet-memory +12 -0
  5. package/bundle/agy-hook.js +59 -59
  6. package/bundle/agy.js +58 -58
  7. package/bundle/api.js +15 -15
  8. package/bundle/audit.js +2 -0
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/code-capabilities.js +2 -0
  11. package/bundle/codex.js +63 -63
  12. package/bundle/context-runtime.js +41 -41
  13. package/bundle/context.js +15 -15
  14. package/bundle/copilot-hook.js +73 -73
  15. package/bundle/cursor-hook.js +73 -73
  16. package/bundle/docker-healthcheck.js +3 -0
  17. package/bundle/doctor.js +4 -4
  18. package/bundle/full-index.js +20 -19
  19. package/bundle/gc.js +5 -3
  20. package/bundle/graph-cli.js +1 -1
  21. package/bundle/graph-index.js +5 -4
  22. package/bundle/graph-ui.js +4 -3
  23. package/bundle/grok-hook.js +52 -52
  24. package/bundle/handoff-refresh.js +2 -2
  25. package/bundle/help-cli.js +4 -4
  26. package/bundle/impact.js +5 -4
  27. package/bundle/incremental.js +5 -5
  28. package/bundle/init.js +35 -35
  29. package/bundle/kiro-hook.js +74 -74
  30. package/bundle/learner.js +8 -6
  31. package/bundle/mcp.js +19 -17
  32. package/bundle/memory-agent.js +4 -4
  33. package/bundle/memory-query.js +3 -3
  34. package/bundle/opencode.js +73 -73
  35. package/bundle/project-manual.js +7 -7
  36. package/bundle/public/index.html +1089 -2306
  37. package/bundle/runtime.js +16 -13
  38. package/bundle/semantic.js +6 -5
  39. package/bundle/service.js +11 -6
  40. package/bundle/snapshot.js +6 -4
  41. package/bundle/status-cli.js +4 -4
  42. package/bundle/toolnet-cli.js +49 -49
  43. package/bundle/work-continuity.js +7 -7
  44. package/package.json +26 -2
  45. package/release-manifest.json +57 -1
package/bundle/mcp.js CHANGED
@@ -1,18 +1,20 @@
1
- var cs=Object.defineProperty;var g=(r,e,t)=>()=>{if(t)throw t[0];try{return r&&(e=r(r=0)),e}catch(n){throw t=[n],n}};var Be=(r,e)=>{for(var t in e)cs(r,t,{get:e[t],enumerable:!0})};function Kt(r){return r.normalize("NFKC").trim().toLowerCase()}function ms(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 ps(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function fs(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 gs(r,e){return r.start<e.end&&e.start<r.end}function $t(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var ls,ds,ae,zt=g(()=>{"use strict";ls=[{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"}],ds=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);ae=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=Kt(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of ls){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 n=$t(t),o=[];for(let s of n)o.some(i=>gs(i,s))||o.push(s);return $t(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=Kt(e);return ds.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 s=o[0];this.allowed(s)||ps(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||fs(e,o.index,o.index+s.length)&&(ms(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}}});var P,ce=g(()=>{"use strict";zt();P=class{scanner;constructor(e={}){this.scanner=new ae(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((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),n=n.slice(0,i.start)+`[REDACTED:${i.type}]`+n.slice(i.end);return{text:n,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[n,o]of Object.entries(e)){let s=n.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[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}}});var R,O,yi,Ie,ot=g(()=>{"use strict";R="sqlite-fts5-bm25",O="lexical",yi="Local Code Search \u2014 SQLite FTS5/BM25",Ie={engine:R,mode:O,displayName:yi,semantic:!1,embedding:!1,vectorDatabase:!1,queryExpansion:!1,synonymExpansion:!1,networkRequired:!1,indexBackend:"sqlite-fts5",ranking:"bm25",compatibilityAliases:["SemanticCodeEngine","semantic_code_search","toolnet-memory semantic","semantic-index"]}});import{existsSync as Di,readFileSync as Ki}from"node:fs";import{homedir as $i}from"node:os";import{join as zi}from"node:path";function Wi(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 Gi(){let r=process.env.TOOLNET_GLOBAL_ENV??zi($i(),".config","toolnet-memory",".env");if(!Di(r))return;let e=Ki(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 s=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Wi(n.slice(o+1)))}}var kn=g(()=>{"use strict";Gi()});var bn={};Be(bn,{loadConfig:()=>Sn});function J(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function Q(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Sn(){return{memory:{autoCapture:J(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:J(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:J(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:J(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:Q(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Q(process.env.MEMORY_RERANK_TOP,10),finalContext:Q(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Q(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:J(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:Q(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var pt=g(()=>{"use strict";kn()});var Po=g(()=>{"use strict"});import{DeleteObjectCommand as fc,GetObjectCommand as gc,HeadObjectCommand as yc,ListObjectsV2Command as hc,PutObjectCommand as kc,S3Client as Sc}from"@aws-sdk/client-s3";import{getSignedUrl as bc}from"@aws-sdk/s3-request-presigner";var se,ht=g(()=>{"use strict";se=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Sc({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 kc({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await bc(this.client,new gc({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 yc({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 fc({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new hc({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{access as Ao,mkdir as wc,readFile as vc,readdir as Cc,rm as xc,stat as Eo,writeFile as Mc}from"node:fs/promises";import{dirname as Pc,join as Ac,relative as Ro,resolve as Ec}from"node:path";var z,kt=g(()=>{"use strict";z=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ec(this.root,t)}async put(e,t){let n=this.path(e);await wc(Pc(n),{recursive:!0}),await Mc(n,t)}async get(e){try{return await vc(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 Ao(this.path(e)),!0}catch{return!1}}async delete(e){await xc(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await Ao(t)}catch{return n}let o=async i=>{let a=await Cc(i,{withFileTypes:!0});for(let c of a){let u=Ac(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Eo(u);n.push({key:Ro(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Eo(t);return s.isDirectory()?await o(t):n.push({key:Ro(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),n}}});import{DeleteObjectCommand as Rc,GetObjectCommand as jc,HeadObjectCommand as Tc,ListObjectsV2Command as Ic,PutObjectCommand as _c,S3Client as Nc}from"@aws-sdk/client-s3";import{getSignedUrl as Oc}from"@aws-sdk/s3-request-presigner";var W,St=g(()=>{"use strict";W=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Nc({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 _c({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Oc(this.client,new jc({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 Tc({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 Rc({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Ic({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{homedir as Lc}from"node:os";import{join as Fc}from"node:path";function bt(r,e){return console.warn(e),new z(r)}function Dc(r){let e=r.localRoot??Fc(Lc(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new W({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(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 W({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(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 se({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new z(e)}var jo=g(()=>{"use strict";ht();kt();St()});var wt,To=g(()=>{"use strict";wt=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")}}});var Io=g(()=>{"use strict";kt()});var _o=g(()=>{"use strict";ht()});var No=g(()=>{"use strict";St()});var vt,Oo=g(()=>{"use strict";vt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let n=JSON.parse(t);if(n.version!==1||n.projectId!==e||!Array.isArray(n.records))throw new Error("Invalid vector snapshot");return n}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Ct,Lo=g(()=>{"use strict";Ct=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var xt,Fo=g(()=>{"use strict";xt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var ie,Mt=g(()=>{"use strict";ie=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Pt,Do=g(()=>{"use strict";Pt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});function Kc(r){return new Promise(e=>setTimeout(e,r))}async function Ko(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=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(o,n*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Kc(c+u)}throw s}var $o=g(()=>{"use strict"});function zc(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:$c.has(n)?(...s)=>Ko(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var $c,zo=g(()=>{"use strict";$o();$c=new Set(["put","get","getText","delete","list"])});function At(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}var Et=g(()=>{"use strict"});function Rt(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 jt=g(()=>{"use strict"});var Tt,Wo=g(()=>{"use strict";Et();jt();Tt=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=At(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 i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(n=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
3
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Rt(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))}}});var Go=g(()=>{"use strict";Et();Wo();jt()});var It,qo=g(()=>{"use strict";It=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var _t,Vo=g(()=>{"use strict";_t=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,n(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,n(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,n(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,n(e.clusters),"application/json")])}}});var Nt,Ho=g(()=>{"use strict";Nt=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,n(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,n(e.dependencies),"application/json")])}}});var Ot,Bo=g(()=>{"use strict";Ot=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e,null,2),"application/json")}}});var Uo={};Be(Uo,{HuggingFaceStorageProvider:()=>se,LocalStorageProvider:()=>z,MemoryStore:()=>wt,PersistentArchitectureStore:()=>_t,PersistentCodeAnalysisStore:()=>Nt,PersistentCodeChunkStore:()=>ie,PersistentCodeGraphStore:()=>Ct,PersistentCodeManifestStore:()=>xt,PersistentCodeVectorStore:()=>Pt,PersistentTypeResolutionStore:()=>It,PersistentVectorStore:()=>vt,PersistentVisualizationStore:()=>Ot,ProjectScopedStorageProvider:()=>Tt,S3StorageProvider:()=>W,createStorageProvider:()=>Dc,mapProjectStoragePath:()=>Rt,sanitizeProjectFolder:()=>At,withStorageRetry:()=>zc});var Jo=g(()=>{"use strict";Po();jo();To();Io();_o();No();Oo();Lo();Fo();Mt();Do();zo();Go();qo();Vo();Ho();Bo()});import{createHash as Wc}from"node:crypto";import{readFile as Gc}from"node:fs/promises";import{join as qc}from"node:path";function Qo(r){return Wc("sha256").update(r).digest("hex")}var Ve,Yo=g(()=>{"use strict";ce();Ve=class{sanitizer=new P;async build(e,t,n,o={}){let s=o.maxLines??80,i=o.overlapLines??10,a=new Map;for(let u of n){let l=a.get(u.filePath)??[];l.push(u),a.set(u.filePath,l)}let c=[];for(let[u,l]of a){let d;try{d=await Gc(qc(t,u),"utf8")}catch{continue}let m=d.split(/\r?\n/),p=l.filter(y=>y.type!=="file"&&typeof y.startLine=="number"&&typeof y.endLine=="number");if(p.length>0)for(let y of p)c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,symbol:y,startLine:y.startLine,endLine:y.endLine,maxLines:s,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,startLine:1,endLine:Math.max(1,m.length),maxLines:s,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:n,lines:o,symbol:s,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),u=Math.min(o.length,Math.max(c,e.endLine)),l=[],d=c,m=0;for(;d<=u;){let p=Math.min(u,d+i-1),y=o.slice(d-1,p).join(`
4
- `).trim();if(y){let S=this.sanitizer.sanitize(y).text,T=Qo(S),G=[t,n,s?.id??"file",String(m),T].join(":");l.push({id:Qo(G).slice(0,32),projectId:t,filePath:n,symbolId:s?.id,symbolName:s?.qualifiedName??s?.name,symbolType:s?.type,startLine:d,endLine:p,content:S,contentHash:T})}if(p>=u)break;d=p-a+1,m++}return l}}});import{DatabaseSync as Vc}from"node:sqlite";var He,Xo=g(()=>{"use strict";He=class{constructor(e){this.projectId=e;this.db.exec("CREATE VIRTUAL TABLE code_fts USING fts5(id UNINDEXED, projectId UNINDEXED, filePath, symbol, content, tokenize='unicode61')")}projectId;db=new Vc(":memory:");chunks=new Map;get size(){return this.chunks.size}build(e){if(this.db.exec("DELETE FROM code_fts"),this.chunks.clear(),e.length===0)return 0;let t=this.db.prepare("INSERT INTO code_fts (id, projectId, filePath, symbol, content) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{for(let n of e)this.chunks.set(n.id,n),t.run(n.id,this.projectId,n.filePath,n.symbolName??"",n.content);this.db.exec("COMMIT")}catch(n){throw this.db.exec("ROLLBACK"),n}return e.length}search(e,t=8){let n=this.toMatchQuery(e);if(!n)return[];let o=this.db.prepare("SELECT id, bm25(code_fts) AS rank FROM code_fts WHERE code_fts MATCH ? ORDER BY rank LIMIT ?").all(n,Math.max(t*4,20)),s=[];for(let i of o){let a=this.chunks.get(i.id);if(!a)continue;let c=1/(1+Math.abs(i.rank));s.push({chunk:a,score:c})}return s.slice(0,t)}toMatchQuery(e){let t=e.toLowerCase().normalize("NFKC").split(/[^\p{L}\p{N}]+/u).map(n=>n.trim()).filter(n=>n.length>0);return t.length===0?null:t.length===1?`"${t[0]}"`:`(${t.map(n=>`"${n}"`).join(" OR ")})`}close(){this.db.close()}}});function Zo(r,e){let t=r.toLowerCase().replaceAll("\\","/"),n=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(n);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var es=g(()=>{"use strict"});var ts={};Be(ts,{LocalCodeSearchEngineRuntime:()=>Lt,SemanticCodeEngine:()=>Lt});var Lt,rs=g(()=>{"use strict";Mt();Yo();Xo();es();ot();Lt=class{constructor(e){this.options=e;this.fts=new He(e.projectId)}options;fts;get searchContract(){return Ie}async initialize(e){let{projectId:t,rootPath:n,storage:o,graph:s}=this.options,i=new ie(o),a=await new Ve().build(t,n,s.allSymbols(t)),c=await i.load(t),u=!c||c.chunks.length!==a.length||c.chunks.some(d=>!a.some(m=>m.id===d.id));u&&await i.save({version:1,projectId:t,updatedAt:new Date().toISOString(),chunks:a}),e?.({current:a.length,total:a.length,phase:"index",detail:R});let l=this.fts.build(a);return{chunks:a.length,documentsIndexed:l,indexSize:this.fts.size,engine:R,mode:O,embedding:!1,vectorDatabase:!1,savedChunks:u,vectorsLoaded:0,vectorsIndexed:l,vectorsRemoved:0,totalVectors:this.fts.size,savedVectors:u}}async search(e,t=8){let n=this.fts.search(e,t),o=[];for(let s of n){let i=s.chunk,a=Zo(i.filePath,e),c=s.score,u=0,l=c*a;o.push({chunk:i,score:l,lexicalScore:c,vectorScore:u,engine:R,mode:O})}return o}size(){return this.fts.size}}});import"dotenv/config";import{randomUUID as Ws}from"node:crypto";var us={critical:100,high:75,normal:50,temporary:20};function Ft(r){return us[r]}function Dt(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"}ce();var Wt=new P;function Gt(r){return Wt.sanitize(r).text}function ue(r){return Wt.sanitizeValue(r)}var ys=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"]),hs=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"]),ks=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"]),Ss=new Set(["rule","decision","todo","next_action","fix","context","architecture"]);function A(r){return r.normalize("NFKC").trim().toLowerCase()}function Xt(r,e){for(let t of e){let n=r.metadata?.[t];if(typeof n!="string")continue;let o=A(n);if(o)return o}}function Zt(r,e){for(let t of r.tags){let n=A(t);for(let o of e){if(!n.startsWith(o))continue;let s=n.slice(o.length).trim();if(s)return s}}}function le(r){if(typeof r!="string")return;let e=A(r).replaceAll("-","_");if(e==="nextaction")return"next_action";if(Ss.has(e))return e}function I(r){let e=le(r.metadata?.conflictKind);if(e)return e;let t=le(r.metadata?.learningKind);if(t)return t;let n=le(r.metadata?.lifecycleKind);if(n)return n;for(let o of r.tags){let s=A(o);if(!s.startsWith("kind:"))continue;let i=le(s.slice(5));if(i)return i}return r.tags.some(o=>A(o)==="next_action")?"next_action":r.type==="rule"?"rule":r.type==="decision"?"decision":r.type==="todo"?"todo":"other"}function bs(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 Je(r){return new Set(A(r).replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/u).filter(e=>e.length>2&&!hs.has(e)))}function qt(r){return new Set([...Je(r)].filter(e=>!ks.has(e)))}function er(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 ws(r,e){return er(Je(r),Je(e))}function vs(r,e){return er(qt(r),qt(e))}function Vt(r){return new Set(r.tags.map(A).filter(e=>!(ys.has(e)||e.startsWith("class:")||e.startsWith("kind:")||e.startsWith("level:"))))}function Cs(r,e){let t=Vt(r),n=Vt(e);for(let o of t)if(n.has(o))return!0;return!1}function Ht(r){return Xt(r,["topic","topicKey"])??Zt(r,["topic:"])}function Bt(r){return Xt(r,["entity","entityKey","subject","taskId","taskKey"])??Zt(r,["entity:","subject:","task:"])}function Ut(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(A).filter(Boolean)):new Set}function xs(r,e){let t=Ut(r);if(t.size===0)return!1;let n=Ut(e);for(let o of t)if(n.has(o))return!0;return!1}function q(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 Ms(r){let e=q(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function Ps(r){let e=Number(r.metadata?.confidence);return Number.isFinite(e)?Math.max(0,Math.min(1,e)):0}function As(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function Jt(r){let e=q(r),t=As(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=Ps(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function Es(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 Rs(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 js(r,e){if(e.id===r.id||e.projectId!==r.projectId)return!1;let t=bs(e);if(["superseded","resolved","completed","stale"].includes(t))return!1;let n=I(r),o=I(e);if(!Es(n,o))return!1;let s=Ht(r),i=Ht(e);if(s&&i&&s===i)return!0;let a=Bt(r),c=Bt(e);if(a&&c&&a===c||Cs(r,e))return!0;let u=Rs(n,o),l=vs(r.content,e.content);return!!(l>=u||ws(r.content,e.content)>=u||xs(r,e)&&l>=Math.max(.3,u-.2))}function Qt(r){return I(r)==="rule"&&q(r).userExplicit}function Ts(r,e){return!Qt(r)||!Qt(e)?!1:r.createdAt>=e.createdAt}function Yt(r){let e=q(r);return e.userExplicit||e.sourceVerified||e.testVerified}function de(r){return r==="todo"||r==="next_action"}function Ue(r,e){return r.createdAt>=e.createdAt}var me=class{resolve(e,t){let n=I(e),o={kind:n,superseded:[],conflicts:[],completed:[],resolved:[]};if(n==="other")return o;let s=Jt(e);for(let i of t){if(!js(e,i))continue;let a=I(i),c=Jt(i);if(n==="fix"&&de(a)){if(Yt(e)){o.completed.push(i);continue}o.conflicts.push(i);continue}if(n==="fix"&&a==="context"){if(Yt(e)&&s>=c){o.resolved.push(i);continue}o.conflicts.push(i);continue}if(de(n)&&a==="fix"){if(q(e).userExplicit||s>c){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(de(n)&&de(a)){if(s>c||s===c&&Ue(e,i)){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(s>c){o.superseded.push(i);continue}if(s<c){o.conflicts.push(i);continue}if(Ts(e,i)){o.superseded.push(i);continue}if(["context","fix","architecture","decision"].includes(n)&&Ue(e,i)){o.superseded.push(i);continue}if(!Ms(i)&&Ue(e,i)){o.superseded.push(i);continue}o.conflicts.push(i)}return o}findSuperseded(e,t){return this.resolve(e,t).superseded}};var Is=new Set(["code","decision","rule","todo","summary"]);function _s(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function tr(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 Ns(r,e){let t=tr(e)-tr(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 s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function rr(r){let e=new Set,t=[];for(let n of r){let o=n.trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function nr(r){let e=new Map;for(let o of r){if(!Is.has(o.type)||o.metadata?.supersededBy)continue;let s=_s(o.content);if(!s)continue;let i=[o.projectId,o.type,s].join("\0"),a=e.get(i)??[];a.push(o),e.set(i,a)}let t=[],n=0;for(let o of e.values()){if(o.length<2)continue;let s=[...o].sort(Ns),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:rr(s.flatMap(c=>c.tags)),mergedSources:rr(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function Qe(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 Os(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Ls(r){let e=Qe(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 Fs(r){return Qe(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function Ds(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 or(r,e=Date.now()){let t=50,n=[],o=Qe(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 s=r.content.trim().length;s<12?(t-=30,n.push("very short content")):s<30?(t-=10,n.push("limited context")):s<=1200?(t+=8,n.push("useful context density")):s>5e3&&(t-=15,n.push("excessively large memory")),Ds(r.content)&&(t-=35,n.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,n.push("confirmed across multiple sources"));let a=Os(r,e)>=Ls(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=Fs(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"||o==="transient";return{score:t,tier:u,stale:a,protected:c,pruneEligible:!c&&(u==="noise"&&l||a&&(u==="noise"||u==="weak")),reasons:n}}var Ks={critical:100,high:75,normal:50,temporary:20},$s={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function sr(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 Ye(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function zs(r){return!!r.metadata?.supersededBy||r.metadata?.lifecycleState==="superseded"}function Xe(r,e=Date.now()){if(Ye(r,e)||zs(r))return!1;let t=r.metadata?.lifecycleState;return!(t==="completed"||t==="resolved"||t==="conflicting"||t==="stale")}function V(r,e=Date.now()){if(!Xe(r,e))return 0;let t=Ks[r.importance];if(r.importance==="critical")return t;let n=$s[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var pe=class{memories=new Map;conflicts=new me;remember(e){let n=(e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?new Date(e.createdAt).toISOString():void 0)??new Date().toISOString(),o=Gt(e.content.trim()),s=e.importance??Dt(e.type,o),i={id:Ws(),projectId:e.projectId,type:e.type,content:o,importance:s,importanceScore:Ft(s),tags:e.tags??[],source:e.source??"agent",createdAt:n,updatedAt:n,expiresAt:e.expiresAt??sr(e.type,s,new Date(n)),metadata:ue(e.metadata)};i.metadata={...i.metadata??{},lifecycleState:"active"},i.metadata={...i.metadata,conflictKind:I(i)};let a=this.conflicts.resolve(i,this.list(e.projectId));if(a.superseded.length>0){i.metadata={...i.metadata??{},supersedes:a.superseded.map(c=>c.id)};for(let c of a.superseded)c.updatedAt=n,c.metadata={...c.metadata??{},supersededBy:i.id,supersededAt:n,lifecycleState:"superseded"},this.memories.set(c.id,c)}if(a.completed.length>0){i.metadata={...i.metadata??{},completes:a.completed.map(c=>c.id)};for(let c of a.completed)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"completed",completedBy:i.id,completedAt:n},this.memories.set(c.id,c)}if(a.resolved.length>0){i.metadata={...i.metadata??{},resolves:a.resolved.map(c=>c.id)};for(let c of a.resolved)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"resolved",resolvedBy:i.id,resolvedAt:n},this.memories.set(c.id,c)}if(a.conflicts.length>0){let c=a.conflicts.map(u=>u.id);i.metadata={...i.metadata??{},conflictsWith:c,lifecycleState:"conflicting"};for(let u of a.conflicts){let l=Array.isArray(u.metadata?.conflictsWith)?u.metadata?.conflictsWith:[],d=new Set(l.filter(m=>typeof m=="string"));d.add(i.id),u.updatedAt=n,u.metadata={...u.metadata??{},conflictsWith:[...d]},this.memories.set(u.id,u)}}return this.memories.set(i.id,i),i}importRecords(e){let t=0;for(let n of e){if(!n?.id)continue;let o=ue(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=>Xe(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(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=o.filter(l=>i.includes(l)).length,c=o.length===0?0:a/o.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,n)}consolidate(e,t=Date.now()){let n=nr(this.list(e)),o=[],s=0;for(let i of n.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),o.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:o.length,duplicatesRemoved:s,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 s=or(o,t);n.reviewed+=1,n[s.tier]+=1,s.stale&&(n.stale+=1),s.protected&&(n.protected+=1),o.metadata={...o.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(o.id,o),s.pruneEligible&&this.memories.delete(o.id)&&(n.pruned+=1)}return n}pruneExpired(e,t=Date.now()){let n=0;for(let[o,s]of this.memories)s.projectId===e&&Ye(s,t)&&(this.memories.delete(o),n++);return n}pruneSuperseded(e,t=30,n=Date.now()){let o=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;n-new Date(c).getTime()>=s&&(this.memories.delete(i),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{createHash as Js}from"node:crypto";import{existsSync as ye,mkdirSync as Qs,readFileSync as Ys,renameSync as Xs,writeFileSync as Zs}from"node:fs";import{basename as ei,dirname as he,join as B,parse as pr,resolve as N}from"node:path";import{createHash as cr}from"node:crypto";import{spawnSync as Gs}from"node:child_process";var H="git-remote-v1",qs=new Set(["github.com","gitlab.com","bitbucket.org"]);function ur(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:(qs.has(r)&&(t=t.toLowerCase()),t)}function Vs(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,s=ur(t,e.pathname);return s?`${o}/${s}`:null}function Hs(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=ur(t,e[2]??"");return n?`${t}/${n}`:null}function ir(r){let e=r.trim();return e?e.includes("://")?Vs(e):Hs(e):null}function Bs(r){return cr("sha256").update(`${H}:${r}`).digest("hex")}function lr(r){return cr("sha256").update(`toolnet-project:${H}:${r}`).digest("hex").slice(0,16)}function Us(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function Ze(r,e){let t=Gs("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function ar(r,e){let t=Us(r);return t?{scheme:H,canonicalRemote:r,fingerprint:Bs(r),repositoryName:t,source:e}:null}function dr(r){let e=Ze(r,["remote","get-url","origin"]);if(e){let o=ir(e);if(o)return ar(o,"origin")}let t=Ze(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=Ze(r,["remote","get-url",o]);if(!s)continue;let i=ir(s);i&&n.add(i)}return n.size!==1?null:ar([...n][0],"unique-remote")}var fr=".toolnet",ti="project.json";function ri(r){return Js("sha256").update(r).digest("hex").slice(0,16)}function F(r){return B(r,fr,ti)}function gr(r){return ye(F(r))}function mr(r,e){let t=N(r),n=pr(t).root;for(;;){if(gr(t))return t;if(t===n||e&&t===N(e))break;let o=he(t);if(o===t)break;t=o}return null}function et(r){let e=N(r),t=pr(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>ye(B(e,s))))return e;if(e===t)break;let o=he(e);if(o===e)break;e=o}return N(r)}function fe(r){let e;try{e=JSON.parse(Ys(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:he(he(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 ge(r,e){let t=B(r,fr);Qs(t,{recursive:!0});let n=F(r),o=`${n}.tmp-${process.pid}`;Zs(o,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),Xs(o,n)}function _(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 tt(r){return{version:1,scheme:H,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function ni(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 ke=class{adopt(e,t){let n=et(N(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(gr(n)){let a=fe(F(n));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return _(a,n)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=tt(t.gitIdentity));let i={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(s).length?s:void 0};return ge(n,i),_(i,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),s=F(o.rootPath),i=fe(s),a=ni(i);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=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:tt(t)},i.updatedAt=new Date().toISOString(),ge(o.rootPath,i)),_(i,o.rootPath)}findExisting(e=process.cwd()){let t=N(e),n=et(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>ye(B(n,c))),i=mr(t,s?n:void 0);if(!i)return null;let a=fe(F(i));return _(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=N(e),n=et(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>ye(B(n,d))),i=mr(t,s?n:void 0);if(i){let d=F(i),m=fe(d);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),ge(i,m)),_(m,i)}let a=new Date().toISOString(),c=ei(n),u=dr(n),l={version:1,id:u?lr(u.canonicalRemote):ri(n),name:c,remote:u?.repositoryName??c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:tt(u)}:void 0};return ge(n,l),_(l,n)}};function rt(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var Se=class{score(e,t){let n=rt(e),o=rt([t.content,...t.tags??[],t.type].join(" "));if(n.length===0||o.length===0)return 0;let s=new Map;for(let a of o)s.set(a,(s.get(a)??0)+1);let i=0;for(let a of n){let c=s.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/n.length}};function yr(r,e=Date.now()){let t=r.updatedAt??r.createdAt,n=new Date(t).getTime();if(!Number.isFinite(n))return 0;let o=Math.max(0,e-n)/864e5;return Math.exp(-Math.LN2*o/30)}function hr(r){return V(r)/100}var oi={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function kr(r){return oi[r]??.4}var be=class{analyze(e){let t=e.toLowerCase(),n=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&n.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&n.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&n.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&n.push("summary"),{query:e,preferredTypes:n}}};var we=class{bm25=new Se;analyzer=new be;search(e,t,n={}){let o=n.topK??8,s=n.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(n.types?.length&&!n.types.includes(c.type))continue;let u=this.bm25.score(e,c),l=yr(c),d=hr(c),m=kr(c.type);i.preferredTypes.includes(c.type)&&(m=Math.min(1,m+.25));let p=u*.55+d*.2+l*.15+m*.1;u<=0||p<s||a.push({memory:c,score:p,scores:{keyword:u,recency:l,importance:d,type:m}})}return a.sort((c,u)=>u.score-c.score).slice(0,o)}};var ve=class{build(e,t=6e3){let n=[],o=0;for(let s of e){let i=s.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(o+a.length>t)break;n.push(a),o+=a.length}return n.join(`
6
- `)}};var Ce=class{constructor(e){this.memory=e}memory;searcher=new we;contextBuilder=new ve;search(e,t,n={}){return this.searcher.search(t,this.memory.list(e),n)}context(e,t,n={}){let o=this.search(e,t,n);return this.contextBuilder.build(o)}};var xe=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(n=>n.projectId===e&&(n.name===t||n.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let n of e)this.addSymbol(n);for(let n of t)this.addEdge(n)}clearProject(e){for(let[t,n]of this.symbols)n.projectId===e&&this.symbols.delete(t);for(let[t,n]of this.edges)n.projectId===e&&this.edges.delete(t)}};var Me=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(o=>o.type==="CALLS"&&o.to===t).map(o=>o.from).map(o=>this.graph.getSymbol(o)).filter(o=>!!o)}};import{McpServer as lc}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as dc}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Sr}from"zod";var br={query:Sr.string(),limit:Sr.number().int().min(1).max(20).optional()};async function wr(r,e){return r.retrieval.search(r.project.id,e.query,{topK:e.limit??8}).map(n=>({id:n.memory.id,type:n.memory.type,content:n.memory.content,importance:n.memory.importance,score:n.score,tags:n.memory.tags}))}import{z as U}from"zod";import{createConnection as ai}from"node:net";import{homedir as si}from"node:os";import{join as ii}from"node:path";function vr(){return process.env.TOOLNET_SERVICE_SOCKET??ii(si(),".toolnet","run","service.sock")}function Cr(r,e={}){let t=e.socketPath??vr(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=ai({path:t}),a="",c=!1,u=d=>{c||(c=!0,clearTimeout(l),i.destroy(),d())},l=setTimeout(()=>{u(()=>{s(new Error(`ToolNet service timeout after ${n}ms`))})},n);i.setEncoding("utf8"),i.once("connect",()=>{i.write(`${JSON.stringify(r)}
1
+ var qs=Object.defineProperty;var g=(r,e,t)=>()=>{if(t)throw t[0];try{return r&&(e=r(r=0)),e}catch(n){throw t=[n],n}};var Ze=(r,e)=>{for(var t in e)qs(r,t,{get:e[t],enumerable:!0})};function er(r){return r.normalize("NFKC").trim().toLowerCase()}function Bs(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 Ys(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function Js(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 Qs(r,e){return r.start<e.end&&e.start<r.end}function tr(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var Vs,Us,pe,rr=g(()=>{"use strict";Vs=[{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"}],Us=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);pe=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=er(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of Vs){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 n=tr(t),o=[];for(let s of n)o.some(i=>Qs(i,s))||o.push(s);return tr(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=er(e);return Us.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 s=o[0];this.allowed(s)||Ys(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Js(e,o.index,o.index+s.length)&&(Bs(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}}});var E,fe=g(()=>{"use strict";rr();E=class{scanner;constructor(e={}){this.scanner=new pe(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((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),n=n.slice(0,i.start)+`[REDACTED:${i.type}]`+n.slice(i.end);return{text:n,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[n,o]of Object.entries(e)){let s=n.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[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}}});var I,D,ha,De,pt=g(()=>{"use strict";I="sqlite-fts5-bm25",D="lexical",ha="Local Code Search \u2014 SQLite FTS5/BM25",De={engine:I,mode:D,displayName:ha,semantic:!1,embedding:!1,vectorDatabase:!1,queryExpansion:!1,synonymExpansion:!1,networkRequired:!1,indexBackend:"sqlite-fts5",ranking:"bm25",compatibilityAliases:["SemanticCodeEngine","semantic_code_search","toolnet-memory semantic","semantic-index"]}});import{existsSync as Ka,readFileSync as $a}from"node:fs";import{homedir as za}from"node:os";import{join as Wa}from"node:path";function Ga(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 qa(){let r=process.env.TOOLNET_GLOBAL_ENV??Wa(za(),".config","toolnet-memory",".env");if(!Ka(r))return;let e=$a(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 s=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Ga(n.slice(o+1)))}}var qn=g(()=>{"use strict";qa()});var Vn={};Ze(Vn,{loadConfig:()=>Hn});function X(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function Z(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Hn(){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:Z(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Z(process.env.MEMORY_RERANK_TOP,10),finalContext:Z(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Z(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:Z(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var vt=g(()=>{"use strict";qn()});var Xo=g(()=>{"use strict"});import{DeleteObjectCommand as gu,GetObjectCommand as yu,HeadObjectCommand as hu,ListObjectsV2Command as ku,PutObjectCommand as Su,S3Client as bu}from"@aws-sdk/client-s3";import{getSignedUrl as wu}from"@aws-sdk/s3-request-presigner";var ce,Pt=g(()=>{"use strict";ce=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new bu({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 Su({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await wu(this.client,new yu({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 hu({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 gu({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new ku({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{access as Zo,mkdir as vu,readFile as Cu,readdir as xu,rm as Mu,stat as es,writeFile as Pu}from"node:fs/promises";import{dirname as Eu,join as Au,relative as ts,resolve as Ru}from"node:path";var q,Et=g(()=>{"use strict";q=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ru(this.root,t)}async put(e,t){let n=this.path(e);await vu(Eu(n),{recursive:!0}),await Pu(n,t)}async get(e){try{return await Cu(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 Zo(this.path(e)),!0}catch{return!1}}async delete(e){await Mu(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await Zo(t)}catch{return n}let o=async i=>{let a=await xu(i,{withFileTypes:!0});for(let c of a){let u=Au(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await es(u);n.push({key:ts(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await es(t);return s.isDirectory()?await o(t):n.push({key:ts(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),n}}});import{DeleteObjectCommand as Tu,GetObjectCommand as Iu,HeadObjectCommand as ju,ListObjectsV2Command as _u,PutObjectCommand as Nu,S3Client as Ou}from"@aws-sdk/client-s3";import{getSignedUrl as Lu}from"@aws-sdk/s3-request-presigner";var H,At=g(()=>{"use strict";H=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ou({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 Nu({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Lu(this.client,new Iu({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 ju({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 Tu({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new _u({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{createCipheriv as Du,createDecipheriv as Fu,createHash as Ku,randomBytes as $u,timingSafeEqual as zu}from"node:crypto";import{readFileSync as Wu}from"node:fs";function qu(r){return r?["1","true","yes","on","enabled"].includes(r.trim().toLowerCase()):!1}function It(r=process.env){return qu(r.TOOLNET_REMOTE_ENCRYPTION)}function rs(r){let e=r.trim();if(!e)throw new k("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let t;if(e.startsWith("hex:")){let n=e.slice(4);if(!/^[0-9a-f]{64}$/iu.test(n))throw new k("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");t=Buffer.from(n,"hex")}else if(/^[0-9a-f]{64}$/iu.test(e))t=Buffer.from(e,"hex");else{let n=e.startsWith("base64:")?e.slice(7):e;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(n))throw new k("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");t=Buffer.from(n,n.includes("-")||n.includes("_")?"base64url":"base64")}if(t.length!==Tt)throw new k("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${Tt} bytes.`);return t}function is(r=process.env){let e=r.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),t=r.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(e&&t)throw new k("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(e)return rs(e);if(t){let n;try{n=Wu(t,"utf8")}catch(o){throw new k("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${t}.`,o instanceof Error?o.message:String(o)].join(" "))}return rs(n)}}function as(r){return Ku("sha256").update(r).digest().subarray(0,ue)}function cs(r){return Buffer.from(`${Gu}${r}`,"utf8")}function jt(r){return r.byteLength<K.length?!1:Buffer.from(r).subarray(0,K.length).equals(K)}function us(r,e,t){if(t.byteLength!==Tt)throw new k("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let n=typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e),o=$u(le),s=Du(ss,t,o);s.setAAD(cs(r));let i=Buffer.concat([s.update(n),s.final()]),a=s.getAuthTag(),c=Buffer.alloc(os),u=0;return K.copy(c,u),u+=K.length,c.writeUInt8(ns,u),u+=1,as(t).copy(c,u),u+=ue,o.copy(c,u),u+=le,a.copy(c,u),Buffer.concat([c,i])}function ls(r,e,t){let n=Buffer.from(e);if(!jt(n))throw new k("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(n.length<os)throw new k("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=K.length,s=n.readUInt8(o);if(o+=1,s!==ns)throw new k("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let i=n.subarray(o,o+ue);o+=ue;let a=as(t);if(!zu(i,a))throw new k("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let c=n.subarray(o,o+le);o+=le;let u=n.subarray(o,o+Rt);o+=Rt;let l=n.subarray(o),d=Fu(ss,t,c);d.setAAD(cs(r)),d.setAuthTag(u);try{return Buffer.concat([d.update(l),d.final()])}catch{throw new k("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var K,ns,ue,le,Rt,os,Gu,ss,Tt,k,ds=g(()=>{"use strict";K=Buffer.from("TNMEME01","ascii"),ns=1,ue=8,le=12,Rt=16,os=K.length+1+ue+le+Rt,Gu="toolnet-memory:remote-encryption:v1:",ss="aes-256-gcm",Tt=32,k=class extends Error{constructor(t,n){super(n);this.code=t;this.name="RemoteEncryptionError"}code}});function _t(r,e=process.env){if(r.name==="local")return It(e)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),r;let t=It(e),n=t?is(e):void 0;return new Je(r,{enabled:t,key:n})}var Je,Nt=g(()=>{"use strict";ds();Je=class{constructor(e,t){this.inner=e;this.options=t;if(this.name=e.name,t.enabled&&!t.key)throw new k("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(e,t,n){if(!this.options.enabled){await this.inner.put(e,t,n);return}let o=this.options.key;if(!o)throw new k("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=us(e,t,o);await this.inner.put(e,s,"application/octet-stream")}async get(e){let t=await this.inner.get(e);if(!t)return null;if(!jt(t))return t;if(!this.options.enabled)throw new k("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let n=this.options.key;if(!n)throw new k("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return ls(e,t,n)}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){return this.inner.exists(e)}async delete(e){await this.inner.delete(e)}async list(e=""){return this.inner.list(e)}}});import{homedir as Hu}from"node:os";import{join as Vu}from"node:path";function de(r){return _t(r)}function Ot(r,e){return console.warn(e),de(new q(r))}function Uu(r){let e=r.localRoot??Vu(Hu(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?de(new H({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):Ot(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?de(new H({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):Ot(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?de(new ce({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):Ot(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return de(new q(e))}var ms=g(()=>{"use strict";Pt();Et();At();Nt()});var Lt,ps=g(()=>{"use strict";Lt=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")}}});var fs=g(()=>{"use strict";Et()});var gs=g(()=>{"use strict";Pt()});var ys=g(()=>{"use strict";At()});var Dt,hs=g(()=>{"use strict";Dt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let n=JSON.parse(t);if(n.version!==1||n.projectId!==e||!Array.isArray(n.records))throw new Error("Invalid vector snapshot");return n}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Ft,ks=g(()=>{"use strict";Ft=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Kt,Ss=g(()=>{"use strict";Kt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var me,$t=g(()=>{"use strict";me=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var zt,bs=g(()=>{"use strict";zt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});function Bu(r){return new Promise(e=>setTimeout(e,r))}async function ws(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=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(o,n*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Bu(c+u)}throw s}var vs=g(()=>{"use strict"});function Ju(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:Yu.has(n)?(...s)=>ws(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var Yu,Cs=g(()=>{"use strict";vs();Yu=new Set(["put","get","getText","delete","list"])});function Wt(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}var Gt=g(()=>{"use strict"});function qt(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 Ht=g(()=>{"use strict"});var Vt,xs=g(()=>{"use strict";Gt();Ht();Vt=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=Wt(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 i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(n=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
3
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=qt(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))}}});var Ms=g(()=>{"use strict";Gt();xs();Ht()});var Ut,Ps=g(()=>{"use strict";Ut=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Bt,Es=g(()=>{"use strict";Bt=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,n(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,n(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,n(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,n(e.clusters),"application/json")])}}});var Yt,As=g(()=>{"use strict";Yt=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,n(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,n(e.dependencies),"application/json")])}}});var Jt,Rs=g(()=>{"use strict";Jt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e,null,2),"application/json")}}});var Ts={};Ze(Ts,{HuggingFaceStorageProvider:()=>ce,LocalStorageProvider:()=>q,MemoryStore:()=>Lt,PersistentArchitectureStore:()=>Bt,PersistentCodeAnalysisStore:()=>Yt,PersistentCodeChunkStore:()=>me,PersistentCodeGraphStore:()=>Ft,PersistentCodeManifestStore:()=>Kt,PersistentCodeVectorStore:()=>zt,PersistentTypeResolutionStore:()=>Ut,PersistentVectorStore:()=>Dt,PersistentVisualizationStore:()=>Jt,ProjectScopedStorageProvider:()=>Vt,RemoteEncryptedStorageProvider:()=>Je,S3StorageProvider:()=>H,createStorageProvider:()=>Uu,mapProjectStoragePath:()=>qt,sanitizeProjectFolder:()=>Wt,withOptionalRemoteEncryption:()=>_t,withStorageRetry:()=>Ju});var Is=g(()=>{"use strict";Xo();ms();ps();fs();gs();ys();hs();ks();Ss();$t();bs();Cs();Ms();Ps();Es();As();Rs();Nt()});import{createHash as Qu}from"node:crypto";import{readFile as Xu}from"node:fs/promises";import{join as Zu}from"node:path";function js(r){return Qu("sha256").update(r).digest("hex")}var Qe,_s=g(()=>{"use strict";fe();Qe=class{sanitizer=new E;async build(e,t,n,o={}){let s=o.maxLines??80,i=o.overlapLines??10,a=new Map;for(let u of n){let l=a.get(u.filePath)??[];l.push(u),a.set(u.filePath,l)}let c=[];for(let[u,l]of a){let d;try{d=await Xu(Zu(t,u),"utf8")}catch{continue}let m=d.split(/\r?\n/),p=l.filter(y=>y.type!=="file"&&typeof y.startLine=="number"&&typeof y.endLine=="number");if(p.length>0)for(let y of p)c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,symbol:y,startLine:y.startLine,endLine:y.endLine,maxLines:s,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,startLine:1,endLine:Math.max(1,m.length),maxLines:s,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:n,lines:o,symbol:s,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),u=Math.min(o.length,Math.max(c,e.endLine)),l=[],d=c,m=0;for(;d<=u;){let p=Math.min(u,d+i-1),y=o.slice(d-1,p).join(`
4
+ `).trim();if(y){let b=this.sanitizer.sanitize(y).text,_=js(b),V=[t,n,s?.id??"file",String(m),_].join(":");l.push({id:js(V).slice(0,32),projectId:t,filePath:n,symbolId:s?.id,symbolName:s?.qualifiedName??s?.name,symbolType:s?.type,startLine:d,endLine:p,content:b,contentHash:_})}if(p>=u)break;d=p-a+1,m++}return l}}});import{DatabaseSync as el}from"node:sqlite";var Xe,Ns=g(()=>{"use strict";Xe=class{constructor(e){this.projectId=e;this.db.exec("CREATE VIRTUAL TABLE code_fts USING fts5(id UNINDEXED, projectId UNINDEXED, filePath, symbol, content, tokenize='unicode61')")}projectId;db=new el(":memory:");chunks=new Map;get size(){return this.chunks.size}build(e){if(this.db.exec("DELETE FROM code_fts"),this.chunks.clear(),e.length===0)return 0;let t=this.db.prepare("INSERT INTO code_fts (id, projectId, filePath, symbol, content) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{for(let n of e)this.chunks.set(n.id,n),t.run(n.id,this.projectId,n.filePath,n.symbolName??"",n.content);this.db.exec("COMMIT")}catch(n){throw this.db.exec("ROLLBACK"),n}return e.length}search(e,t=8){let n=this.toMatchQuery(e);if(!n)return[];let o=this.db.prepare("SELECT id, bm25(code_fts) AS rank FROM code_fts WHERE code_fts MATCH ? ORDER BY rank LIMIT ?").all(n,Math.max(t*4,20)),s=[];for(let i of o){let a=this.chunks.get(i.id);if(!a)continue;let c=1/(1+Math.abs(i.rank));s.push({chunk:a,score:c})}return s.slice(0,t)}toMatchQuery(e){let t=e.toLowerCase().normalize("NFKC").split(/[^\p{L}\p{N}]+/u).map(n=>n.trim()).filter(n=>n.length>0);return t.length===0?null:t.length===1?`"${t[0]}"`:`(${t.map(n=>`"${n}"`).join(" OR ")})`}close(){this.db.close()}}});function Os(r,e){let t=r.toLowerCase().replaceAll("\\","/"),n=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(n);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var Ls=g(()=>{"use strict"});var Ds={};Ze(Ds,{LocalCodeSearchEngineRuntime:()=>Qt,SemanticCodeEngine:()=>Qt});var Qt,Fs=g(()=>{"use strict";$t();_s();Ns();Ls();pt();Qt=class{constructor(e){this.options=e;this.fts=new Xe(e.projectId)}options;fts;get searchContract(){return De}async initialize(e){let{projectId:t,rootPath:n,storage:o,graph:s}=this.options,i=new me(o),a=await new Qe().build(t,n,s.allSymbols(t)),c=await i.load(t),u=!c||c.chunks.length!==a.length||c.chunks.some(d=>!a.some(m=>m.id===d.id));u&&await i.save({version:1,projectId:t,updatedAt:new Date().toISOString(),chunks:a}),e?.({current:a.length,total:a.length,phase:"index",detail:I});let l=this.fts.build(a);return{chunks:a.length,documentsIndexed:l,indexSize:this.fts.size,engine:I,mode:D,embedding:!1,vectorDatabase:!1,savedChunks:u,vectorsLoaded:0,vectorsIndexed:l,vectorsRemoved:0,totalVectors:this.fts.size,savedVectors:u}}async search(e,t=8){let n=this.fts.search(e,t),o=[];for(let s of n){let i=s.chunk,a=Os(i.filePath,e),c=s.score,u=0,l=c*a;o.push({chunk:i,score:l,lexicalScore:c,vectorScore:u,engine:I,mode:D})}return o}size(){return this.fts.size}}});import"dotenv/config";import{randomUUID as xi}from"node:crypto";var Hs={critical:100,high:75,normal:50,temporary:20};function Xt(r){return Hs[r]}function Zt(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"}fe();var nr=new E;function or(r){return nr.sanitize(r).text}function A(r){return nr.sanitizeValue(r)}var Xs=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"]),Zs=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"]),ei=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"]),ti=new Set(["rule","decision","todo","next_action","fix","context","architecture"]);function R(r){return r.normalize("NFKC").trim().toLowerCase()}function pr(r,e){for(let t of e){let n=r.metadata?.[t];if(typeof n!="string")continue;let o=R(n);if(o)return o}}function fr(r,e){for(let t of r.tags){let n=R(t);for(let o of e){if(!n.startsWith(o))continue;let s=n.slice(o.length).trim();if(s)return s}}}function ge(r){if(typeof r!="string")return;let e=R(r).replaceAll("-","_");if(e==="nextaction")return"next_action";if(ti.has(e))return e}function N(r){let e=ge(r.metadata?.conflictKind);if(e)return e;let t=ge(r.metadata?.learningKind);if(t)return t;let n=ge(r.metadata?.lifecycleKind);if(n)return n;for(let o of r.tags){let s=R(o);if(!s.startsWith("kind:"))continue;let i=ge(s.slice(5));if(i)return i}return r.tags.some(o=>R(o)==="next_action")?"next_action":r.type==="rule"?"rule":r.type==="decision"?"decision":r.type==="todo"?"todo":"other"}function ri(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 tt(r){return new Set(R(r).replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/u).filter(e=>e.length>2&&!Zs.has(e)))}function sr(r){return new Set([...tt(r)].filter(e=>!ei.has(e)))}function gr(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 ni(r,e){return gr(tt(r),tt(e))}function oi(r,e){return gr(sr(r),sr(e))}function ir(r){return new Set(r.tags.map(R).filter(e=>!(Xs.has(e)||e.startsWith("class:")||e.startsWith("kind:")||e.startsWith("level:"))))}function si(r,e){let t=ir(r),n=ir(e);for(let o of t)if(n.has(o))return!0;return!1}function ar(r){return pr(r,["topic","topicKey"])??fr(r,["topic:"])}function cr(r){return pr(r,["entity","entityKey","subject","taskId","taskKey"])??fr(r,["entity:","subject:","task:"])}function ur(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(R).filter(Boolean)):new Set}function ii(r,e){let t=ur(r);if(t.size===0)return!1;let n=ur(e);for(let o of t)if(n.has(o))return!0;return!1}function U(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 ai(r){let e=U(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function ci(r){let e=Number(r.metadata?.confidence);return Number.isFinite(e)?Math.max(0,Math.min(1,e)):0}function ui(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function lr(r){let e=U(r),t=ui(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=ci(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function li(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 di(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 mi(r,e){if(e.id===r.id||e.projectId!==r.projectId)return!1;let t=ri(e);if(["superseded","resolved","completed","stale"].includes(t))return!1;let n=N(r),o=N(e);if(!li(n,o))return!1;let s=ar(r),i=ar(e);if(s&&i&&s===i)return!0;let a=cr(r),c=cr(e);if(a&&c&&a===c||si(r,e))return!0;let u=di(n,o),l=oi(r.content,e.content);return!!(l>=u||ni(r.content,e.content)>=u||ii(r,e)&&l>=Math.max(.3,u-.2))}function dr(r){return N(r)==="rule"&&U(r).userExplicit}function pi(r,e){return!dr(r)||!dr(e)?!1:r.createdAt>=e.createdAt}function mr(r){let e=U(r);return e.userExplicit||e.sourceVerified||e.testVerified}function ye(r){return r==="todo"||r==="next_action"}function et(r,e){return r.createdAt>=e.createdAt}var he=class{resolve(e,t){let n=N(e),o={kind:n,superseded:[],conflicts:[],completed:[],resolved:[]};if(n==="other")return o;let s=lr(e);for(let i of t){if(!mi(e,i))continue;let a=N(i),c=lr(i);if(n==="fix"&&ye(a)){if(mr(e)){o.completed.push(i);continue}o.conflicts.push(i);continue}if(n==="fix"&&a==="context"){if(mr(e)&&s>=c){o.resolved.push(i);continue}o.conflicts.push(i);continue}if(ye(n)&&a==="fix"){if(U(e).userExplicit||s>c){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(ye(n)&&ye(a)){if(s>c||s===c&&et(e,i)){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(s>c){o.superseded.push(i);continue}if(s<c){o.conflicts.push(i);continue}if(pi(e,i)){o.superseded.push(i);continue}if(["context","fix","architecture","decision"].includes(n)&&et(e,i)){o.superseded.push(i);continue}if(!ai(i)&&et(e,i)){o.superseded.push(i);continue}o.conflicts.push(i)}return o}findSuperseded(e,t){return this.resolve(e,t).superseded}};var fi=new Set(["code","decision","rule","todo","summary"]);function gi(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function yr(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 yi(r,e){let t=yr(e)-yr(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 s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function hr(r){let e=new Set,t=[];for(let n of r){let o=n.trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function kr(r){let e=new Map;for(let o of r){if(!fi.has(o.type)||o.metadata?.supersededBy)continue;let s=gi(o.content);if(!s)continue;let i=[o.projectId,o.type,s].join("\0"),a=e.get(i)??[];a.push(o),e.set(i,a)}let t=[],n=0;for(let o of e.values()){if(o.length<2)continue;let s=[...o].sort(yi),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:hr(s.flatMap(c=>c.tags)),mergedSources:hr(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function rt(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 hi(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function ki(r){let e=rt(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 Si(r){return rt(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function bi(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 Sr(r,e=Date.now()){let t=50,n=[],o=rt(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 s=r.content.trim().length;s<12?(t-=30,n.push("very short content")):s<30?(t-=10,n.push("limited context")):s<=1200?(t+=8,n.push("useful context density")):s>5e3&&(t-=15,n.push("excessively large memory")),bi(r.content)&&(t-=35,n.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,n.push("confirmed across multiple sources"));let a=hi(r,e)>=ki(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=Si(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"||o==="transient";return{score:t,tier:u,stale:a,protected:c,pruneEligible:!c&&(u==="noise"&&l||a&&(u==="noise"||u==="weak")),reasons:n}}var wi={critical:100,high:75,normal:50,temporary:20},vi={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function br(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 nt(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function Ci(r){return!!r.metadata?.supersededBy||r.metadata?.lifecycleState==="superseded"}function ot(r,e=Date.now()){if(nt(r,e)||Ci(r))return!1;let t=r.metadata?.lifecycleState;return!(t==="completed"||t==="resolved"||t==="conflicting"||t==="stale")}function B(r,e=Date.now()){if(!ot(r,e))return 0;let t=wi[r.importance];if(r.importance==="critical")return t;let n=vi[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var ke=class{memories=new Map;conflicts=new he;remember(e){let n=(e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?new Date(e.createdAt).toISOString():void 0)??new Date().toISOString(),o=or(e.content.trim()),s=e.importance??Zt(e.type,o),i={id:xi(),projectId:e.projectId,type:e.type,content:o,importance:s,importanceScore:Xt(s),tags:e.tags??[],source:e.source??"agent",createdAt:n,updatedAt:n,expiresAt:e.expiresAt??br(e.type,s,new Date(n)),metadata:A(e.metadata)};i.metadata={...i.metadata??{},lifecycleState:"active"},i.metadata={...i.metadata,conflictKind:N(i)};let a=this.conflicts.resolve(i,this.list(e.projectId));if(a.superseded.length>0){i.metadata={...i.metadata??{},supersedes:a.superseded.map(c=>c.id)};for(let c of a.superseded)c.updatedAt=n,c.metadata={...c.metadata??{},supersededBy:i.id,supersededAt:n,lifecycleState:"superseded"},this.memories.set(c.id,c)}if(a.completed.length>0){i.metadata={...i.metadata??{},completes:a.completed.map(c=>c.id)};for(let c of a.completed)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"completed",completedBy:i.id,completedAt:n},this.memories.set(c.id,c)}if(a.resolved.length>0){i.metadata={...i.metadata??{},resolves:a.resolved.map(c=>c.id)};for(let c of a.resolved)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"resolved",resolvedBy:i.id,resolvedAt:n},this.memories.set(c.id,c)}if(a.conflicts.length>0){let c=a.conflicts.map(u=>u.id);i.metadata={...i.metadata??{},conflictsWith:c,lifecycleState:"conflicting"};for(let u of a.conflicts){let l=Array.isArray(u.metadata?.conflictsWith)?u.metadata?.conflictsWith:[],d=new Set(l.filter(m=>typeof m=="string"));d.add(i.id),u.updatedAt=n,u.metadata={...u.metadata??{},conflictsWith:[...d]},this.memories.set(u.id,u)}}return this.memories.set(i.id,i),i}importRecords(e){let t=0;for(let n of e){if(!n?.id)continue;let o=A(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=>ot(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(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=B(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=o.filter(l=>i.includes(l)).length,c=o.length===0?0:a/o.length,u=B(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,n)}consolidate(e,t=Date.now()){let n=kr(this.list(e)),o=[],s=0;for(let i of n.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),o.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:o.length,duplicatesRemoved:s,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 s=Sr(o,t);n.reviewed+=1,n[s.tier]+=1,s.stale&&(n.stale+=1),s.protected&&(n.protected+=1),o.metadata={...o.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(o.id,o),s.pruneEligible&&this.memories.delete(o.id)&&(n.pruned+=1)}return n}pruneExpired(e,t=Date.now()){let n=0;for(let[o,s]of this.memories)s.projectId===e&&nt(s,t)&&(this.memories.delete(o),n++);return n}pruneSuperseded(e,t=30,n=Date.now()){let o=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;n-new Date(c).getTime()>=s&&(this.memories.delete(i),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{createHash as Ii}from"node:crypto";import{existsSync as we,mkdirSync as ji,readFileSync as _i,renameSync as Ni,writeFileSync as Oi}from"node:fs";import{basename as Li,dirname as ve,join as J,parse as Ar,resolve as L}from"node:path";import{createHash as Cr}from"node:crypto";import{spawnSync as Mi}from"node:child_process";var Y="git-remote-v1",Pi=new Set(["github.com","gitlab.com","bitbucket.org"]);function xr(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:(Pi.has(r)&&(t=t.toLowerCase()),t)}function Ei(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,s=xr(t,e.pathname);return s?`${o}/${s}`:null}function Ai(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=xr(t,e[2]??"");return n?`${t}/${n}`:null}function wr(r){let e=r.trim();return e?e.includes("://")?Ei(e):Ai(e):null}function Ri(r){return Cr("sha256").update(`${Y}:${r}`).digest("hex")}function Mr(r){return Cr("sha256").update(`toolnet-project:${Y}:${r}`).digest("hex").slice(0,16)}function Ti(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function st(r,e){let t=Mi("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function vr(r,e){let t=Ti(r);return t?{scheme:Y,canonicalRemote:r,fingerprint:Ri(r),repositoryName:t,source:e}:null}function Pr(r){let e=st(r,["remote","get-url","origin"]);if(e){let o=wr(e);if(o)return vr(o,"origin")}let t=st(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=st(r,["remote","get-url",o]);if(!s)continue;let i=wr(s);i&&n.add(i)}return n.size!==1?null:vr([...n][0],"unique-remote")}var Rr=".toolnet",Di="project.json";function Fi(r){return Ii("sha256").update(r).digest("hex").slice(0,16)}function $(r){return J(r,Rr,Di)}function Tr(r){return we($(r))}function Er(r,e){let t=L(r),n=Ar(t).root;for(;;){if(Tr(t))return t;if(t===n||e&&t===L(e))break;let o=ve(t);if(o===t)break;t=o}return null}function it(r){let e=L(r),t=Ar(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>we(J(e,s))))return e;if(e===t)break;let o=ve(e);if(o===e)break;e=o}return L(r)}function Se(r){let e;try{e=JSON.parse(_i(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:ve(ve(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 be(r,e){let t=J(r,Rr);ji(t,{recursive:!0});let n=$(r),o=`${n}.tmp-${process.pid}`;Oi(o,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),Ni(o,n)}function O(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 at(r){return{version:1,scheme:Y,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function Ki(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 Ce=class{adopt(e,t){let n=it(L(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(Tr(n)){let a=Se($(n));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return O(a,n)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=at(t.gitIdentity));let i={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(s).length?s:void 0};return be(n,i),O(i,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),s=$(o.rootPath),i=Se(s),a=Ki(i);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=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:at(t)},i.updatedAt=new Date().toISOString(),be(o.rootPath,i)),O(i,o.rootPath)}findExisting(e=process.cwd()){let t=L(e),n=it(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>we(J(n,c))),i=Er(t,s?n:void 0);if(!i)return null;let a=Se($(i));return O(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=L(e),n=it(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>we(J(n,d))),i=Er(t,s?n:void 0);if(i){let d=$(i),m=Se(d);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),be(i,m)),O(m,i)}let a=new Date().toISOString(),c=Li(n),u=Pr(n),l={version:1,id:u?Mr(u.canonicalRemote):Fi(n),name:c,remote:u?.repositoryName??c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:at(u)}:void 0};return be(n,l),O(l,n)}};function ct(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var xe=class{score(e,t){let n=ct(e),o=ct([t.content,...t.tags??[],t.type].join(" "));if(n.length===0||o.length===0)return 0;let s=new Map;for(let a of o)s.set(a,(s.get(a)??0)+1);let i=0;for(let a of n){let c=s.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/n.length}};function Ir(r,e=Date.now()){let t=r.updatedAt??r.createdAt,n=new Date(t).getTime();if(!Number.isFinite(n))return 0;let o=Math.max(0,e-n)/864e5;return Math.exp(-Math.LN2*o/30)}function jr(r){return B(r)/100}var $i={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function _r(r){return $i[r]??.4}var Me=class{analyze(e){let t=e.toLowerCase(),n=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&n.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&n.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&n.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&n.push("summary"),{query:e,preferredTypes:n}}};var Pe=class{bm25=new xe;analyzer=new Me;search(e,t,n={}){let o=n.topK??8,s=n.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(n.types?.length&&!n.types.includes(c.type))continue;let u=this.bm25.score(e,c),l=Ir(c),d=jr(c),m=_r(c.type);i.preferredTypes.includes(c.type)&&(m=Math.min(1,m+.25));let p=u*.55+d*.2+l*.15+m*.1;u<=0||p<s||a.push({memory:c,score:p,scores:{keyword:u,recency:l,importance:d,type:m}})}return a.sort((c,u)=>u.score-c.score).slice(0,o)}};var Ee=class{build(e,t=6e3){let n=[],o=0;for(let s of e){let i=s.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(o+a.length>t)break;n.push(a),o+=a.length}return n.join(`
6
+ `)}};var Ae=class{constructor(e){this.memory=e}memory;searcher=new Pe;contextBuilder=new Ee;search(e,t,n={}){return this.searcher.search(t,this.memory.list(e),n)}context(e,t,n={}){let o=this.search(e,t,n);return this.contextBuilder.build(o)}};var Re=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(n=>n.projectId===e&&(n.name===t||n.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let n of e)this.addSymbol(n);for(let n of t)this.addEdge(n)}clearProject(e){for(let[t,n]of this.symbols)n.projectId===e&&this.symbols.delete(t);for(let[t,n]of this.edges)n.projectId===e&&this.edges.delete(t)}};var Te=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(o=>o.type==="CALLS"&&o.to===t).map(o=>o.from).map(o=>this.graph.getSymbol(o)).filter(o=>!!o)}};import{McpServer as du}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as mu}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Nr}from"zod";var Or={query:Nr.string(),limit:Nr.number().int().min(1).max(20).optional()};async function Lr(r,e){return r.retrieval.search(r.project.id,e.query,{topK:e.limit??8}).map(n=>({id:n.memory.id,type:n.memory.type,content:n.memory.content,importance:n.memory.importance,score:n.score,tags:n.memory.tags}))}import{z as Q}from"zod";import{createConnection as Gi}from"node:net";import{homedir as zi}from"node:os";import{join as Wi}from"node:path";function Dr(){return process.env.TOOLNET_SERVICE_SOCKET??Wi(zi(),".toolnet","run","service.sock")}function Fr(r,e={}){let t=e.socketPath??Dr(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=Gi({path:t}),a="",c=!1,u=d=>{c||(c=!0,clearTimeout(l),i.destroy(),d())},l=setTimeout(()=>{u(()=>{s(new Error(`ToolNet service timeout after ${n}ms`))})},n);i.setEncoding("utf8"),i.once("connect",()=>{i.write(`${JSON.stringify(r)}
7
7
  `)}),i.on("data",d=>{a+=d;let m=a.indexOf(`
8
- `);if(m===-1)return;let p=a.slice(0,m).trim();u(()=>{try{o(JSON.parse(p))}catch(y){s(y instanceof Error?y:new Error(String(y)))}})}),i.once("error",d=>{u(()=>{s(d)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function ci(r,e={}){let t=await Cr({type:"hydrate",project:r},e);if(!t.ok||t.type!=="hydrate")throw new Error(t.ok?"Invalid ToolNet service hydrate response":t.error);return t}async function xr(r,e={}){try{return await ci(r,e)}catch{return null}}async function Pe(r,e={}){try{let t=await Cr({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var Mr={type:U.enum(["activity","decision","rule","todo","summary"]),content:U.string().min(1),tags:U.array(U.string()).optional(),importance:U.enum(["critical","high","normal","temporary"]).optional()};async function Pr(r,e){let t=r.memory.remember({projectId:r.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),Pe(r.project),t}import{z as ui}from"zod";var Ar={id:ui.string().min(1)};async function Er(r,e){let t=r.memory.delete(e.id);return t&&r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),t&&Pe(r.project),{deleted:t}}import{z as li}from"zod";var Rr={name:li.string().min(1)};async function jr(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as di}from"zod";var Ae=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Tr=new Set(["CALLS","CALL_REFERENCE"]),w=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let n=t.trim().toLowerCase();return n?this.graph.allSymbols(e).filter(o=>o.name.toLowerCase().includes(n)||(o.qualifiedName?.toLowerCase().includes(n)??!1)||o.filePath.toLowerCase().includes(n)).sort((o,s)=>{let i=o.name.toLowerCase()===n,a=s.name.toLowerCase()===n;return i!==a?i?-1:1:o.filePath.localeCompare(s.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Tr)}callees(e,t){return this.relatedOutgoing(e,t,Tr)}dependents(e,t){return this.relatedIncoming(e,t,Ae)}dependencies(e,t){return this.relatedOutgoing(e,t,Ae)}neighborhood(e,t,n=1){let o=this.graph.getSymbol(t);return!o||o.projectId!==e?null:{center:o,incoming:this.walk(e,t,"incoming",n),outgoing:this.walk(e,t,"outgoing",n)}}shortestPath(e,t,n,o=12){let s=this.graph.getSymbol(t),i=this.graph.getSymbol(n);if(!s||!i||s.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===n)return{found:!0,distance:0,symbols:[s],edges:[]};let a=this.graph.allEdges(e).filter(m=>Ae.has(m.type)),c=new Map;for(let m of a){let p=c.get(m.from)??[];p.push(m),c.set(m.from,p)}let u=[{id:t,depth:0}],l=new Set([t]),d=new Map;for(;u.length>0;){let m=u.shift();if(!(m.depth>=o)){for(let p of c.get(m.id)??[])if(!l.has(p.to)){if(l.add(p.to),d.set(p.to,{node:m.id,edge:p}),p.to===n)return this.buildPath(t,n,d);u.push({id:p.to,depth:m.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,n){let o=[t],s=[],i=t;for(;i!==e;){let c=n.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};s.push(c.edge),i=c.node,o.push(i)}o.reverse(),s.reverse();let a=o.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:s.length,symbols:a,edges:s}}walk(e,t,n,o){let s=this.graph.allEdges(e).filter(u=>Ae.has(u.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let u=i.shift();if(!(u.depth>=o))for(let l of s){if(!(n==="incoming"?l.to===u.id:l.from===u.id))continue;let m=n==="incoming"?l.from:l.to;if(a.has(m))continue;let p=this.graph.getSymbol(m);p&&(a.add(m),c.push({symbol:p,depth:u.depth+1,via:l}),i.push({id:m,depth:u.depth+1}))}}return c}relatedIncoming(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.to===t&&n.has(s.type)).map(s=>s.from))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}relatedOutgoing(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.from===t&&n.has(s.type)).map(s=>s.to))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function v(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let n=new w(r.graph),o=n.findSymbols(r.project.id,e).find(s=>s.name===e||s.qualifiedName===e);return o||(n.findSymbols(r.project.id,e)[0]??null)}function b(r){return{id:r.id,name:r.name,qualifiedName:r.qualifiedName,type:r.type,filePath:r.filePath,startLine:r.startLine,endLine:r.endLine}}var Ir={symbolId:di.string().min(1)};async function _r(r,e){let t=v(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let o=new w(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:b(t),count:o.length,callers:o.map(b)}}import{z as Nr}from"zod";var Or={query:Nr.string().min(1),limit:Nr.number().int().min(1).max(50).optional()};async function Lr(r,e){let t=e.query.toLowerCase(),n=e.limit??20;return r.graph.allSymbols(r.project.id).filter(o=>o.name.toLowerCase().includes(t)||o.qualifiedName?.toLowerCase().includes(t)||o.filePath.toLowerCase().includes(t)).slice(0,n)}import{z as Fr}from"zod";function Ee(r,e){let t=r.allSymbols(e),n=r.allEdges(e),o=i=>t.filter(a=>a.type===i).length,s=i=>n.filter(a=>a.type===i).length;return{files:o("file"),classes:o("class"),interfaces:o("interface"),functions:o("function"),methods:o("method"),properties:o("property"),routes:o("route"),symbols:t.length,edges:n.length,calls:s("CALLS"),callReferences:s("CALL_REFERENCE"),imports:s("IMPORTS"),inherits:s("INHERITS"),implements:s("IMPLEMENTS"),usesType:s("USES_TYPE"),tests:s("TESTS"),routeEdges:s("ROUTE"),writes:s("WRITES")}}var Dr={query:Fr.string().optional(),memoryLimit:Fr.number().int().min(1).max(20).optional()};async function Kr(r,e){let t=Ee(r.graph,r.project.id),n=r.memory.recent(r.project.id,5),o=e.query?r.retrieval.search(r.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:t,recent:n,relevant:o.map(s=>s.memory)}}import{z as pi}from"zod";var mi=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],E=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",n){let o=new Date().toISOString(),s=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,s),c=[];for(let l of mi){let d=`${i}/${l}`,m=await this.storage.get(d);m&&(await this.storage.put(`${a}/${l}`,m,"application/json"),c.push(l))}if(c.length===0)return null;let u={version:1,id:s,projectId:e,createdAt:o,reason:t,objects:c,metadata:n};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(u,null,2),"application/json"),u}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),s=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{s.push(JSON.parse(a))}catch{}}return s.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.getText(`${n}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let s=JSON.parse(o);if(s.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of s.objects){let u=await this.storage.get(`${n}/${c}`);u&&(await this.storage.put(`${i}/${c}`,u,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.list(n);for(let s of o)await this.storage.delete(s.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),s=0;for(let i of o)await this.remove(e,i.id),s++;return s}};var $r={reason:pi.string().optional()};async function zr(r,e){if(!r.storage)throw new Error("Storage unavailable");return new E(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function Wr(r){if(!r.storage)throw new Error("Storage unavailable");return new E(r.storage).list(r.project.id)}import{z as fi}from"zod";var Gr={snapshotId:fi.string().min(1)};async function qr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new E(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as nt}from"zod";var Re=class{constructor(e){this.graph=e}graph;callees(e,t,n=3){return this.walk(e,t,"out",n)}callers(e,t,n=3){return this.walk(e,t,"in",n)}walk(e,t,n,o){let s=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(u=>u.type==="CALLS"||u.type==="CALL_REFERENCE");for(;a.length;){let u=a.shift();if(u.depth>=o)continue;let l=n==="out"?c.filter(d=>d.from===u.id):c.filter(d=>d.to===u.id);for(let d of l){let m=n==="out"?d.to:d.from;if(i.has(m))continue;i.add(m);let p=this.graph.getSymbol(m);if(!p)continue;let y=u.depth+1;s.push({symbol:p,depth:y}),a.push({id:m,depth:y})}}return s}};var Vr={symbolId:nt.string().min(1),direction:nt.enum(["callers","callees"]).optional(),depth:nt.number().int().min(1).max(10).optional()};async function Hr(r,e){let t=new Re(r.graph),n=e.direction??"callees",o=e.depth??3,s=n==="callers"?t.callers(r.project.id,e.symbolId,o):t.callees(r.project.id,e.symbolId,o);return{direction:n,depth:o,results:s.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as Br}from"zod";var je=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=n)continue;let u=o.filter(l=>l.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(l.type));for(let l of u){if(s.has(l.from))continue;s.add(l.from);let d=this.graph.getSymbol(l.from);if(!d)continue;let m=c.depth+1;a.push({symbol:d,depth:m,relation:l.type}),i.push({id:l.from,depth:m})}}return a}};var Ur={symbolId:Br.string().min(1),depth:Br.number().int().min(1).max(10).optional()};async function Jr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new je(r.graph).analyze(r.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:o.map(s=>({id:s.symbol.id,name:s.symbol.name,qualifiedName:s.symbol.qualifiedName,filePath:s.symbol.filePath,type:s.symbol.type,relation:s.relation,depth:s.depth}))}}async function Qr(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:Ee(r.graph,r.project.id)}}import{z as Yr}from"zod";var gi=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Te=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>gi.has(i.type)),o=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,u=0,l=0;for(let d of n){let m=o.get(d.from),p=o.get(d.to);!m||!p||m.filePath===p.filePath||(m.filePath===i&&(a.add(p.filePath),u++),p.filePath===i&&(c.add(m.filePath),l++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:u,incomingEdges:l}})}};var Xr={filePath:Yr.string().min(1),direction:Yr.enum(["dependencies","dependents","both"]).optional()};async function Zr(r,e){let n=new Te(r.graph).analyze(r.project.id).find(c=>c.filePath===e.filePath);if(!n)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let o=r.graph.allSymbols(r.project.id).filter(c=>c.type==="file"),s=new Map(o.map(c=>[c.filePath,c])),i=c=>({id:s.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:n.filePath,outgoingEdges:n.outgoingEdges,incomingEdges:n.incomingEdges,dependencies:a==="dependents"?[]:n.dependencies.map(i),dependents:a==="dependencies"?[]:n.dependents.map(i)}}ot();import{z as en}from"zod";var tn={query:en.string().min(1),limit:en.number().int().min(1).max(20).optional()};async function rn(r,e){if(!r.codeSemantic)return{available:!1,engine:R,mode:O,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",results:[]};let t=await r.codeSemantic.search(e.query,e.limit??8);return{available:!0,engine:R,mode:O,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",searchContract:Ie,results:t.map(n=>({id:n.chunk.id,filePath:n.chunk.filePath,symbol:n.chunk.symbolName,symbolType:n.chunk.symbolType,startLine:n.chunk.startLine,endLine:n.chunk.endLine,score:n.score,lexicalScore:n.lexicalScore,vectorScore:n.vectorScore,engine:n.engine,mode:n.mode,content:n.chunk.content}))}}import{z as it}from"zod";import{execFile as hi}from"node:child_process";import{promisify as ki}from"node:util";var st=ki(hi);function Si(r){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let n of r.matchAll(t)){let o=Number(n[1]),s=Number(n[2]??1);e.push({startLine:o,endLine:Math.max(o,o+s-1)})}return e}function bi(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function nn(r){let e="";try{e=(await st("git",["diff","HEAD","--name-status","--no-renames"],{cwd:r,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let n of e.split(/\r?\n/).filter(Boolean)){let[o,...s]=n.split(" "),i=s.at(-1);if(!i)continue;let a="";try{a=(await st("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:bi(o),ranges:Si(a)})}try{let n=await st("git",["ls-files","--others","--exclude-standard"],{cwd:r});for(let o of n.stdout.split(/\r?\n/).filter(Boolean))t.some(s=>s.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}function wi(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var _e=class{constructor(e){this.graph=e}graph;map(e,t){let n=this.graph.allSymbols(e),o=[];for(let s of t){let i=n.filter(u=>u.filePath===s.filePath),c=i.filter(u=>u.type!=="file").filter(u=>wi(u,s));if(c.length===0){let u=i.find(l=>l.type==="file");u&&o.push({symbol:u,fileStatus:s.status,direct:!0});continue}for(let u of c)o.push({symbol:u,fileStatus:s.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var vi={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Ci(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function on(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var Ne=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Map,i=0;for(let l of t){l.fileStatus==="deleted"?i+=8:l.fileStatus==="renamed"?i+=5:i+=2,l.symbol.type==="interface"&&(i+=5),l.symbol.type==="class"&&(i+=3);let d=new Set([l.symbol.id]),m=[{id:l.symbol.id,depth:0}];for(;m.length;){let p=m.shift();if(p.depth>=n)continue;let y=o.filter(S=>S.to===p.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(S.type));for(let S of y){if(d.has(S.from))continue;d.add(S.from);let T=this.graph.getSymbol(S.from);if(!T)continue;let G=p.depth+1,is=`${l.symbol.id}:${T.id}`;s.set(is,{symbol:T,relation:S.type,depth:G,sourceSymbolId:l.symbol.id});let as=vi[S.type]??1;i+=Math.max(1,as-(G-1)),m.push({id:T.id,depth:G})}}}let a=[...s.values()].sort((l,d)=>l.depth-d.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(on);return u.length===0&&u.push(...c.filter(l=>!on(l)).slice(0,10)),{risk:Ci(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var Oe=class{constructor(e){this.graph=e;this.mapper=new _e(e),this.blast=new Ne(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await nn(t),s=this.mapper.map(e,o),i=this.blast.analyze(e,s,n.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,n={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,n.maxDepth??4)}}};var sn={mode:it.enum(["git_diff","file"]).optional(),filePath:it.string().optional(),depth:it.number().int().min(1).max(10).optional()};async function an(r,e){let t=new Oe(r.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(r.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(r.project.id,r.project.rootPath,{maxDepth:e.depth})}import{z as xi}from"zod";var cn={symbol:xi.string().min(1)};async function un(r,e){let t=v(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let o=new w(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:b(t),count:o.length,dependents:o.map(b)}}import{z as at}from"zod";var ln={from:at.string().min(1),to:at.string().min(1),maxDepth:at.number().int().min(1).max(30).optional()};async function dn(r,e){let t=v(r,e.from),n=v(r,e.to);if(!t||!n)return{found:!1,fromFound:!!t,toFound:!!n,path:[],edges:[]};let s=new w(r.graph).shortestPath(r.project.id,t.id,n.id,e.maxDepth??12);return{found:s.found,distance:s.distance,from:b(t),to:b(n),path:s.symbols.map(b),edges:s.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as ct}from"zod";var mn={symbol:ct.string().min(1),depth:ct.number().int().min(1).max(5).optional(),limit:ct.number().int().min(1).max(200).optional()};async function pn(r,e){let t=v(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let o=new w(r.graph).neighborhood(r.project.id,t.id,e.depth??1);if(!o)return{found:!1,query:e.symbol};let s=e.limit??50;return{found:!0,center:b(o.center),incomingCount:o.incoming.length,outgoingCount:o.outgoing.length,incoming:o.incoming.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:b(i.symbol)})),outgoing:o.outgoing.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:b(i.symbol)}))}}import{z as lt}from"zod";function Mi(r){return r.replaceAll("\\","/").toLowerCase()}var Le=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,n);a&&o.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let s=new Map;for(let i of o){let a=i.kind==="route"?i.symbolId:i.filePath,c=s.get(a);(!c||i.score>c.score)&&s.set(a,i)}return[...s.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let n=Mi(e.filePath),o=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let s=null,i=0;if(n.startsWith("bin/"))s="cli",i=100,o.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(n))s="cli",i=90,o.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(n))s="main",i=90,o.push("main/server file");else if(n.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(n))s="runtime",i=75,o.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(n)){let c=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,u=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(n.startsWith("packages/")||c===0||u>0)&&(s="package",i=n.startsWith("packages/")?70:55,o.push("package/public index"))}return s?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,o.push("no incoming dependency")),{kind:s,score:i,reasons:o}):null}};var fn=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function ut(r){return r.replaceAll("\\","/").toLowerCase()}function Pi(r){let e=ut(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Ai(r){let e=ut(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var Fe=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=new Set(new Le(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Pi(i.filePath)||o.has(i.id)||Ai(i)||n.filter(p=>p.to===i.id&&fn.has(p.type)).length>0)continue;let c=n.filter(p=>p.from===i.id&&fn.has(p.type)),u=["no incoming usage edge"],l=50;(i.type==="function"||i.type==="method")&&(l+=20,u.push("callable symbol")),i.type==="property"&&(l-=15),c.length===0&&(l+=10,u.push("no outgoing dependency")),ut(i.filePath).includes("/internal/")&&(l+=10,u.push("internal implementation")),i.name.startsWith("_")&&(l+=5);let m=l>=75?"high":l>=55?"medium":"low";s.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:m,score:l,reasons:u})}return s.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var yn={confidence:lt.enum(["high","medium","low","all"]).optional(),filePath:lt.string().min(1).optional(),limit:lt.number().int().min(1).max(500).optional()},gn={high:3,medium:2,low:1};async function hn(r,e){let n=new Fe(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=gn[e.confidence];n=n.filter(a=>gn[a.confidence]>=i)}e.filePath&&(n=n.filter(i=>i.filePath===e.filePath));let o=n.length,s=e.limit??100;return{total:o,high:n.filter(i=>i.confidence==="high").length,medium:n.filter(i=>i.confidence==="medium").length,low:n.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:n.slice(0,s)}}import{z as ft}from"zod";import{existsSync as Ji,readFileSync as Qi}from"node:fs";import{join as Yi}from"node:path";var Cd=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Ed,existsSync as Ei,fsyncSync as Rd,mkdirSync as jd,openSync as Td,readFileSync as Ri,renameSync as Id,writeFileSync as _d}from"node:fs";import{dirname as Od,join as ji}from"node:path";function Ti(r){return ji(r.rootPath,".toolnet","work","current.json")}function dt(r){let e=Ti(r);if(!Ei(e))return null;try{let t=JSON.parse(Ri(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as Ii,mkdirSync as Kd,readFileSync as _i,renameSync as $d,writeFileSync as zd}from"node:fs";import{dirname as Gd,join as Ni}from"node:path";function Oi(r){return Ni(r.rootPath,".toolnet","context","session-origin.json")}function mt(r){let e=Oi(r);if(!Ii(e))return null;try{let t=JSON.parse(_i(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function Li(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function De(r){let e=Li(r),t=/(?:agent trước|previous agent|ai trước|phiên trước)/u.test(e),n=/(?:đang làm gì|làm tới đâu|dừng ở đâu|dở ở đâu|stopped where|working on|current task|file nào|last touched|làm gì tiếp|next action|next step)/u.test(e);return t&&n?"summary":/(?:agent trước là ai|previous agent|ai trước là ai|phiên trước là ai)/u.test(e)?"previous_agent":/(?:task hiện tại|current task|đang làm gì|đang làm task nào|dở ở đâu|dừng ở đâu|stopped where)/u.test(e)?"current_task":/(?:tiếp theo|next action|next step|làm gì tiếp|phải làm gì tiếp)/u.test(e)?"next_action":/(?:file cuối|last file|file nào|đang sửa file|last touched)/u.test(e)?"last_file":/(?:blocker|vướng|kẹt|lỗi gì|blocked)/u.test(e)?"blocker":/(?:decision|quyết định|đã chốt|important decision)/u.test(e)?"decision":/(?:đã xong|completed|hoàn thành|done|todo nào xong)/u.test(e)?"completed":/(?:status|trạng thái|tiến độ|progress)/u.test(e)?"status":"summary"}import{existsSync as qi,mkdirSync as Nm,readFileSync as Vi}from"node:fs";import{join as wn}from"node:path";ce();pt();var bm=new P;function Hi(r){return wn(r.rootPath,".toolnet","memory","checkpoints")}function Bi(r){return wn(Hi(r),"latest.json")}function Ui(r){let e=Bi(r);if(!qi(e))return null;try{let t=JSON.parse(Vi(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function vn(r){return Ui(r)}var Xi={previous_agent:{previous_agent:100,task:35,phase:25},current_task:{task:100,request:95,activity:90,phase:75,file:65,next_action:55,blocker:45},next_action:{next_action:100,todo:80,task:65,blocker:60,file:40},last_file:{file:100,task:65,next_action:40},blocker:{blocker:100,task:60,next_action:50,file:35},decision:{decision:100,rule:85,architecture:80,task:45,file:30},completed:{completed:100,progress:70,task:30},status:{progress:100,task:85,phase:75,blocker:65,next_action:60},summary:{task:100,request:98,activity:96,next_action:95,file:90,blocker:85,previous_agent:80,phase:75,completed:60,todo:60,decision:55,rule:54,architecture:53,fix:52,progress:50,test:45,goal:35}},Zi={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function ea(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function f(r,e){let t=e.value.replace(/\s+/g," ").trim();t&&r.push({...e,value:t,score:0})}function ta(r){let e=Yi(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ji(e))return null;try{let n=JSON.parse(Qi(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function ra(r){let e=vn(r);if(!e)return[];let t=[];e.request&&f(t,{kind:"request",value:e.request,source:"checkpoint"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"checkpoint"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"checkpoint"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"checkpoint"});let n=e.files.active.at(-1);n&&f(t,{kind:"file",value:n,source:"checkpoint"});for(let o of e.nextActions)f(t,{kind:"next_action",value:o,source:"checkpoint"});for(let o of e.blockers)f(t,{kind:"blocker",value:o,source:"checkpoint"});for(let o of e.completed.tasks)f(t,{kind:"completed",value:o,source:"checkpoint"});for(let o of e.remaining.tasks)f(t,{kind:"todo",value:o,source:"checkpoint"});for(let o of e.durableFacts)f(t,{kind:o.kind,value:o.content,source:"checkpoint"});return t}function na(r){let e=ta(r);if(!e)return[];let t=[];f(t,{kind:"previous_agent",value:e.source.agent,source:"handoff"}),e.request&&f(t,{kind:"request",value:e.request,source:"handoff"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"handoff"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"handoff"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"handoff"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"handoff"}),e.files.current&&f(t,{kind:"file",value:e.files.current,source:"handoff"}),e.nextAction&&f(t,{kind:"next_action",value:e.nextAction,source:"handoff"});for(let n of e.blockers)f(t,{kind:"blocker",value:n,source:"handoff"});for(let n of e.decisions)f(t,{kind:"decision",value:n,source:"handoff"});for(let n of e.completed.tasks)f(t,{kind:"completed",value:n,source:"handoff"});for(let n of e.remaining.todos)f(t,{kind:"todo",value:n,source:"handoff"});return f(t,{kind:"test",value:`Test status: ${e.tests.status}`,source:"handoff"}),f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"handoff"}),t}function oa(r){let e=mt(r);if(!e)return[];let t=[];return f(t,{kind:"previous_agent",value:e.agent,source:"session-origin"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase,source:"session-origin"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask,source:"session-origin"}),e.lastTouchedFile&&f(t,{kind:"file",value:e.lastTouchedFile,source:"session-origin"}),e.latestNextAction&&f(t,{kind:"next_action",value:e.latestNextAction,source:"session-origin"}),e.latestBlocker&&f(t,{kind:"blocker",value:e.latestBlocker,source:"session-origin"}),e.latestDecision&&f(t,{kind:"decision",value:e.latestDecision,source:"session-origin"}),t}function sa(r){let e=dt(r);if(!e)return[];let t=[];e.currentRequest&&f(t,{kind:"request",value:e.currentRequest,source:"work-state"}),e.currentActivity&&f(t,{kind:"activity",value:e.currentActivity,source:"work-state"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"work-state"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase.title,source:"work-state"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask.title,source:"work-state"});let n=e.activeFiles?.at(-1)??e.filesTouched.at(-1);n&&f(t,{kind:"file",value:n,source:"work-state"});for(let o of e.nextActions.slice(0,5))f(t,{kind:"next_action",value:o,source:"work-state"});for(let o of e.blockers.slice(-5))f(t,{kind:"blocker",value:o,source:"work-state"});for(let o of e.decisions.slice(-5))f(t,{kind:"decision",value:o,source:"work-state"});for(let o of e.tasks.filter(s=>s.status==="completed").slice(-8))f(t,{kind:"completed",value:o.title,source:"work-state"});for(let o of e.tasks.filter(s=>s.status!=="completed"&&s.status!=="cancelled").slice(0,8))f(t,{kind:"todo",value:o.title,source:"work-state"});for(let o of e.tests.slice(-5))f(t,{kind:"test",value:o,source:"work-state"});return f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"work-state"}),t}function ia(r,e){let t=Xi[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+Zi[n.source]+Math.max(0,5-o*.01)}))}function aa(r){let e=new Map;for(let t of r){let n=`${t.kind}:${ea(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function Ke(r,e,t={}){let n=De(e),o=[...ra(r),...na(r),...oa(r),...sa(r)],s=aa(ia(n,o)).sort((l,d)=>d.score-l.score),i=Math.max(1,t.maxFacts??12),a=Math.max(300,t.maxChars??3200),c=[],u=0;for(let l of s){if(c.length>=i)break;let d=l.kind.length+l.value.length+l.source.length+16;c.length>0&&u+d>a||(c.push(l),u+=d)}return{intent:n,facts:c,context:{project:{id:r.id,name:r.name},intent:n,selectedFacts:c.map(l=>({kind:l.kind,value:l.value,source:l.source}))},stats:{candidates:o.length,selected:c.length,chars:u}}}var Cn={previous_agent:"Agent tr\u01B0\u1EDBc",request:"Y\xEAu c\u1EA7u hi\u1EC7n t\u1EA1i",activity:"\u0110ang l\xE0m",goal:"M\u1EE5c ti\xEAu",phase:"Phase",task:"Task hi\u1EC7n t\u1EA1i",file:"File hi\u1EC7n t\u1EA1i",todo:"TODO",next_action:"Ti\u1EBFp theo",blocker:"Blocker",decision:"Quy\u1EBFt \u0111\u1ECBnh",rule:"Quy t\u1EAFc",architecture:"Ki\u1EBFn tr\xFAc",fix:"\u0110\xE3 s\u1EEDa",completed:"\u0110\xE3 ho\xE0n th\xE0nh",test:"Test",progress:"Ti\u1EBFn \u0111\u1ED9"},xn=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],ca={previous_agent:["previous_agent"],current_task:["request","activity","task","file","next_action"],next_action:["next_action","task","file","todo"],last_file:["file","task","next_action"],blocker:["blocker"],decision:["decision"],completed:["completed"],status:["progress","task","next_action","blocker"],summary:xn};function ua(r){let e=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)}function la(r){let e=r.filter(n=>n.source==="handoff");if(e.length===0)return r;let t=r.filter(n=>n.source==="checkpoint"&&["rule","architecture","fix"].includes(n.kind));return[...e,...t]}function da(r){let e=new Set,t=[];for(let n of r){let o=`${n.kind}:${n.value.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}`;e.has(o)||(e.add(o),t.push(n))}return t}function Mn(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function ma(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,Mn(n));for(let s of o)t.push(`${Cn[n]}: ${s.value}`)}return t.join(`
9
- `)}function pa(r,e){let t=ca[e]??xn,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,Mn(o));for(let i of s)n.push(`${Cn[o]}: ${i.value}`)}return n.join(`
10
- `)}function Pn(r,e){let t=Ke(r,e,{maxFacts:32,maxChars:6400}),n=da(la(t.facts)),o=ua(e)?ma(n,["todo","task","next_action","file"]):pa(n,String(t.intent));return o?{intent:String(t.intent),answer:o,source:n[0]?.source??"none"}:{intent:String(t.intent),answer:"ToolNet ch\u01B0a c\xF3 \u0111\u1EE7 memory cho c\xE2u h\u1ECFi n\xE0y.",source:"none"}}import{existsSync as fa,mkdirSync as ga,readFileSync as ya,renameSync as ha,rmSync as ka,writeFileSync as Sa}from"node:fs";import{join as An}from"node:path";var ba=720*60*1e3;function En(r){return An(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function Y(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function wa(r){let e=Y(r);return[/\btiếp tục\b/u,/\btiếp tục task\b/u,/\blúc nãy\b/u,/\btrước đó\b/u,/\btask trước\b/u,/\bprevious (?:task|session|work)\b/u,/\bcontinue\b/u,/\bresume\b/u,/\bcurrent task\b/u,/\bđang làm gì\b/u].some(t=>t.test(e))}function va(r){if(wa(r))return!1;let e=Y(r),t=e.split(/\s+/u).filter(Boolean);return[/^(?:tại sao|vì sao|sao vậy)\b/u,/^(?:why|why so|why that)\b/u,/^(?:còn|thế|vậy|rồi sao|sau đó)\b/u,/^(?:what about|and what|then what)\b/u,/^(?:cái đó|việc đó|nó|phần đó)\b/u].some(n=>n.test(e))?!0:t.length<=5&&/\b(?:nó|đó|vậy|thế|that|it|this)\b/u.test(e)}function Ca(r,e,t){let n=En(r);if(!fa(n))return null;try{let o=JSON.parse(ya(n,"utf8"));if(o.schema!=="toolnet.memory-conversation.v1"||o.version!==1||o.projectId!==r.id||!Array.isArray(o.focus))return null;let s=Date.parse(o.updatedAt);return!Number.isFinite(s)||e-s>t?null:o}catch{return null}}function xa(r,e=8){let t=new Set,n=[];for(let o of r){let s=o.value.replace(/\s+/gu," ").trim();if(!s)continue;let i=[o.kind,Y(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function Ma(r,e){let t=En(r),n=An(r.rootPath,".toolnet","context");ga(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{Sa(o,JSON.stringify(e,null,2)+`
11
- `,{encoding:"utf8",mode:384}),ha(o,t)}finally{ka(o,{force:!0})}}function Pa(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
12
- `)}function Aa(r,e){return r.priorFocus.find(t=>t.kind===e)?.value}function Rn(r){if(!r.usedPriorFocus||r.currentIntent!=="summary"||r.priorFocus.length===0)return null;let e=Y(r.originalQuestion),t=/^(?:tại sao|vì sao|sao vậy|why|why so|why that)\b/u.test(e),n=/^(?:rồi sao|sau đó|tiếp thì sao|thế tiếp theo|then what|what next)\b/u.test(e),o=t?["decision","blocker","next_action","task","file"]:n?["next_action","todo","task","blocker","file","decision"]:["task","next_action","file","decision","blocker"],s={task:"Task li\xEAn quan",next_action:"Vi\u1EC7c ti\u1EBFp theo",file:"File li\xEAn quan",decision:"Quy\u1EBFt \u0111\u1ECBnh li\xEAn quan",blocker:"Blocker",todo:"TODO"},i=[];for(let a of o){let c=Aa(r,a);if(c&&(i.push(`${s[a]??a}: ${c}.`),t&&i.length>=2||!t&&i.length>=3))break}return i.length===0?null:{answer:i.join(" "),intent:"summary",source:"conversation-focus"}}function Ea(r){let e=Y(r);return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(e)}function jn(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??ba,s=Ca(r,n,o),i=!!(s&&s.focus.length>0&&va(e)&&!Ea(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",Pa(s),"","Use the compact focus only to resolve the current follow-up question.","Do not reconstruct or request raw session transcripts."].join(`
13
- `):e.trim(),c=De(e),l=Ke(r,a,{maxFacts:8,maxChars:1800}).facts.map(m=>({kind:m.kind,value:m.value,source:m.source})),d=xa(i&&s?[...l,...s.focus]:l);return Ma(r,{schema:"toolnet.memory-conversation.v1",version:1,projectId:r.id,updatedAt:new Date(n).toISOString(),lastIntent:c,focus:d}),{question:a,originalQuestion:e,usedPriorFocus:i,previousIntent:s?.lastIntent,currentIntent:c,priorFocus:s?.focus??[],focusCount:d.length}}import{existsSync as Ra,readFileSync as ja}from"node:fs";import{join as Ta}from"node:path";function j(r){return!!r?.trim()}function Tn(r){let e=[],t=[],n=100;j(r.goal)||j(r.request)||(e.push("goal_or_request"),n-=20),j(r.activity)||j(r.current.task?.title)||j(r.current.phase?.title)||(e.push("current_work"),n-=25),j(r.nextAction)||j(r.remaining.todos[0])||(e.push("next_action"),n-=25),r.tests.status!=="unknown"||r.tests.recent.length>0||(r.tests.checks?.length??0)>0||(r.evidence?.commands.length??0)>0||(r.evidence?.references.length??0)>0||(e.push("evidence"),n-=20),j(r.files.current)||r.files.recent.length>0||(r.files.active?.length??0)>0||(r.files.modified?.length??0)>0||(r.files.created?.length??0)>0||(e.push("files"),n-=10),r.tests.status==="failing"&&t.push("tests_failing"),r.blockers.length>0&&t.push("active_blockers"),n=Math.max(0,Math.min(100,n));let u=e.includes("current_work")||e.includes("next_action"),l;return n>=80&&!u?l="high":n>=50?l="medium":l="low",{confidence:l,score:n,missingContext:e,warnings:t}}var In={compact:{completed:3,evidence:3,files:5,blockers:2,maxChars:1800},normal:{completed:10,evidence:10,files:15,blockers:5,maxChars:4200},benchmark:{completed:30,evidence:30,files:40,blockers:10,maxChars:1e4}};function D(r){let e=new Set,t=[];for(let n of r){let o=n?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function K(r){return r.length>0?r.map(e=>`- ${e}`).join(`
14
- `):"- none"}function Ia(r,e){return r.length<=e?r:[r.slice(0,e).trimEnd(),"","[Structured handoff truncated]"].join(`
15
- `)}function _n(r,e){if(e)return e;let t=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/\bbenchmark\b/u.test(t)||/\bdeep handoff\b/u.test(t)||/\bfull handoff\b/u.test(t)||/\btakeover\b/u.test(t)||/\btake over\b/u.test(t)||/tiếp quản/u.test(t)||/bằng chứng đầy đủ/u.test(t)||/evidence.*(?:file|test|command)/u.test(t)?"benchmark":/\bcompact\b/u.test(t)||/\bbrief\b/u.test(t)||/ngắn gọn/u.test(t)||/tóm tắt ngắn/u.test(t)?"compact":"normal"}function _a(r,e="normal"){let t=In[e],n=D([`Source agent: ${r.source.agent}`,`Captured: ${r.capturedAt}`,r.goal?`Goal: ${r.goal}`:void 0,r.request?`Request: ${r.request}`:void 0,r.activity?`Activity: ${r.activity}`:void 0,r.current.phase?`Phase: ${r.current.phase.title} [${r.current.phase.status}]`:void 0,r.current.task?`Task: ${r.current.task.title} [${r.current.task.status}]`:void 0,r.current.file?`Current file: ${r.current.file}`:void 0,`Progress: ${JSON.stringify(r.progress)}`]),o=D([...r.completed.phases.map(u=>`Phase: ${u}`),...r.completed.tasks.map(u=>`Task: ${u}`)]).slice(0,t.completed),s=D([`Tests status: ${r.tests.status}`,...r.tests.recent.map(u=>`Test: ${u}`),...(r.tests.checks??[]).map(u=>`Check [${u.status}] ${u.kind}: ${u.command}`),...(r.evidence?.commands??[]).map(u=>`Command: ${u}`),...(r.evidence?.references??[]).map(u=>`Reference: ${u}`),...r.decisions.map(u=>`Decision: ${u}`),...r.attention.map(u=>`Attention: ${u}`)]).slice(0,t.evidence),i=D([r.files.current,...(r.files.active??[]).map(u=>`Active: ${u}`),...(r.files.modified??[]).map(u=>`Modified: ${u}`),...(r.files.created??[]).map(u=>`Created: ${u}`),...(r.files.deleted??[]).map(u=>`Deleted: ${u}`),...r.files.recent.map(u=>`Recent: ${u}`)]).slice(0,t.files),a=D(r.blockers).slice(0,t.blockers),c=D([r.nextAction,r.nextAction?void 0:r.remaining.todos[0]]).slice(0,1);return{currentState:n,completed:o,evidence:s,filesTouched:i,blockers:a,nextAction:c}}function Na(r,e,t){return[`HANDOFF_DETAIL: ${e}`,`CONTINUITY_CONFIDENCE: ${t.confidence}`,`QUALITY_SCORE: ${t.score}`,`MISSING_CONTEXT: ${t.missingContext.length>0?t.missingContext.join(", "):"none"}`,`QUALITY_WARNINGS: ${t.warnings.length>0?t.warnings.join(", "):"none"}`,"","CURRENT_STATE",K(r.currentState),"","COMPLETED",K(r.completed),"","EVIDENCE",K(r.evidence),"","FILES_TOUCHED",K(r.filesTouched),"","BLOCKERS",K(r.blockers),"","NEXT_ACTION",K(r.nextAction)].join(`
16
- `)}function Nn(r,e="normal"){let t=Ta(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ra(t))return null;try{let o=JSON.parse(ja(t,"utf8")).continuity;if(!o||o.schema!=="toolnet.handoff.v2"||o.version!==2)return null;let s=_a(o,e),i=Tn(o),a=Ia(Na(s,e,i),In[e].maxChars);return{detail:e,data:s,quality:i,text:a}}catch{return null}}function Oa(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}var La=[/\bhandoff\b/u,/\bcontinuity\b/u,/\bcontinue\b/u,/\bresume\b/u,/\btakeover\b/u,/\btake over\b/u,/tiếp tục/u,/tiếp quản/u,/bàn giao/u,/dừng ở đâu/u,/đang làm gì/u],Fa=[/\bcurrent state\b/u,/\bcurrent task\b/u,/\bevidence\b/u,/\breport locations?\b/u,/\bfiles?\b/u,/\burls?\b/u,/\bassets?\b/u,/\btests?\b/u,/\bcommands?\b/u,/\bblockers?\b/u,/\bnext actions?\b/u,/trạng thái hiện tại/u,/task hiện tại/u,/bằng chứng/u,/vị trí báo cáo/u,/file/u,/url/u,/blocker/u,/việc tiếp theo/u,/bước tiếp theo/u],Da=[/\bsummarize\b/u,/\bsummary\b/u,/\bfull state\b/u,/\bfull context\b/u,/tóm tắt/u,/đầy đủ/u,/toàn bộ trạng thái/u];function Ka(r){let e=0;for(let t of Fa)t.test(r)&&(e+=1);return e}function On(r,e){let t=Oa(r);if(/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(t)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(t)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(t))return!1;if(e==="summary"||e==="status")return!0;if(!t)return!1;let o=La.some(a=>a.test(t)),s=Da.some(a=>a.test(t)),i=Ka(t);return!!(o&&i>=1||s&&i>=2||i>=4)}var Fn={question:ft.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:ft.enum(["local"]).optional().describe("Returns deterministic local memory only. No external AI is used."),detail:ft.enum(["compact","normal","benchmark"]).optional().describe("Handoff detail level. compact=minimal, normal=standard, benchmark=deep evidence/files/tests for agent takeover.")};function Ln(r,e,t,n,o){if(!On(e,t))return{answer:n};let s=_n(e,o),i=Nn(r.project,s);return i?{answer:i.text,handoff:i.data,detail:i.detail,confidence:i.quality.confidence,missingContext:i.quality.missingContext,quality:i.quality}:{answer:n}}async function Dn(r,e){let t=jn(r.project,e.question),n=Rn(t);if(n)return{...Ln(r,t.originalQuestion,String(n.intent),n.answer,e.detail),mode:"local",usedAi:!1,source:n.source,intent:n.intent};let o=Pn(r.project,t.originalQuestion),s=Ln(r,t.originalQuestion,String(o.intent),o.answer,e.detail);return"handoff"in s?{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent,routing:"deterministic-handoff"}:{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent}}import{z as Vn}from"zod";import{chmodSync as mp,existsSync as Kn,mkdirSync as pp,readFileSync as $n,renameSync as fp,writeFileSync as gp}from"node:fs";import{dirname as hp,join as X}from"node:path";var zn="toolnet.context-offload.v1",$a="toolnet.context-offload-asset.v1";function Wn(r){return X(r,".toolnet","offload")}function Gn(r){return X(Wn(r),"assets")}function za(r){return X(Wn(r),"graph.json")}function gt(){return{schema:zn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Wa(r){let e=za(r);if(!Kn(e))return gt();try{let t=JSON.parse($n(e,"utf8"));return t.schema!==zn||t.version!==1||!Array.isArray(t.nodes)?gt():t}catch{return gt()}}function Ga(r,e){let t=e.trim().toLowerCase();if(!/^[a-f0-9]{8,64}$/u.test(t))throw new Error("Invalid context offload asset reference.");if(t.length===64&&Kn(X(Gn(r),`${t}.json`)))return t;let n=Wa(r).nodes.map(o=>o.id).filter(o=>o.startsWith(t));if(n.length===0)throw new Error(`Context offload asset not found: ${e}`);if(n.length>1)throw new Error(`Ambiguous context offload asset reference: ${e}`);return n[0]}function qn(r,e,t=6e3){let n=Ga(r,e),o=$n(X(Gn(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==$a||s.version!==1||s.assetId!==n)throw new Error(`Invalid context offload asset: ${e}`);let i=Math.max(200,Math.min(2e4,Math.floor(t)));return{assetId:n,kind:s.event.type,bytes:Buffer.byteLength(o,"utf8"),truncated:o.length>i,content:o.length>i?`${o.slice(0,i)}
17
- [truncated]`:o}}var Hn={assetId:Vn.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:Vn.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function Bn(r,e){return qn(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as Qn}from"zod";import{chmodSync as Cp,existsSync as qa,mkdirSync as xp,readFileSync as Va,readdirSync as Ha,renameSync as Mp,statSync as Ba,writeFileSync as Pp}from"node:fs";import{join as Un}from"node:path";var Ua="toolnet.skill-memory.v1";function Ja(r,e=Number.MAX_SAFE_INTEGER){let t=new Set,n=[];for(let o of r){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!t.has(i)&&(t.add(i),n.push(s),n.length>=e))break}return n}function Qa(r){return Un(r.rootPath,".toolnet","memory","skills")}function Ya(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===Ua&&t.version===1&&t.projectId===e&&typeof t.id=="string"&&typeof t.task=="string"&&Array.isArray(t.steps)&&Array.isArray(t.verification)&&Array.isArray(t.files)}function Xa(r){let e=Qa(r);if(!qa(e))return[];if(!Ba(e).isDirectory())return[];let t=[];for(let n of Ha(e)){if(!n.endsWith(".json"))continue;let o=Un(e,n);try{let s=JSON.parse(Va(o,"utf8"));Ya(s,r.id)&&t.push(s)}catch{}}return t.sort((n,o)=>{let s=o.createdAt.localeCompare(n.createdAt);return s!==0?s:n.id.localeCompare(o.id)})}function Za(r){return Ja(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function ec(r,e){let t=e.normalize("NFKC").toLowerCase().trim();if(!t)return 0;if(r.id.toLowerCase()===t||r.fingerprint.toLowerCase()===t)return 1e3;let n=[r.title,r.task,r.summary,...r.steps,...r.verification,...r.files].join(`
18
- `).normalize("NFKC").toLowerCase(),o=0;r.task.normalize("NFKC").toLowerCase().includes(t)&&(o+=40),r.title.normalize("NFKC").toLowerCase().includes(t)&&(o+=30);for(let s of Za(t))n.includes(s)&&(o+=5),r.task.normalize("NFKC").toLowerCase().includes(s)&&(o+=4),r.files.some(i=>i.toLowerCase().includes(s))&&(o+=3);return o}function Jn(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return Xa(r).map(o=>({...o,score:ec(o,e)})).filter(o=>o.score>0).sort((o,s)=>s.score!==o.score?s.score-o.score:s.createdAt.localeCompare(o.createdAt)).slice(0,n)}var Yn={query:Qn.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:Qn.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function Xn(r,e){let t=Jn(r.project,e.query,e.limit??5);return{schema:"toolnet.skill-memory-search.v1",query:e.query,count:t.length,matches:t}}import{z as lo}from"zod";var Zn="wiki/state.v1.json";function tc(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function rc(r,e){let t=JSON.parse(r);if(t.schema!=="toolnet.wiki.v1"||t.version!==1||t.projectId!==e.id||!Array.isArray(t.pages)||!Array.isArray(t.revisions))throw new Error("Invalid ToolNet Wiki state");return t}var C=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Zn);if(!e){let t=tc(this.project);return await this.save(t),t}return rc(e,this.project)}async save(e){await this.storage.put(Zn,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as ro}from"node:crypto";var k=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function Z(r){let e=new Set,t=[];for(let n of r){let o=n.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function ee(r){let e=r.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new k("Invalid Wiki slug",400);return e}function eo(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(ee(n))}return Z(e)}function nc(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function to(r){return{id:`revision-${ro()}`,pageId:r.id,slug:r.slug,revision:r.revision,title:r.title,...r.summary?{summary:r.summary}:{},content:r.content,tags:[...r.tags],links:[...r.links],createdAt:r.updatedAt}}function L(r){return structuredClone(r)}var x=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async summary(){let e=await this.ensureState(),t=new Set(e.pages.flatMap(n=>n.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:Z(e.pages.flatMap(n=>n.tags)).sort((n,o)=>n.localeCompare(o)),links:e.pages.reduce((n,o)=>n+o.links.length,0),orphanPages:e.pages.filter(n=>n.links.length===0&&!t.has(n.slug)).length,automatedPages:e.pages.filter(n=>n.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return L([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=ee(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new k(`Wiki page not found: ${e}`,404);return L(o)}async createPage(e){return this.mutate(t=>{let n=e.title.trim(),o=e.content.trim();if(!n)throw new k("Wiki title is required",400);let s=ee(e.slug??n);if(t.pages.some(c=>c.slug===s))throw new k(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${ro()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:Z(e.tags??[]),links:eo(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(to(a)),L(a)})}async updatePage(e,t){return this.mutate(n=>{let o=ee(e),s=n.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new k(`Wiki page not found: ${e}`,404);if(t.title!==void 0){let i=t.title.trim();if(!i)throw new k("Wiki title is required",400);s.title=i}if(t.summary!==void 0){let i=t.summary.trim();i?s.summary=i:delete s.summary}return t.content!==void 0&&(s.content=t.content.trim(),s.links=eo(s.content)),t.tags!==void 0&&(s.tags=Z(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(to(s)),L(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return L(n.revisions.filter(o=>o.pageId===t.id).sort((o,s)=>s.revision-o.revision))}async backlinks(e){let t=await this.getPage(e),n=await this.ensureState();return L(n.pages.filter(o=>o.links.includes(t.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(e,t=10){let n=await this.ensureState(),o=Z(nc(e));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(t))),i=[];for(let a of n.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),m=a.tags.map(y=>y.toLowerCase()),p=0;for(let y of o)u===y&&(p+=12),c===y&&(p+=10),c.includes(y)&&(p+=6),u.includes(y)&&(p+=5),m.some(S=>S===y)?p+=5:m.some(S=>S.includes(y))&&(p+=3),l.includes(y)&&(p+=2),d.includes(y)&&(p+=1);p>0&&i.push({page:L(a),score:p})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};import{createHash as oc,randomUUID as no}from"node:crypto";var oo="wiki/governance.v1.json",co="toolnet.knowledge-governance.v1",so=500,te={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function sc(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function yt(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function io(r){return oc("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ic(r){let e=[r.title,r.summary??"",r.content.slice(0,2e3),...r.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function ac(r){let e=r.sourceType==="skill"?.96:r.sourceType==="memory"?.94:.88,t=r.tags.map(n=>n.toLowerCase());return(t.includes("permanent")||t.includes("task"))&&(e+=.03),r.content.length>=200&&(e+=.02),r.content.length<80&&(e-=.05),r.title.length<4&&(e-=.05),sc(e)}function ao(r){let e=new Date().toISOString();return{schema:co,version:1,projectId:r,policy:{...te},reviews:[],audit:[],createdAt:e,updatedAt:e}}function uo(r){let e=r.autoApproveThreshold??te.autoApproveThreshold,t=r.criticalApproveThreshold??te.criticalApproveThreshold,n=r.staleAfterDays??te.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new k("Invalid autoApproveThreshold",400);if(!Number.isFinite(t)||t<.5||t>1)throw new k("Invalid criticalApproveThreshold",400);if(!Number.isInteger(n)||n<1||n>3650)throw new k("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:t,staleAfterDays:n}}var re=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(oo);if(!e){let t=ao(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==co||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:uo(t.policy??te)}}catch{let t=ao(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(oo,JSON.stringify(e,null,2),"application/json")}},ne=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,t,n,o={}){e.audit.push({id:no(),action:t,principal:n,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),e.audit.length>so&&(e.audit=e.audit.slice(-so))}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=await e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,t){return this.mutate(n=>(n.policy=uo({...n.policy,...e}),this.audit(n,"policy:update",t,{metadata:{...n.policy}}),{...n.policy}))}async summary(){let e=await this.ensureState(),t=n=>e.reviews.filter(o=>o.status===n).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:t("pending"),approved:t("approved"),rejected:t("rejected"),superseded:t("superseded"),criticalPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="critical").length,conflictPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let t=await this.ensureState();return structuredClone(t.reviews.filter(n=>!e||n.status===e).sort((n,o)=>o.updatedAt.localeCompare(n.updatedAt)))}async auditLog(e=100){let t=await this.ensureState(),n=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(t.audit.slice(-n).reverse())}async assess(e,t){let n=await this.ensureState(),o=ac(e),s=yt(e.title),i=t.filter(l=>l.slug!==e.slug&&yt(l.title)===s&&io(l.content)!==io(e.content)).map(l=>l.slug),a=ic(e),c=[];o<n.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<n.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<n.policy.autoApproveThreshold||a&&o<n.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,t){let n=await this.assess(e,t);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:n,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:n,review:structuredClone(s)};if(!n.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:n.confidence,risk:n.risk}}),{allowed:!0,mode:"auto-approved",assessment:n};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(s)};let i=new Date().toISOString(),a={id:no(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:n.confidence,risk:n.risk,reasons:[...n.reasons],conflicts:[...n.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(a)}})}async markApplied(e,t){await this.mutate(n=>{let o=n.reviews.find(s=>s.sourceKey===e&&s.digest===t&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(n,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:e}))})}async decide(e,t,n){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===e);if(!s)throw new k(`Governance review not found: ${e}`,404);if(s.status!=="pending")throw new k("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=t.principal,s.updatedAt=i,t.note?.trim()&&(s.reviewNote=t.note.trim()),t.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s);if(t.action==="supersede")return s.status="superseded",t.targetReviewId&&(s.supersededBy=t.targetReviewId),this.audit(o,"knowledge:superseded",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:t.targetReviewId}}),structuredClone(s);if(t.action==="merge"){if(!t.targetReviewId)throw new k("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===t.targetReviewId);if(!u)throw new k("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await n.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new k(`Wiki page '${s.slug}' is manually managed`,409);return c?await n.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await n.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let t=await this.ensureState(),n=await e.listPages(),o=Date.now(),s=t.policy.staleAfterDays*864e5,i=n.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of n){let d=yt(l.title),m=a.get(d)??[];m.push(l),a.set(d,m)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(m=>m.slug)})),u=t.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:n.length,automatedPages:n.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:n.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<t.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var mo={query:lo.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:lo.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function po(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new x(new C(t,r.project));await n.initialize();let o=await n.search(e.query,e.limit??5);return{schema:"toolnet.wiki-search.v1",query:e.query,count:o.length,results:o.map(({page:s,score:i})=>({id:s.id,slug:s.slug,title:s.title,summary:s.summary,tags:s.tags,links:s.links,revision:s.revision,updatedAt:s.updatedAt,score:i}))}}import{z as cc}from"zod";var fo={page:cc.string().min(1).max(200).describe("Wiki page slug or page id.")};async function go(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new x(new C(t,r.project));await n.initialize();let o=await n.getPage(e.page),s=await n.backlinks(o.slug);return{schema:"toolnet.wiki-read.v1",page:o,backlinks:s.map(i=>({slug:i.slug,title:i.title}))}}import{z as uc}from"zod";var yo={includePending:uc.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function ho(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new ne(new re(t,r.project));await n.initialize();let o=new x(new C(t,r.project));await o.initialize();let s=await n.summary(),i=await n.quality(o),a=e.includePending?(await n.listReviews("pending")).slice(0,10).map(c=>({id:c.id,sourceType:c.sourceType,title:c.title,confidence:c.confidence,risk:c.risk,reasons:c.reasons})):void 0;return{schema:"toolnet.knowledge-governance-status.v1",summary:s,quality:{stalePages:i.stalePages.length,duplicateTitles:i.duplicateTitles.length,pendingReviews:i.pendingReviews,conflicts:i.conflicts},...a?{pending:a}:{}}}var ko={};function So(r){let e=r.project.id;return{project:{id:e,name:r.project.name,remote:r.project.remote??r.project.name,rootPath:r.project.rootPath},runtime:r.runtime?{phase:r.runtime.phase,dependencies:{memory:{...r.runtime.dependencies.memory},graph:{...r.runtime.dependencies.graph},semantic:{...r.runtime.dependencies.semantic}},metrics:{...r.runtime.metrics},errors:[...r.runtime.errors],dataSource:r.runtime.dataSource,lastUpdatedAt:r.runtime.lastUpdatedAt}:null,storage:r.storage?.name??null,data:{memories:r.memory.exportProject(e).length,graphSymbols:r.graph.allSymbols(e).length,graphEdges:r.graph.allEdges(e).length,semanticAvailable:r.codeSemantic!==void 0}}}function h(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}var mc=["# ToolNet Memory \u2014 Persistent Project Continuity","","ToolNet Memory provides persistent work continuity across coding agents and sessions.","","CONTINUITY RULES:","","1. When the user asks to continue, resume, finish, pick up, or return to previous work,"," call memory_agent_ask BEFORE reconstructing previous work from git, files, or session history.","",'2. Use memory_agent_ask with mode="local" for direct continuity facts such as:'," - current task"," - completed work"," - current/last file"," - TODOs"," - blockers"," - next action","",'3. ToolNet Memory Agent is local-only; use mode="local" for all continuity questions.',"","4. NEVER reconstruct previous work by reading or searching raw agent/session history, including:"," - .toolnet/journal/**, .toolnet/runtime/sources/**, and legacy .toolnet/sessions/**"," - state.json"," - events.jsonl"," - raw transcripts"," - ~/.gemini/antigravity-cli/brain/**"," - another coding agent's internal session history","","5. Do not search the filesystem for the implementation or JSON schema of memory_agent_ask."," Invoke the MCP tool directly.","","6. After ToolNet resolves continuity, inspect the current repository only to verify current truth."," Current repository evidence overrides stale memory.","","7. Do not ask the user to repeat project context already available through ToolNet Memory.","","8. Do not call memory_agent_ask for unrelated coding questions when current context is sufficient.","","9. Large tool/file payloads may be stored outside prompt context."," If the compact graph references a needed asset, call context_offload_read.","","10. Never bulk-load offloaded assets. Read only the minimum asset required."].join("\\n");function pc(r){let e=new lc({name:"toolnet-memory",version:"0.1.0"},{instructions:mc});return e.tool("memory_search","Search relevant long-term memory for the current project.",br,async t=>h(await wr(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Mr,async t=>h(await Pr(r,t))),e.tool("memory_forget","Delete a memory by id.",Ar,async t=>h(await Er(r,t))),e.tool("find_symbol","Find code symbols by exact name.",Rr,async t=>h(await jr(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Ir,async t=>h(await _r(r,t))),e.tool("code_search","Search indexed code symbols and files.",Or,async t=>h(await Lr(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",Dr,async t=>h(await Kr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Vr,async t=>h(await Hr(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Ur,async t=>h(await Jr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>h(await Qr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Xr,async t=>h(await Zr(r,t))),e.tool("semantic_code_search","Legacy-compatible local code search using SQLite FTS5/BM25 lexical ranking. No embeddings or vector database.",tn,async t=>h(await rn(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",$r,async t=>h(await zr(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>h(await Wr(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Gr,async t=>h(await qr(r,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",sn,async t=>h(await an(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",cn,async t=>h(await un(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",ln,async t=>h(await dn(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",mn,async t=>h(await pn(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",yn,async t=>h(await hn(r,t))),e.tool("memory_agent_ask",["Ask ToolNet Memory Agent about previous project work.","CALL THIS TOOL before guessing when the user asks to continue/resume previous work,","mentions a previous agent/session, asks what was unfinished, what file was last touched,","which TODOs are complete, blockers, decisions, or what should happen next.","Use mode=local for continuity questions. Memory Agent is deterministic and local-only; no external AI provider is used.","Do not use it for unrelated coding questions when current repository context is already sufficient.","Returns concise selected memory instead of raw transcripts or full memory dumps.","Short conversational follow-ups are supported using compact ToolNet Memory focus; raw transcripts are never replayed."].join(" "),Fn,async t=>h(await Dn(r,t))),e.tool("context_offload_read",["Read one external ToolNet tool/file asset referenced by the compact context graph.","Use only when needed for the current task.","Never bulk-load all offloaded assets."].join(" "),Hn,async t=>h(await Bn(r,t))),e.tool("skill_memory_search",["Search successful ToolNet project work promoted into reusable Skill Memory SOPs.","Call this before repeating a task that may have been solved successfully before.","Returns compact procedure steps, files and verification evidence.","Raw transcripts are never returned."].join(" "),Yn,async t=>h(await Xn(r,t))),e.tool("wiki_search",["Search the ToolNet project Wiki for durable project knowledge.","Use Wiki before rereading broad project history when a maintained knowledge page may exist.","Returns compact metadata; call wiki_read only for the page needed."].join(" "),mo,async t=>h(await po(r,t))),e.tool("wiki_read",["Read one ToolNet Wiki page by slug or id.","Returns the maintained page plus compact backlinks.","Do not bulk-read unrelated Wiki pages."].join(" "),fo,async t=>h(await go(r,t))),e.tool("toolnet_status",["Inspect ToolNet MCP runtime health.","Returns dependency readiness, degraded state, retry counts,","startup timing, hydration timing, storage source and project data counts."].join(" "),ko,async()=>h(So(r))),e.tool("knowledge_governance_status",["Inspect ToolNet Knowledge Governance health.","Returns review counts, confidence, conflicts, stale knowledge, and optional compact pending reviews.","Use this before trusting or changing important durable project knowledge."].join(" "),yo,async t=>h(await ho(r,t))),e}async function bo(r){let e=pc(r),t=new dc;await e.connect(t)}function wo(){return new Date().toISOString()}function M(r){r.lastUpdatedAt=wo()}function $e(r=Date.now()){return{phase:"starting",dependencies:{memory:{state:"idle",attempts:0},graph:{state:"idle",attempts:0},semantic:{state:"idle",attempts:0}},metrics:{processStartedAtMs:r,hydrationRuns:0,retryCount:0},errors:[],dataSource:"none",lastUpdatedAt:wo()}}function vo(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",M(r)}function Co(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,M(r)}function ze(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,M(r))}function We(r,e){r.dependencies[e].attempts+=1,M(r)}function Ge(r){r.metrics.retryCount+=1,M(r)}function $(r,e,t=Date.now()){let n=r.dependencies[e];n.state="ready",n.lastError=void 0,n.readyAfterMs=t-r.metrics.processStartedAtMs,M(r)}function oe(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),M(r)}function xo(r,e=Date.now()){r.metrics.hydrationFinishedAtMs=e,r.metrics.hydrationStartedAtMs!==void 0&&(r.metrics.hydrationMs=e-r.metrics.hydrationStartedAtMs),r.errors=Object.entries(r.dependencies).filter(([,n])=>n.state==="failed").map(([n,o])=>`${n}: ${o.lastError??"unknown error"}`);let t=Object.values(r.dependencies).every(n=>n.state==="ready");r.phase=t?"ready":"degraded",M(r)}function Mo(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],M(r)}async function qe(r,e){let t=Math.max(1,Math.floor(e.attempts)),n;for(let o=1;o<=t;o+=1){e.onAttempt?.(o);try{return await r()}catch(s){if(n=s,o>=t)break;e.onRetry?.(o,s),e.delayMs>0&&await new Promise(i=>{setTimeout(i,e.delayMs)})}}throw n instanceof Error?n:new Error(String(n??"operation failed"))}function ns(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function Hc(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function Bc(r){let e=r.runtime;return e?{memory:e.dependencies.memory.state==="ready"?"ready":"failed",graph:e.dependencies.graph.state==="ready"?"ready":"failed",semantic:e.dependencies.semantic.state==="ready"?"ready":"failed",errors:[...e.errors]}:{memory:"failed",graph:"failed",semantic:"failed",errors:["runtime unavailable"]}}async function os(r){let e=r.runtime??$e(Date.now());r.runtime=e,Co(e);let t=ns(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=Hc(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await xr(r.project,{timeoutMs:ns(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});o&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(o.memory),$(e,"memory")),e.dependencies.graph.state!=="ready"&&(o.graph&&r.graph.import(o.graph.symbols,o.graph.edges),$(e,"graph")))}try{let[{loadConfig:o},s]=await Promise.all([Promise.resolve().then(()=>(pt(),bn)),Promise.resolve().then(()=>(Jo(),Uo))]),i=o(),a=s.createStorageProvider({provider:i.storage.provider,r2:i.storage.r2,s3:i.storage.s3,huggingface:i.storage.huggingface,localRoot:i.storage.localRoot}),c=s.withStorageRetry(a,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),u=new s.ProjectScopedStorageProvider(c,r.project.id,r.project.name,r.project.remote??r.project.name),l=new s.MemoryStore(u);r.storage=u,r.memoryStore=l;let d=e.dependencies.memory.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",ze(e,"memory");try{let p=await qe(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"memory")},onRetry:()=>{Ge(e)}});r.memory.importRecords(p),$(e,"memory")}catch(p){oe(e,"memory",p)}})(),m=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",ze(e,"graph");try{let p=await qe(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"graph")},onRetry:()=>{Ge(e)}});p&&r.graph.import(p.symbols,p.edges),$(e,"graph")}catch(p){oe(e,"graph",p)}})();if(await Promise.all([d,m]),e.dependencies.semantic.state!=="ready"){ze(e,"semantic");try{let{SemanticCodeEngine:p}=await Promise.resolve().then(()=>(rs(),ts)),y=new p({projectId:r.project.id,rootPath:r.project.rootPath,storage:u,graph:r.graph});await qe(()=>y.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"semantic")},onRetry:()=>{Ge(e)}}),r.codeSemantic=y,$(e,"semantic")}catch(p){oe(e,"semantic",p)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&oe(e,s,o)}return xo(e),Bc(r)}function ss(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function Uc(){let r=Date.now(),e=new ke().detect(),t=new pe,n=new Ce(t),o=new xe,s=new Me(o),i=$e(r),a={project:e,memory:t,retrieval:n,graph:o,references:s,runtime:i};await bo(a),vo(i);let c=async()=>{try{await os(a),i.phase==="degraded"&&setTimeout(()=>{c()},ss()).unref()}catch(u){Mo(i,u),setTimeout(()=>{i.phase="degraded",c()},ss()).unref()}};c()}Uc().catch(r=>{console.error(r),process.exit(1)});
8
+ `);if(m===-1)return;let p=a.slice(0,m).trim();u(()=>{try{o(JSON.parse(p))}catch(y){s(y instanceof Error?y:new Error(String(y)))}})}),i.once("error",d=>{u(()=>{s(d)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function qi(r,e={}){let t=await Fr({type:"hydrate",project:r},e);if(!t.ok||t.type!=="hydrate")throw new Error(t.ok?"Invalid ToolNet service hydrate response":t.error);return t}async function Kr(r,e={}){try{return await qi(r,e)}catch{return null}}async function Ie(r,e={}){try{let t=await Fr({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}import{appendFileSync as Hi,closeSync as Vi,existsSync as $r,mkdirSync as zr,openSync as Ui,readFileSync as Wr,statSync as Bi,unlinkSync as Gr,writeFileSync as Yi}from"node:fs";import{createHash as Ji,randomUUID as qr}from"node:crypto";import{dirname as Hr,join as dt}from"node:path";var ut="0".repeat(64),Qi=3e4,Xi=100,Zi=20;function ea(r){return new Promise(e=>{setTimeout(e,r)})}function ta(r){return dt(r.rootPath,".toolnet","audit")}function Vr(r){return dt(ta(r),"events.jsonl")}function Ur(r){return dt(r.rootPath,".toolnet","runtime","locks","audit.lock")}function lt(r){if(Array.isArray(r))return r.map(lt);if(!r||typeof r!="object")return r;let e=r;return Object.fromEntries(Object.keys(e).sort().map(t=>[t,lt(e[t])]))}function ra(r){return JSON.stringify(lt(r))}function Br(r){return Ji("sha256").update(ra(r),"utf8").digest("hex")}function na(){let r=process.env.TOOLNET_AGENT_ID?.trim()||process.env.TOOLNET_AGENT?.trim();return r?{kind:"agent",id:r}:{kind:"system",id:`pid:${process.pid}`}}function Yr(r){let e=Vr(r);if(!$r(e))return[];let t=Wr(e,"utf8"),n=[];for(let o of t.split(/\r?\n/u)){let s=o.trim();s&&n.push(JSON.parse(s))}return n}function oa(r){try{return Date.now()-Bi(r).mtimeMs>Qi}catch{return!0}}async function sa(r){let e=Ur(r);zr(Hr(e),{recursive:!0,mode:448});for(let t=0;t<Xi;t+=1){let n=qr();try{let o=Ui(e,"wx",384);try{Yi(o,JSON.stringify({token:n,pid:process.pid,createdAt:new Date().toISOString()})+`
9
+ `)}finally{Vi(o)}return n}catch(o){if(o.code!=="EEXIST")throw o;if(oa(e)){try{Gr(e)}catch{}continue}await ea(Zi)}}throw new Error("AUDIT_LOCK_TIMEOUT")}function ia(r,e){let t=Ur(r);if($r(t))try{if(JSON.parse(Wr(t,"utf8")).token!==e)return;Gr(t)}catch{}}function aa(r){return Yr(r).at(-1)}async function ca(r,e){let t=await sa(r);try{let n=aa(r);if(n){let l=ua(r);if(!l.valid)throw new Error(["AUDIT_LOG_INTEGRITY_FAILED",l.error??""].filter(Boolean).join(" "))}let o=e.details?A(e.details):void 0,s=e.target?A(e.target):void 0,i=A(e.actor??na()),a={version:1,sequence:(n?.sequence??0)+1,id:qr(),at:e.at??new Date().toISOString(),projectId:r.id,action:e.action,outcome:e.outcome,actor:i,...s?{target:s}:{},...o?{details:o}:{},previousHash:n?.hash??ut},c={...a,hash:Br(a)},u=Vr(r);return zr(Hr(u),{recursive:!0,mode:448}),Hi(u,JSON.stringify(c)+`
10
+ `,{encoding:"utf8",mode:384}),c}finally{ia(r,t)}}async function Jr(r,e){try{return await ca(r,e),!0}catch(t){return console.warn(`[audit] ${t instanceof Error?t.message:String(t)}`),!1}}function ua(r){let e;try{e=Yr(r)}catch(o){return{valid:!1,records:0,lastHash:ut,firstInvalidLine:1,error:o instanceof Error?o.message:String(o)}}let t=ut,n=1;for(let o=0;o<e.length;o+=1){let s=e[o];if(s.sequence!==n)return{valid:!1,records:e.length,lastHash:t,firstInvalidLine:o+1,error:"AUDIT_SEQUENCE_INVALID"};if(s.previousHash!==t)return{valid:!1,records:e.length,lastHash:t,firstInvalidLine:o+1,error:"AUDIT_PREVIOUS_HASH_INVALID"};let{hash:i,...a}=s,c=Br(a);if(i!==c)return{valid:!1,records:e.length,lastHash:t,firstInvalidLine:o+1,error:"AUDIT_HASH_INVALID"};t=i,n+=1}return{valid:!0,records:e.length,lastHash:t}}var Qr={type:Q.enum(["activity","decision","rule","todo","summary"]),content:Q.string().min(1),tags:Q.array(Q.string()).optional(),importance:Q.enum(["critical","high","normal","temporary"]).optional()};async function Xr(r,e){let t=r.memory.remember({projectId:r.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),await Jr(r.project,{action:"memory.save",outcome:"success",actor:{kind:"mcp",id:process.env.TOOLNET_AGENT_ID?.trim()||"mcp"},details:{memoryId:t.id,type:t.type,importance:t.importance,source:"mcp"}}),Ie(r.project),t}import{z as la}from"zod";var Zr={id:la.string().min(1)};async function en(r,e){let t=r.memory.delete(e.id);return t&&r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),t&&Ie(r.project),{deleted:t}}import{z as da}from"zod";var tn={name:da.string().min(1)};async function rn(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as ma}from"zod";var je=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),nn=new Set(["CALLS","CALL_REFERENCE"]),v=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let n=t.trim().toLowerCase();return n?this.graph.allSymbols(e).filter(o=>o.name.toLowerCase().includes(n)||(o.qualifiedName?.toLowerCase().includes(n)??!1)||o.filePath.toLowerCase().includes(n)).sort((o,s)=>{let i=o.name.toLowerCase()===n,a=s.name.toLowerCase()===n;return i!==a?i?-1:1:o.filePath.localeCompare(s.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,nn)}callees(e,t){return this.relatedOutgoing(e,t,nn)}dependents(e,t){return this.relatedIncoming(e,t,je)}dependencies(e,t){return this.relatedOutgoing(e,t,je)}neighborhood(e,t,n=1){let o=this.graph.getSymbol(t);return!o||o.projectId!==e?null:{center:o,incoming:this.walk(e,t,"incoming",n),outgoing:this.walk(e,t,"outgoing",n)}}shortestPath(e,t,n,o=12){let s=this.graph.getSymbol(t),i=this.graph.getSymbol(n);if(!s||!i||s.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===n)return{found:!0,distance:0,symbols:[s],edges:[]};let a=this.graph.allEdges(e).filter(m=>je.has(m.type)),c=new Map;for(let m of a){let p=c.get(m.from)??[];p.push(m),c.set(m.from,p)}let u=[{id:t,depth:0}],l=new Set([t]),d=new Map;for(;u.length>0;){let m=u.shift();if(!(m.depth>=o)){for(let p of c.get(m.id)??[])if(!l.has(p.to)){if(l.add(p.to),d.set(p.to,{node:m.id,edge:p}),p.to===n)return this.buildPath(t,n,d);u.push({id:p.to,depth:m.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,n){let o=[t],s=[],i=t;for(;i!==e;){let c=n.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};s.push(c.edge),i=c.node,o.push(i)}o.reverse(),s.reverse();let a=o.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:s.length,symbols:a,edges:s}}walk(e,t,n,o){let s=this.graph.allEdges(e).filter(u=>je.has(u.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let u=i.shift();if(!(u.depth>=o))for(let l of s){if(!(n==="incoming"?l.to===u.id:l.from===u.id))continue;let m=n==="incoming"?l.from:l.to;if(a.has(m))continue;let p=this.graph.getSymbol(m);p&&(a.add(m),c.push({symbol:p,depth:u.depth+1,via:l}),i.push({id:m,depth:u.depth+1}))}}return c}relatedIncoming(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.to===t&&n.has(s.type)).map(s=>s.from))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}relatedOutgoing(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.from===t&&n.has(s.type)).map(s=>s.to))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function C(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let n=new v(r.graph),o=n.findSymbols(r.project.id,e).find(s=>s.name===e||s.qualifiedName===e);return o||(n.findSymbols(r.project.id,e)[0]??null)}function w(r){return{id:r.id,name:r.name,qualifiedName:r.qualifiedName,type:r.type,filePath:r.filePath,startLine:r.startLine,endLine:r.endLine}}var on={symbolId:ma.string().min(1)};async function sn(r,e){let t=C(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let o=new v(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:w(t),count:o.length,callers:o.map(w)}}import{z as an}from"zod";var cn={query:an.string().min(1),limit:an.number().int().min(1).max(50).optional()};async function un(r,e){let t=e.query.toLowerCase(),n=e.limit??20;return r.graph.allSymbols(r.project.id).filter(o=>o.name.toLowerCase().includes(t)||o.qualifiedName?.toLowerCase().includes(t)||o.filePath.toLowerCase().includes(t)).slice(0,n)}import{z as ln}from"zod";function _e(r,e){let t=r.allSymbols(e),n=r.allEdges(e),o=i=>t.filter(a=>a.type===i).length,s=i=>n.filter(a=>a.type===i).length;return{files:o("file"),classes:o("class"),interfaces:o("interface"),functions:o("function"),methods:o("method"),properties:o("property"),routes:o("route"),symbols:t.length,edges:n.length,calls:s("CALLS"),callReferences:s("CALL_REFERENCE"),imports:s("IMPORTS"),inherits:s("INHERITS"),implements:s("IMPLEMENTS"),usesType:s("USES_TYPE"),tests:s("TESTS"),routeEdges:s("ROUTE"),writes:s("WRITES")}}var dn={query:ln.string().optional(),memoryLimit:ln.number().int().min(1).max(20).optional()};async function mn(r,e){let t=_e(r.graph,r.project.id),n=r.memory.recent(r.project.id,5),o=e.query?r.retrieval.search(r.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:t,recent:n,relevant:o.map(s=>s.memory)}}import{z as fa}from"zod";var pa=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],T=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",n){let o=new Date().toISOString(),s=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,s),c=[];for(let l of pa){let d=`${i}/${l}`,m=await this.storage.get(d);m&&(await this.storage.put(`${a}/${l}`,m,"application/json"),c.push(l))}if(c.length===0)return null;let u={version:1,id:s,projectId:e,createdAt:o,reason:t,objects:c,metadata:n};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(u,null,2),"application/json"),u}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),s=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{s.push(JSON.parse(a))}catch{}}return s.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.getText(`${n}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let s=JSON.parse(o);if(s.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of s.objects){let u=await this.storage.get(`${n}/${c}`);u&&(await this.storage.put(`${i}/${c}`,u,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.list(n);for(let s of o)await this.storage.delete(s.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),s=0;for(let i of o)await this.remove(e,i.id),s++;return s}};var pn={reason:fa.string().optional()};async function fn(r,e){if(!r.storage)throw new Error("Storage unavailable");return new T(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function gn(r){if(!r.storage)throw new Error("Storage unavailable");return new T(r.storage).list(r.project.id)}import{z as ga}from"zod";var yn={snapshotId:ga.string().min(1)};async function hn(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new T(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as mt}from"zod";var Ne=class{constructor(e){this.graph=e}graph;callees(e,t,n=3){return this.walk(e,t,"out",n)}callers(e,t,n=3){return this.walk(e,t,"in",n)}walk(e,t,n,o){let s=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(u=>u.type==="CALLS"||u.type==="CALL_REFERENCE");for(;a.length;){let u=a.shift();if(u.depth>=o)continue;let l=n==="out"?c.filter(d=>d.from===u.id):c.filter(d=>d.to===u.id);for(let d of l){let m=n==="out"?d.to:d.from;if(i.has(m))continue;i.add(m);let p=this.graph.getSymbol(m);if(!p)continue;let y=u.depth+1;s.push({symbol:p,depth:y}),a.push({id:m,depth:y})}}return s}};var kn={symbolId:mt.string().min(1),direction:mt.enum(["callers","callees"]).optional(),depth:mt.number().int().min(1).max(10).optional()};async function Sn(r,e){let t=new Ne(r.graph),n=e.direction??"callees",o=e.depth??3,s=n==="callers"?t.callers(r.project.id,e.symbolId,o):t.callees(r.project.id,e.symbolId,o);return{direction:n,depth:o,results:s.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as bn}from"zod";var Oe=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=n)continue;let u=o.filter(l=>l.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(l.type));for(let l of u){if(s.has(l.from))continue;s.add(l.from);let d=this.graph.getSymbol(l.from);if(!d)continue;let m=c.depth+1;a.push({symbol:d,depth:m,relation:l.type}),i.push({id:l.from,depth:m})}}return a}};var wn={symbolId:bn.string().min(1),depth:bn.number().int().min(1).max(10).optional()};async function vn(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new Oe(r.graph).analyze(r.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:o.map(s=>({id:s.symbol.id,name:s.symbol.name,qualifiedName:s.symbol.qualifiedName,filePath:s.symbol.filePath,type:s.symbol.type,relation:s.relation,depth:s.depth}))}}async function Cn(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:_e(r.graph,r.project.id)}}import{z as xn}from"zod";var ya=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Le=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>ya.has(i.type)),o=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,u=0,l=0;for(let d of n){let m=o.get(d.from),p=o.get(d.to);!m||!p||m.filePath===p.filePath||(m.filePath===i&&(a.add(p.filePath),u++),p.filePath===i&&(c.add(m.filePath),l++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:u,incomingEdges:l}})}};var Mn={filePath:xn.string().min(1),direction:xn.enum(["dependencies","dependents","both"]).optional()};async function Pn(r,e){let n=new Le(r.graph).analyze(r.project.id).find(c=>c.filePath===e.filePath);if(!n)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let o=r.graph.allSymbols(r.project.id).filter(c=>c.type==="file"),s=new Map(o.map(c=>[c.filePath,c])),i=c=>({id:s.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:n.filePath,outgoingEdges:n.outgoingEdges,incomingEdges:n.incomingEdges,dependencies:a==="dependents"?[]:n.dependencies.map(i),dependents:a==="dependencies"?[]:n.dependents.map(i)}}pt();import{z as En}from"zod";var An={query:En.string().min(1),limit:En.number().int().min(1).max(20).optional()};async function Rn(r,e){if(!r.codeSemantic)return{available:!1,engine:I,mode:D,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",results:[]};let t=await r.codeSemantic.search(e.query,e.limit??8);return{available:!0,engine:I,mode:D,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",searchContract:De,results:t.map(n=>({id:n.chunk.id,filePath:n.chunk.filePath,symbol:n.chunk.symbolName,symbolType:n.chunk.symbolType,startLine:n.chunk.startLine,endLine:n.chunk.endLine,score:n.score,lexicalScore:n.lexicalScore,vectorScore:n.vectorScore,engine:n.engine,mode:n.mode,content:n.chunk.content}))}}import{z as gt}from"zod";import{execFile as ka}from"node:child_process";import{promisify as Sa}from"node:util";var ft=Sa(ka);function ba(r){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let n of r.matchAll(t)){let o=Number(n[1]),s=Number(n[2]??1);e.push({startLine:o,endLine:Math.max(o,o+s-1)})}return e}function wa(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function Tn(r){let e="";try{e=(await ft("git",["diff","HEAD","--name-status","--no-renames"],{cwd:r,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let n of e.split(/\r?\n/).filter(Boolean)){let[o,...s]=n.split(" "),i=s.at(-1);if(!i)continue;let a="";try{a=(await ft("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:wa(o),ranges:ba(a)})}try{let n=await ft("git",["ls-files","--others","--exclude-standard"],{cwd:r});for(let o of n.stdout.split(/\r?\n/).filter(Boolean))t.some(s=>s.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}function va(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var Fe=class{constructor(e){this.graph=e}graph;map(e,t){let n=this.graph.allSymbols(e),o=[];for(let s of t){let i=n.filter(u=>u.filePath===s.filePath),c=i.filter(u=>u.type!=="file").filter(u=>va(u,s));if(c.length===0){let u=i.find(l=>l.type==="file");u&&o.push({symbol:u,fileStatus:s.status,direct:!0});continue}for(let u of c)o.push({symbol:u,fileStatus:s.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var Ca={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function xa(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function In(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var Ke=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Map,i=0;for(let l of t){l.fileStatus==="deleted"?i+=8:l.fileStatus==="renamed"?i+=5:i+=2,l.symbol.type==="interface"&&(i+=5),l.symbol.type==="class"&&(i+=3);let d=new Set([l.symbol.id]),m=[{id:l.symbol.id,depth:0}];for(;m.length;){let p=m.shift();if(p.depth>=n)continue;let y=o.filter(b=>b.to===p.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(b.type));for(let b of y){if(d.has(b.from))continue;d.add(b.from);let _=this.graph.getSymbol(b.from);if(!_)continue;let V=p.depth+1,Ws=`${l.symbol.id}:${_.id}`;s.set(Ws,{symbol:_,relation:b.type,depth:V,sourceSymbolId:l.symbol.id});let Gs=Ca[b.type]??1;i+=Math.max(1,Gs-(V-1)),m.push({id:_.id,depth:V})}}}let a=[...s.values()].sort((l,d)=>l.depth-d.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(In);return u.length===0&&u.push(...c.filter(l=>!In(l)).slice(0,10)),{risk:xa(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var $e=class{constructor(e){this.graph=e;this.mapper=new Fe(e),this.blast=new Ke(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await Tn(t),s=this.mapper.map(e,o),i=this.blast.analyze(e,s,n.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,n={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,n.maxDepth??4)}}};var jn={mode:gt.enum(["git_diff","file"]).optional(),filePath:gt.string().optional(),depth:gt.number().int().min(1).max(10).optional()};async function _n(r,e){let t=new $e(r.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(r.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(r.project.id,r.project.rootPath,{maxDepth:e.depth})}import{z as Ma}from"zod";var Nn={symbol:Ma.string().min(1)};async function On(r,e){let t=C(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let o=new v(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:w(t),count:o.length,dependents:o.map(w)}}import{z as yt}from"zod";var Ln={from:yt.string().min(1),to:yt.string().min(1),maxDepth:yt.number().int().min(1).max(30).optional()};async function Dn(r,e){let t=C(r,e.from),n=C(r,e.to);if(!t||!n)return{found:!1,fromFound:!!t,toFound:!!n,path:[],edges:[]};let s=new v(r.graph).shortestPath(r.project.id,t.id,n.id,e.maxDepth??12);return{found:s.found,distance:s.distance,from:w(t),to:w(n),path:s.symbols.map(w),edges:s.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as ht}from"zod";var Fn={symbol:ht.string().min(1),depth:ht.number().int().min(1).max(5).optional(),limit:ht.number().int().min(1).max(200).optional()};async function Kn(r,e){let t=C(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let o=new v(r.graph).neighborhood(r.project.id,t.id,e.depth??1);if(!o)return{found:!1,query:e.symbol};let s=e.limit??50;return{found:!0,center:w(o.center),incomingCount:o.incoming.length,outgoingCount:o.outgoing.length,incoming:o.incoming.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:w(i.symbol)})),outgoing:o.outgoing.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:w(i.symbol)}))}}import{z as St}from"zod";function Pa(r){return r.replaceAll("\\","/").toLowerCase()}var ze=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,n);a&&o.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let s=new Map;for(let i of o){let a=i.kind==="route"?i.symbolId:i.filePath,c=s.get(a);(!c||i.score>c.score)&&s.set(a,i)}return[...s.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let n=Pa(e.filePath),o=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let s=null,i=0;if(n.startsWith("bin/"))s="cli",i=100,o.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(n))s="cli",i=90,o.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(n))s="main",i=90,o.push("main/server file");else if(n.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(n))s="runtime",i=75,o.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(n)){let c=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,u=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(n.startsWith("packages/")||c===0||u>0)&&(s="package",i=n.startsWith("packages/")?70:55,o.push("package/public index"))}return s?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,o.push("no incoming dependency")),{kind:s,score:i,reasons:o}):null}};var $n=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function kt(r){return r.replaceAll("\\","/").toLowerCase()}function Ea(r){let e=kt(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Aa(r){let e=kt(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var We=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=new Set(new ze(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Ea(i.filePath)||o.has(i.id)||Aa(i)||n.filter(p=>p.to===i.id&&$n.has(p.type)).length>0)continue;let c=n.filter(p=>p.from===i.id&&$n.has(p.type)),u=["no incoming usage edge"],l=50;(i.type==="function"||i.type==="method")&&(l+=20,u.push("callable symbol")),i.type==="property"&&(l-=15),c.length===0&&(l+=10,u.push("no outgoing dependency")),kt(i.filePath).includes("/internal/")&&(l+=10,u.push("internal implementation")),i.name.startsWith("_")&&(l+=5);let m=l>=75?"high":l>=55?"medium":"low";s.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:m,score:l,reasons:u})}return s.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var Wn={confidence:St.enum(["high","medium","low","all"]).optional(),filePath:St.string().min(1).optional(),limit:St.number().int().min(1).max(500).optional()},zn={high:3,medium:2,low:1};async function Gn(r,e){let n=new We(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=zn[e.confidence];n=n.filter(a=>zn[a.confidence]>=i)}e.filePath&&(n=n.filter(i=>i.filePath===e.filePath));let o=n.length,s=e.limit??100;return{total:o,high:n.filter(i=>i.confidence==="high").length,medium:n.filter(i=>i.confidence==="medium").length,low:n.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:n.slice(0,s)}}import{z as Ct}from"zod";import{existsSync as Ja,readFileSync as Qa}from"node:fs";import{join as Xa}from"node:path";var Fm=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Gm,existsSync as Ra,fsyncSync as qm,mkdirSync as Hm,openSync as Vm,readFileSync as Ta,renameSync as Um,writeFileSync as Bm}from"node:fs";import{dirname as Jm,join as Ia}from"node:path";function ja(r){return Ia(r.rootPath,".toolnet","work","current.json")}function bt(r){let e=ja(r);if(!Ra(e))return null;try{let t=JSON.parse(Ta(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as _a,mkdirSync as ep,readFileSync as Na,renameSync as tp,writeFileSync as rp}from"node:fs";import{dirname as op,join as Oa}from"node:path";function La(r){return Oa(r.rootPath,".toolnet","context","session-origin.json")}function wt(r){let e=La(r);if(!_a(e))return null;try{let t=JSON.parse(Na(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function Da(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function Ge(r){let e=Da(r),t=/(?:agent trước|previous agent|ai trước|phiên trước)/u.test(e),n=/(?:đang làm gì|làm tới đâu|dừng ở đâu|dở ở đâu|stopped where|working on|current task|file nào|last touched|làm gì tiếp|next action|next step)/u.test(e);return t&&n?"summary":/(?:agent trước là ai|previous agent|ai trước là ai|phiên trước là ai)/u.test(e)?"previous_agent":/(?:task hiện tại|current task|đang làm gì|đang làm task nào|dở ở đâu|dừng ở đâu|stopped where)/u.test(e)?"current_task":/(?:tiếp theo|next action|next step|làm gì tiếp|phải làm gì tiếp)/u.test(e)?"next_action":/(?:file cuối|last file|file nào|đang sửa file|last touched)/u.test(e)?"last_file":/(?:blocker|vướng|kẹt|lỗi gì|blocked)/u.test(e)?"blocker":/(?:decision|quyết định|đã chốt|important decision)/u.test(e)?"decision":/(?:đã xong|completed|hoàn thành|done|todo nào xong)/u.test(e)?"completed":/(?:status|trạng thái|tiến độ|progress)/u.test(e)?"status":"summary"}import{existsSync as Ha,mkdirSync as Yp,readFileSync as Va}from"node:fs";import{join as Un}from"node:path";fe();vt();var Op=new E;function Ua(r){return Un(r.rootPath,".toolnet","memory","checkpoints")}function Ba(r){return Un(Ua(r),"latest.json")}function Ya(r){let e=Ba(r);if(!Ha(e))return null;try{let t=JSON.parse(Va(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function Bn(r){return Ya(r)}var Za={previous_agent:{previous_agent:100,task:35,phase:25},current_task:{task:100,request:95,activity:90,phase:75,file:65,next_action:55,blocker:45},next_action:{next_action:100,todo:80,task:65,blocker:60,file:40},last_file:{file:100,task:65,next_action:40},blocker:{blocker:100,task:60,next_action:50,file:35},decision:{decision:100,rule:85,architecture:80,task:45,file:30},completed:{completed:100,progress:70,task:30},status:{progress:100,task:85,phase:75,blocker:65,next_action:60},summary:{task:100,request:98,activity:96,next_action:95,file:90,blocker:85,previous_agent:80,phase:75,completed:60,todo:60,decision:55,rule:54,architecture:53,fix:52,progress:50,test:45,goal:35}},ec={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function tc(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function f(r,e){let t=e.value.replace(/\s+/g," ").trim();t&&r.push({...e,value:t,score:0})}function rc(r){let e=Xa(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ja(e))return null;try{let n=JSON.parse(Qa(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function nc(r){let e=Bn(r);if(!e)return[];let t=[];e.request&&f(t,{kind:"request",value:e.request,source:"checkpoint"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"checkpoint"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"checkpoint"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"checkpoint"});let n=e.files.active.at(-1);n&&f(t,{kind:"file",value:n,source:"checkpoint"});for(let o of e.nextActions)f(t,{kind:"next_action",value:o,source:"checkpoint"});for(let o of e.blockers)f(t,{kind:"blocker",value:o,source:"checkpoint"});for(let o of e.completed.tasks)f(t,{kind:"completed",value:o,source:"checkpoint"});for(let o of e.remaining.tasks)f(t,{kind:"todo",value:o,source:"checkpoint"});for(let o of e.durableFacts)f(t,{kind:o.kind,value:o.content,source:"checkpoint"});return t}function oc(r){let e=rc(r);if(!e)return[];let t=[];f(t,{kind:"previous_agent",value:e.source.agent,source:"handoff"}),e.request&&f(t,{kind:"request",value:e.request,source:"handoff"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"handoff"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"handoff"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"handoff"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"handoff"}),e.files.current&&f(t,{kind:"file",value:e.files.current,source:"handoff"}),e.nextAction&&f(t,{kind:"next_action",value:e.nextAction,source:"handoff"});for(let n of e.blockers)f(t,{kind:"blocker",value:n,source:"handoff"});for(let n of e.decisions)f(t,{kind:"decision",value:n,source:"handoff"});for(let n of e.completed.tasks)f(t,{kind:"completed",value:n,source:"handoff"});for(let n of e.remaining.todos)f(t,{kind:"todo",value:n,source:"handoff"});return f(t,{kind:"test",value:`Test status: ${e.tests.status}`,source:"handoff"}),f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"handoff"}),t}function sc(r){let e=wt(r);if(!e)return[];let t=[];return f(t,{kind:"previous_agent",value:e.agent,source:"session-origin"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase,source:"session-origin"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask,source:"session-origin"}),e.lastTouchedFile&&f(t,{kind:"file",value:e.lastTouchedFile,source:"session-origin"}),e.latestNextAction&&f(t,{kind:"next_action",value:e.latestNextAction,source:"session-origin"}),e.latestBlocker&&f(t,{kind:"blocker",value:e.latestBlocker,source:"session-origin"}),e.latestDecision&&f(t,{kind:"decision",value:e.latestDecision,source:"session-origin"}),t}function ic(r){let e=bt(r);if(!e)return[];let t=[];e.currentRequest&&f(t,{kind:"request",value:e.currentRequest,source:"work-state"}),e.currentActivity&&f(t,{kind:"activity",value:e.currentActivity,source:"work-state"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"work-state"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase.title,source:"work-state"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask.title,source:"work-state"});let n=e.activeFiles?.at(-1)??e.filesTouched.at(-1);n&&f(t,{kind:"file",value:n,source:"work-state"});for(let o of e.nextActions.slice(0,5))f(t,{kind:"next_action",value:o,source:"work-state"});for(let o of e.blockers.slice(-5))f(t,{kind:"blocker",value:o,source:"work-state"});for(let o of e.decisions.slice(-5))f(t,{kind:"decision",value:o,source:"work-state"});for(let o of e.tasks.filter(s=>s.status==="completed").slice(-8))f(t,{kind:"completed",value:o.title,source:"work-state"});for(let o of e.tasks.filter(s=>s.status!=="completed"&&s.status!=="cancelled").slice(0,8))f(t,{kind:"todo",value:o.title,source:"work-state"});for(let o of e.tests.slice(-5))f(t,{kind:"test",value:o,source:"work-state"});return f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"work-state"}),t}function ac(r,e){let t=Za[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+ec[n.source]+Math.max(0,5-o*.01)}))}function cc(r){let e=new Map;for(let t of r){let n=`${t.kind}:${tc(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function qe(r,e,t={}){let n=Ge(e),o=[...nc(r),...oc(r),...sc(r),...ic(r)],s=cc(ac(n,o)).sort((l,d)=>d.score-l.score),i=Math.max(1,t.maxFacts??12),a=Math.max(300,t.maxChars??3200),c=[],u=0;for(let l of s){if(c.length>=i)break;let d=l.kind.length+l.value.length+l.source.length+16;c.length>0&&u+d>a||(c.push(l),u+=d)}return{intent:n,facts:c,context:{project:{id:r.id,name:r.name},intent:n,selectedFacts:c.map(l=>({kind:l.kind,value:l.value,source:l.source}))},stats:{candidates:o.length,selected:c.length,chars:u}}}var Yn={previous_agent:"Agent tr\u01B0\u1EDBc",request:"Y\xEAu c\u1EA7u hi\u1EC7n t\u1EA1i",activity:"\u0110ang l\xE0m",goal:"M\u1EE5c ti\xEAu",phase:"Phase",task:"Task hi\u1EC7n t\u1EA1i",file:"File hi\u1EC7n t\u1EA1i",todo:"TODO",next_action:"Ti\u1EBFp theo",blocker:"Blocker",decision:"Quy\u1EBFt \u0111\u1ECBnh",rule:"Quy t\u1EAFc",architecture:"Ki\u1EBFn tr\xFAc",fix:"\u0110\xE3 s\u1EEDa",completed:"\u0110\xE3 ho\xE0n th\xE0nh",test:"Test",progress:"Ti\u1EBFn \u0111\u1ED9"},Jn=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],uc={previous_agent:["previous_agent"],current_task:["request","activity","task","file","next_action"],next_action:["next_action","task","file","todo"],last_file:["file","task","next_action"],blocker:["blocker"],decision:["decision"],completed:["completed"],status:["progress","task","next_action","blocker"],summary:Jn};function lc(r){let e=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)}function dc(r){let e=r.filter(n=>n.source==="handoff");if(e.length===0)return r;let t=r.filter(n=>n.source==="checkpoint"&&["rule","architecture","fix"].includes(n.kind));return[...e,...t]}function mc(r){let e=new Set,t=[];for(let n of r){let o=`${n.kind}:${n.value.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}`;e.has(o)||(e.add(o),t.push(n))}return t}function Qn(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function pc(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,Qn(n));for(let s of o)t.push(`${Yn[n]}: ${s.value}`)}return t.join(`
11
+ `)}function fc(r,e){let t=uc[e]??Jn,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,Qn(o));for(let i of s)n.push(`${Yn[o]}: ${i.value}`)}return n.join(`
12
+ `)}function Xn(r,e){let t=qe(r,e,{maxFacts:32,maxChars:6400}),n=mc(dc(t.facts)),o=lc(e)?pc(n,["todo","task","next_action","file"]):fc(n,String(t.intent));return o?{intent:String(t.intent),answer:o,source:n[0]?.source??"none"}:{intent:String(t.intent),answer:"ToolNet ch\u01B0a c\xF3 \u0111\u1EE7 memory cho c\xE2u h\u1ECFi n\xE0y.",source:"none"}}import{existsSync as gc,mkdirSync as yc,readFileSync as hc,renameSync as kc,rmSync as Sc,writeFileSync as bc}from"node:fs";import{join as Zn}from"node:path";var wc=720*60*1e3;function eo(r){return Zn(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function ee(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function vc(r){let e=ee(r);return[/\btiếp tục\b/u,/\btiếp tục task\b/u,/\blúc nãy\b/u,/\btrước đó\b/u,/\btask trước\b/u,/\bprevious (?:task|session|work)\b/u,/\bcontinue\b/u,/\bresume\b/u,/\bcurrent task\b/u,/\bđang làm gì\b/u].some(t=>t.test(e))}function Cc(r){if(vc(r))return!1;let e=ee(r),t=e.split(/\s+/u).filter(Boolean);return[/^(?:tại sao|vì sao|sao vậy)\b/u,/^(?:why|why so|why that)\b/u,/^(?:còn|thế|vậy|rồi sao|sau đó)\b/u,/^(?:what about|and what|then what)\b/u,/^(?:cái đó|việc đó|nó|phần đó)\b/u].some(n=>n.test(e))?!0:t.length<=5&&/\b(?:nó|đó|vậy|thế|that|it|this)\b/u.test(e)}function xc(r,e,t){let n=eo(r);if(!gc(n))return null;try{let o=JSON.parse(hc(n,"utf8"));if(o.schema!=="toolnet.memory-conversation.v1"||o.version!==1||o.projectId!==r.id||!Array.isArray(o.focus))return null;let s=Date.parse(o.updatedAt);return!Number.isFinite(s)||e-s>t?null:o}catch{return null}}function Mc(r,e=8){let t=new Set,n=[];for(let o of r){let s=o.value.replace(/\s+/gu," ").trim();if(!s)continue;let i=[o.kind,ee(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function Pc(r,e){let t=eo(r),n=Zn(r.rootPath,".toolnet","context");yc(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{bc(o,JSON.stringify(e,null,2)+`
13
+ `,{encoding:"utf8",mode:384}),kc(o,t)}finally{Sc(o,{force:!0})}}function Ec(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
14
+ `)}function Ac(r,e){return r.priorFocus.find(t=>t.kind===e)?.value}function to(r){if(!r.usedPriorFocus||r.currentIntent!=="summary"||r.priorFocus.length===0)return null;let e=ee(r.originalQuestion),t=/^(?:tại sao|vì sao|sao vậy|why|why so|why that)\b/u.test(e),n=/^(?:rồi sao|sau đó|tiếp thì sao|thế tiếp theo|then what|what next)\b/u.test(e),o=t?["decision","blocker","next_action","task","file"]:n?["next_action","todo","task","blocker","file","decision"]:["task","next_action","file","decision","blocker"],s={task:"Task li\xEAn quan",next_action:"Vi\u1EC7c ti\u1EBFp theo",file:"File li\xEAn quan",decision:"Quy\u1EBFt \u0111\u1ECBnh li\xEAn quan",blocker:"Blocker",todo:"TODO"},i=[];for(let a of o){let c=Ac(r,a);if(c&&(i.push(`${s[a]??a}: ${c}.`),t&&i.length>=2||!t&&i.length>=3))break}return i.length===0?null:{answer:i.join(" "),intent:"summary",source:"conversation-focus"}}function Rc(r){let e=ee(r);return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(e)}function ro(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??wc,s=xc(r,n,o),i=!!(s&&s.focus.length>0&&Cc(e)&&!Rc(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",Ec(s),"","Use the compact focus only to resolve the current follow-up question.","Do not reconstruct or request raw session transcripts."].join(`
15
+ `):e.trim(),c=Ge(e),l=qe(r,a,{maxFacts:8,maxChars:1800}).facts.map(m=>({kind:m.kind,value:m.value,source:m.source})),d=Mc(i&&s?[...l,...s.focus]:l);return Pc(r,{schema:"toolnet.memory-conversation.v1",version:1,projectId:r.id,updatedAt:new Date(n).toISOString(),lastIntent:c,focus:d}),{question:a,originalQuestion:e,usedPriorFocus:i,previousIntent:s?.lastIntent,currentIntent:c,priorFocus:s?.focus??[],focusCount:d.length}}import{existsSync as Tc,readFileSync as Ic}from"node:fs";import{join as jc}from"node:path";function j(r){return!!r?.trim()}function no(r){let e=[],t=[],n=100;j(r.goal)||j(r.request)||(e.push("goal_or_request"),n-=20),j(r.activity)||j(r.current.task?.title)||j(r.current.phase?.title)||(e.push("current_work"),n-=25),j(r.nextAction)||j(r.remaining.todos[0])||(e.push("next_action"),n-=25),r.tests.status!=="unknown"||r.tests.recent.length>0||(r.tests.checks?.length??0)>0||(r.evidence?.commands.length??0)>0||(r.evidence?.references.length??0)>0||(e.push("evidence"),n-=20),j(r.files.current)||r.files.recent.length>0||(r.files.active?.length??0)>0||(r.files.modified?.length??0)>0||(r.files.created?.length??0)>0||(e.push("files"),n-=10),r.tests.status==="failing"&&t.push("tests_failing"),r.blockers.length>0&&t.push("active_blockers"),n=Math.max(0,Math.min(100,n));let u=e.includes("current_work")||e.includes("next_action"),l;return n>=80&&!u?l="high":n>=50?l="medium":l="low",{confidence:l,score:n,missingContext:e,warnings:t}}var oo={compact:{completed:3,evidence:3,files:5,blockers:2,maxChars:1800},normal:{completed:10,evidence:10,files:15,blockers:5,maxChars:4200},benchmark:{completed:30,evidence:30,files:40,blockers:10,maxChars:1e4}};function z(r){let e=new Set,t=[];for(let n of r){let o=n?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function W(r){return r.length>0?r.map(e=>`- ${e}`).join(`
16
+ `):"- none"}function _c(r,e){return r.length<=e?r:[r.slice(0,e).trimEnd(),"","[Structured handoff truncated]"].join(`
17
+ `)}function so(r,e){if(e)return e;let t=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/\bbenchmark\b/u.test(t)||/\bdeep handoff\b/u.test(t)||/\bfull handoff\b/u.test(t)||/\btakeover\b/u.test(t)||/\btake over\b/u.test(t)||/tiếp quản/u.test(t)||/bằng chứng đầy đủ/u.test(t)||/evidence.*(?:file|test|command)/u.test(t)?"benchmark":/\bcompact\b/u.test(t)||/\bbrief\b/u.test(t)||/ngắn gọn/u.test(t)||/tóm tắt ngắn/u.test(t)?"compact":"normal"}function Nc(r,e="normal"){let t=oo[e],n=z([`Source agent: ${r.source.agent}`,`Captured: ${r.capturedAt}`,r.goal?`Goal: ${r.goal}`:void 0,r.request?`Request: ${r.request}`:void 0,r.activity?`Activity: ${r.activity}`:void 0,r.current.phase?`Phase: ${r.current.phase.title} [${r.current.phase.status}]`:void 0,r.current.task?`Task: ${r.current.task.title} [${r.current.task.status}]`:void 0,r.current.file?`Current file: ${r.current.file}`:void 0,`Progress: ${JSON.stringify(r.progress)}`]),o=z([...r.completed.phases.map(u=>`Phase: ${u}`),...r.completed.tasks.map(u=>`Task: ${u}`)]).slice(0,t.completed),s=z([`Tests status: ${r.tests.status}`,...r.tests.recent.map(u=>`Test: ${u}`),...(r.tests.checks??[]).map(u=>`Check [${u.status}] ${u.kind}: ${u.command}`),...(r.evidence?.commands??[]).map(u=>`Command: ${u}`),...(r.evidence?.references??[]).map(u=>`Reference: ${u}`),...r.decisions.map(u=>`Decision: ${u}`),...r.attention.map(u=>`Attention: ${u}`)]).slice(0,t.evidence),i=z([r.files.current,...(r.files.active??[]).map(u=>`Active: ${u}`),...(r.files.modified??[]).map(u=>`Modified: ${u}`),...(r.files.created??[]).map(u=>`Created: ${u}`),...(r.files.deleted??[]).map(u=>`Deleted: ${u}`),...r.files.recent.map(u=>`Recent: ${u}`)]).slice(0,t.files),a=z(r.blockers).slice(0,t.blockers),c=z([r.nextAction,r.nextAction?void 0:r.remaining.todos[0]]).slice(0,1);return{currentState:n,completed:o,evidence:s,filesTouched:i,blockers:a,nextAction:c}}function Oc(r,e,t){return[`HANDOFF_DETAIL: ${e}`,`CONTINUITY_CONFIDENCE: ${t.confidence}`,`QUALITY_SCORE: ${t.score}`,`MISSING_CONTEXT: ${t.missingContext.length>0?t.missingContext.join(", "):"none"}`,`QUALITY_WARNINGS: ${t.warnings.length>0?t.warnings.join(", "):"none"}`,"","CURRENT_STATE",W(r.currentState),"","COMPLETED",W(r.completed),"","EVIDENCE",W(r.evidence),"","FILES_TOUCHED",W(r.filesTouched),"","BLOCKERS",W(r.blockers),"","NEXT_ACTION",W(r.nextAction)].join(`
18
+ `)}function io(r,e="normal"){let t=jc(r.rootPath,".toolnet","work","handoff-latest.json");if(!Tc(t))return null;try{let o=JSON.parse(Ic(t,"utf8")).continuity;if(!o||o.schema!=="toolnet.handoff.v2"||o.version!==2)return null;let s=Nc(o,e),i=no(o),a=_c(Oc(s,e,i),oo[e].maxChars);return{detail:e,data:s,quality:i,text:a}}catch{return null}}function Lc(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}var Dc=[/\bhandoff\b/u,/\bcontinuity\b/u,/\bcontinue\b/u,/\bresume\b/u,/\btakeover\b/u,/\btake over\b/u,/tiếp tục/u,/tiếp quản/u,/bàn giao/u,/dừng ở đâu/u,/đang làm gì/u],Fc=[/\bcurrent state\b/u,/\bcurrent task\b/u,/\bevidence\b/u,/\breport locations?\b/u,/\bfiles?\b/u,/\burls?\b/u,/\bassets?\b/u,/\btests?\b/u,/\bcommands?\b/u,/\bblockers?\b/u,/\bnext actions?\b/u,/trạng thái hiện tại/u,/task hiện tại/u,/bằng chứng/u,/vị trí báo cáo/u,/file/u,/url/u,/blocker/u,/việc tiếp theo/u,/bước tiếp theo/u],Kc=[/\bsummarize\b/u,/\bsummary\b/u,/\bfull state\b/u,/\bfull context\b/u,/tóm tắt/u,/đầy đủ/u,/toàn bộ trạng thái/u];function $c(r){let e=0;for(let t of Fc)t.test(r)&&(e+=1);return e}function ao(r,e){let t=Lc(r);if(/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(t)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(t)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(t))return!1;if(e==="summary"||e==="status")return!0;if(!t)return!1;let o=Dc.some(a=>a.test(t)),s=Kc.some(a=>a.test(t)),i=$c(t);return!!(o&&i>=1||s&&i>=2||i>=4)}var uo={question:Ct.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:Ct.enum(["local"]).optional().describe("Returns deterministic local memory only. No external AI is used."),detail:Ct.enum(["compact","normal","benchmark"]).optional().describe("Handoff detail level. compact=minimal, normal=standard, benchmark=deep evidence/files/tests for agent takeover.")};function co(r,e,t,n,o){if(!ao(e,t))return{answer:n};let s=so(e,o),i=io(r.project,s);return i?{answer:i.text,handoff:i.data,detail:i.detail,confidence:i.quality.confidence,missingContext:i.quality.missingContext,quality:i.quality}:{answer:n}}async function lo(r,e){let t=ro(r.project,e.question),n=to(t);if(n)return{...co(r,t.originalQuestion,String(n.intent),n.answer,e.detail),mode:"local",usedAi:!1,source:n.source,intent:n.intent};let o=Xn(r.project,t.originalQuestion),s=co(r,t.originalQuestion,String(o.intent),o.answer,e.detail);return"handoff"in s?{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent,routing:"deterministic-handoff"}:{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent}}import{z as ko}from"zod";import{chmodSync as Af,existsSync as mo,mkdirSync as Rf,readFileSync as po,renameSync as Tf,writeFileSync as If}from"node:fs";import{dirname as _f,join as te}from"node:path";var fo="toolnet.context-offload.v1",zc="toolnet.context-offload-asset.v1";function go(r){return te(r,".toolnet","offload")}function yo(r){return te(go(r),"assets")}function Wc(r){return te(go(r),"graph.json")}function xt(){return{schema:fo,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Gc(r){let e=Wc(r);if(!mo(e))return xt();try{let t=JSON.parse(po(e,"utf8"));return t.schema!==fo||t.version!==1||!Array.isArray(t.nodes)?xt():t}catch{return xt()}}function qc(r,e){let t=e.trim().toLowerCase();if(!/^[a-f0-9]{8,64}$/u.test(t))throw new Error("Invalid context offload asset reference.");if(t.length===64&&mo(te(yo(r),`${t}.json`)))return t;let n=Gc(r).nodes.map(o=>o.id).filter(o=>o.startsWith(t));if(n.length===0)throw new Error(`Context offload asset not found: ${e}`);if(n.length>1)throw new Error(`Ambiguous context offload asset reference: ${e}`);return n[0]}function ho(r,e,t=6e3){let n=qc(r,e),o=po(te(yo(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==zc||s.version!==1||s.assetId!==n)throw new Error(`Invalid context offload asset: ${e}`);let i=Math.max(200,Math.min(2e4,Math.floor(t)));return{assetId:n,kind:s.event.type,bytes:Buffer.byteLength(o,"utf8"),truncated:o.length>i,content:o.length>i?`${o.slice(0,i)}
19
+ [truncated]`:o}}var So={assetId:ko.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:ko.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function bo(r,e){return ho(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as Co}from"zod";import{chmodSync as Kf,existsSync as Hc,mkdirSync as $f,readFileSync as Vc,readdirSync as Uc,renameSync as zf,statSync as Bc,writeFileSync as Wf}from"node:fs";import{join as wo}from"node:path";var Yc="toolnet.skill-memory.v1";function Jc(r,e=Number.MAX_SAFE_INTEGER){let t=new Set,n=[];for(let o of r){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!t.has(i)&&(t.add(i),n.push(s),n.length>=e))break}return n}function Qc(r){return wo(r.rootPath,".toolnet","memory","skills")}function Xc(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===Yc&&t.version===1&&t.projectId===e&&typeof t.id=="string"&&typeof t.task=="string"&&Array.isArray(t.steps)&&Array.isArray(t.verification)&&Array.isArray(t.files)}function Zc(r){let e=Qc(r);if(!Hc(e))return[];if(!Bc(e).isDirectory())return[];let t=[];for(let n of Uc(e)){if(!n.endsWith(".json"))continue;let o=wo(e,n);try{let s=JSON.parse(Vc(o,"utf8"));Xc(s,r.id)&&t.push(s)}catch{}}return t.sort((n,o)=>{let s=o.createdAt.localeCompare(n.createdAt);return s!==0?s:n.id.localeCompare(o.id)})}function eu(r){return Jc(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function tu(r,e){let t=e.normalize("NFKC").toLowerCase().trim();if(!t)return 0;if(r.id.toLowerCase()===t||r.fingerprint.toLowerCase()===t)return 1e3;let n=[r.title,r.task,r.summary,...r.steps,...r.verification,...r.files].join(`
20
+ `).normalize("NFKC").toLowerCase(),o=0;r.task.normalize("NFKC").toLowerCase().includes(t)&&(o+=40),r.title.normalize("NFKC").toLowerCase().includes(t)&&(o+=30);for(let s of eu(t))n.includes(s)&&(o+=5),r.task.normalize("NFKC").toLowerCase().includes(s)&&(o+=4),r.files.some(i=>i.toLowerCase().includes(s))&&(o+=3);return o}function vo(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return Zc(r).map(o=>({...o,score:tu(o,e)})).filter(o=>o.score>0).sort((o,s)=>s.score!==o.score?s.score-o.score:s.createdAt.localeCompare(o.createdAt)).slice(0,n)}var xo={query:Co.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:Co.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function Mo(r,e){let t=vo(r.project,e.query,e.limit??5);return{schema:"toolnet.skill-memory-search.v1",query:e.query,count:t.length,matches:t}}import{z as Do}from"zod";var Po="wiki/state.v1.json";function ru(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function nu(r,e){let t=JSON.parse(r);if(t.schema!=="toolnet.wiki.v1"||t.version!==1||t.projectId!==e.id||!Array.isArray(t.pages)||!Array.isArray(t.revisions))throw new Error("Invalid ToolNet Wiki state");return t}var x=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Po);if(!e){let t=ru(this.project);return await this.save(t),t}return nu(e,this.project)}async save(e){await this.storage.put(Po,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as Ro}from"node:crypto";var S=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function re(r){let e=new Set,t=[];for(let n of r){let o=n.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function ne(r){let e=r.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new S("Invalid Wiki slug",400);return e}function Eo(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(ne(n))}return re(e)}function ou(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function Ao(r){return{id:`revision-${Ro()}`,pageId:r.id,slug:r.slug,revision:r.revision,title:r.title,...r.summary?{summary:r.summary}:{},content:r.content,tags:[...r.tags],links:[...r.links],createdAt:r.updatedAt}}function F(r){return structuredClone(r)}var M=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async summary(){let e=await this.ensureState(),t=new Set(e.pages.flatMap(n=>n.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:re(e.pages.flatMap(n=>n.tags)).sort((n,o)=>n.localeCompare(o)),links:e.pages.reduce((n,o)=>n+o.links.length,0),orphanPages:e.pages.filter(n=>n.links.length===0&&!t.has(n.slug)).length,automatedPages:e.pages.filter(n=>n.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return F([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=ne(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new S(`Wiki page not found: ${e}`,404);return F(o)}async createPage(e){return this.mutate(t=>{let n=e.title.trim(),o=e.content.trim();if(!n)throw new S("Wiki title is required",400);let s=ne(e.slug??n);if(t.pages.some(c=>c.slug===s))throw new S(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${Ro()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:re(e.tags??[]),links:Eo(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(Ao(a)),F(a)})}async updatePage(e,t){return this.mutate(n=>{let o=ne(e),s=n.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new S(`Wiki page not found: ${e}`,404);if(t.title!==void 0){let i=t.title.trim();if(!i)throw new S("Wiki title is required",400);s.title=i}if(t.summary!==void 0){let i=t.summary.trim();i?s.summary=i:delete s.summary}return t.content!==void 0&&(s.content=t.content.trim(),s.links=Eo(s.content)),t.tags!==void 0&&(s.tags=re(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(Ao(s)),F(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return F(n.revisions.filter(o=>o.pageId===t.id).sort((o,s)=>s.revision-o.revision))}async backlinks(e){let t=await this.getPage(e),n=await this.ensureState();return F(n.pages.filter(o=>o.links.includes(t.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(e,t=10){let n=await this.ensureState(),o=re(ou(e));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(t))),i=[];for(let a of n.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),m=a.tags.map(y=>y.toLowerCase()),p=0;for(let y of o)u===y&&(p+=12),c===y&&(p+=10),c.includes(y)&&(p+=6),u.includes(y)&&(p+=5),m.some(b=>b===y)?p+=5:m.some(b=>b.includes(y))&&(p+=3),l.includes(y)&&(p+=2),d.includes(y)&&(p+=1);p>0&&i.push({page:F(a),score:p})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};import{createHash as su,randomUUID as To}from"node:crypto";var Io="wiki/governance.v1.json",Oo="toolnet.knowledge-governance.v1",jo=500,oe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function iu(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function Mt(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function _o(r){return su("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function au(r){let e=[r.title,r.summary??"",r.content.slice(0,2e3),...r.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function cu(r){let e=r.sourceType==="skill"?.96:r.sourceType==="memory"?.94:.88,t=r.tags.map(n=>n.toLowerCase());return(t.includes("permanent")||t.includes("task"))&&(e+=.03),r.content.length>=200&&(e+=.02),r.content.length<80&&(e-=.05),r.title.length<4&&(e-=.05),iu(e)}function No(r){let e=new Date().toISOString();return{schema:Oo,version:1,projectId:r,policy:{...oe},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Lo(r){let e=r.autoApproveThreshold??oe.autoApproveThreshold,t=r.criticalApproveThreshold??oe.criticalApproveThreshold,n=r.staleAfterDays??oe.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new S("Invalid autoApproveThreshold",400);if(!Number.isFinite(t)||t<.5||t>1)throw new S("Invalid criticalApproveThreshold",400);if(!Number.isInteger(n)||n<1||n>3650)throw new S("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:t,staleAfterDays:n}}var se=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Io);if(!e){let t=No(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==Oo||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:Lo(t.policy??oe)}}catch{let t=No(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(Io,JSON.stringify(e,null,2),"application/json")}},ie=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,t,n,o={}){e.audit.push({id:To(),action:t,principal:n,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),e.audit.length>jo&&(e.audit=e.audit.slice(-jo))}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=await e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,t){return this.mutate(n=>(n.policy=Lo({...n.policy,...e}),this.audit(n,"policy:update",t,{metadata:{...n.policy}}),{...n.policy}))}async summary(){let e=await this.ensureState(),t=n=>e.reviews.filter(o=>o.status===n).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:t("pending"),approved:t("approved"),rejected:t("rejected"),superseded:t("superseded"),criticalPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="critical").length,conflictPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let t=await this.ensureState();return structuredClone(t.reviews.filter(n=>!e||n.status===e).sort((n,o)=>o.updatedAt.localeCompare(n.updatedAt)))}async auditLog(e=100){let t=await this.ensureState(),n=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(t.audit.slice(-n).reverse())}async assess(e,t){let n=await this.ensureState(),o=cu(e),s=Mt(e.title),i=t.filter(l=>l.slug!==e.slug&&Mt(l.title)===s&&_o(l.content)!==_o(e.content)).map(l=>l.slug),a=au(e),c=[];o<n.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<n.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<n.policy.autoApproveThreshold||a&&o<n.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,t){let n=await this.assess(e,t);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:n,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:n,review:structuredClone(s)};if(!n.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:n.confidence,risk:n.risk}}),{allowed:!0,mode:"auto-approved",assessment:n};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(s)};let i=new Date().toISOString(),a={id:To(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:n.confidence,risk:n.risk,reasons:[...n.reasons],conflicts:[...n.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(a)}})}async markApplied(e,t){await this.mutate(n=>{let o=n.reviews.find(s=>s.sourceKey===e&&s.digest===t&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(n,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:e}))})}async decide(e,t,n){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===e);if(!s)throw new S(`Governance review not found: ${e}`,404);if(s.status!=="pending")throw new S("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=t.principal,s.updatedAt=i,t.note?.trim()&&(s.reviewNote=t.note.trim()),t.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s);if(t.action==="supersede")return s.status="superseded",t.targetReviewId&&(s.supersededBy=t.targetReviewId),this.audit(o,"knowledge:superseded",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:t.targetReviewId}}),structuredClone(s);if(t.action==="merge"){if(!t.targetReviewId)throw new S("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===t.targetReviewId);if(!u)throw new S("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await n.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new S(`Wiki page '${s.slug}' is manually managed`,409);return c?await n.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await n.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let t=await this.ensureState(),n=await e.listPages(),o=Date.now(),s=t.policy.staleAfterDays*864e5,i=n.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of n){let d=Mt(l.title),m=a.get(d)??[];m.push(l),a.set(d,m)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(m=>m.slug)})),u=t.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:n.length,automatedPages:n.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:n.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<t.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Fo={query:Do.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:Do.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function Ko(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new M(new x(t,r.project));await n.initialize();let o=await n.search(e.query,e.limit??5);return{schema:"toolnet.wiki-search.v1",query:e.query,count:o.length,results:o.map(({page:s,score:i})=>({id:s.id,slug:s.slug,title:s.title,summary:s.summary,tags:s.tags,links:s.links,revision:s.revision,updatedAt:s.updatedAt,score:i}))}}import{z as uu}from"zod";var $o={page:uu.string().min(1).max(200).describe("Wiki page slug or page id.")};async function zo(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new M(new x(t,r.project));await n.initialize();let o=await n.getPage(e.page),s=await n.backlinks(o.slug);return{schema:"toolnet.wiki-read.v1",page:o,backlinks:s.map(i=>({slug:i.slug,title:i.title}))}}import{z as lu}from"zod";var Wo={includePending:lu.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function Go(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new ie(new se(t,r.project));await n.initialize();let o=new M(new x(t,r.project));await o.initialize();let s=await n.summary(),i=await n.quality(o),a=e.includePending?(await n.listReviews("pending")).slice(0,10).map(c=>({id:c.id,sourceType:c.sourceType,title:c.title,confidence:c.confidence,risk:c.risk,reasons:c.reasons})):void 0;return{schema:"toolnet.knowledge-governance-status.v1",summary:s,quality:{stalePages:i.stalePages.length,duplicateTitles:i.duplicateTitles.length,pendingReviews:i.pendingReviews,conflicts:i.conflicts},...a?{pending:a}:{}}}var qo={};function Ho(r){let e=r.project.id;return{project:{id:e,name:r.project.name,remote:r.project.remote??r.project.name,rootPath:r.project.rootPath},runtime:r.runtime?{phase:r.runtime.phase,dependencies:{memory:{...r.runtime.dependencies.memory},graph:{...r.runtime.dependencies.graph},semantic:{...r.runtime.dependencies.semantic}},metrics:{...r.runtime.metrics},errors:[...r.runtime.errors],dataSource:r.runtime.dataSource,lastUpdatedAt:r.runtime.lastUpdatedAt}:null,storage:r.storage?.name??null,data:{memories:r.memory.exportProject(e).length,graphSymbols:r.graph.allSymbols(e).length,graphEdges:r.graph.allEdges(e).length,semanticAvailable:r.codeSemantic!==void 0}}}function h(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}var pu=["# ToolNet Memory \u2014 Persistent Project Continuity","","ToolNet Memory provides persistent work continuity across coding agents and sessions.","","CONTINUITY RULES:","","1. When the user asks to continue, resume, finish, pick up, or return to previous work,"," call memory_agent_ask BEFORE reconstructing previous work from git, files, or session history.","",'2. Use memory_agent_ask with mode="local" for direct continuity facts such as:'," - current task"," - completed work"," - current/last file"," - TODOs"," - blockers"," - next action","",'3. ToolNet Memory Agent is local-only; use mode="local" for all continuity questions.',"","4. NEVER reconstruct previous work by reading or searching raw agent/session history, including:"," - .toolnet/journal/**, .toolnet/runtime/sources/**, and legacy .toolnet/sessions/**"," - state.json"," - events.jsonl"," - raw transcripts"," - ~/.gemini/antigravity-cli/brain/**"," - another coding agent's internal session history","","5. Do not search the filesystem for the implementation or JSON schema of memory_agent_ask."," Invoke the MCP tool directly.","","6. After ToolNet resolves continuity, inspect the current repository only to verify current truth."," Current repository evidence overrides stale memory.","","7. Do not ask the user to repeat project context already available through ToolNet Memory.","","8. Do not call memory_agent_ask for unrelated coding questions when current context is sufficient.","","9. Large tool/file payloads may be stored outside prompt context."," If the compact graph references a needed asset, call context_offload_read.","","10. Never bulk-load offloaded assets. Read only the minimum asset required."].join("\\n");function fu(r){let e=new du({name:"toolnet-memory",version:"0.1.0"},{instructions:pu});return e.tool("memory_search","Search relevant long-term memory for the current project.",Or,async t=>h(await Lr(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Qr,async t=>h(await Xr(r,t))),e.tool("memory_forget","Delete a memory by id.",Zr,async t=>h(await en(r,t))),e.tool("find_symbol","Find code symbols by exact name.",tn,async t=>h(await rn(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",on,async t=>h(await sn(r,t))),e.tool("code_search","Search indexed code symbols and files.",cn,async t=>h(await un(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",dn,async t=>h(await mn(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",kn,async t=>h(await Sn(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",wn,async t=>h(await vn(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>h(await Cn(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Mn,async t=>h(await Pn(r,t))),e.tool("semantic_code_search","Legacy-compatible local code search using SQLite FTS5/BM25 lexical ranking. No embeddings or vector database.",An,async t=>h(await Rn(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",pn,async t=>h(await fn(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>h(await gn(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",yn,async t=>h(await hn(r,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",jn,async t=>h(await _n(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Nn,async t=>h(await On(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Ln,async t=>h(await Dn(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Fn,async t=>h(await Kn(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Wn,async t=>h(await Gn(r,t))),e.tool("memory_agent_ask",["Ask ToolNet Memory Agent about previous project work.","CALL THIS TOOL before guessing when the user asks to continue/resume previous work,","mentions a previous agent/session, asks what was unfinished, what file was last touched,","which TODOs are complete, blockers, decisions, or what should happen next.","Use mode=local for continuity questions. Memory Agent is deterministic and local-only; no external AI provider is used.","Do not use it for unrelated coding questions when current repository context is already sufficient.","Returns concise selected memory instead of raw transcripts or full memory dumps.","Short conversational follow-ups are supported using compact ToolNet Memory focus; raw transcripts are never replayed."].join(" "),uo,async t=>h(await lo(r,t))),e.tool("context_offload_read",["Read one external ToolNet tool/file asset referenced by the compact context graph.","Use only when needed for the current task.","Never bulk-load all offloaded assets."].join(" "),So,async t=>h(await bo(r,t))),e.tool("skill_memory_search",["Search successful ToolNet project work promoted into reusable Skill Memory SOPs.","Call this before repeating a task that may have been solved successfully before.","Returns compact procedure steps, files and verification evidence.","Raw transcripts are never returned."].join(" "),xo,async t=>h(await Mo(r,t))),e.tool("wiki_search",["Search the ToolNet project Wiki for durable project knowledge.","Use Wiki before rereading broad project history when a maintained knowledge page may exist.","Returns compact metadata; call wiki_read only for the page needed."].join(" "),Fo,async t=>h(await Ko(r,t))),e.tool("wiki_read",["Read one ToolNet Wiki page by slug or id.","Returns the maintained page plus compact backlinks.","Do not bulk-read unrelated Wiki pages."].join(" "),$o,async t=>h(await zo(r,t))),e.tool("toolnet_status",["Inspect ToolNet MCP runtime health.","Returns dependency readiness, degraded state, retry counts,","startup timing, hydration timing, storage source and project data counts."].join(" "),qo,async()=>h(Ho(r))),e.tool("knowledge_governance_status",["Inspect ToolNet Knowledge Governance health.","Returns review counts, confidence, conflicts, stale knowledge, and optional compact pending reviews.","Use this before trusting or changing important durable project knowledge."].join(" "),Wo,async t=>h(await Go(r,t))),e}async function Vo(r){let e=fu(r),t=new mu;await e.connect(t)}function Uo(){return new Date().toISOString()}function P(r){r.lastUpdatedAt=Uo()}function He(r=Date.now()){return{phase:"starting",dependencies:{memory:{state:"idle",attempts:0},graph:{state:"idle",attempts:0},semantic:{state:"idle",attempts:0}},metrics:{processStartedAtMs:r,hydrationRuns:0,retryCount:0},errors:[],dataSource:"none",lastUpdatedAt:Uo()}}function Bo(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",P(r)}function Yo(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,P(r)}function Ve(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,P(r))}function Ue(r,e){r.dependencies[e].attempts+=1,P(r)}function Be(r){r.metrics.retryCount+=1,P(r)}function G(r,e,t=Date.now()){let n=r.dependencies[e];n.state="ready",n.lastError=void 0,n.readyAfterMs=t-r.metrics.processStartedAtMs,P(r)}function ae(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),P(r)}function Jo(r,e=Date.now()){r.metrics.hydrationFinishedAtMs=e,r.metrics.hydrationStartedAtMs!==void 0&&(r.metrics.hydrationMs=e-r.metrics.hydrationStartedAtMs),r.errors=Object.entries(r.dependencies).filter(([,n])=>n.state==="failed").map(([n,o])=>`${n}: ${o.lastError??"unknown error"}`);let t=Object.values(r.dependencies).every(n=>n.state==="ready");r.phase=t?"ready":"degraded",P(r)}function Qo(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],P(r)}async function Ye(r,e){let t=Math.max(1,Math.floor(e.attempts)),n;for(let o=1;o<=t;o+=1){e.onAttempt?.(o);try{return await r()}catch(s){if(n=s,o>=t)break;e.onRetry?.(o,s),e.delayMs>0&&await new Promise(i=>{setTimeout(i,e.delayMs)})}}throw n instanceof Error?n:new Error(String(n??"operation failed"))}function Ks(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function tl(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function rl(r){let e=r.runtime;return e?{memory:e.dependencies.memory.state==="ready"?"ready":"failed",graph:e.dependencies.graph.state==="ready"?"ready":"failed",semantic:e.dependencies.semantic.state==="ready"?"ready":"failed",errors:[...e.errors]}:{memory:"failed",graph:"failed",semantic:"failed",errors:["runtime unavailable"]}}async function $s(r){let e=r.runtime??He(Date.now());r.runtime=e,Yo(e);let t=Ks(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=tl(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await Kr(r.project,{timeoutMs:Ks(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});o&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(o.memory),G(e,"memory")),e.dependencies.graph.state!=="ready"&&(o.graph&&r.graph.import(o.graph.symbols,o.graph.edges),G(e,"graph")))}try{let[{loadConfig:o},s]=await Promise.all([Promise.resolve().then(()=>(vt(),Vn)),Promise.resolve().then(()=>(Is(),Ts))]),i=o(),a=s.createStorageProvider({provider:i.storage.provider,r2:i.storage.r2,s3:i.storage.s3,huggingface:i.storage.huggingface,localRoot:i.storage.localRoot}),c=s.withStorageRetry(a,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),u=new s.ProjectScopedStorageProvider(c,r.project.id,r.project.name,r.project.remote??r.project.name),l=new s.MemoryStore(u);r.storage=u,r.memoryStore=l;let d=e.dependencies.memory.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Ve(e,"memory");try{let p=await Ye(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Ue(e,"memory")},onRetry:()=>{Be(e)}});r.memory.importRecords(p),G(e,"memory")}catch(p){ae(e,"memory",p)}})(),m=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Ve(e,"graph");try{let p=await Ye(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Ue(e,"graph")},onRetry:()=>{Be(e)}});p&&r.graph.import(p.symbols,p.edges),G(e,"graph")}catch(p){ae(e,"graph",p)}})();if(await Promise.all([d,m]),e.dependencies.semantic.state!=="ready"){Ve(e,"semantic");try{let{SemanticCodeEngine:p}=await Promise.resolve().then(()=>(Fs(),Ds)),y=new p({projectId:r.project.id,rootPath:r.project.rootPath,storage:u,graph:r.graph});await Ye(()=>y.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{Ue(e,"semantic")},onRetry:()=>{Be(e)}}),r.codeSemantic=y,G(e,"semantic")}catch(p){ae(e,"semantic",p)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&ae(e,s,o)}return Jo(e),rl(r)}function zs(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function nl(){let r=Date.now(),e=new Ce().detect(),t=new ke,n=new Ae(t),o=new Re,s=new Te(o),i=He(r),a={project:e,memory:t,retrieval:n,graph:o,references:s,runtime:i};await Vo(a),Bo(i);let c=async()=>{try{await $s(a),i.phase==="degraded"&&setTimeout(()=>{c()},zs()).unref()}catch(u){Qo(i,u),setTimeout(()=>{i.phase="degraded",c()},zs()).unref()}};c()}nl().catch(r=>{console.error(r),process.exit(1)});