toolnet-memory 0.3.14 → 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +0 -1
  2. package/.release-target +1 -1
  3. package/README.md +25 -1
  4. package/bin/toolnet-memory +5 -0
  5. package/bundle/agy-hook.js +67 -67
  6. package/bundle/agy.js +61 -61
  7. package/bundle/api.js +15 -15
  8. package/bundle/auto-integrate.js +28 -28
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/claude-hook.js +51 -50
  11. package/bundle/codex-context.js +25 -24
  12. package/bundle/codex.js +71 -71
  13. package/bundle/context-runtime.js +45 -44
  14. package/bundle/context.js +15 -15
  15. package/bundle/continuity-certify.js +13 -13
  16. package/bundle/copilot-hook.js +87 -85
  17. package/bundle/copilot.js +4 -4
  18. package/bundle/cursor-hook.js +87 -85
  19. package/bundle/cursor.js +4 -4
  20. package/bundle/doctor.js +4 -4
  21. package/bundle/full-index.js +20 -20
  22. package/bundle/gc.js +3 -0
  23. package/bundle/graph-index.js +4 -4
  24. package/bundle/graph-ui.js +3 -3
  25. package/bundle/grok-hook.js +60 -59
  26. package/bundle/grok.js +5 -5
  27. package/bundle/handoff-refresh.js +10 -10
  28. package/bundle/help-cli.js +4 -4
  29. package/bundle/impact.js +4 -4
  30. package/bundle/incremental.js +5 -4
  31. package/bundle/init.js +37 -37
  32. package/bundle/integration-status.js +4 -4
  33. package/bundle/kiro-hook.js +82 -81
  34. package/bundle/learner.js +6 -6
  35. package/bundle/mcp.js +17 -17
  36. package/bundle/memory-agent.js +7 -7
  37. package/bundle/memory-query.js +7 -7
  38. package/bundle/opencode.js +80 -80
  39. package/bundle/project-manual.js +7 -7
  40. package/bundle/recovery-certify.js +15 -15
  41. package/bundle/runtime.js +13 -12
  42. package/bundle/semantic.js +5 -5
  43. package/bundle/snapshot.js +4 -4
  44. package/bundle/status-cli.js +4 -4
  45. package/bundle/toolnet-cli.js +60 -60
  46. package/bundle/work-continuity.js +7 -7
  47. package/package.json +9 -3
  48. package/release-manifest.json +54 -3
package/bundle/mcp.js CHANGED
@@ -1,18 +1,18 @@
1
- var jo=Object.defineProperty;var y=(r,e,t)=>()=>{if(t)throw t[0];try{return r&&(e=r(r=0)),e}catch(n){throw t=[n],n}};var Ie=(r,e)=>{for(var t in e)jo(r,t,{get:e[t],enumerable:!0})};var Ro,X,vt=y(()=>{"use strict";Ro=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],X=class{scan(e){let t=[];for(let n of Ro){let o=new RegExp(n.regex.source,n.regex.flags);for(let s of e.matchAll(o))t.push({type:n.type,value:s[0]})}return t}hasSecrets(e){return this.scan(e).length>0}}});var P,Z=y(()=>{"use strict";vt();P=class{scanner=new X;sanitize(e){let t=e,n=this.scanner.scan(e),o=new Set;for(let s of n)o.add(s.type),t=t.split(s.value).join(`[REDACTED:${s.type}]`);return{text:t,redacted:n.length,secretTypes:[...o]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[n,o]of Object.entries(e)){let s=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")?t[n]="[REDACTED]":t[n]=this.sanitizeValue(o)}return t}return e}}});import{existsSync as zs,readFileSync as Gs}from"node:fs";import{homedir as qs}from"node:os";import{join as Vs}from"node:path";function Hs(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 Bs(){let r=process.env.TOOLNET_GLOBAL_ENV??Vs(qs(),".config","toolnet-memory",".env");if(!zs(r))return;let e=Gs(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]=Hs(n.slice(o+1)))}}var Fr=y(()=>{"use strict";Bs()});var Kr={};Ie(Kr,{loadConfig:()=>Dr});function $(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function W(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Dr(){return{memory:{autoCapture:$(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:$(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:$(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:$(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:W(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:W(process.env.MEMORY_RERANK_TOP,10),finalContext:W(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:W(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:$(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:W(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Je=y(()=>{"use strict";Fr()});var Vn=y(()=>{"use strict"});import{DeleteObjectCommand as ka,GetObjectCommand as Sa,HeadObjectCommand as ba,ListObjectsV2Command as va,PutObjectCommand as wa,S3Client as Ca}from"@aws-sdk/client-s3";import{getSignedUrl as xa}from"@aws-sdk/s3-request-presigner";var Q,Ze=y(()=>{"use strict";Q=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ca({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 wa({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await xa(this.client,new Sa({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 ba({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 ka({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new va({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 Hn,mkdir as Ma,readFile as Pa,readdir as Aa,rm as ja,stat as Bn,writeFile as Ea}from"node:fs/promises";import{dirname as Ra,join as Ta,relative as Un,resolve as Ia}from"node:path";var _,et=y(()=>{"use strict";_=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ia(this.root,t)}async put(e,t){let n=this.path(e);await Ma(Ra(n),{recursive:!0}),await Ea(n,t)}async get(e){try{return await Pa(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 Hn(this.path(e)),!0}catch{return!1}}async delete(e){await ja(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await Hn(t)}catch{return n}let o=async i=>{let a=await Aa(i,{withFileTypes:!0});for(let c of a){let u=Ta(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Bn(u);n.push({key:Un(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Bn(t);return s.isDirectory()?await o(t):n.push({key:Un(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),n}}});import{DeleteObjectCommand as Na,GetObjectCommand as _a,HeadObjectCommand as Oa,ListObjectsV2Command as La,PutObjectCommand as Fa,S3Client as Da}from"@aws-sdk/client-s3";import{getSignedUrl as Ka}from"@aws-sdk/s3-request-presigner";var O,tt=y(()=>{"use strict";O=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Da({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 Fa({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Ka(this.client,new _a({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 Oa({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 Na({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new La({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 $a}from"node:os";import{join as Wa}from"node:path";function rt(r,e){return console.warn(e),new _(r)}function za(r){let e=r.localRoot??Wa($a(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):rt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new O({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):rt(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 Q({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):rt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new _(e)}var Jn=y(()=>{"use strict";Ze();et();tt()});var nt,Qn=y(()=>{"use strict";nt=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 Yn=y(()=>{"use strict";et()});var Xn=y(()=>{"use strict";Ze()});var Zn=y(()=>{"use strict";tt()});var ot,eo=y(()=>{"use strict";ot=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 st,to=y(()=>{"use strict";st=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 it,ro=y(()=>{"use strict";it=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 Y,at=y(()=>{"use strict";Y=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 ct,no=y(()=>{"use strict";ct=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 Ga(r){return new Promise(e=>setTimeout(e,r))}async function oo(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 Ga(c+u)}throw s}var so=y(()=>{"use strict"});function Va(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:qa.has(n)?(...s)=>oo(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var qa,io=y(()=>{"use strict";so();qa=new Set(["put","get","getText","delete","list"])});function ut(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 lt=y(()=>{"use strict"});function dt(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 mt=y(()=>{"use strict"});var pt,ao=y(()=>{"use strict";lt();mt();pt=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=ut(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=dt(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 co=y(()=>{"use strict";lt();ao();mt()});var ft,uo=y(()=>{"use strict";ft=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 gt,lo=y(()=>{"use strict";gt=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,mo=y(()=>{"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 ht,po=y(()=>{"use strict";ht=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 fo={};Ie(fo,{HuggingFaceStorageProvider:()=>Q,LocalStorageProvider:()=>_,MemoryStore:()=>nt,PersistentArchitectureStore:()=>gt,PersistentCodeAnalysisStore:()=>yt,PersistentCodeChunkStore:()=>Y,PersistentCodeGraphStore:()=>st,PersistentCodeManifestStore:()=>it,PersistentCodeVectorStore:()=>ct,PersistentTypeResolutionStore:()=>ft,PersistentVectorStore:()=>ot,PersistentVisualizationStore:()=>ht,ProjectScopedStorageProvider:()=>pt,S3StorageProvider:()=>O,createStorageProvider:()=>za,mapProjectStoragePath:()=>dt,sanitizeProjectFolder:()=>ut,withStorageRetry:()=>Va});var go=y(()=>{"use strict";Vn();Jn();Qn();Yn();Xn();Zn();eo();to();ro();at();no();io();co();uo();lo();mo();po()});import{createHash as Ha}from"node:crypto";import{readFile as Ba}from"node:fs/promises";import{join as Ua}from"node:path";function yo(r){return Ha("sha256").update(r).digest("hex")}var Re,ho=y(()=>{"use strict";Z();Re=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 Ba(Ua(t,u),"utf8")}catch{continue}let m=d.split(/\r?\n/),p=l.filter(g=>g.type!=="file"&&typeof g.startLine=="number"&&typeof g.endLine=="number");if(p.length>0)for(let g of p)c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,symbol:g,startLine:g.startLine,endLine:g.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),g=o.slice(d-1,p).join(`
4
- `).trim();if(g){let S=this.sanitizer.sanitize(g).text,E=yo(S),L=[t,n,s?.id??"file",String(m),E].join(":");l.push({id:yo(L).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:E})}if(p>=u)break;d=p-a+1,m++}return l}}});import{DatabaseSync as Ja}from"node:sqlite";var Te,ko=y(()=>{"use strict";Te=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 Ja(":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 So(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 bo=y(()=>{"use strict"});var vo={};Ie(vo,{SemanticCodeEngine:()=>kt});var kt,wo=y(()=>{"use strict";at();ho();ko();bo();kt=class{constructor(e){this.options=e;this.fts=new Te(e.projectId)}options;fts;async initialize(e){let{projectId:t,rootPath:n,storage:o,graph:s}=this.options,i=new Y(o),a=await new Re().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"});let l=this.fts.build(a);return{chunks:a.length,vectorsLoaded:0,vectorsIndexed:l,vectorsRemoved:0,totalVectors:this.fts.size,savedChunks:u,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=So(i.filePath,e),c=s.score,u=0,l=c*a;o.push({chunk:i,score:l,vectorScore:u,lexicalScore:c})}return o}size(){return this.fts.size}}});import"dotenv/config";import{randomUUID as Qo}from"node:crypto";var Eo={critical:100,high:75,normal:50,temporary:20};function St(r){return Eo[r]}function bt(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"}Z();var To=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Io=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function wt(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Io.has(e)))}function No(r,e){let t=wt(r),n=wt(e);if(t.size===0||n.size===0)return 0;let o=0;for(let i of t)n.has(i)&&(o+=1);let s=new Set([...t,...n]).size;return s===0?0:o/s}function Ct(r){return new Set(r.tags.filter(e=>!To.has(e.toLowerCase())))}function Ne(r){let e=r.metadata?.evidence;if(!e||typeof e!="object")return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,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 _o(r){let e=Ne(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function Oo(r){let e=Number(r.metadata?.confidence);return!Number.isFinite(e)||e<0?0:e>1?1:e}function Lo(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function xt(r){let e=Ne(r),t=Lo(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=Oo(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function Mt(r){let e=r.metadata?.topic;if(typeof e!="string")return;let t=e.normalize("NFKC").trim().toLowerCase();if(t)return t}function Fo(r,e){let t=Ct(r),n=Ct(e);for(let o of t)if(n.has(o))return!0;return!1}function Do(r,e){if(e.id===r.id||e.projectId!==r.projectId||e.type!==r.type||e.metadata?.supersededBy)return!1;let t=Mt(r),n=Mt(e);return t&&n&&t===n||Fo(r,e)?!0:No(r.content,e.content)>=.6}function Pt(r){return r.type!=="rule"?!1:Ne(r).userExplicit}function Ko(r,e){return!Pt(r)||!Pt(e)?!1:r.createdAt>=e.createdAt}var ee=class{resolve(e,t){if(e.type!=="rule"&&e.type!=="decision")return{superseded:[],conflicts:[]};let n=[],o=[],s=xt(e);for(let i of t){if(!Do(e,i))continue;let a=xt(i);if(s>a){n.push(i);continue}if(s<a){o.push(i);continue}if(Ko(e,i)){n.push(i);continue}if(!_o(i)&&e.createdAt>=i.createdAt){n.push(i);continue}o.push(i)}return{superseded:n,conflicts:o}}findSuperseded(e,t){return this.resolve(e,t).superseded}};var $o=new Set(["code","decision","rule","todo","summary"]);function Wo(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function At(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 zo(r,e){let t=At(e)-At(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 jt(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 Et(r){let e=new Map;for(let o of r){if(!$o.has(o.type)||o.metadata?.supersededBy)continue;let s=Wo(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(zo),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:jt(s.flatMap(c=>c.tags)),mergedSources:jt(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function _e(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 Go(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function qo(r){let e=_e(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 Vo(r){return _e(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function Ho(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 Rt(r,e=Date.now()){let t=50,n=[],o=_e(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")),Ho(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=Go(r,e)>=qo(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=Vo(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 Bo={critical:100,high:75,normal:50,temporary:20},Uo={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function Tt(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 Oe(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function Jo(r){return!!r.metadata?.supersededBy}function Le(r,e=Date.now()){return!Oe(r,e)&&!Jo(r)}function F(r,e=Date.now()){if(!Le(r,e))return 0;let t=Bo[r.importance];if(r.importance==="critical")return t;let n=Uo[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var te=class{memories=new Map;sanitizer=new P;conflicts=new ee;remember(e){let t=new Date().toISOString(),n=this.sanitizer.sanitize(e.content.trim()).text,o=e.importance??bt(e.type,n),s={id:Qo(),projectId:e.projectId,type:e.type,content:n,importance:o,importanceScore:St(o),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??Tt(e.type,o,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.resolve(s,this.list(e.projectId));if(i.superseded.length>0){s.metadata={...s.metadata??{},supersedes:i.superseded.map(a=>a.id)};for(let a of i.superseded)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}if(i.conflicts.length>0){let a=i.conflicts.map(c=>c.id);s.metadata={...s.metadata??{},conflictsWith:a};for(let c of i.conflicts){let u=Array.isArray(c.metadata?.conflictsWith)?c.metadata?.conflictsWith:[],l=new Set(u.filter(d=>typeof d=="string"));l.add(s.id),c.updatedAt=t,c.metadata={...c.metadata??{},conflictsWith:[...l]},this.memories.set(c.id,c)}}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let n of e)n?.id&&(this.memories.set(n.id,n),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,n)=>n.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Le(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=F(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=F(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=Et(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=Rt(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&&Oe(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 Yo}from"node:crypto";import{existsSync as Fe,mkdirSync as Xo,readFileSync as Zo,renameSync as es,writeFileSync as ts}from"node:fs";import{basename as rs,dirname as re,join as oe,parse as _t,resolve as D}from"node:path";var Ot=".toolnet",ns="project.json";function os(r){return Yo("sha256").update(r).digest("hex").slice(0,16)}function De(r){return oe(r,Ot,ns)}function ss(r){return Fe(De(r))}function is(r,e){let t=D(r),n=_t(t).root;for(;;){if(ss(t))return t;if(t===n||e&&t===D(e))break;let o=re(t);if(o===t)break;t=o}return null}function as(r){let e=D(r),t=_t(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>Fe(oe(e,s))))return e;if(e===t)break;let o=re(e);if(o===e)break;e=o}return D(r)}function cs(r){let e;try{e=JSON.parse(Zo(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:re(re(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 It(r,e){let t=oe(r,Ot);Xo(t,{recursive:!0});let n=De(r),o=`${n}.tmp-${process.pid}`;ts(o,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),es(o,n)}function Nt(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}var ne=class{detect(e=process.cwd()){let t=D(e),n=as(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Fe(oe(n,l))),i=is(t,s?n:void 0);if(i){let l=De(i),d=cs(l);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),It(i,d)),Nt(d,i)}let a=new Date().toISOString(),c=rs(n),u={version:1,id:os(n),name:c,remote:c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return It(n,u),Nt(u,n)}};function Ke(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=Ke(e),o=Ke([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 Lt(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 Ft(r){return F(r)/100}var us={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function Dt(r){return us[r]??.4}var ie=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 ae=class{bm25=new se;analyzer=new ie;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=Lt(c),d=Ft(c),m=Dt(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 ce=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 ue=class{constructor(e){this.memory=e}memory;searcher=new ae;contextBuilder=new ce;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 le=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 de=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 fa}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as ga}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Kt}from"zod";var $t={query:Kt.string(),limit:Kt.number().int().min(1).max(20).optional()};async function Wt(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 K}from"zod";import{createConnection as ms}from"node:net";import{homedir as ls}from"node:os";import{join as ds}from"node:path";function zt(){return process.env.TOOLNET_SERVICE_SOCKET??ds(ls(),".toolnet","run","service.sock")}function Gt(r,e={}){let t=e.socketPath??zt(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=ms({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 Lo=Object.defineProperty;var y=(r,e,t)=>()=>{if(t)throw t[0];try{return r&&(e=r(r=0)),e}catch(n){throw t=[n],n}};var Oe=(r,e)=>{for(var t in e)Lo(r,t,{get:e[t],enumerable:!0})};function Ct(r){return r.normalize("NFKC").trim().toLowerCase()}function $o(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 zo(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function Wo(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 Go(r,e){return r.start<e.end&&e.start<r.end}function xt(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var Do,Ko,X,Mt=y(()=>{"use strict";Do=[{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"}],Ko=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);X=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=Ct(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of Do){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=xt(t),o=[];for(let s of n)o.some(i=>Go(i,s))||o.push(s);return xt(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=Ct(e);return Ko.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)||zo(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Wo(e,o.index,o.index+s.length)&&($o(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,ee=y(()=>{"use strict";Mt();P=class{scanner;constructor(e={}){this.scanner=new X(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}}});import{existsSync as Zs,readFileSync as Xs}from"node:fs";import{homedir as ei}from"node:os";import{join as ti}from"node:path";function ri(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 ni(){let r=process.env.TOOLNET_GLOBAL_ENV??ti(ei(),".config","toolnet-memory",".env");if(!Zs(r))return;let e=Xs(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]=ri(n.slice(o+1)))}}var Vr=y(()=>{"use strict";ni()});var Br={};Oe(Br,{loadConfig:()=>Hr});function z(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function W(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Hr(){return{memory:{autoCapture:z(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:z(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:z(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:z(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:W(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:W(process.env.MEMORY_RERANK_TOP,10),finalContext:W(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:W(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:z(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:W(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Ye=y(()=>{"use strict";Vr()});var Xn=y(()=>{"use strict"});import{DeleteObjectCommand as ja,GetObjectCommand as Ea,HeadObjectCommand as Ta,ListObjectsV2Command as Ra,PutObjectCommand as Ia,S3Client as Na}from"@aws-sdk/client-s3";import{getSignedUrl as _a}from"@aws-sdk/s3-request-presigner";var Y,tt=y(()=>{"use strict";Y=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Na({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 Ia({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await _a(this.client,new Ea({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 Ta({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 ja({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Ra({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 eo,mkdir as Oa,readFile as La,readdir as Fa,rm as Da,stat as to,writeFile as Ka}from"node:fs/promises";import{dirname as $a,join as za,relative as ro,resolve as Wa}from"node:path";var O,rt=y(()=>{"use strict";O=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Wa(this.root,t)}async put(e,t){let n=this.path(e);await Oa($a(n),{recursive:!0}),await Ka(n,t)}async get(e){try{return await La(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 eo(this.path(e)),!0}catch{return!1}}async delete(e){await Da(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await eo(t)}catch{return n}let o=async i=>{let a=await Fa(i,{withFileTypes:!0});for(let c of a){let u=za(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await to(u);n.push({key:ro(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await to(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 Ga,GetObjectCommand as qa,HeadObjectCommand as Va,ListObjectsV2Command as Ha,PutObjectCommand as Ba,S3Client as Ua}from"@aws-sdk/client-s3";import{getSignedUrl as Ja}from"@aws-sdk/s3-request-presigner";var L,nt=y(()=>{"use strict";L=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ua({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 Ba({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Ja(this.client,new qa({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 Va({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 Ga({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Ha({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 Qa}from"node:os";import{join as Ya}from"node:path";function ot(r,e){return console.warn(e),new O(r)}function Za(r){let e=r.localRoot??Ya(Qa(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new L({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?new L({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?new Y({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):ot(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new O(e)}var no=y(()=>{"use strict";tt();rt();nt()});var st,oo=y(()=>{"use strict";st=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 so=y(()=>{"use strict";rt()});var io=y(()=>{"use strict";tt()});var ao=y(()=>{"use strict";nt()});var it,co=y(()=>{"use strict";it=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 at,uo=y(()=>{"use strict";at=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 ct,lo=y(()=>{"use strict";ct=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 Z,ut=y(()=>{"use strict";Z=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 lt,mo=y(()=>{"use strict";lt=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 Xa(r){return new Promise(e=>setTimeout(e,r))}async function po(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 Xa(c+u)}throw s}var fo=y(()=>{"use strict"});function tc(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:ec.has(n)?(...s)=>po(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var ec,go=y(()=>{"use strict";fo();ec=new Set(["put","get","getText","delete","list"])});function dt(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 mt=y(()=>{"use strict"});function pt(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 ft=y(()=>{"use strict"});var gt,yo=y(()=>{"use strict";mt();ft();gt=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=dt(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=pt(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 ho=y(()=>{"use strict";mt();yo();ft()});var yt,ko=y(()=>{"use strict";yt=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 ht,So=y(()=>{"use strict";ht=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 kt,bo=y(()=>{"use strict";kt=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 St,vo=y(()=>{"use strict";St=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 wo={};Oe(wo,{HuggingFaceStorageProvider:()=>Y,LocalStorageProvider:()=>O,MemoryStore:()=>st,PersistentArchitectureStore:()=>ht,PersistentCodeAnalysisStore:()=>kt,PersistentCodeChunkStore:()=>Z,PersistentCodeGraphStore:()=>at,PersistentCodeManifestStore:()=>ct,PersistentCodeVectorStore:()=>lt,PersistentTypeResolutionStore:()=>yt,PersistentVectorStore:()=>it,PersistentVisualizationStore:()=>St,ProjectScopedStorageProvider:()=>gt,S3StorageProvider:()=>L,createStorageProvider:()=>Za,mapProjectStoragePath:()=>pt,sanitizeProjectFolder:()=>dt,withStorageRetry:()=>tc});var Co=y(()=>{"use strict";Xn();no();oo();so();io();ao();co();uo();lo();ut();mo();go();ho();ko();So();bo();vo()});import{createHash as rc}from"node:crypto";import{readFile as nc}from"node:fs/promises";import{join as oc}from"node:path";function xo(r){return rc("sha256").update(r).digest("hex")}var Ne,Mo=y(()=>{"use strict";ee();Ne=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 nc(oc(t,u),"utf8")}catch{continue}let m=d.split(/\r?\n/),p=l.filter(g=>g.type!=="file"&&typeof g.startLine=="number"&&typeof g.endLine=="number");if(p.length>0)for(let g of p)c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,symbol:g,startLine:g.startLine,endLine:g.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),g=o.slice(d-1,p).join(`
4
+ `).trim();if(g){let S=this.sanitizer.sanitize(g).text,E=xo(S),F=[t,n,s?.id??"file",String(m),E].join(":");l.push({id:xo(F).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:E})}if(p>=u)break;d=p-a+1,m++}return l}}});import{DatabaseSync as sc}from"node:sqlite";var _e,Po=y(()=>{"use strict";_e=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 sc(":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 Ao(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 jo=y(()=>{"use strict"});var Eo={};Oe(Eo,{SemanticCodeEngine:()=>bt});var bt,To=y(()=>{"use strict";ut();Mo();Po();jo();bt=class{constructor(e){this.options=e;this.fts=new _e(e.projectId)}options;fts;async initialize(e){let{projectId:t,rootPath:n,storage:o,graph:s}=this.options,i=new Z(o),a=await new Ne().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"});let l=this.fts.build(a);return{chunks:a.length,vectorsLoaded:0,vectorsIndexed:l,vectorsRemoved:0,totalVectors:this.fts.size,savedChunks:u,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=Ao(i.filePath,e),c=s.score,u=0,l=c*a;o.push({chunk:i,score:l,vectorScore:u,lexicalScore:c})}return o}size(){return this.fts.size}}});import"dotenv/config";import{randomUUID as us}from"node:crypto";var Fo={critical:100,high:75,normal:50,temporary:20};function vt(r){return Fo[r]}function wt(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"}ee();var Pt=new P;function At(r){return Pt.sanitize(r).text}function te(r){return Pt.sanitizeValue(r)}var qo=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Vo=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","use","using","the","a","an","cho","v\xE0","l\xE0","c\u1EE7a","to","for","with","quy\u1EBFt","\u0111\u1ECBnh"]);function jt(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Vo.has(e)))}function Ho(r,e){let t=jt(r),n=jt(e);if(t.size===0||n.size===0)return 0;let o=0;for(let i of t)n.has(i)&&(o+=1);let s=new Set([...t,...n]).size;return s===0?0:o/s}function Et(r){return new Set(r.tags.filter(e=>!qo.has(e.toLowerCase())))}function Le(r){let e=r.metadata?.evidence;if(!e||typeof e!="object")return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,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 Bo(r){let e=Le(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function Uo(r){let e=Number(r.metadata?.confidence);return!Number.isFinite(e)||e<0?0:e>1?1:e}function Jo(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function Tt(r){let e=Le(r),t=Jo(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=Uo(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function Rt(r){let e=r.metadata?.topic;if(typeof e!="string")return;let t=e.normalize("NFKC").trim().toLowerCase();if(t)return t}function Qo(r,e){let t=Et(r),n=Et(e);for(let o of t)if(n.has(o))return!0;return!1}function Yo(r,e){if(e.id===r.id||e.projectId!==r.projectId||e.type!==r.type||e.metadata?.supersededBy)return!1;let t=Rt(r),n=Rt(e);return t&&n&&t===n||Qo(r,e)?!0:Ho(r.content,e.content)>=.6}function It(r){return r.type!=="rule"?!1:Le(r).userExplicit}function Zo(r,e){return!It(r)||!It(e)?!1:r.createdAt>=e.createdAt}var re=class{resolve(e,t){if(e.type!=="rule"&&e.type!=="decision")return{superseded:[],conflicts:[]};let n=[],o=[],s=Tt(e);for(let i of t){if(!Yo(e,i))continue;let a=Tt(i);if(s>a){n.push(i);continue}if(s<a){o.push(i);continue}if(Zo(e,i)){n.push(i);continue}if(!Bo(i)&&e.createdAt>=i.createdAt){n.push(i);continue}o.push(i)}return{superseded:n,conflicts:o}}findSuperseded(e,t){return this.resolve(e,t).superseded}};var Xo=new Set(["code","decision","rule","todo","summary"]);function es(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function Nt(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 ts(r,e){let t=Nt(e)-Nt(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 _t(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 Ot(r){let e=new Map;for(let o of r){if(!Xo.has(o.type)||o.metadata?.supersededBy)continue;let s=es(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(ts),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:_t(s.flatMap(c=>c.tags)),mergedSources:_t(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function Fe(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 rs(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function ns(r){let e=Fe(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 os(r){return Fe(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function ss(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 Lt(r,e=Date.now()){let t=50,n=[],o=Fe(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")),ss(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=rs(r,e)>=ns(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=os(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 is={critical:100,high:75,normal:50,temporary:20},as={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function Ft(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 De(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function cs(r){return!!r.metadata?.supersededBy}function Ke(r,e=Date.now()){return!De(r,e)&&!cs(r)}function D(r,e=Date.now()){if(!Ke(r,e))return 0;let t=is[r.importance];if(r.importance==="critical")return t;let n=as[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var ne=class{memories=new Map;conflicts=new re;remember(e){let t=new Date().toISOString(),n=At(e.content.trim()),o=e.importance??wt(e.type,n),s={id:us(),projectId:e.projectId,type:e.type,content:n,importance:o,importanceScore:vt(o),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??Ft(e.type,o,new Date(t)),metadata:te(e.metadata)},i=this.conflicts.resolve(s,this.list(e.projectId));if(i.superseded.length>0){s.metadata={...s.metadata??{},supersedes:i.superseded.map(a=>a.id)};for(let a of i.superseded)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}if(i.conflicts.length>0){let a=i.conflicts.map(c=>c.id);s.metadata={...s.metadata??{},conflictsWith:a};for(let c of i.conflicts){let u=Array.isArray(c.metadata?.conflictsWith)?c.metadata?.conflictsWith:[],l=new Set(u.filter(d=>typeof d=="string"));l.add(s.id),c.updatedAt=t,c.metadata={...c.metadata??{},conflictsWith:[...l]},this.memories.set(c.id,c)}}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let n of e){if(!n?.id)continue;let o=te(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=>Ke(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=D(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=D(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=Ot(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=Lt(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&&De(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 ls}from"node:crypto";import{existsSync as oe,mkdirSync as ds,readFileSync as ms,renameSync as ps,writeFileSync as fs}from"node:fs";import{basename as gs,dirname as se,join as K,parse as Wt,resolve as R}from"node:path";var Gt=".toolnet",ys="project.json";function hs(r){return ls("sha256").update(r).digest("hex").slice(0,16)}function ie(r){return K(r,Gt,ys)}function ks(r){return oe(ie(r))}function Dt(r,e){let t=R(r),n=Wt(t).root;for(;;){if(ks(t))return t;if(t===n||e&&t===R(e))break;let o=se(t);if(o===t)break;t=o}return null}function Kt(r){let e=R(r),t=Wt(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>oe(K(e,s))))return e;if(e===t)break;let o=se(e);if(o===e)break;e=o}return R(r)}function $t(r){let e;try{e=JSON.parse(ms(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:se(se(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 zt(r,e){let t=K(r,Gt);ds(t,{recursive:!0});let n=ie(r),o=`${n}.tmp-${process.pid}`;fs(o,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),ps(o,n)}function $e(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}var ae=class{findExisting(e=process.cwd()){let t=R(e),n=Kt(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>oe(K(n,c))),i=Dt(t,s?n:void 0);if(!i)return null;let a=$t(ie(i));return $e(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=R(e),n=Kt(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>oe(K(n,l))),i=Dt(t,s?n:void 0);if(i){let l=ie(i),d=$t(l);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),zt(i,d)),$e(d,i)}let a=new Date().toISOString(),c=gs(n),u={version:1,id:hs(n),name:c,remote:c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return zt(n,u),$e(u,n)}};function ze(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var ce=class{score(e,t){let n=ze(e),o=ze([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 qt(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 Vt(r){return D(r)/100}var Ss={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function Ht(r){return Ss[r]??.4}var ue=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 le=class{bm25=new ce;analyzer=new ue;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=qt(c),d=Vt(c),m=Ht(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 de=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 me=class{constructor(e){this.memory=e}memory;searcher=new le;contextBuilder=new de;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 pe=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 fe=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 xa}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Ma}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Bt}from"zod";var Ut={query:Bt.string(),limit:Bt.number().int().min(1).max(20).optional()};async function Jt(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 $}from"zod";import{createConnection as ws}from"node:net";import{homedir as bs}from"node:os";import{join as vs}from"node:path";function Qt(){return process.env.TOOLNET_SERVICE_SOCKET??vs(bs(),".toolnet","run","service.sock")}function Yt(r,e={}){let t=e.socketPath??Qt(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=ws({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(g){s(g instanceof Error?g:new Error(String(g)))}})}),i.once("error",d=>{u(()=>{s(d)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function ps(r,e={}){let t=await Gt({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 qt(r,e={}){try{return await ps(r,e)}catch{return null}}async function me(r,e={}){try{let t=await Gt({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var Vt={type:K.enum(["activity","decision","rule","todo","summary"]),content:K.string().min(1),tags:K.array(K.string()).optional(),importance:K.enum(["critical","high","normal","temporary"]).optional()};async function Ht(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)),me(r.project),t}import{z as fs}from"zod";var Bt={id:fs.string().min(1)};async function Ut(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&&me(r.project),{deleted:t}}import{z as gs}from"zod";var Jt={name:gs.string().min(1)};async function Qt(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as ys}from"zod";var pe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Yt=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,Yt)}callees(e,t){return this.relatedOutgoing(e,t,Yt)}dependents(e,t){return this.relatedIncoming(e,t,pe)}dependencies(e,t){return this.relatedOutgoing(e,t,pe)}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=>pe.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=>pe.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 w(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 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 Xt={symbolId:ys.string().min(1)};async function Zt(r,e){let t=w(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:b(t),count:o.length,callers:o.map(b)}}import{z as er}from"zod";var tr={query:er.string().min(1),limit:er.number().int().min(1).max(50).optional()};async function rr(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 nr}from"zod";function fe(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 or={query:nr.string().optional(),memoryLimit:nr.number().int().min(1).max(20).optional()};async function sr(r,e){let t=fe(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 ks}from"zod";var hs=["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"],A=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 hs){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 ir={reason:ks.string().optional()};async function ar(r,e){if(!r.storage)throw new Error("Storage unavailable");return new A(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function cr(r){if(!r.storage)throw new Error("Storage unavailable");return new A(r.storage).list(r.project.id)}import{z as Ss}from"zod";var ur={snapshotId:Ss.string().min(1)};async function lr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new A(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as $e}from"zod";var ge=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 g=u.depth+1;s.push({symbol:p,depth:g}),a.push({id:m,depth:g})}}return s}};var dr={symbolId:$e.string().min(1),direction:$e.enum(["callers","callees"]).optional(),depth:$e.number().int().min(1).max(10).optional()};async function mr(r,e){let t=new ge(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 pr}from"zod";var ye=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 fr={symbolId:pr.string().min(1),depth:pr.number().int().min(1).max(10).optional()};async function gr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new ye(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 yr(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:fe(r.graph,r.project.id)}}import{z as hr}from"zod";var bs=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),he=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>bs.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 kr={filePath:hr.string().min(1),direction:hr.enum(["dependencies","dependents","both"]).optional()};async function Sr(r,e){let n=new he(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)}}import{z as br}from"zod";var vr={query:br.string().min(1),limit:br.number().int().min(1).max(20).optional()};async function wr(r,e){return r.codeSemantic?{available:!0,results:(await r.codeSemantic.search(e.query,e.limit??8)).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,vectorScore:n.vectorScore,lexicalScore:n.lexicalScore,content:n.chunk.content}))}:{available:!1,results:[]}}import{z as ze}from"zod";import{execFile as vs}from"node:child_process";import{promisify as ws}from"node:util";var We=ws(vs);function Cs(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 xs(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function Cr(r){let e="";try{e=(await We("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 We("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:xs(o),ranges:Cs(a)})}try{let n=await We("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 Ms(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 ke=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=>Ms(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 Ps={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function As(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function xr(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var Se=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 g=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 g){if(d.has(S.from))continue;d.add(S.from);let E=this.graph.getSymbol(S.from);if(!E)continue;let L=p.depth+1,Po=`${l.symbol.id}:${E.id}`;s.set(Po,{symbol:E,relation:S.type,depth:L,sourceSymbolId:l.symbol.id});let Ao=Ps[S.type]??1;i+=Math.max(1,Ao-(L-1)),m.push({id:E.id,depth:L})}}}let a=[...s.values()].sort((l,d)=>l.depth-d.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(xr);return u.length===0&&u.push(...c.filter(l=>!xr(l)).slice(0,10)),{risk:As(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var be=class{constructor(e){this.graph=e;this.mapper=new ke(e),this.blast=new Se(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await Cr(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 Mr={mode:ze.enum(["git_diff","file"]).optional(),filePath:ze.string().optional(),depth:ze.number().int().min(1).max(10).optional()};async function Pr(r,e){let t=new be(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 js}from"zod";var Ar={symbol:js.string().min(1)};async function jr(r,e){let t=w(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:b(t),count:o.length,dependents:o.map(b)}}import{z as Ge}from"zod";var Er={from:Ge.string().min(1),to:Ge.string().min(1),maxDepth:Ge.number().int().min(1).max(30).optional()};async function Rr(r,e){let t=w(r,e.from),n=w(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: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 qe}from"zod";var Tr={symbol:qe.string().min(1),depth:qe.number().int().min(1).max(5).optional(),limit:qe.number().int().min(1).max(200).optional()};async function Ir(r,e){let t=w(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: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 He}from"zod";function Es(r){return r.replaceAll("\\","/").toLowerCase()}var ve=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=Es(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 Nr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Ve(r){return r.replaceAll("\\","/").toLowerCase()}function Rs(r){let e=Ve(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Ts(r){let e=Ve(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 ve(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Rs(i.filePath)||o.has(i.id)||Ts(i)||n.filter(p=>p.to===i.id&&Nr.has(p.type)).length>0)continue;let c=n.filter(p=>p.from===i.id&&Nr.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")),Ve(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 Or={confidence:He.enum(["high","medium","low","all"]).optional(),filePath:He.string().min(1).optional(),limit:He.number().int().min(1).max(500).optional()},_r={high:3,medium:2,low:1};async function Lr(r,e){let n=new we(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=_r[e.confidence];n=n.filter(a=>_r[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 Qe}from"zod";import{existsSync as Zs,readFileSync as ei}from"node:fs";import{join as ti}from"node:path";var Sl=new Int32Array(new SharedArrayBuffer(4));import{closeSync as xl,existsSync as Is,fsyncSync as Ml,mkdirSync as Pl,openSync as Al,readFileSync as Ns,renameSync as jl,writeFileSync as El}from"node:fs";import{dirname as Tl,join as _s}from"node:path";function Os(r){return _s(r.rootPath,".toolnet","work","current.json")}function Be(r){let e=Os(r);if(!Is(e))return null;try{let t=JSON.parse(Ns(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as Ls,mkdirSync as _l,readFileSync as Fs,renameSync as Ol,writeFileSync as Ll}from"node:fs";import{dirname as Dl,join as Ds}from"node:path";function Ks(r){return Ds(r.rootPath,".toolnet","context","session-origin.json")}function Ue(r){let e=Ks(r);if(!Ls(e))return null;try{let t=JSON.parse(Fs(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function $s(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function Ce(r){let e=$s(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 Us,mkdirSync as Ed,readFileSync as Js}from"node:fs";import{join as $r}from"node:path";Z();Je();var gd=new P;function Qs(r){return $r(r.rootPath,".toolnet","memory","checkpoints")}function Ys(r){return $r(Qs(r),"latest.json")}function Xs(r){let e=Ys(r);if(!Us(e))return null;try{let t=JSON.parse(Js(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function Wr(r){return Xs(r)}var ri={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}},ni={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function oi(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 si(r){let e=ti(r.rootPath,".toolnet","work","handoff-latest.json");if(!Zs(e))return null;try{let n=JSON.parse(ei(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function ii(r){let e=Wr(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 ai(r){let e=si(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 ci(r){let e=Ue(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 ui(r){let e=Be(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 li(r,e){let t=ri[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+ni[n.source]+Math.max(0,5-o*.01)}))}function di(r){let e=new Map;for(let t of r){let n=`${t.kind}:${oi(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function xe(r,e,t={}){let n=Ce(e),o=[...ii(r),...ai(r),...ci(r),...ui(r)],s=di(li(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 zr={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"},Gr=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],mi={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:Gr};function pi(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 fi(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 gi(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 qr(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function yi(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,qr(n));for(let s of o)t.push(`${zr[n]}: ${s.value}`)}return t.join(`
9
- `)}function hi(r,e){let t=mi[e]??Gr,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,qr(o));for(let i of s)n.push(`${zr[o]}: ${i.value}`)}return n.join(`
10
- `)}function Vr(r,e){let t=xe(r,e,{maxFacts:32,maxChars:6400}),n=gi(fi(t.facts)),o=pi(e)?yi(n,["todo","task","next_action","file"]):hi(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 ki,mkdirSync as Si,readFileSync as bi,renameSync as vi,rmSync as wi,writeFileSync as Ci}from"node:fs";import{join as Hr}from"node:path";var xi=720*60*1e3;function Br(r){return Hr(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function z(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function Mi(r){let e=z(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 Pi(r){if(Mi(r))return!1;let e=z(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 Ai(r,e,t){let n=Br(r);if(!ki(n))return null;try{let o=JSON.parse(bi(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 ji(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,z(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function Ei(r,e){let t=Br(r),n=Hr(r.rootPath,".toolnet","context");Si(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{Ci(o,JSON.stringify(e,null,2)+`
11
- `,{encoding:"utf8",mode:384}),vi(o,t)}finally{wi(o,{force:!0})}}function Ri(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
12
- `)}function Ti(r,e){return r.priorFocus.find(t=>t.kind===e)?.value}function Ur(r){if(!r.usedPriorFocus||r.currentIntent!=="summary"||r.priorFocus.length===0)return null;let e=z(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=Ti(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 Ii(r){let e=z(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 Jr(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??xi,s=Ai(r,n,o),i=!!(s&&s.focus.length>0&&Pi(e)&&!Ii(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",Ri(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=Ce(e),l=xe(r,a,{maxFacts:8,maxChars:1800}).facts.map(m=>({kind:m.kind,value:m.value,source:m.source})),d=ji(i&&s?[...l,...s.focus]:l);return Ei(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 Ni,readFileSync as _i}from"node:fs";import{join as Oi}from"node:path";function j(r){return!!r?.trim()}function Qr(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 Yr={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 T(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 I(r){return r.length>0?r.map(e=>`- ${e}`).join(`
14
- `):"- none"}function Li(r,e){return r.length<=e?r:[r.slice(0,e).trimEnd(),"","[Structured handoff truncated]"].join(`
15
- `)}function Xr(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 Fi(r,e="normal"){let t=Yr[e],n=T([`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=T([...r.completed.phases.map(u=>`Phase: ${u}`),...r.completed.tasks.map(u=>`Task: ${u}`)]).slice(0,t.completed),s=T([`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=T([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=T(r.blockers).slice(0,t.blockers),c=T([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 Di(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",I(r.currentState),"","COMPLETED",I(r.completed),"","EVIDENCE",I(r.evidence),"","FILES_TOUCHED",I(r.filesTouched),"","BLOCKERS",I(r.blockers),"","NEXT_ACTION",I(r.nextAction)].join(`
16
- `)}function Zr(r,e="normal"){let t=Oi(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ni(t))return null;try{let o=JSON.parse(_i(t,"utf8")).continuity;if(!o||o.schema!=="toolnet.handoff.v2"||o.version!==2)return null;let s=Fi(o,e),i=Qr(o),a=Li(Di(s,e,i),Yr[e].maxChars);return{detail:e,data:s,quality:i,text:a}}catch{return null}}function Ki(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}var $i=[/\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],Wi=[/\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],zi=[/\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 Gi(r){let e=0;for(let t of Wi)t.test(r)&&(e+=1);return e}function en(r,e){let t=Ki(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=$i.some(a=>a.test(t)),s=zi.some(a=>a.test(t)),i=Gi(t);return!!(o&&i>=1||s&&i>=2||i>=4)}var rn={question:Qe.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:Qe.enum(["local"]).optional().describe("Returns deterministic local memory only. No external AI is used."),detail:Qe.enum(["compact","normal","benchmark"]).optional().describe("Handoff detail level. compact=minimal, normal=standard, benchmark=deep evidence/files/tests for agent takeover.")};function tn(r,e,t,n,o){if(!en(e,t))return{answer:n};let s=Xr(e,o),i=Zr(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 nn(r,e){let t=Jr(r.project,e.question),n=Ur(t);if(n)return{...tn(r,t.originalQuestion,String(n.intent),n.answer,e.detail),mode:"local",usedAi:!1,source:n.source,intent:n.intent};let o=Vr(r.project,t.originalQuestion),s=tn(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 dn}from"zod";import{chmodSync as am,existsSync as on,mkdirSync as cm,readFileSync as sn,renameSync as um,writeFileSync as lm}from"node:fs";import{dirname as mm,join as G}from"node:path";var an="toolnet.context-offload.v1",qi="toolnet.context-offload-asset.v1";function cn(r){return G(r,".toolnet","offload")}function un(r){return G(cn(r),"assets")}function Vi(r){return G(cn(r),"graph.json")}function Ye(){return{schema:an,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Hi(r){let e=Vi(r);if(!on(e))return Ye();try{let t=JSON.parse(sn(e,"utf8"));return t.schema!==an||t.version!==1||!Array.isArray(t.nodes)?Ye():t}catch{return Ye()}}function Bi(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&&on(G(un(r),`${t}.json`)))return t;let n=Hi(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 ln(r,e,t=6e3){let n=Bi(r,e),o=sn(G(un(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==qi||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 mn={assetId:dn.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:dn.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function pn(r,e){return ln(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as yn}from"zod";import{chmodSync as km,existsSync as Ui,mkdirSync as Sm,readFileSync as Ji,readdirSync as Qi,renameSync as bm,statSync as Yi,writeFileSync as vm}from"node:fs";import{join as fn}from"node:path";var Xi="toolnet.skill-memory.v1";function Zi(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 ea(r){return fn(r.rootPath,".toolnet","memory","skills")}function ta(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===Xi&&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 ra(r){let e=ea(r);if(!Ui(e))return[];if(!Yi(e).isDirectory())return[];let t=[];for(let n of Qi(e)){if(!n.endsWith(".json"))continue;let o=fn(e,n);try{let s=JSON.parse(Ji(o,"utf8"));ta(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 na(r){return Zi(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function oa(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 na(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 gn(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return ra(r).map(o=>({...o,score:oa(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 hn={query:yn.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:yn.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function kn(r,e){let t=gn(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 Rn}from"zod";var Sn="wiki/state.v1.json";function sa(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function ia(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(Sn);if(!e){let t=sa(this.project);return await this.save(t),t}return ia(e,this.project)}async save(e){await this.storage.put(Sn,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as wn}from"node:crypto";var k=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function q(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 V(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 bn(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(V(n))}return q(e)}function aa(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function vn(r){return{id:`revision-${wn()}`,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 R(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:q(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 R([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=V(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new k(`Wiki page not found: ${e}`,404);return R(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=V(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-${wn()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:q(e.tags??[]),links:bn(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(vn(a)),R(a)})}async updatePage(e,t){return this.mutate(n=>{let o=V(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=bn(s.content)),t.tags!==void 0&&(s.tags=q(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(vn(s)),R(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return R(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 R(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=q(aa(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(g=>g.toLowerCase()),p=0;for(let g of o)u===g&&(p+=12),c===g&&(p+=10),c.includes(g)&&(p+=6),u.includes(g)&&(p+=5),m.some(S=>S===g)?p+=5:m.some(S=>S.includes(g))&&(p+=3),l.includes(g)&&(p+=2),d.includes(g)&&(p+=1);p>0&&i.push({page:R(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 ca,randomUUID as Cn}from"node:crypto";var xn="wiki/governance.v1.json",jn="toolnet.knowledge-governance.v1",Mn=500,H={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function ua(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function Xe(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Pn(r){return ca("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function la(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 da(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),ua(e)}function An(r){let e=new Date().toISOString();return{schema:jn,version:1,projectId:r,policy:{...H},reviews:[],audit:[],createdAt:e,updatedAt:e}}function En(r){let e=r.autoApproveThreshold??H.autoApproveThreshold,t=r.criticalApproveThreshold??H.criticalApproveThreshold,n=r.staleAfterDays??H.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 B=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(xn);if(!e){let t=An(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==jn||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:En(t.policy??H)}}catch{let t=An(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(xn,JSON.stringify(e,null,2),"application/json")}},U=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:Cn(),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>Mn&&(e.audit=e.audit.slice(-Mn))}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=En({...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=da(e),s=Xe(e.title),i=t.filter(l=>l.slug!==e.slug&&Xe(l.title)===s&&Pn(l.content)!==Pn(e.content)).map(l=>l.slug),a=la(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:Cn(),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=Xe(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 Tn={query:Rn.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:Rn.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function In(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 ma}from"zod";var Nn={page:ma.string().min(1).max(200).describe("Wiki page slug or page id.")};async function _n(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 pa}from"zod";var On={includePending:pa.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function Ln(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new U(new B(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 Fn={};function Dn(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 ya=["# 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 ha(r){let e=new fa({name:"toolnet-memory",version:"0.1.0"},{instructions:ya});return e.tool("memory_search","Search relevant long-term memory for the current project.",$t,async t=>h(await Wt(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Vt,async t=>h(await Ht(r,t))),e.tool("memory_forget","Delete a memory by id.",Bt,async t=>h(await Ut(r,t))),e.tool("find_symbol","Find code symbols by exact name.",Jt,async t=>h(await Qt(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Xt,async t=>h(await Zt(r,t))),e.tool("code_search","Search indexed code symbols and files.",tr,async t=>h(await rr(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",or,async t=>h(await sr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",dr,async t=>h(await mr(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",fr,async t=>h(await gr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>h(await yr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",kr,async t=>h(await Sr(r,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",vr,async t=>h(await wr(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",ir,async t=>h(await ar(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>h(await cr(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",ur,async t=>h(await lr(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.",Mr,async t=>h(await Pr(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Ar,async t=>h(await jr(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Er,async t=>h(await Rr(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Tr,async t=>h(await Ir(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Or,async t=>h(await Lr(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 direct state facts and mode=ai for composite or ambiguous continuity questions.","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(" "),rn,async t=>h(await nn(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(" "),mn,async t=>h(await pn(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(" "),hn,async t=>h(await kn(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(" "),Tn,async t=>h(await In(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(" "),Nn,async t=>h(await _n(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(" "),Fn,async()=>h(Dn(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(" "),On,async t=>h(await Ln(r,t))),e}async function Kn(r){let e=ha(r),t=new ga;await e.connect(t)}function $n(){return new Date().toISOString()}function M(r){r.lastUpdatedAt=$n()}function Me(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:$n()}}function Wn(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",M(r)}function zn(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,M(r)}function Pe(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,M(r))}function Ae(r,e){r.dependencies[e].attempts+=1,M(r)}function je(r){r.metrics.retryCount+=1,M(r)}function N(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 J(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),M(r)}function Gn(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 qn(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],M(r)}async function Ee(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 Co(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function Qa(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function Ya(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 xo(r){let e=r.runtime??Me(Date.now());r.runtime=e,zn(e);let t=Co(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=Qa(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await qt(r.project,{timeoutMs:Co(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});o&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(o.memory),N(e,"memory")),e.dependencies.graph.state!=="ready"&&(o.graph&&r.graph.import(o.graph.symbols,o.graph.edges),N(e,"graph")))}try{let[{loadConfig:o},s]=await Promise.all([Promise.resolve().then(()=>(Je(),Kr)),Promise.resolve().then(()=>(go(),fo))]),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",Pe(e,"memory");try{let p=await Ee(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Ae(e,"memory")},onRetry:()=>{je(e)}});r.memory.importRecords(p),N(e,"memory")}catch(p){J(e,"memory",p)}})(),m=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Pe(e,"graph");try{let p=await Ee(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Ae(e,"graph")},onRetry:()=>{je(e)}});p&&r.graph.import(p.symbols,p.edges),N(e,"graph")}catch(p){J(e,"graph",p)}})();if(await Promise.all([d,m]),e.dependencies.semantic.state!=="ready"){Pe(e,"semantic");try{let{SemanticCodeEngine:p}=await Promise.resolve().then(()=>(wo(),vo)),g=new p({projectId:r.project.id,rootPath:r.project.rootPath,storage:u,graph:r.graph});await Ee(()=>g.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{Ae(e,"semantic")},onRetry:()=>{je(e)}}),r.codeSemantic=g,N(e,"semantic")}catch(p){J(e,"semantic",p)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&J(e,s,o)}return Gn(e),Ya(r)}function Mo(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function Xa(){let r=Date.now(),e=new ne().detect(),t=new te,n=new ue(t),o=new le,s=new de(o),i=Me(r),a={project:e,memory:t,retrieval:n,graph:o,references:s,runtime:i};await Kn(a),Wn(i);let c=async()=>{try{await xo(a),i.phase==="degraded"&&setTimeout(()=>{c()},Mo()).unref()}catch(u){qn(i,u),setTimeout(()=>{i.phase="degraded",c()},Mo()).unref()}};c()}Xa().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(g){s(g instanceof Error?g:new Error(String(g)))}})}),i.once("error",d=>{u(()=>{s(d)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function Cs(r,e={}){let t=await Yt({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 Zt(r,e={}){try{return await Cs(r,e)}catch{return null}}async function ge(r,e={}){try{let t=await Yt({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var Xt={type:$.enum(["activity","decision","rule","todo","summary"]),content:$.string().min(1),tags:$.array($.string()).optional(),importance:$.enum(["critical","high","normal","temporary"]).optional()};async function er(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)),ge(r.project),t}import{z as xs}from"zod";var tr={id:xs.string().min(1)};async function rr(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&&ge(r.project),{deleted:t}}import{z as Ms}from"zod";var nr={name:Ms.string().min(1)};async function or(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as Ps}from"zod";var ye=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),sr=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,sr)}callees(e,t){return this.relatedOutgoing(e,t,sr)}dependents(e,t){return this.relatedIncoming(e,t,ye)}dependencies(e,t){return this.relatedOutgoing(e,t,ye)}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=>ye.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=>ye.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 w(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 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:Ps.string().min(1)};async function ar(r,e){let t=w(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:b(t),count:o.length,callers:o.map(b)}}import{z as cr}from"zod";var ur={query:cr.string().min(1),limit:cr.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 dr}from"zod";function he(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 mr={query:dr.string().optional(),memoryLimit:dr.number().int().min(1).max(20).optional()};async function pr(r,e){let t=he(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 js}from"zod";var As=["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"],A=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 As){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 fr={reason:js.string().optional()};async function gr(r,e){if(!r.storage)throw new Error("Storage unavailable");return new A(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function yr(r){if(!r.storage)throw new Error("Storage unavailable");return new A(r.storage).list(r.project.id)}import{z as Es}from"zod";var hr={snapshotId:Es.string().min(1)};async function kr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new A(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as We}from"zod";var ke=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 g=u.depth+1;s.push({symbol:p,depth:g}),a.push({id:m,depth:g})}}return s}};var Sr={symbolId:We.string().min(1),direction:We.enum(["callers","callees"]).optional(),depth:We.number().int().min(1).max(10).optional()};async function br(r,e){let t=new ke(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 vr}from"zod";var Se=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 wr={symbolId:vr.string().min(1),depth:vr.number().int().min(1).max(10).optional()};async function Cr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new Se(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 xr(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:he(r.graph,r.project.id)}}import{z as Mr}from"zod";var Ts=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),be=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>Ts.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 Pr={filePath:Mr.string().min(1),direction:Mr.enum(["dependencies","dependents","both"]).optional()};async function Ar(r,e){let n=new be(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)}}import{z as jr}from"zod";var Er={query:jr.string().min(1),limit:jr.number().int().min(1).max(20).optional()};async function Tr(r,e){return r.codeSemantic?{available:!0,results:(await r.codeSemantic.search(e.query,e.limit??8)).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,vectorScore:n.vectorScore,lexicalScore:n.lexicalScore,content:n.chunk.content}))}:{available:!1,results:[]}}import{z as qe}from"zod";import{execFile as Rs}from"node:child_process";import{promisify as Is}from"node:util";var Ge=Is(Rs);function Ns(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 _s(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function Rr(r){let e="";try{e=(await Ge("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 Ge("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:_s(o),ranges:Ns(a)})}try{let n=await Ge("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 Os(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 ve=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=>Os(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 Ls={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Fs(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function Ir(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var we=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 g=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 g){if(d.has(S.from))continue;d.add(S.from);let E=this.graph.getSymbol(S.from);if(!E)continue;let F=p.depth+1,_o=`${l.symbol.id}:${E.id}`;s.set(_o,{symbol:E,relation:S.type,depth:F,sourceSymbolId:l.symbol.id});let Oo=Ls[S.type]??1;i+=Math.max(1,Oo-(F-1)),m.push({id:E.id,depth:F})}}}let a=[...s.values()].sort((l,d)=>l.depth-d.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(Ir);return u.length===0&&u.push(...c.filter(l=>!Ir(l)).slice(0,10)),{risk:Fs(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var Ce=class{constructor(e){this.graph=e;this.mapper=new ve(e),this.blast=new we(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await Rr(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 Nr={mode:qe.enum(["git_diff","file"]).optional(),filePath:qe.string().optional(),depth:qe.number().int().min(1).max(10).optional()};async function _r(r,e){let t=new Ce(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 Ds}from"zod";var Or={symbol:Ds.string().min(1)};async function Lr(r,e){let t=w(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:b(t),count:o.length,dependents:o.map(b)}}import{z as Ve}from"zod";var Fr={from:Ve.string().min(1),to:Ve.string().min(1),maxDepth:Ve.number().int().min(1).max(30).optional()};async function Dr(r,e){let t=w(r,e.from),n=w(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: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 He}from"zod";var Kr={symbol:He.string().min(1),depth:He.number().int().min(1).max(5).optional(),limit:He.number().int().min(1).max(200).optional()};async function $r(r,e){let t=w(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: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 Ue}from"zod";function Ks(r){return r.replaceAll("\\","/").toLowerCase()}var xe=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=Ks(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 zr=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function Be(r){return r.replaceAll("\\","/").toLowerCase()}function $s(r){let e=Be(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function zs(r){let e=Be(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var Me=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=new Set(new xe(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||$s(i.filePath)||o.has(i.id)||zs(i)||n.filter(p=>p.to===i.id&&zr.has(p.type)).length>0)continue;let c=n.filter(p=>p.from===i.id&&zr.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")),Be(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 Gr={confidence:Ue.enum(["high","medium","low","all"]).optional(),filePath:Ue.string().min(1).optional(),limit:Ue.number().int().min(1).max(500).optional()},Wr={high:3,medium:2,low:1};async function qr(r,e){let n=new Me(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=Wr[e.confidence];n=n.filter(a=>Wr[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 Ze}from"zod";import{existsSync as ui,readFileSync as li}from"node:fs";import{join as di}from"node:path";var Rl=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Ll,existsSync as Ws,fsyncSync as Fl,mkdirSync as Dl,openSync as Kl,readFileSync as Gs,renameSync as $l,writeFileSync as zl}from"node:fs";import{dirname as Gl,join as qs}from"node:path";function Vs(r){return qs(r.rootPath,".toolnet","work","current.json")}function Je(r){let e=Vs(r);if(!Ws(e))return null;try{let t=JSON.parse(Gs(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as Hs,mkdirSync as Bl,readFileSync as Bs,renameSync as Ul,writeFileSync as Jl}from"node:fs";import{dirname as Yl,join as Us}from"node:path";function Js(r){return Us(r.rootPath,".toolnet","context","session-origin.json")}function Qe(r){let e=Js(r);if(!Hs(e))return null;try{let t=JSON.parse(Bs(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function Qs(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function Pe(r){let e=Qs(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 oi,mkdirSync as Wd,readFileSync as si}from"node:fs";import{join as Ur}from"node:path";ee();Ye();var jd=new P;function ii(r){return Ur(r.rootPath,".toolnet","memory","checkpoints")}function ai(r){return Ur(ii(r),"latest.json")}function ci(r){let e=ai(r);if(!oi(e))return null;try{let t=JSON.parse(si(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function Jr(r){return ci(r)}var mi={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}},pi={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function fi(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 gi(r){let e=di(r.rootPath,".toolnet","work","handoff-latest.json");if(!ui(e))return null;try{let n=JSON.parse(li(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function yi(r){let e=Jr(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 hi(r){let e=gi(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 ki(r){let e=Qe(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 Si(r){let e=Je(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 bi(r,e){let t=mi[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+pi[n.source]+Math.max(0,5-o*.01)}))}function vi(r){let e=new Map;for(let t of r){let n=`${t.kind}:${fi(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function Ae(r,e,t={}){let n=Pe(e),o=[...yi(r),...hi(r),...ki(r),...Si(r)],s=vi(bi(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 Qr={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"},Yr=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],wi={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:Yr};function Ci(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 xi(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 Mi(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 Zr(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function Pi(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,Zr(n));for(let s of o)t.push(`${Qr[n]}: ${s.value}`)}return t.join(`
9
+ `)}function Ai(r,e){let t=wi[e]??Yr,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,Zr(o));for(let i of s)n.push(`${Qr[o]}: ${i.value}`)}return n.join(`
10
+ `)}function Xr(r,e){let t=Ae(r,e,{maxFacts:32,maxChars:6400}),n=Mi(xi(t.facts)),o=Ci(e)?Pi(n,["todo","task","next_action","file"]):Ai(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 ji,mkdirSync as Ei,readFileSync as Ti,renameSync as Ri,rmSync as Ii,writeFileSync as Ni}from"node:fs";import{join as en}from"node:path";var _i=720*60*1e3;function tn(r){return en(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function G(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function Oi(r){let e=G(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 Li(r){if(Oi(r))return!1;let e=G(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 Fi(r,e,t){let n=tn(r);if(!ji(n))return null;try{let o=JSON.parse(Ti(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 Di(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,G(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function Ki(r,e){let t=tn(r),n=en(r.rootPath,".toolnet","context");Ei(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{Ni(o,JSON.stringify(e,null,2)+`
11
+ `,{encoding:"utf8",mode:384}),Ri(o,t)}finally{Ii(o,{force:!0})}}function $i(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
12
+ `)}function zi(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=G(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=zi(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 Wi(r){let e=G(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 nn(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??_i,s=Fi(r,n,o),i=!!(s&&s.focus.length>0&&Li(e)&&!Wi(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",$i(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=Pe(e),l=Ae(r,a,{maxFacts:8,maxChars:1800}).facts.map(m=>({kind:m.kind,value:m.value,source:m.source})),d=Di(i&&s?[...l,...s.focus]:l);return Ki(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 Gi,readFileSync as qi}from"node:fs";import{join as Vi}from"node:path";function j(r){return!!r?.trim()}function on(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 sn={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 I(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 N(r){return r.length>0?r.map(e=>`- ${e}`).join(`
14
+ `):"- none"}function Hi(r,e){return r.length<=e?r:[r.slice(0,e).trimEnd(),"","[Structured handoff truncated]"].join(`
15
+ `)}function an(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 Bi(r,e="normal"){let t=sn[e],n=I([`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=I([...r.completed.phases.map(u=>`Phase: ${u}`),...r.completed.tasks.map(u=>`Task: ${u}`)]).slice(0,t.completed),s=I([`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=I([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=I(r.blockers).slice(0,t.blockers),c=I([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 Ui(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",N(r.currentState),"","COMPLETED",N(r.completed),"","EVIDENCE",N(r.evidence),"","FILES_TOUCHED",N(r.filesTouched),"","BLOCKERS",N(r.blockers),"","NEXT_ACTION",N(r.nextAction)].join(`
16
+ `)}function cn(r,e="normal"){let t=Vi(r.rootPath,".toolnet","work","handoff-latest.json");if(!Gi(t))return null;try{let o=JSON.parse(qi(t,"utf8")).continuity;if(!o||o.schema!=="toolnet.handoff.v2"||o.version!==2)return null;let s=Bi(o,e),i=on(o),a=Hi(Ui(s,e,i),sn[e].maxChars);return{detail:e,data:s,quality:i,text:a}}catch{return null}}function Ji(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}var Qi=[/\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],Yi=[/\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],Zi=[/\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 Xi(r){let e=0;for(let t of Yi)t.test(r)&&(e+=1);return e}function un(r,e){let t=Ji(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=Qi.some(a=>a.test(t)),s=Zi.some(a=>a.test(t)),i=Xi(t);return!!(o&&i>=1||s&&i>=2||i>=4)}var dn={question:Ze.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:Ze.enum(["local"]).optional().describe("Returns deterministic local memory only. No external AI is used."),detail:Ze.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(!un(e,t))return{answer:n};let s=an(e,o),i=cn(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 mn(r,e){let t=nn(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=Xr(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 Sn}from"zod";import{chmodSync as bm,existsSync as pn,mkdirSync as vm,readFileSync as fn,renameSync as wm,writeFileSync as Cm}from"node:fs";import{dirname as Mm,join as q}from"node:path";var gn="toolnet.context-offload.v1",ea="toolnet.context-offload-asset.v1";function yn(r){return q(r,".toolnet","offload")}function hn(r){return q(yn(r),"assets")}function ta(r){return q(yn(r),"graph.json")}function Xe(){return{schema:gn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function ra(r){let e=ta(r);if(!pn(e))return Xe();try{let t=JSON.parse(fn(e,"utf8"));return t.schema!==gn||t.version!==1||!Array.isArray(t.nodes)?Xe():t}catch{return Xe()}}function na(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&&pn(q(hn(r),`${t}.json`)))return t;let n=ra(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 kn(r,e,t=6e3){let n=na(r,e),o=fn(q(hn(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==ea||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 bn={assetId:Sn.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:Sn.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function vn(r,e){return kn(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as xn}from"zod";import{chmodSync as Rm,existsSync as oa,mkdirSync as Im,readFileSync as sa,readdirSync as ia,renameSync as Nm,statSync as aa,writeFileSync as _m}from"node:fs";import{join as wn}from"node:path";var ca="toolnet.skill-memory.v1";function ua(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 la(r){return wn(r.rootPath,".toolnet","memory","skills")}function da(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===ca&&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 ma(r){let e=la(r);if(!oa(e))return[];if(!aa(e).isDirectory())return[];let t=[];for(let n of ia(e)){if(!n.endsWith(".json"))continue;let o=wn(e,n);try{let s=JSON.parse(sa(o,"utf8"));da(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 pa(r){return ua(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function fa(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 pa(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 Cn(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return ma(r).map(o=>({...o,score:fa(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 Mn={query:xn.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:xn.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function Pn(r,e){let t=Cn(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 Dn}from"zod";var An="wiki/state.v1.json";function ga(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function ya(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(An);if(!e){let t=ga(this.project);return await this.save(t),t}return ya(e,this.project)}async save(e){await this.storage.put(An,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as Tn}from"node:crypto";var k=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function V(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 H(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 jn(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(H(n))}return V(e)}function ha(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function En(r){return{id:`revision-${Tn()}`,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 T(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:V(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 T([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=H(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new k(`Wiki page not found: ${e}`,404);return T(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=H(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-${Tn()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:V(e.tags??[]),links:jn(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(En(a)),T(a)})}async updatePage(e,t){return this.mutate(n=>{let o=H(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=jn(s.content)),t.tags!==void 0&&(s.tags=V(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(En(s)),T(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return T(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 T(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=V(ha(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(g=>g.toLowerCase()),p=0;for(let g of o)u===g&&(p+=12),c===g&&(p+=10),c.includes(g)&&(p+=6),u.includes(g)&&(p+=5),m.some(S=>S===g)?p+=5:m.some(S=>S.includes(g))&&(p+=3),l.includes(g)&&(p+=2),d.includes(g)&&(p+=1);p>0&&i.push({page:T(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 ka,randomUUID as Rn}from"node:crypto";var In="wiki/governance.v1.json",Ln="toolnet.knowledge-governance.v1",Nn=500,B={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Sa(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function et(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function _n(r){return ka("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ba(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 va(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),Sa(e)}function On(r){let e=new Date().toISOString();return{schema:Ln,version:1,projectId:r,policy:{...B},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Fn(r){let e=r.autoApproveThreshold??B.autoApproveThreshold,t=r.criticalApproveThreshold??B.criticalApproveThreshold,n=r.staleAfterDays??B.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 U=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(In);if(!e){let t=On(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==Ln||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:Fn(t.policy??B)}}catch{let t=On(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(In,JSON.stringify(e,null,2),"application/json")}},J=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:Rn(),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>Nn&&(e.audit=e.audit.slice(-Nn))}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=Fn({...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=va(e),s=et(e.title),i=t.filter(l=>l.slug!==e.slug&&et(l.title)===s&&_n(l.content)!==_n(e.content)).map(l=>l.slug),a=ba(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:Rn(),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=et(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 Kn={query:Dn.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:Dn.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function $n(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 wa}from"zod";var zn={page:wa.string().min(1).max(200).describe("Wiki page slug or page id.")};async function Wn(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 Ca}from"zod";var Gn={includePending:Ca.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function qn(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new J(new U(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 Vn={};function Hn(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 Pa=["# 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 Aa(r){let e=new xa({name:"toolnet-memory",version:"0.1.0"},{instructions:Pa});return e.tool("memory_search","Search relevant long-term memory for the current project.",Ut,async t=>h(await Jt(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Xt,async t=>h(await er(r,t))),e.tool("memory_forget","Delete a memory by id.",tr,async t=>h(await rr(r,t))),e.tool("find_symbol","Find code symbols by exact name.",nr,async t=>h(await or(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",ir,async t=>h(await ar(r,t))),e.tool("code_search","Search indexed code symbols and files.",ur,async t=>h(await lr(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",mr,async t=>h(await pr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Sr,async t=>h(await br(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",wr,async t=>h(await Cr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>h(await xr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Pr,async t=>h(await Ar(r,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Er,async t=>h(await Tr(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",fr,async t=>h(await gr(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>h(await yr(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",hr,async t=>h(await kr(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.",Nr,async t=>h(await _r(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",Or,async t=>h(await Lr(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",Fr,async t=>h(await Dr(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",Kr,async t=>h(await $r(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",Gr,async t=>h(await qr(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 direct state facts and mode=ai for composite or ambiguous continuity questions.","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(" "),dn,async t=>h(await mn(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(" "),bn,async t=>h(await vn(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(" "),Mn,async t=>h(await Pn(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(" "),Kn,async t=>h(await $n(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(" "),zn,async t=>h(await Wn(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(" "),Vn,async()=>h(Hn(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(" "),Gn,async t=>h(await qn(r,t))),e}async function Bn(r){let e=Aa(r),t=new Ma;await e.connect(t)}function Un(){return new Date().toISOString()}function M(r){r.lastUpdatedAt=Un()}function je(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:Un()}}function Jn(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",M(r)}function Qn(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,M(r)}function Ee(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,M(r))}function Te(r,e){r.dependencies[e].attempts+=1,M(r)}function Re(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 Q(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),M(r)}function Yn(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 Zn(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],M(r)}async function Ie(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 Ro(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function ic(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function ac(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 Io(r){let e=r.runtime??je(Date.now());r.runtime=e,Qn(e);let t=Ro(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=ic(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await Zt(r.project,{timeoutMs:Ro(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(()=>(Ye(),Br)),Promise.resolve().then(()=>(Co(),wo))]),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",Ee(e,"memory");try{let p=await Ie(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Te(e,"memory")},onRetry:()=>{Re(e)}});r.memory.importRecords(p),_(e,"memory")}catch(p){Q(e,"memory",p)}})(),m=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Ee(e,"graph");try{let p=await Ie(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{Te(e,"graph")},onRetry:()=>{Re(e)}});p&&r.graph.import(p.symbols,p.edges),_(e,"graph")}catch(p){Q(e,"graph",p)}})();if(await Promise.all([d,m]),e.dependencies.semantic.state!=="ready"){Ee(e,"semantic");try{let{SemanticCodeEngine:p}=await Promise.resolve().then(()=>(To(),Eo)),g=new p({projectId:r.project.id,rootPath:r.project.rootPath,storage:u,graph:r.graph});await Ie(()=>g.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{Te(e,"semantic")},onRetry:()=>{Re(e)}}),r.codeSemantic=g,_(e,"semantic")}catch(p){Q(e,"semantic",p)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&Q(e,s,o)}return Yn(e),ac(r)}function No(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function cc(){let r=Date.now(),e=new ae().detect(),t=new ne,n=new me(t),o=new pe,s=new fe(o),i=je(r),a={project:e,memory:t,retrieval:n,graph:o,references:s,runtime:i};await Bn(a),Jn(i);let c=async()=>{try{await Io(a),i.phase==="degraded"&&setTimeout(()=>{c()},No()).unref()}catch(u){Zn(i,u),setTimeout(()=>{i.phase="degraded",c()},No()).unref()}};c()}cc().catch(r=>{console.error(r),process.exit(1)});