toolnet-memory 0.3.14 → 0.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +0 -1
  2. package/.release-target +1 -1
  3. package/README.md +182 -6
  4. package/bin/toolnet-memory +5 -0
  5. package/bundle/agy-hook.js +71 -71
  6. package/bundle/agy.js +65 -65
  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 +29 -28
  12. package/bundle/codex.js +77 -77
  13. package/bundle/context-runtime.js +44 -43
  14. package/bundle/context.js +15 -15
  15. package/bundle/continuity-certify.js +13 -13
  16. package/bundle/copilot-hook.js +88 -86
  17. package/bundle/copilot.js +4 -4
  18. package/bundle/cursor-hook.js +88 -86
  19. package/bundle/cursor.js +4 -4
  20. package/bundle/doctor.js +4 -4
  21. package/bundle/full-index.js +21 -21
  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 +64 -63
  26. package/bundle/grok.js +5 -5
  27. package/bundle/handoff-refresh.js +10 -10
  28. package/bundle/help-cli.js +3 -3
  29. package/bundle/impact.js +4 -4
  30. package/bundle/incremental.js +5 -4
  31. package/bundle/init.js +38 -37
  32. package/bundle/integration-status.js +4 -4
  33. package/bundle/kiro-hook.js +93 -92
  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 +84 -84
  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 +21 -3
  48. package/release-manifest.json +104 -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 cs=Object.defineProperty;var g=(r,e,t)=>()=>{if(t)throw t[0];try{return r&&(e=r(r=0)),e}catch(n){throw t=[n],n}};var Be=(r,e)=>{for(var t in e)cs(r,t,{get:e[t],enumerable:!0})};function Kt(r){return r.normalize("NFKC").trim().toLowerCase()}function ms(r){if(r.length===0)return 0;let e=new Map;for(let n of r)e.set(n,(e.get(n)??0)+1);let t=0;for(let n of e.values()){let o=n/r.length;t-=o*Math.log2(o)}return t}function ps(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function fs(r,e,t){let n=r.slice(Math.max(0,e-48),e),o=r.slice(t,Math.min(r.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${n} ${o}`)}function gs(r,e){return r.start<e.end&&e.start<r.end}function $t(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var ls,ds,ae,zt=g(()=>{"use strict";ls=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],ds=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);ae=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=Kt(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of ls){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of e.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||t.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let n=$t(t),o=[];for(let s of n)o.some(i=>gs(i,s))||o.push(s);return $t(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=Kt(e);return ds.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],n=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(n)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||ps(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||fs(e,o.index,o.index+s.length)&&(ms(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}}});var P,ce=g(()=>{"use strict";zt();P=class{scanner;constructor(e={}){this.scanner=new ae(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let n=e,o=[...t].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),n=n.slice(0,i.start)+`[REDACTED:${i.type}]`+n.slice(i.end);return{text:n,redacted:t.length,secretTypes:[...s].sort()}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[n,o]of Object.entries(e)){let s=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){t[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}}});var R,O,yi,Ie,ot=g(()=>{"use strict";R="sqlite-fts5-bm25",O="lexical",yi="Local Code Search \u2014 SQLite FTS5/BM25",Ie={engine:R,mode:O,displayName:yi,semantic:!1,embedding:!1,vectorDatabase:!1,queryExpansion:!1,synonymExpansion:!1,networkRequired:!1,indexBackend:"sqlite-fts5",ranking:"bm25",compatibilityAliases:["SemanticCodeEngine","semantic_code_search","toolnet-memory semantic","semantic-index"]}});import{existsSync as Di,readFileSync as Ki}from"node:fs";import{homedir as $i}from"node:os";import{join as zi}from"node:path";function Wi(r){let e=r.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Gi(){let r=process.env.TOOLNET_GLOBAL_ENV??zi($i(),".config","toolnet-memory",".env");if(!Di(r))return;let e=Ki(r,"utf8");for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let o=n.indexOf("=");if(o<=0)continue;let s=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Wi(n.slice(o+1)))}}var kn=g(()=>{"use strict";Gi()});var bn={};Be(bn,{loadConfig:()=>Sn});function J(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function Q(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Sn(){return{memory:{autoCapture:J(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:J(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:J(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:J(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:Q(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Q(process.env.MEMORY_RERANK_TOP,10),finalContext:Q(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Q(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:J(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:Q(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var pt=g(()=>{"use strict";kn()});var Po=g(()=>{"use strict"});import{DeleteObjectCommand as fc,GetObjectCommand as gc,HeadObjectCommand as yc,ListObjectsV2Command as hc,PutObjectCommand as kc,S3Client as Sc}from"@aws-sdk/client-s3";import{getSignedUrl as bc}from"@aws-sdk/s3-request-presigner";var se,ht=g(()=>{"use strict";se=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Sc({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new kc({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await bc(this.client,new gc({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new yc({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new fc({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new hc({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{access as Ao,mkdir as wc,readFile as vc,readdir as Cc,rm as xc,stat as Eo,writeFile as Mc}from"node:fs/promises";import{dirname as Pc,join as Ac,relative as Ro,resolve as Ec}from"node:path";var z,kt=g(()=>{"use strict";z=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ec(this.root,t)}async put(e,t){let n=this.path(e);await wc(Pc(n),{recursive:!0}),await Mc(n,t)}async get(e){try{return await vc(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await Ao(this.path(e)),!0}catch{return!1}}async delete(e){await xc(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await Ao(t)}catch{return n}let o=async i=>{let a=await Cc(i,{withFileTypes:!0});for(let c of a){let u=Ac(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Eo(u);n.push({key:Ro(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Eo(t);return s.isDirectory()?await o(t):n.push({key:Ro(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),n}}});import{DeleteObjectCommand as Rc,GetObjectCommand as jc,HeadObjectCommand as Tc,ListObjectsV2Command as Ic,PutObjectCommand as _c,S3Client as Nc}from"@aws-sdk/client-s3";import{getSignedUrl as Oc}from"@aws-sdk/s3-request-presigner";var W,St=g(()=>{"use strict";W=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Nc({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new _c({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Oc(this.client,new jc({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Tc({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Rc({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Ic({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}}});import{homedir as Lc}from"node:os";import{join as Fc}from"node:path";function bt(r,e){return console.warn(e),new z(r)}function Dc(r){let e=r.localRoot??Fc(Lc(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new W({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new W({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new se({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):bt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new z(e)}var jo=g(()=>{"use strict";ht();kt();St()});var wt,To=g(()=>{"use strict";wt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let n=JSON.parse(t);if(!Array.isArray(n))throw new Error("Invalid memory snapshot");return n}async save(e,t){let n=JSON.stringify(t,null,2);await this.storage.put(this.key(e),n,"application/json")}}});var Io=g(()=>{"use strict";kt()});var _o=g(()=>{"use strict";ht()});var No=g(()=>{"use strict";St()});var vt,Oo=g(()=>{"use strict";vt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let n=JSON.parse(t);if(n.version!==1||n.projectId!==e||!Array.isArray(n.records))throw new Error("Invalid vector snapshot");return n}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Ct,Lo=g(()=>{"use strict";Ct=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var xt,Fo=g(()=>{"use strict";xt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var ie,Mt=g(()=>{"use strict";ie=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Pt,Do=g(()=>{"use strict";Pt=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});function Kc(r){return new Promise(e=>setTimeout(e,r))}async function Ko(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await r()}catch(a){if(s=a,i>=t)break;let c=Math.min(o,n*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Kc(c+u)}throw s}var $o=g(()=>{"use strict"});function zc(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:$c.has(n)?(...s)=>Ko(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var $c,zo=g(()=>{"use strict";$o();$c=new Set(["put","get","getText","delete","list"])});function At(r){let e=r.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}var Et=g(()=>{"use strict"});function Rt(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var jt=g(()=>{"use strict"});var Tt,Wo=g(()=>{"use strict";Et();jt();Tt=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=At(o??n),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),n=t,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(n=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
3
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Rt(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,n){return await this.ensureRegistered(),this.provider.put(this.key(e),t,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}}});var Go=g(()=>{"use strict";Et();Wo();jt()});var It,qo=g(()=>{"use strict";It=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","resolution","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var _t,Vo=g(()=>{"use strict";_t=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","architecture"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/entry-points.json`,n(e.entryPoints),"application/json"),this.storage.put(`${t}/hotspots.json`,n(e.hotspots),"application/json"),this.storage.put(`${t}/layers.json`,n(e.layers),"application/json"),this.storage.put(`${t}/clusters.json`,n(e.clusters),"application/json")])}}});var Nt,Ho=g(()=>{"use strict";Nt=class{constructor(e){this.storage=e}storage;base(e){return["projects",e,"code","analysis"].join("/")}async load(e){let t=await this.storage.getText(`${this.base(e)}/current.json`);return t?JSON.parse(t):null}async save(e){let t=this.base(e.projectId),n=o=>JSON.stringify({version:e.version,projectId:e.projectId,updatedAt:e.updatedAt,data:o},null,2);await Promise.all([this.storage.put(`${t}/current.json`,JSON.stringify(e,null,2),"application/json"),this.storage.put(`${t}/dead-code.json`,n(e.deadCode),"application/json"),this.storage.put(`${t}/dependencies.json`,n(e.dependencies),"application/json")])}}});var Ot,Bo=g(()=>{"use strict";Ot=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","visualization","graph.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e,null,2),"application/json")}}});var Uo={};Be(Uo,{HuggingFaceStorageProvider:()=>se,LocalStorageProvider:()=>z,MemoryStore:()=>wt,PersistentArchitectureStore:()=>_t,PersistentCodeAnalysisStore:()=>Nt,PersistentCodeChunkStore:()=>ie,PersistentCodeGraphStore:()=>Ct,PersistentCodeManifestStore:()=>xt,PersistentCodeVectorStore:()=>Pt,PersistentTypeResolutionStore:()=>It,PersistentVectorStore:()=>vt,PersistentVisualizationStore:()=>Ot,ProjectScopedStorageProvider:()=>Tt,S3StorageProvider:()=>W,createStorageProvider:()=>Dc,mapProjectStoragePath:()=>Rt,sanitizeProjectFolder:()=>At,withStorageRetry:()=>zc});var Jo=g(()=>{"use strict";Po();jo();To();Io();_o();No();Oo();Lo();Fo();Mt();Do();zo();Go();qo();Vo();Ho();Bo()});import{createHash as Wc}from"node:crypto";import{readFile as Gc}from"node:fs/promises";import{join as qc}from"node:path";function Qo(r){return Wc("sha256").update(r).digest("hex")}var Ve,Yo=g(()=>{"use strict";ce();Ve=class{sanitizer=new P;async build(e,t,n,o={}){let s=o.maxLines??80,i=o.overlapLines??10,a=new Map;for(let u of n){let l=a.get(u.filePath)??[];l.push(u),a.set(u.filePath,l)}let c=[];for(let[u,l]of a){let d;try{d=await Gc(qc(t,u),"utf8")}catch{continue}let m=d.split(/\r?\n/),p=l.filter(y=>y.type!=="file"&&typeof y.startLine=="number"&&typeof y.endLine=="number");if(p.length>0)for(let y of p)c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,symbol:y,startLine:y.startLine,endLine:y.endLine,maxLines:s,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:u,lines:m,startLine:1,endLine:Math.max(1,m.length),maxLines:s,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:n,lines:o,symbol:s,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),u=Math.min(o.length,Math.max(c,e.endLine)),l=[],d=c,m=0;for(;d<=u;){let p=Math.min(u,d+i-1),y=o.slice(d-1,p).join(`
4
+ `).trim();if(y){let S=this.sanitizer.sanitize(y).text,T=Qo(S),G=[t,n,s?.id??"file",String(m),T].join(":");l.push({id:Qo(G).slice(0,32),projectId:t,filePath:n,symbolId:s?.id,symbolName:s?.qualifiedName??s?.name,symbolType:s?.type,startLine:d,endLine:p,content:S,contentHash:T})}if(p>=u)break;d=p-a+1,m++}return l}}});import{DatabaseSync as Vc}from"node:sqlite";var He,Xo=g(()=>{"use strict";He=class{constructor(e){this.projectId=e;this.db.exec("CREATE VIRTUAL TABLE code_fts USING fts5(id UNINDEXED, projectId UNINDEXED, filePath, symbol, content, tokenize='unicode61')")}projectId;db=new Vc(":memory:");chunks=new Map;get size(){return this.chunks.size}build(e){if(this.db.exec("DELETE FROM code_fts"),this.chunks.clear(),e.length===0)return 0;let t=this.db.prepare("INSERT INTO code_fts (id, projectId, filePath, symbol, content) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{for(let n of e)this.chunks.set(n.id,n),t.run(n.id,this.projectId,n.filePath,n.symbolName??"",n.content);this.db.exec("COMMIT")}catch(n){throw this.db.exec("ROLLBACK"),n}return e.length}search(e,t=8){let n=this.toMatchQuery(e);if(!n)return[];let o=this.db.prepare("SELECT id, bm25(code_fts) AS rank FROM code_fts WHERE code_fts MATCH ? ORDER BY rank LIMIT ?").all(n,Math.max(t*4,20)),s=[];for(let i of o){let a=this.chunks.get(i.id);if(!a)continue;let c=1/(1+Math.abs(i.rank));s.push({chunk:a,score:c})}return s.slice(0,t)}toMatchQuery(e){let t=e.toLowerCase().normalize("NFKC").split(/[^\p{L}\p{N}]+/u).map(n=>n.trim()).filter(n=>n.length>0);return t.length===0?null:t.length===1?`"${t[0]}"`:`(${t.map(n=>`"${n}"`).join(" OR ")})`}close(){this.db.close()}}});function Zo(r,e){let t=r.toLowerCase().replaceAll("\\","/"),n=e.toLowerCase(),o=/\b(test|tests|spec|fixture|mock)\b/.test(n);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!o?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var es=g(()=>{"use strict"});var ts={};Be(ts,{LocalCodeSearchEngineRuntime:()=>Lt,SemanticCodeEngine:()=>Lt});var Lt,rs=g(()=>{"use strict";Mt();Yo();Xo();es();ot();Lt=class{constructor(e){this.options=e;this.fts=new He(e.projectId)}options;fts;get searchContract(){return Ie}async initialize(e){let{projectId:t,rootPath:n,storage:o,graph:s}=this.options,i=new ie(o),a=await new Ve().build(t,n,s.allSymbols(t)),c=await i.load(t),u=!c||c.chunks.length!==a.length||c.chunks.some(d=>!a.some(m=>m.id===d.id));u&&await i.save({version:1,projectId:t,updatedAt:new Date().toISOString(),chunks:a}),e?.({current:a.length,total:a.length,phase:"index",detail:R});let l=this.fts.build(a);return{chunks:a.length,documentsIndexed:l,indexSize:this.fts.size,engine:R,mode:O,embedding:!1,vectorDatabase:!1,savedChunks:u,vectorsLoaded:0,vectorsIndexed:l,vectorsRemoved:0,totalVectors:this.fts.size,savedVectors:u}}async search(e,t=8){let n=this.fts.search(e,t),o=[];for(let s of n){let i=s.chunk,a=Zo(i.filePath,e),c=s.score,u=0,l=c*a;o.push({chunk:i,score:l,lexicalScore:c,vectorScore:u,engine:R,mode:O})}return o}size(){return this.fts.size}}});import"dotenv/config";import{randomUUID as Ws}from"node:crypto";var us={critical:100,high:75,normal:50,temporary:20};function Ft(r){return us[r]}function Dt(r,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c")||t.includes("must not")||t.includes("critical")?"critical":r==="rule"||r==="decision"?"high":r==="todo"?"normal":r==="activity"||r==="summary"?"temporary":"normal"}ce();var Wt=new P;function Gt(r){return Wt.sanitize(r).text}function ue(r){return Wt.sanitizeValue(r)}var ys=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","next_action","next-action","opencode","agy","codex","claude","kiro","cursor","copilot","grok","toolnet","kilo"]),hs=new Set(["d\xF9ng","s\u1EED","d\u1EE5ng","cho","v\xE0","l\xE0","c\u1EE7a","v\u1EDBi","m\u1ED9t","c\xE1c","use","using","the","a","an","to","for","with","and","of","quy\u1EBFt","\u0111\u1ECBnh"]),ks=new Set(["todo","task","next","step","action","need","needs","needed","remaining","fix","fixed","fixing","resolve","resolved","implemented","complete","completed","done","pass","passed","passing","tests","test","c\u1EA7n","l\xE0m","s\u1EEDa","\u0111\xE3","x\u1EED","l\xFD","ho\xE0n","t\u1EA5t","th\xE0nh","ti\u1EBFp","theo","b\u01B0\u1EDBc"]),Ss=new Set(["rule","decision","todo","next_action","fix","context","architecture"]);function A(r){return r.normalize("NFKC").trim().toLowerCase()}function Xt(r,e){for(let t of e){let n=r.metadata?.[t];if(typeof n!="string")continue;let o=A(n);if(o)return o}}function Zt(r,e){for(let t of r.tags){let n=A(t);for(let o of e){if(!n.startsWith(o))continue;let s=n.slice(o.length).trim();if(s)return s}}}function le(r){if(typeof r!="string")return;let e=A(r).replaceAll("-","_");if(e==="nextaction")return"next_action";if(Ss.has(e))return e}function I(r){let e=le(r.metadata?.conflictKind);if(e)return e;let t=le(r.metadata?.learningKind);if(t)return t;let n=le(r.metadata?.lifecycleKind);if(n)return n;for(let o of r.tags){let s=A(o);if(!s.startsWith("kind:"))continue;let i=le(s.slice(5));if(i)return i}return r.tags.some(o=>A(o)==="next_action")?"next_action":r.type==="rule"?"rule":r.type==="decision"?"decision":r.type==="todo"?"todo":"other"}function bs(r){let e=r.metadata?.lifecycleState;return typeof e=="string"&&["active","conflicting","superseded","resolved","completed","stale"].includes(e)?e:r.metadata?.supersededBy?"superseded":"active"}function Je(r){return new Set(A(r).replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/u).filter(e=>e.length>2&&!hs.has(e)))}function qt(r){return new Set([...Je(r)].filter(e=>!ks.has(e)))}function er(r,e){if(r.size===0||e.size===0)return 0;let t=0;for(let o of r)e.has(o)&&(t+=1);let n=new Set([...r,...e]).size;return n===0?0:t/n}function ws(r,e){return er(Je(r),Je(e))}function vs(r,e){return er(qt(r),qt(e))}function Vt(r){return new Set(r.tags.map(A).filter(e=>!(ys.has(e)||e.startsWith("class:")||e.startsWith("kind:")||e.startsWith("level:"))))}function Cs(r,e){let t=Vt(r),n=Vt(e);for(let o of t)if(n.has(o))return!0;return!1}function Ht(r){return Xt(r,["topic","topicKey"])??Zt(r,["topic:"])}function Bt(r){return Xt(r,["entity","entityKey","subject","taskId","taskKey"])??Zt(r,["entity:","subject:","task:"])}function Ut(r){let e=r.metadata?.provenance;if(!e||typeof e!="object"||Array.isArray(e))return new Set;let t=e.sourcePaths;return Array.isArray(t)?new Set(t.filter(n=>typeof n=="string").map(A).filter(Boolean)):new Set}function xs(r,e){let t=Ut(r);if(t.size===0)return!1;let n=Ut(e);for(let o of t)if(n.has(o))return!0;return!1}function q(r){let e=r.metadata?.evidence;if(!e||typeof e!="object"||Array.isArray(e))return{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1};let t=e,n=Number(t.crossSessionConfirmations);return{userExplicit:t.userExplicit===!0,sourceVerified:t.sourceVerified===!0,testVerified:t.testVerified===!0,crossSessionConfirmations:Number.isFinite(n)?Math.max(0,n):0,assistantDerived:t.assistantDerived===!0}}function Ms(r){let e=q(r);return e.userExplicit||e.sourceVerified||e.testVerified||e.crossSessionConfirmations>0}function Ps(r){let e=Number(r.metadata?.confidence);return Number.isFinite(e)?Math.max(0,Math.min(1,e)):0}function As(r){return r.importance==="critical"?20:r.importance==="high"?12:r.importance==="normal"?5:0}function Jt(r){let e=q(r),t=As(r);return e.userExplicit&&(t+=100),e.sourceVerified&&(t+=60),e.testVerified&&(t+=60),t+=Math.min(5,e.crossSessionConfirmations)*12,t+=Ps(r)*10,r.metadata?.knowledgeClass==="permanent"&&(t+=10),e.assistantDerived&&(t-=15),Math.round(t*1e3)/1e3}function Es(r,e){if(r==="other"||e==="other")return!1;if(r===e)return!0;let t=new Set(["todo","next_action"]);return!!(t.has(r)&&t.has(e)||r==="fix"&&t.has(e)||e==="fix"&&t.has(r)||r==="fix"&&e==="context"||e==="fix"&&r==="context")}function Rs(r,e){if(r==="fix"&&e==="context"||e==="fix"&&r==="context")return .65;let t=new Set(["todo","next_action","fix"]);return t.has(r)&&t.has(e)?.38:r==="rule"||r==="decision"?.6:.5}function js(r,e){if(e.id===r.id||e.projectId!==r.projectId)return!1;let t=bs(e);if(["superseded","resolved","completed","stale"].includes(t))return!1;let n=I(r),o=I(e);if(!Es(n,o))return!1;let s=Ht(r),i=Ht(e);if(s&&i&&s===i)return!0;let a=Bt(r),c=Bt(e);if(a&&c&&a===c||Cs(r,e))return!0;let u=Rs(n,o),l=vs(r.content,e.content);return!!(l>=u||ws(r.content,e.content)>=u||xs(r,e)&&l>=Math.max(.3,u-.2))}function Qt(r){return I(r)==="rule"&&q(r).userExplicit}function Ts(r,e){return!Qt(r)||!Qt(e)?!1:r.createdAt>=e.createdAt}function Yt(r){let e=q(r);return e.userExplicit||e.sourceVerified||e.testVerified}function de(r){return r==="todo"||r==="next_action"}function Ue(r,e){return r.createdAt>=e.createdAt}var me=class{resolve(e,t){let n=I(e),o={kind:n,superseded:[],conflicts:[],completed:[],resolved:[]};if(n==="other")return o;let s=Jt(e);for(let i of t){if(!js(e,i))continue;let a=I(i),c=Jt(i);if(n==="fix"&&de(a)){if(Yt(e)){o.completed.push(i);continue}o.conflicts.push(i);continue}if(n==="fix"&&a==="context"){if(Yt(e)&&s>=c){o.resolved.push(i);continue}o.conflicts.push(i);continue}if(de(n)&&a==="fix"){if(q(e).userExplicit||s>c){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(de(n)&&de(a)){if(s>c||s===c&&Ue(e,i)){o.superseded.push(i);continue}o.conflicts.push(i);continue}if(s>c){o.superseded.push(i);continue}if(s<c){o.conflicts.push(i);continue}if(Ts(e,i)){o.superseded.push(i);continue}if(["context","fix","architecture","decision"].includes(n)&&Ue(e,i)){o.superseded.push(i);continue}if(!Ms(i)&&Ue(e,i)){o.superseded.push(i);continue}o.conflicts.push(i)}return o}findSuperseded(e,t){return this.resolve(e,t).superseded}};var Is=new Set(["code","decision","rule","todo","summary"]);function _s(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function tr(r){return r.tags.includes("class:permanent")?4:r.tags.includes("class:task")?3:r.tags.includes("class:session")?2:r.tags.includes("class:transient")?1:0}function Ns(r,e){let t=tr(e)-tr(r);if(t!==0)return t;let n=e.importanceScore-r.importanceScore;if(n!==0)return n;let o=e.updatedAt.localeCompare(r.updatedAt);if(o!==0)return o;let s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function rr(r){let e=new Set,t=[];for(let n of r){let o=n.trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function nr(r){let e=new Map;for(let o of r){if(!Is.has(o.type)||o.metadata?.supersededBy)continue;let s=_s(o.content);if(!s)continue;let i=[o.projectId,o.type,s].join("\0"),a=e.get(i)??[];a.push(o),e.set(i,a)}let t=[],n=0;for(let o of e.values()){if(o.length<2)continue;let s=[...o].sort(Ns),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:rr(s.flatMap(c=>c.tags)),mergedSources:rr(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function Qe(r){if(r.tags.includes("class:permanent"))return"permanent";if(r.tags.includes("class:task"))return"task";if(r.tags.includes("class:session"))return"session";if(r.tags.includes("class:transient"))return"transient"}function Os(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Ls(r){let e=Qe(r);if(e==="permanent")return 730;if(e==="task")return 180;if(e==="session")return 45;if(e==="transient")return 7;switch(r.type){case"rule":return 730;case"decision":return 365;case"code":return 180;case"todo":return 120;case"summary":return 45;case"activity":return 14}}function Fs(r){return Qe(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function Ds(r){let e=r.normalize("NFKC").toLowerCase().trim();return e.length<8?!0:[/^ok(?:ay)?[.!]?$/u,/^done[.!]?$/u,/^thanks?[.!]?$/u,/^test(?:ing)?[.!]?$/u,/^npm notice\b/u,/^changed \d+ packages?/u,/^packages? are looking for funding/u].some(t=>t.test(e))}function or(r,e=Date.now()){let t=50,n=[],o=Qe(r);switch(o==="permanent"?(t+=25,n.push("permanent project knowledge")):o==="task"?(t+=15,n.push("active task knowledge")):o==="session"?(t+=2,n.push("session-scoped knowledge")):o==="transient"&&(t-=25,n.push("transient knowledge")),r.importance){case"critical":t+=25,n.push("critical importance");break;case"high":t+=15,n.push("high importance");break;case"normal":break;case"temporary":t-=15,n.push("temporary importance");break}(r.type==="rule"||r.type==="decision")&&(t+=10,n.push("durable knowledge type"));let s=r.content.trim().length;s<12?(t-=30,n.push("very short content")):s<30?(t-=10,n.push("limited context")):s<=1200?(t+=8,n.push("useful context density")):s>5e3&&(t-=15,n.push("excessively large memory")),Ds(r.content)&&(t-=35,n.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,n.push("confirmed across multiple sources"));let a=Os(r,e)>=Ls(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=Fs(r);t=Math.max(0,Math.min(100,Math.round(t)));let u;t>=80?u="trusted":t>=55?u="useful":t>=30?u="weak":u="noise";let l=r.importance==="temporary"||r.type==="activity"||o==="transient";return{score:t,tier:u,stale:a,protected:c,pruneEligible:!c&&(u==="noise"&&l||a&&(u==="noise"||u==="weak")),reasons:n}}var Ks={critical:100,high:75,normal:50,temporary:20},$s={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function sr(r,e,t=new Date){let n;if(e==="temporary"&&(n=30),r==="activity"&&(n=Math.min(n??14,14)),r==="summary"&&(n=Math.min(n??30,30)),!!n)return new Date(t.getTime()+n*864e5).toISOString()}function Ye(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function zs(r){return!!r.metadata?.supersededBy||r.metadata?.lifecycleState==="superseded"}function Xe(r,e=Date.now()){if(Ye(r,e)||zs(r))return!1;let t=r.metadata?.lifecycleState;return!(t==="completed"||t==="resolved"||t==="conflicting"||t==="stale")}function V(r,e=Date.now()){if(!Xe(r,e))return 0;let t=Ks[r.importance];if(r.importance==="critical")return t;let n=$s[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var pe=class{memories=new Map;conflicts=new me;remember(e){let n=(e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?new Date(e.createdAt).toISOString():void 0)??new Date().toISOString(),o=Gt(e.content.trim()),s=e.importance??Dt(e.type,o),i={id:Ws(),projectId:e.projectId,type:e.type,content:o,importance:s,importanceScore:Ft(s),tags:e.tags??[],source:e.source??"agent",createdAt:n,updatedAt:n,expiresAt:e.expiresAt??sr(e.type,s,new Date(n)),metadata:ue(e.metadata)};i.metadata={...i.metadata??{},lifecycleState:"active"},i.metadata={...i.metadata,conflictKind:I(i)};let a=this.conflicts.resolve(i,this.list(e.projectId));if(a.superseded.length>0){i.metadata={...i.metadata??{},supersedes:a.superseded.map(c=>c.id)};for(let c of a.superseded)c.updatedAt=n,c.metadata={...c.metadata??{},supersededBy:i.id,supersededAt:n,lifecycleState:"superseded"},this.memories.set(c.id,c)}if(a.completed.length>0){i.metadata={...i.metadata??{},completes:a.completed.map(c=>c.id)};for(let c of a.completed)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"completed",completedBy:i.id,completedAt:n},this.memories.set(c.id,c)}if(a.resolved.length>0){i.metadata={...i.metadata??{},resolves:a.resolved.map(c=>c.id)};for(let c of a.resolved)c.updatedAt=n,c.metadata={...c.metadata??{},lifecycleState:"resolved",resolvedBy:i.id,resolvedAt:n},this.memories.set(c.id,c)}if(a.conflicts.length>0){let c=a.conflicts.map(u=>u.id);i.metadata={...i.metadata??{},conflictsWith:c,lifecycleState:"conflicting"};for(let u of a.conflicts){let l=Array.isArray(u.metadata?.conflictsWith)?u.metadata?.conflictsWith:[],d=new Set(l.filter(m=>typeof m=="string"));d.add(i.id),u.updatedAt=n,u.metadata={...u.metadata??{},conflictsWith:[...d]},this.memories.set(u.id,u)}}return this.memories.set(i.id,i),i}importRecords(e){let t=0;for(let n of e){if(!n?.id)continue;let o=ue(n);this.memories.set(o.id,o),t++}return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,n)=>n.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Xe(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(n=>n.type===t)}search(e){let t=e.query.trim().toLowerCase(),n=e.limit??10,o=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=V(s);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>s.tags.includes(c)))}).map(s=>{let i=s.content.toLowerCase(),a=o.filter(l=>i.includes(l)).length,c=o.length===0?0:a/o.length,u=V(s)/500;return{memory:s,score:c+u,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,n)}consolidate(e,t=Date.now()){let n=nr(this.list(e)),o=[],s=0;for(let i of n.groups){let a=this.memories.get(i.canonicalId);if(a){a.tags=i.mergedTags,a.metadata={...a.metadata??{},consolidation:{version:1,consolidatedAt:new Date(t).toISOString(),mergedIds:i.duplicateIds,sources:i.mergedSources}},this.memories.set(a.id,a),o.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:o.length,duplicatesRemoved:s,canonicalIds:o}}reviewLifecycle(e,t=Date.now()){let n={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let o of this.list(e)){let s=or(o,t);n.reviewed+=1,n[s.tier]+=1,s.stale&&(n.stale+=1),s.protected&&(n.protected+=1),o.metadata={...o.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:s.score,tier:s.tier,stale:s.stale,protected:s.protected,reasons:s.reasons}},this.memories.set(o.id,o),s.pruneEligible&&this.memories.delete(o.id)&&(n.pruned+=1)}return n}pruneExpired(e,t=Date.now()){let n=0;for(let[o,s]of this.memories)s.projectId===e&&Ye(s,t)&&(this.memories.delete(o),n++);return n}pruneSuperseded(e,t=30,n=Date.now()){let o=0,s=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;n-new Date(c).getTime()>=s&&(this.memories.delete(i),o++)}return o}clearProject(e){let t=0;for(let[n,o]of this.memories)o.projectId===e&&(this.memories.delete(n),t++);return t}};import{createHash as Js}from"node:crypto";import{existsSync as ye,mkdirSync as Qs,readFileSync as Ys,renameSync as Xs,writeFileSync as Zs}from"node:fs";import{basename as ei,dirname as he,join as B,parse as pr,resolve as N}from"node:path";import{createHash as cr}from"node:crypto";import{spawnSync as Gs}from"node:child_process";var H="git-remote-v1",qs=new Set(["github.com","gitlab.com","bitbucket.org"]);function ur(r,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(n=>!n||n==="."||n==="..")?null:(qs.has(r)&&(t=t.toLowerCase()),t)}function Vs(r){let e;try{e=new URL(r)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let n=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!n?`${t}:${e.port}`:t,s=ur(t,e.pathname);return s?`${o}/${s}`:null}function Hs(r){let e=r.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let n=ur(t,e[2]??"");return n?`${t}/${n}`:null}function ir(r){let e=r.trim();return e?e.includes("://")?Vs(e):Hs(e):null}function Bs(r){return cr("sha256").update(`${H}:${r}`).digest("hex")}function lr(r){return cr("sha256").update(`toolnet-project:${H}:${r}`).digest("hex").slice(0,16)}function Us(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function Ze(r,e){let t=Gs("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function ar(r,e){let t=Us(r);return t?{scheme:H,canonicalRemote:r,fingerprint:Bs(r),repositoryName:t,source:e}:null}function dr(r){let e=Ze(r,["remote","get-url","origin"]);if(e){let o=ir(e);if(o)return ar(o,"origin")}let t=Ze(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=Ze(r,["remote","get-url",o]);if(!s)continue;let i=ir(s);i&&n.add(i)}return n.size!==1?null:ar([...n][0],"unique-remote")}var fr=".toolnet",ti="project.json";function ri(r){return Js("sha256").update(r).digest("hex").slice(0,16)}function F(r){return B(r,fr,ti)}function gr(r){return ye(F(r))}function mr(r,e){let t=N(r),n=pr(t).root;for(;;){if(gr(t))return t;if(t===n||e&&t===N(e))break;let o=he(t);if(o===t)break;t=o}return null}function et(r){let e=N(r),t=pr(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>ye(B(e,s))))return e;if(e===t)break;let o=he(e);if(o===e)break;e=o}return N(r)}function fe(r){let e;try{e=JSON.parse(Ys(r,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${r}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let n=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:he(he(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:n,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:n,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function ge(r,e){let t=B(r,fr);Qs(t,{recursive:!0});let n=F(r),o=`${n}.tmp-${process.pid}`;Zs(o,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),Xs(o,n)}function _(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}function tt(r){return{version:1,scheme:H,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function ni(r){let e=r.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var ke=class{adopt(e,t){let n=et(N(e));if(!t.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!t.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!t.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(gr(n)){let a=fe(F(n));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return _(a,n)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=tt(t.gitIdentity));let i={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:n,createdAt:t.createdAt??o,updatedAt:o,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return ge(n,i),_(i,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),s=F(o.rootPath),i=fe(s),a=ni(i);if(a&&a!==t.fingerprint&&!n.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:tt(t)},i.updatedAt=new Date().toISOString(),ge(o.rootPath,i)),_(i,o.rootPath)}findExisting(e=process.cwd()){let t=N(e),n=et(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>ye(B(n,c))),i=mr(t,s?n:void 0);if(!i)return null;let a=fe(F(i));return _(a,i)}requireExisting(e=process.cwd()){let t=this.findExisting(e);if(!t)throw new Error("PROJECT_NOT_INITIALIZED");return t}detect(e=process.cwd()){let t=N(e),n=et(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>ye(B(n,d))),i=mr(t,s?n:void 0);if(i){let d=F(i),m=fe(d);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),ge(i,m)),_(m,i)}let a=new Date().toISOString(),c=ei(n),u=dr(n),l={version:1,id:u?lr(u.canonicalRemote):ri(n),name:c,remote:u?.repositoryName??c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:tt(u)}:void 0};return ge(n,l),_(l,n)}};function rt(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var Se=class{score(e,t){let n=rt(e),o=rt([t.content,...t.tags??[],t.type].join(" "));if(n.length===0||o.length===0)return 0;let s=new Map;for(let a of o)s.set(a,(s.get(a)??0)+1);let i=0;for(let a of n){let c=s.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/n.length}};function yr(r,e=Date.now()){let t=r.updatedAt??r.createdAt,n=new Date(t).getTime();if(!Number.isFinite(n))return 0;let o=Math.max(0,e-n)/864e5;return Math.exp(-Math.LN2*o/30)}function hr(r){return V(r)/100}var oi={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function kr(r){return oi[r]??.4}var be=class{analyze(e){let t=e.toLowerCase(),n=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&n.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&n.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&n.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&n.push("summary"),{query:e,preferredTypes:n}}};var we=class{bm25=new Se;analyzer=new be;search(e,t,n={}){let o=n.topK??8,s=n.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(n.types?.length&&!n.types.includes(c.type))continue;let u=this.bm25.score(e,c),l=yr(c),d=hr(c),m=kr(c.type);i.preferredTypes.includes(c.type)&&(m=Math.min(1,m+.25));let p=u*.55+d*.2+l*.15+m*.1;u<=0||p<s||a.push({memory:c,score:p,scores:{keyword:u,recency:l,importance:d,type:m}})}return a.sort((c,u)=>u.score-c.score).slice(0,o)}};var ve=class{build(e,t=6e3){let n=[],o=0;for(let s of e){let i=s.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(o+a.length>t)break;n.push(a),o+=a.length}return n.join(`
6
+ `)}};var Ce=class{constructor(e){this.memory=e}memory;searcher=new we;contextBuilder=new ve;search(e,t,n={}){return this.searcher.search(t,this.memory.list(e),n)}context(e,t,n={}){let o=this.search(e,t,n);return this.contextBuilder.build(o)}};var xe=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(n=>n.projectId===e&&(n.name===t||n.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let n of e)this.addSymbol(n);for(let n of t)this.addEdge(n)}clearProject(e){for(let[t,n]of this.symbols)n.projectId===e&&this.symbols.delete(t);for(let[t,n]of this.edges)n.projectId===e&&this.edges.delete(t)}};var Me=class{constructor(e){this.graph=e}graph;findSymbol(e,t){return this.graph.findByName(e,t)}findCallers(e,t){return this.graph.allEdges(e).filter(o=>o.type==="CALLS"&&o.to===t).map(o=>o.from).map(o=>this.graph.getSymbol(o)).filter(o=>!!o)}};import{McpServer as lc}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as dc}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as Sr}from"zod";var br={query:Sr.string(),limit:Sr.number().int().min(1).max(20).optional()};async function wr(r,e){return r.retrieval.search(r.project.id,e.query,{topK:e.limit??8}).map(n=>({id:n.memory.id,type:n.memory.type,content:n.memory.content,importance:n.memory.importance,score:n.score,tags:n.memory.tags}))}import{z as U}from"zod";import{createConnection as ai}from"node:net";import{homedir as si}from"node:os";import{join as ii}from"node:path";function vr(){return process.env.TOOLNET_SERVICE_SOCKET??ii(si(),".toolnet","run","service.sock")}function Cr(r,e={}){let t=e.socketPath??vr(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=ai({path:t}),a="",c=!1,u=d=>{c||(c=!0,clearTimeout(l),i.destroy(),d())},l=setTimeout(()=>{u(()=>{s(new Error(`ToolNet service timeout after ${n}ms`))})},n);i.setEncoding("utf8"),i.once("connect",()=>{i.write(`${JSON.stringify(r)}
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(y){s(y instanceof Error?y:new Error(String(y)))}})}),i.once("error",d=>{u(()=>{s(d)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function ci(r,e={}){let t=await Cr({type:"hydrate",project:r},e);if(!t.ok||t.type!=="hydrate")throw new Error(t.ok?"Invalid ToolNet service hydrate response":t.error);return t}async function xr(r,e={}){try{return await ci(r,e)}catch{return null}}async function Pe(r,e={}){try{let t=await Cr({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var Mr={type:U.enum(["activity","decision","rule","todo","summary"]),content:U.string().min(1),tags:U.array(U.string()).optional(),importance:U.enum(["critical","high","normal","temporary"]).optional()};async function Pr(r,e){let t=r.memory.remember({projectId:r.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),Pe(r.project),t}import{z as ui}from"zod";var Ar={id:ui.string().min(1)};async function Er(r,e){let t=r.memory.delete(e.id);return t&&r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),t&&Pe(r.project),{deleted:t}}import{z as li}from"zod";var Rr={name:li.string().min(1)};async function jr(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as di}from"zod";var Ae=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Tr=new Set(["CALLS","CALL_REFERENCE"]),w=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let n=t.trim().toLowerCase();return n?this.graph.allSymbols(e).filter(o=>o.name.toLowerCase().includes(n)||(o.qualifiedName?.toLowerCase().includes(n)??!1)||o.filePath.toLowerCase().includes(n)).sort((o,s)=>{let i=o.name.toLowerCase()===n,a=s.name.toLowerCase()===n;return i!==a?i?-1:1:o.filePath.localeCompare(s.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Tr)}callees(e,t){return this.relatedOutgoing(e,t,Tr)}dependents(e,t){return this.relatedIncoming(e,t,Ae)}dependencies(e,t){return this.relatedOutgoing(e,t,Ae)}neighborhood(e,t,n=1){let o=this.graph.getSymbol(t);return!o||o.projectId!==e?null:{center:o,incoming:this.walk(e,t,"incoming",n),outgoing:this.walk(e,t,"outgoing",n)}}shortestPath(e,t,n,o=12){let s=this.graph.getSymbol(t),i=this.graph.getSymbol(n);if(!s||!i||s.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===n)return{found:!0,distance:0,symbols:[s],edges:[]};let a=this.graph.allEdges(e).filter(m=>Ae.has(m.type)),c=new Map;for(let m of a){let p=c.get(m.from)??[];p.push(m),c.set(m.from,p)}let u=[{id:t,depth:0}],l=new Set([t]),d=new Map;for(;u.length>0;){let m=u.shift();if(!(m.depth>=o)){for(let p of c.get(m.id)??[])if(!l.has(p.to)){if(l.add(p.to),d.set(p.to,{node:m.id,edge:p}),p.to===n)return this.buildPath(t,n,d);u.push({id:p.to,depth:m.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,n){let o=[t],s=[],i=t;for(;i!==e;){let c=n.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};s.push(c.edge),i=c.node,o.push(i)}o.reverse(),s.reverse();let a=o.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:s.length,symbols:a,edges:s}}walk(e,t,n,o){let s=this.graph.allEdges(e).filter(u=>Ae.has(u.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let u=i.shift();if(!(u.depth>=o))for(let l of s){if(!(n==="incoming"?l.to===u.id:l.from===u.id))continue;let m=n==="incoming"?l.from:l.to;if(a.has(m))continue;let p=this.graph.getSymbol(m);p&&(a.add(m),c.push({symbol:p,depth:u.depth+1,via:l}),i.push({id:m,depth:u.depth+1}))}}return c}relatedIncoming(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.to===t&&n.has(s.type)).map(s=>s.from))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}relatedOutgoing(e,t,n){return[...new Set(this.graph.allEdges(e).filter(s=>s.from===t&&n.has(s.type)).map(s=>s.to))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function v(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let n=new w(r.graph),o=n.findSymbols(r.project.id,e).find(s=>s.name===e||s.qualifiedName===e);return o||(n.findSymbols(r.project.id,e)[0]??null)}function b(r){return{id:r.id,name:r.name,qualifiedName:r.qualifiedName,type:r.type,filePath:r.filePath,startLine:r.startLine,endLine:r.endLine}}var Ir={symbolId:di.string().min(1)};async function _r(r,e){let t=v(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let o=new w(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:b(t),count:o.length,callers:o.map(b)}}import{z as Nr}from"zod";var Or={query:Nr.string().min(1),limit:Nr.number().int().min(1).max(50).optional()};async function Lr(r,e){let t=e.query.toLowerCase(),n=e.limit??20;return r.graph.allSymbols(r.project.id).filter(o=>o.name.toLowerCase().includes(t)||o.qualifiedName?.toLowerCase().includes(t)||o.filePath.toLowerCase().includes(t)).slice(0,n)}import{z as Fr}from"zod";function Ee(r,e){let t=r.allSymbols(e),n=r.allEdges(e),o=i=>t.filter(a=>a.type===i).length,s=i=>n.filter(a=>a.type===i).length;return{files:o("file"),classes:o("class"),interfaces:o("interface"),functions:o("function"),methods:o("method"),properties:o("property"),routes:o("route"),symbols:t.length,edges:n.length,calls:s("CALLS"),callReferences:s("CALL_REFERENCE"),imports:s("IMPORTS"),inherits:s("INHERITS"),implements:s("IMPLEMENTS"),usesType:s("USES_TYPE"),tests:s("TESTS"),routeEdges:s("ROUTE"),writes:s("WRITES")}}var Dr={query:Fr.string().optional(),memoryLimit:Fr.number().int().min(1).max(20).optional()};async function Kr(r,e){let t=Ee(r.graph,r.project.id),n=r.memory.recent(r.project.id,5),o=e.query?r.retrieval.search(r.project.id,e.query,{topK:e.memoryLimit??5}):[];return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:t,recent:n,relevant:o.map(s=>s.memory)}}import{z as pi}from"zod";var mi=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],E=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",n){let o=new Date().toISOString(),s=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,s),c=[];for(let l of mi){let d=`${i}/${l}`,m=await this.storage.get(d);m&&(await this.storage.put(`${a}/${l}`,m,"application/json"),c.push(l))}if(c.length===0)return null;let u={version:1,id:s,projectId:e,createdAt:o,reason:t,objects:c,metadata:n};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(u,null,2),"application/json"),u}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),s=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{s.push(JSON.parse(a))}catch{}}return s.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.getText(`${n}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let s=JSON.parse(o);if(s.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of s.objects){let u=await this.storage.get(`${n}/${c}`);u&&(await this.storage.put(`${i}/${c}`,u,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let n=this.snapshotPrefix(e,t),o=await this.storage.list(n);for(let s of o)await this.storage.delete(s.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),s=0;for(let i of o)await this.remove(e,i.id),s++;return s}};var $r={reason:pi.string().optional()};async function zr(r,e){if(!r.storage)throw new Error("Storage unavailable");return new E(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function Wr(r){if(!r.storage)throw new Error("Storage unavailable");return new E(r.storage).list(r.project.id)}import{z as fi}from"zod";var Gr={snapshotId:fi.string().min(1)};async function qr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new E(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as nt}from"zod";var Re=class{constructor(e){this.graph=e}graph;callees(e,t,n=3){return this.walk(e,t,"out",n)}callers(e,t,n=3){return this.walk(e,t,"in",n)}walk(e,t,n,o){let s=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(u=>u.type==="CALLS"||u.type==="CALL_REFERENCE");for(;a.length;){let u=a.shift();if(u.depth>=o)continue;let l=n==="out"?c.filter(d=>d.from===u.id):c.filter(d=>d.to===u.id);for(let d of l){let m=n==="out"?d.to:d.from;if(i.has(m))continue;i.add(m);let p=this.graph.getSymbol(m);if(!p)continue;let y=u.depth+1;s.push({symbol:p,depth:y}),a.push({id:m,depth:y})}}return s}};var Vr={symbolId:nt.string().min(1),direction:nt.enum(["callers","callees"]).optional(),depth:nt.number().int().min(1).max(10).optional()};async function Hr(r,e){let t=new Re(r.graph),n=e.direction??"callees",o=e.depth??3,s=n==="callers"?t.callers(r.project.id,e.symbolId,o):t.callees(r.project.id,e.symbolId,o);return{direction:n,depth:o,results:s.map(i=>({id:i.symbol.id,name:i.symbol.name,qualifiedName:i.symbol.qualifiedName,type:i.symbol.type,filePath:i.symbol.filePath,depth:i.depth}))}}import{z as Br}from"zod";var je=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=n)continue;let u=o.filter(l=>l.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(l.type));for(let l of u){if(s.has(l.from))continue;s.add(l.from);let d=this.graph.getSymbol(l.from);if(!d)continue;let m=c.depth+1;a.push({symbol:d,depth:m,relation:l.type}),i.push({id:l.from,depth:m})}}return a}};var Ur={symbolId:Br.string().min(1),depth:Br.number().int().min(1).max(10).optional()};async function Jr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new je(r.graph).analyze(r.project.id,t.id,e.depth??4);return{found:!0,target:{id:t.id,name:t.name,qualifiedName:t.qualifiedName,filePath:t.filePath,type:t.type},impacts:o.map(s=>({id:s.symbol.id,name:s.symbol.name,qualifiedName:s.symbol.qualifiedName,filePath:s.symbol.filePath,type:s.symbol.type,relation:s.relation,depth:s.depth}))}}async function Qr(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:Ee(r.graph,r.project.id)}}import{z as Yr}from"zod";var gi=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Te=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>gi.has(i.type)),o=new Map(t.map(i=>[i.id,i]));return[...new Set(t.map(i=>i.filePath))].sort().map(i=>{let a=new Set,c=new Set,u=0,l=0;for(let d of n){let m=o.get(d.from),p=o.get(d.to);!m||!p||m.filePath===p.filePath||(m.filePath===i&&(a.add(p.filePath),u++),p.filePath===i&&(c.add(m.filePath),l++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:u,incomingEdges:l}})}};var Xr={filePath:Yr.string().min(1),direction:Yr.enum(["dependencies","dependents","both"]).optional()};async function Zr(r,e){let n=new Te(r.graph).analyze(r.project.id).find(c=>c.filePath===e.filePath);if(!n)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let o=r.graph.allSymbols(r.project.id).filter(c=>c.type==="file"),s=new Map(o.map(c=>[c.filePath,c])),i=c=>({id:s.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:n.filePath,outgoingEdges:n.outgoingEdges,incomingEdges:n.incomingEdges,dependencies:a==="dependents"?[]:n.dependencies.map(i),dependents:a==="dependencies"?[]:n.dependents.map(i)}}ot();import{z as en}from"zod";var tn={query:en.string().min(1),limit:en.number().int().min(1).max(20).optional()};async function rn(r,e){if(!r.codeSemantic)return{available:!1,engine:R,mode:O,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",results:[]};let t=await r.codeSemantic.search(e.query,e.limit??8);return{available:!0,engine:R,mode:O,semantic:!1,embedding:!1,vectorDatabase:!1,legacyAlias:"semantic_code_search",searchContract:Ie,results:t.map(n=>({id:n.chunk.id,filePath:n.chunk.filePath,symbol:n.chunk.symbolName,symbolType:n.chunk.symbolType,startLine:n.chunk.startLine,endLine:n.chunk.endLine,score:n.score,lexicalScore:n.lexicalScore,vectorScore:n.vectorScore,engine:n.engine,mode:n.mode,content:n.chunk.content}))}}import{z as it}from"zod";import{execFile as hi}from"node:child_process";import{promisify as ki}from"node:util";var st=ki(hi);function Si(r){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let n of r.matchAll(t)){let o=Number(n[1]),s=Number(n[2]??1);e.push({startLine:o,endLine:Math.max(o,o+s-1)})}return e}function bi(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function nn(r){let e="";try{e=(await st("git",["diff","HEAD","--name-status","--no-renames"],{cwd:r,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let n of e.split(/\r?\n/).filter(Boolean)){let[o,...s]=n.split(" "),i=s.at(-1);if(!i)continue;let a="";try{a=(await st("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:bi(o),ranges:Si(a)})}try{let n=await st("git",["ls-files","--others","--exclude-standard"],{cwd:r});for(let o of n.stdout.split(/\r?\n/).filter(Boolean))t.some(s=>s.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}function wi(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var _e=class{constructor(e){this.graph=e}graph;map(e,t){let n=this.graph.allSymbols(e),o=[];for(let s of t){let i=n.filter(u=>u.filePath===s.filePath),c=i.filter(u=>u.type!=="file").filter(u=>wi(u,s));if(c.length===0){let u=i.find(l=>l.type==="file");u&&o.push({symbol:u,fileStatus:s.status,direct:!0});continue}for(let u of c)o.push({symbol:u,fileStatus:s.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var vi={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function Ci(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function on(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var Ne=class{constructor(e){this.graph=e}graph;analyze(e,t,n=4){let o=this.graph.allEdges(e),s=new Map,i=0;for(let l of t){l.fileStatus==="deleted"?i+=8:l.fileStatus==="renamed"?i+=5:i+=2,l.symbol.type==="interface"&&(i+=5),l.symbol.type==="class"&&(i+=3);let d=new Set([l.symbol.id]),m=[{id:l.symbol.id,depth:0}];for(;m.length;){let p=m.shift();if(p.depth>=n)continue;let y=o.filter(S=>S.to===p.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(S.type));for(let S of y){if(d.has(S.from))continue;d.add(S.from);let T=this.graph.getSymbol(S.from);if(!T)continue;let G=p.depth+1,is=`${l.symbol.id}:${T.id}`;s.set(is,{symbol:T,relation:S.type,depth:G,sourceSymbolId:l.symbol.id});let as=vi[S.type]??1;i+=Math.max(1,as-(G-1)),m.push({id:T.id,depth:G})}}}let a=[...s.values()].sort((l,d)=>l.depth-d.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(on);return u.length===0&&u.push(...c.filter(l=>!on(l)).slice(0,10)),{risk:Ci(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var Oe=class{constructor(e){this.graph=e;this.mapper=new _e(e),this.blast=new Ne(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await nn(t),s=this.mapper.map(e,o),i=this.blast.analyze(e,s,n.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,n={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,n.maxDepth??4)}}};var sn={mode:it.enum(["git_diff","file"]).optional(),filePath:it.string().optional(),depth:it.number().int().min(1).max(10).optional()};async function an(r,e){let t=new Oe(r.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(r.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(r.project.id,r.project.rootPath,{maxDepth:e.depth})}import{z as xi}from"zod";var cn={symbol:xi.string().min(1)};async function un(r,e){let t=v(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let o=new w(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:b(t),count:o.length,dependents:o.map(b)}}import{z as at}from"zod";var ln={from:at.string().min(1),to:at.string().min(1),maxDepth:at.number().int().min(1).max(30).optional()};async function dn(r,e){let t=v(r,e.from),n=v(r,e.to);if(!t||!n)return{found:!1,fromFound:!!t,toFound:!!n,path:[],edges:[]};let s=new w(r.graph).shortestPath(r.project.id,t.id,n.id,e.maxDepth??12);return{found:s.found,distance:s.distance,from:b(t),to:b(n),path:s.symbols.map(b),edges:s.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as ct}from"zod";var mn={symbol:ct.string().min(1),depth:ct.number().int().min(1).max(5).optional(),limit:ct.number().int().min(1).max(200).optional()};async function pn(r,e){let t=v(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let o=new w(r.graph).neighborhood(r.project.id,t.id,e.depth??1);if(!o)return{found:!1,query:e.symbol};let s=e.limit??50;return{found:!0,center:b(o.center),incomingCount:o.incoming.length,outgoingCount:o.outgoing.length,incoming:o.incoming.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:b(i.symbol)})),outgoing:o.outgoing.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:b(i.symbol)}))}}import{z as lt}from"zod";function Mi(r){return r.replaceAll("\\","/").toLowerCase()}var Le=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,n);a&&o.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let s=new Map;for(let i of o){let a=i.kind==="route"?i.symbolId:i.filePath,c=s.get(a);(!c||i.score>c.score)&&s.set(a,i)}return[...s.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let n=Mi(e.filePath),o=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let s=null,i=0;if(n.startsWith("bin/"))s="cli",i=100,o.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(n))s="cli",i=90,o.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(n))s="main",i=90,o.push("main/server file");else if(n.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(n))s="runtime",i=75,o.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(n)){let c=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,u=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(n.startsWith("packages/")||c===0||u>0)&&(s="package",i=n.startsWith("packages/")?70:55,o.push("package/public index"))}return s?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,o.push("no incoming dependency")),{kind:s,score:i,reasons:o}):null}};var fn=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function ut(r){return r.replaceAll("\\","/").toLowerCase()}function Pi(r){let e=ut(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function Ai(r){let e=ut(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var Fe=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=new Set(new Le(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||Pi(i.filePath)||o.has(i.id)||Ai(i)||n.filter(p=>p.to===i.id&&fn.has(p.type)).length>0)continue;let c=n.filter(p=>p.from===i.id&&fn.has(p.type)),u=["no incoming usage edge"],l=50;(i.type==="function"||i.type==="method")&&(l+=20,u.push("callable symbol")),i.type==="property"&&(l-=15),c.length===0&&(l+=10,u.push("no outgoing dependency")),ut(i.filePath).includes("/internal/")&&(l+=10,u.push("internal implementation")),i.name.startsWith("_")&&(l+=5);let m=l>=75?"high":l>=55?"medium":"low";s.push({symbolId:i.id,name:i.name,qualifiedName:i.qualifiedName,type:i.type,filePath:i.filePath,startLine:i.startLine,confidence:m,score:l,reasons:u})}return s.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var yn={confidence:lt.enum(["high","medium","low","all"]).optional(),filePath:lt.string().min(1).optional(),limit:lt.number().int().min(1).max(500).optional()},gn={high:3,medium:2,low:1};async function hn(r,e){let n=new Fe(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=gn[e.confidence];n=n.filter(a=>gn[a.confidence]>=i)}e.filePath&&(n=n.filter(i=>i.filePath===e.filePath));let o=n.length,s=e.limit??100;return{total:o,high:n.filter(i=>i.confidence==="high").length,medium:n.filter(i=>i.confidence==="medium").length,low:n.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:n.slice(0,s)}}import{z as ft}from"zod";import{existsSync as Ji,readFileSync as Qi}from"node:fs";import{join as Yi}from"node:path";var Cd=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Ed,existsSync as Ei,fsyncSync as Rd,mkdirSync as jd,openSync as Td,readFileSync as Ri,renameSync as Id,writeFileSync as _d}from"node:fs";import{dirname as Od,join as ji}from"node:path";function Ti(r){return ji(r.rootPath,".toolnet","work","current.json")}function dt(r){let e=Ti(r);if(!Ei(e))return null;try{let t=JSON.parse(Ri(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as Ii,mkdirSync as Kd,readFileSync as _i,renameSync as $d,writeFileSync as zd}from"node:fs";import{dirname as Gd,join as Ni}from"node:path";function Oi(r){return Ni(r.rootPath,".toolnet","context","session-origin.json")}function mt(r){let e=Oi(r);if(!Ii(e))return null;try{let t=JSON.parse(_i(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function Li(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function De(r){let e=Li(r),t=/(?:agent trước|previous agent|ai trước|phiên trước)/u.test(e),n=/(?:đang làm gì|làm tới đâu|dừng ở đâu|dở ở đâu|stopped where|working on|current task|file nào|last touched|làm gì tiếp|next action|next step)/u.test(e);return t&&n?"summary":/(?:agent trước là ai|previous agent|ai trước là ai|phiên trước là ai)/u.test(e)?"previous_agent":/(?:task hiện tại|current task|đang làm gì|đang làm task nào|dở ở đâu|dừng ở đâu|stopped where)/u.test(e)?"current_task":/(?:tiếp theo|next action|next step|làm gì tiếp|phải làm gì tiếp)/u.test(e)?"next_action":/(?:file cuối|last file|file nào|đang sửa file|last touched)/u.test(e)?"last_file":/(?:blocker|vướng|kẹt|lỗi gì|blocked)/u.test(e)?"blocker":/(?:decision|quyết định|đã chốt|important decision)/u.test(e)?"decision":/(?:đã xong|completed|hoàn thành|done|todo nào xong)/u.test(e)?"completed":/(?:status|trạng thái|tiến độ|progress)/u.test(e)?"status":"summary"}import{existsSync as qi,mkdirSync as Nm,readFileSync as Vi}from"node:fs";import{join as wn}from"node:path";ce();pt();var bm=new P;function Hi(r){return wn(r.rootPath,".toolnet","memory","checkpoints")}function Bi(r){return wn(Hi(r),"latest.json")}function Ui(r){let e=Bi(r);if(!qi(e))return null;try{let t=JSON.parse(Vi(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function vn(r){return Ui(r)}var Xi={previous_agent:{previous_agent:100,task:35,phase:25},current_task:{task:100,request:95,activity:90,phase:75,file:65,next_action:55,blocker:45},next_action:{next_action:100,todo:80,task:65,blocker:60,file:40},last_file:{file:100,task:65,next_action:40},blocker:{blocker:100,task:60,next_action:50,file:35},decision:{decision:100,rule:85,architecture:80,task:45,file:30},completed:{completed:100,progress:70,task:30},status:{progress:100,task:85,phase:75,blocker:65,next_action:60},summary:{task:100,request:98,activity:96,next_action:95,file:90,blocker:85,previous_agent:80,phase:75,completed:60,todo:60,decision:55,rule:54,architecture:53,fix:52,progress:50,test:45,goal:35}},Zi={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function ea(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function f(r,e){let t=e.value.replace(/\s+/g," ").trim();t&&r.push({...e,value:t,score:0})}function ta(r){let e=Yi(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ji(e))return null;try{let n=JSON.parse(Qi(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function ra(r){let e=vn(r);if(!e)return[];let t=[];e.request&&f(t,{kind:"request",value:e.request,source:"checkpoint"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"checkpoint"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"checkpoint"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"checkpoint"});let n=e.files.active.at(-1);n&&f(t,{kind:"file",value:n,source:"checkpoint"});for(let o of e.nextActions)f(t,{kind:"next_action",value:o,source:"checkpoint"});for(let o of e.blockers)f(t,{kind:"blocker",value:o,source:"checkpoint"});for(let o of e.completed.tasks)f(t,{kind:"completed",value:o,source:"checkpoint"});for(let o of e.remaining.tasks)f(t,{kind:"todo",value:o,source:"checkpoint"});for(let o of e.durableFacts)f(t,{kind:o.kind,value:o.content,source:"checkpoint"});return t}function na(r){let e=ta(r);if(!e)return[];let t=[];f(t,{kind:"previous_agent",value:e.source.agent,source:"handoff"}),e.request&&f(t,{kind:"request",value:e.request,source:"handoff"}),e.activity&&f(t,{kind:"activity",value:e.activity,source:"handoff"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"handoff"}),e.current.phase&&f(t,{kind:"phase",value:e.current.phase.title,source:"handoff"}),e.current.task&&f(t,{kind:"task",value:e.current.task.title,source:"handoff"}),e.files.current&&f(t,{kind:"file",value:e.files.current,source:"handoff"}),e.nextAction&&f(t,{kind:"next_action",value:e.nextAction,source:"handoff"});for(let n of e.blockers)f(t,{kind:"blocker",value:n,source:"handoff"});for(let n of e.decisions)f(t,{kind:"decision",value:n,source:"handoff"});for(let n of e.completed.tasks)f(t,{kind:"completed",value:n,source:"handoff"});for(let n of e.remaining.todos)f(t,{kind:"todo",value:n,source:"handoff"});return f(t,{kind:"test",value:`Test status: ${e.tests.status}`,source:"handoff"}),f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"handoff"}),t}function oa(r){let e=mt(r);if(!e)return[];let t=[];return f(t,{kind:"previous_agent",value:e.agent,source:"session-origin"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase,source:"session-origin"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask,source:"session-origin"}),e.lastTouchedFile&&f(t,{kind:"file",value:e.lastTouchedFile,source:"session-origin"}),e.latestNextAction&&f(t,{kind:"next_action",value:e.latestNextAction,source:"session-origin"}),e.latestBlocker&&f(t,{kind:"blocker",value:e.latestBlocker,source:"session-origin"}),e.latestDecision&&f(t,{kind:"decision",value:e.latestDecision,source:"session-origin"}),t}function sa(r){let e=dt(r);if(!e)return[];let t=[];e.currentRequest&&f(t,{kind:"request",value:e.currentRequest,source:"work-state"}),e.currentActivity&&f(t,{kind:"activity",value:e.currentActivity,source:"work-state"}),e.goal&&f(t,{kind:"goal",value:e.goal,source:"work-state"}),e.currentPhase&&f(t,{kind:"phase",value:e.currentPhase.title,source:"work-state"}),e.currentTask&&f(t,{kind:"task",value:e.currentTask.title,source:"work-state"});let n=e.activeFiles?.at(-1)??e.filesTouched.at(-1);n&&f(t,{kind:"file",value:n,source:"work-state"});for(let o of e.nextActions.slice(0,5))f(t,{kind:"next_action",value:o,source:"work-state"});for(let o of e.blockers.slice(-5))f(t,{kind:"blocker",value:o,source:"work-state"});for(let o of e.decisions.slice(-5))f(t,{kind:"decision",value:o,source:"work-state"});for(let o of e.tasks.filter(s=>s.status==="completed").slice(-8))f(t,{kind:"completed",value:o.title,source:"work-state"});for(let o of e.tasks.filter(s=>s.status!=="completed"&&s.status!=="cancelled").slice(0,8))f(t,{kind:"todo",value:o.title,source:"work-state"});for(let o of e.tests.slice(-5))f(t,{kind:"test",value:o,source:"work-state"});return f(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"work-state"}),t}function ia(r,e){let t=Xi[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+Zi[n.source]+Math.max(0,5-o*.01)}))}function aa(r){let e=new Map;for(let t of r){let n=`${t.kind}:${ea(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function Ke(r,e,t={}){let n=De(e),o=[...ra(r),...na(r),...oa(r),...sa(r)],s=aa(ia(n,o)).sort((l,d)=>d.score-l.score),i=Math.max(1,t.maxFacts??12),a=Math.max(300,t.maxChars??3200),c=[],u=0;for(let l of s){if(c.length>=i)break;let d=l.kind.length+l.value.length+l.source.length+16;c.length>0&&u+d>a||(c.push(l),u+=d)}return{intent:n,facts:c,context:{project:{id:r.id,name:r.name},intent:n,selectedFacts:c.map(l=>({kind:l.kind,value:l.value,source:l.source}))},stats:{candidates:o.length,selected:c.length,chars:u}}}var Cn={previous_agent:"Agent tr\u01B0\u1EDBc",request:"Y\xEAu c\u1EA7u hi\u1EC7n t\u1EA1i",activity:"\u0110ang l\xE0m",goal:"M\u1EE5c ti\xEAu",phase:"Phase",task:"Task hi\u1EC7n t\u1EA1i",file:"File hi\u1EC7n t\u1EA1i",todo:"TODO",next_action:"Ti\u1EBFp theo",blocker:"Blocker",decision:"Quy\u1EBFt \u0111\u1ECBnh",rule:"Quy t\u1EAFc",architecture:"Ki\u1EBFn tr\xFAc",fix:"\u0110\xE3 s\u1EEDa",completed:"\u0110\xE3 ho\xE0n th\xE0nh",test:"Test",progress:"Ti\u1EBFn \u0111\u1ED9"},xn=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],ca={previous_agent:["previous_agent"],current_task:["request","activity","task","file","next_action"],next_action:["next_action","task","file","todo"],last_file:["file","task","next_action"],blocker:["blocker"],decision:["decision"],completed:["completed"],status:["progress","task","next_action","blocker"],summary:xn};function ua(r){let e=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)}function la(r){let e=r.filter(n=>n.source==="handoff");if(e.length===0)return r;let t=r.filter(n=>n.source==="checkpoint"&&["rule","architecture","fix"].includes(n.kind));return[...e,...t]}function da(r){let e=new Set,t=[];for(let n of r){let o=`${n.kind}:${n.value.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}`;e.has(o)||(e.add(o),t.push(n))}return t}function Mn(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function ma(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,Mn(n));for(let s of o)t.push(`${Cn[n]}: ${s.value}`)}return t.join(`
9
+ `)}function pa(r,e){let t=ca[e]??xn,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,Mn(o));for(let i of s)n.push(`${Cn[o]}: ${i.value}`)}return n.join(`
10
+ `)}function Pn(r,e){let t=Ke(r,e,{maxFacts:32,maxChars:6400}),n=da(la(t.facts)),o=ua(e)?ma(n,["todo","task","next_action","file"]):pa(n,String(t.intent));return o?{intent:String(t.intent),answer:o,source:n[0]?.source??"none"}:{intent:String(t.intent),answer:"ToolNet ch\u01B0a c\xF3 \u0111\u1EE7 memory cho c\xE2u h\u1ECFi n\xE0y.",source:"none"}}import{existsSync as fa,mkdirSync as ga,readFileSync as ya,renameSync as ha,rmSync as ka,writeFileSync as Sa}from"node:fs";import{join as An}from"node:path";var ba=720*60*1e3;function En(r){return An(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function Y(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function wa(r){let e=Y(r);return[/\btiếp tục\b/u,/\btiếp tục task\b/u,/\blúc nãy\b/u,/\btrước đó\b/u,/\btask trước\b/u,/\bprevious (?:task|session|work)\b/u,/\bcontinue\b/u,/\bresume\b/u,/\bcurrent task\b/u,/\bđang làm gì\b/u].some(t=>t.test(e))}function va(r){if(wa(r))return!1;let e=Y(r),t=e.split(/\s+/u).filter(Boolean);return[/^(?:tại sao|vì sao|sao vậy)\b/u,/^(?:why|why so|why that)\b/u,/^(?:còn|thế|vậy|rồi sao|sau đó)\b/u,/^(?:what about|and what|then what)\b/u,/^(?:cái đó|việc đó|nó|phần đó)\b/u].some(n=>n.test(e))?!0:t.length<=5&&/\b(?:nó|đó|vậy|thế|that|it|this)\b/u.test(e)}function Ca(r,e,t){let n=En(r);if(!fa(n))return null;try{let o=JSON.parse(ya(n,"utf8"));if(o.schema!=="toolnet.memory-conversation.v1"||o.version!==1||o.projectId!==r.id||!Array.isArray(o.focus))return null;let s=Date.parse(o.updatedAt);return!Number.isFinite(s)||e-s>t?null:o}catch{return null}}function xa(r,e=8){let t=new Set,n=[];for(let o of r){let s=o.value.replace(/\s+/gu," ").trim();if(!s)continue;let i=[o.kind,Y(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function Ma(r,e){let t=En(r),n=An(r.rootPath,".toolnet","context");ga(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{Sa(o,JSON.stringify(e,null,2)+`
11
+ `,{encoding:"utf8",mode:384}),ha(o,t)}finally{ka(o,{force:!0})}}function Pa(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
12
+ `)}function Aa(r,e){return r.priorFocus.find(t=>t.kind===e)?.value}function Rn(r){if(!r.usedPriorFocus||r.currentIntent!=="summary"||r.priorFocus.length===0)return null;let e=Y(r.originalQuestion),t=/^(?:tại sao|vì sao|sao vậy|why|why so|why that)\b/u.test(e),n=/^(?:rồi sao|sau đó|tiếp thì sao|thế tiếp theo|then what|what next)\b/u.test(e),o=t?["decision","blocker","next_action","task","file"]:n?["next_action","todo","task","blocker","file","decision"]:["task","next_action","file","decision","blocker"],s={task:"Task li\xEAn quan",next_action:"Vi\u1EC7c ti\u1EBFp theo",file:"File li\xEAn quan",decision:"Quy\u1EBFt \u0111\u1ECBnh li\xEAn quan",blocker:"Blocker",todo:"TODO"},i=[];for(let a of o){let c=Aa(r,a);if(c&&(i.push(`${s[a]??a}: ${c}.`),t&&i.length>=2||!t&&i.length>=3))break}return i.length===0?null:{answer:i.join(" "),intent:"summary",source:"conversation-focus"}}function Ea(r){let e=Y(r);return/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(e)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(e)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(e)}function jn(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??ba,s=Ca(r,n,o),i=!!(s&&s.focus.length>0&&va(e)&&!Ea(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",Pa(s),"","Use the compact focus only to resolve the current follow-up question.","Do not reconstruct or request raw session transcripts."].join(`
13
+ `):e.trim(),c=De(e),l=Ke(r,a,{maxFacts:8,maxChars:1800}).facts.map(m=>({kind:m.kind,value:m.value,source:m.source})),d=xa(i&&s?[...l,...s.focus]:l);return Ma(r,{schema:"toolnet.memory-conversation.v1",version:1,projectId:r.id,updatedAt:new Date(n).toISOString(),lastIntent:c,focus:d}),{question:a,originalQuestion:e,usedPriorFocus:i,previousIntent:s?.lastIntent,currentIntent:c,priorFocus:s?.focus??[],focusCount:d.length}}import{existsSync as Ra,readFileSync as ja}from"node:fs";import{join as Ta}from"node:path";function j(r){return!!r?.trim()}function Tn(r){let e=[],t=[],n=100;j(r.goal)||j(r.request)||(e.push("goal_or_request"),n-=20),j(r.activity)||j(r.current.task?.title)||j(r.current.phase?.title)||(e.push("current_work"),n-=25),j(r.nextAction)||j(r.remaining.todos[0])||(e.push("next_action"),n-=25),r.tests.status!=="unknown"||r.tests.recent.length>0||(r.tests.checks?.length??0)>0||(r.evidence?.commands.length??0)>0||(r.evidence?.references.length??0)>0||(e.push("evidence"),n-=20),j(r.files.current)||r.files.recent.length>0||(r.files.active?.length??0)>0||(r.files.modified?.length??0)>0||(r.files.created?.length??0)>0||(e.push("files"),n-=10),r.tests.status==="failing"&&t.push("tests_failing"),r.blockers.length>0&&t.push("active_blockers"),n=Math.max(0,Math.min(100,n));let u=e.includes("current_work")||e.includes("next_action"),l;return n>=80&&!u?l="high":n>=50?l="medium":l="low",{confidence:l,score:n,missingContext:e,warnings:t}}var In={compact:{completed:3,evidence:3,files:5,blockers:2,maxChars:1800},normal:{completed:10,evidence:10,files:15,blockers:5,maxChars:4200},benchmark:{completed:30,evidence:30,files:40,blockers:10,maxChars:1e4}};function D(r){let e=new Set,t=[];for(let n of r){let o=n?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function K(r){return r.length>0?r.map(e=>`- ${e}`).join(`
14
+ `):"- none"}function Ia(r,e){return r.length<=e?r:[r.slice(0,e).trimEnd(),"","[Structured handoff truncated]"].join(`
15
+ `)}function _n(r,e){if(e)return e;let t=r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim();return/\bbenchmark\b/u.test(t)||/\bdeep handoff\b/u.test(t)||/\bfull handoff\b/u.test(t)||/\btakeover\b/u.test(t)||/\btake over\b/u.test(t)||/tiếp quản/u.test(t)||/bằng chứng đầy đủ/u.test(t)||/evidence.*(?:file|test|command)/u.test(t)?"benchmark":/\bcompact\b/u.test(t)||/\bbrief\b/u.test(t)||/ngắn gọn/u.test(t)||/tóm tắt ngắn/u.test(t)?"compact":"normal"}function _a(r,e="normal"){let t=In[e],n=D([`Source agent: ${r.source.agent}`,`Captured: ${r.capturedAt}`,r.goal?`Goal: ${r.goal}`:void 0,r.request?`Request: ${r.request}`:void 0,r.activity?`Activity: ${r.activity}`:void 0,r.current.phase?`Phase: ${r.current.phase.title} [${r.current.phase.status}]`:void 0,r.current.task?`Task: ${r.current.task.title} [${r.current.task.status}]`:void 0,r.current.file?`Current file: ${r.current.file}`:void 0,`Progress: ${JSON.stringify(r.progress)}`]),o=D([...r.completed.phases.map(u=>`Phase: ${u}`),...r.completed.tasks.map(u=>`Task: ${u}`)]).slice(0,t.completed),s=D([`Tests status: ${r.tests.status}`,...r.tests.recent.map(u=>`Test: ${u}`),...(r.tests.checks??[]).map(u=>`Check [${u.status}] ${u.kind}: ${u.command}`),...(r.evidence?.commands??[]).map(u=>`Command: ${u}`),...(r.evidence?.references??[]).map(u=>`Reference: ${u}`),...r.decisions.map(u=>`Decision: ${u}`),...r.attention.map(u=>`Attention: ${u}`)]).slice(0,t.evidence),i=D([r.files.current,...(r.files.active??[]).map(u=>`Active: ${u}`),...(r.files.modified??[]).map(u=>`Modified: ${u}`),...(r.files.created??[]).map(u=>`Created: ${u}`),...(r.files.deleted??[]).map(u=>`Deleted: ${u}`),...r.files.recent.map(u=>`Recent: ${u}`)]).slice(0,t.files),a=D(r.blockers).slice(0,t.blockers),c=D([r.nextAction,r.nextAction?void 0:r.remaining.todos[0]]).slice(0,1);return{currentState:n,completed:o,evidence:s,filesTouched:i,blockers:a,nextAction:c}}function Na(r,e,t){return[`HANDOFF_DETAIL: ${e}`,`CONTINUITY_CONFIDENCE: ${t.confidence}`,`QUALITY_SCORE: ${t.score}`,`MISSING_CONTEXT: ${t.missingContext.length>0?t.missingContext.join(", "):"none"}`,`QUALITY_WARNINGS: ${t.warnings.length>0?t.warnings.join(", "):"none"}`,"","CURRENT_STATE",K(r.currentState),"","COMPLETED",K(r.completed),"","EVIDENCE",K(r.evidence),"","FILES_TOUCHED",K(r.filesTouched),"","BLOCKERS",K(r.blockers),"","NEXT_ACTION",K(r.nextAction)].join(`
16
+ `)}function Nn(r,e="normal"){let t=Ta(r.rootPath,".toolnet","work","handoff-latest.json");if(!Ra(t))return null;try{let o=JSON.parse(ja(t,"utf8")).continuity;if(!o||o.schema!=="toolnet.handoff.v2"||o.version!==2)return null;let s=_a(o,e),i=Tn(o),a=Ia(Na(s,e,i),In[e].maxChars);return{detail:e,data:s,quality:i,text:a}}catch{return null}}function Oa(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}var La=[/\bhandoff\b/u,/\bcontinuity\b/u,/\bcontinue\b/u,/\bresume\b/u,/\btakeover\b/u,/\btake over\b/u,/tiếp tục/u,/tiếp quản/u,/bàn giao/u,/dừng ở đâu/u,/đang làm gì/u],Fa=[/\bcurrent state\b/u,/\bcurrent task\b/u,/\bevidence\b/u,/\breport locations?\b/u,/\bfiles?\b/u,/\burls?\b/u,/\bassets?\b/u,/\btests?\b/u,/\bcommands?\b/u,/\bblockers?\b/u,/\bnext actions?\b/u,/trạng thái hiện tại/u,/task hiện tại/u,/bằng chứng/u,/vị trí báo cáo/u,/file/u,/url/u,/blocker/u,/việc tiếp theo/u,/bước tiếp theo/u],Da=[/\bsummarize\b/u,/\bsummary\b/u,/\bfull state\b/u,/\bfull context\b/u,/tóm tắt/u,/đầy đủ/u,/toàn bộ trạng thái/u];function Ka(r){let e=0;for(let t of Fa)t.test(r)&&(e+=1);return e}function On(r,e){let t=Oa(r);if(/(?:^|\s)(?:todo|to-do)(?:\s|$)/u.test(t)||/(?:việc|task)\s+(?:còn lại|chưa làm|chưa xong|chưa hoàn thành)/u.test(t)||/(?:còn|các)\s+(?:todo|việc)\b/u.test(t))return!1;if(e==="summary"||e==="status")return!0;if(!t)return!1;let o=La.some(a=>a.test(t)),s=Da.some(a=>a.test(t)),i=Ka(t);return!!(o&&i>=1||s&&i>=2||i>=4)}var Fn={question:ft.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:ft.enum(["local"]).optional().describe("Returns deterministic local memory only. No external AI is used."),detail:ft.enum(["compact","normal","benchmark"]).optional().describe("Handoff detail level. compact=minimal, normal=standard, benchmark=deep evidence/files/tests for agent takeover.")};function Ln(r,e,t,n,o){if(!On(e,t))return{answer:n};let s=_n(e,o),i=Nn(r.project,s);return i?{answer:i.text,handoff:i.data,detail:i.detail,confidence:i.quality.confidence,missingContext:i.quality.missingContext,quality:i.quality}:{answer:n}}async function Dn(r,e){let t=jn(r.project,e.question),n=Rn(t);if(n)return{...Ln(r,t.originalQuestion,String(n.intent),n.answer,e.detail),mode:"local",usedAi:!1,source:n.source,intent:n.intent};let o=Pn(r.project,t.originalQuestion),s=Ln(r,t.originalQuestion,String(o.intent),o.answer,e.detail);return"handoff"in s?{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent,routing:"deterministic-handoff"}:{...s,mode:"local",usedAi:!1,source:o.source,intent:o.intent}}import{z as Vn}from"zod";import{chmodSync as mp,existsSync as Kn,mkdirSync as pp,readFileSync as $n,renameSync as fp,writeFileSync as gp}from"node:fs";import{dirname as hp,join as X}from"node:path";var zn="toolnet.context-offload.v1",$a="toolnet.context-offload-asset.v1";function Wn(r){return X(r,".toolnet","offload")}function Gn(r){return X(Wn(r),"assets")}function za(r){return X(Wn(r),"graph.json")}function gt(){return{schema:zn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Wa(r){let e=za(r);if(!Kn(e))return gt();try{let t=JSON.parse($n(e,"utf8"));return t.schema!==zn||t.version!==1||!Array.isArray(t.nodes)?gt():t}catch{return gt()}}function Ga(r,e){let t=e.trim().toLowerCase();if(!/^[a-f0-9]{8,64}$/u.test(t))throw new Error("Invalid context offload asset reference.");if(t.length===64&&Kn(X(Gn(r),`${t}.json`)))return t;let n=Wa(r).nodes.map(o=>o.id).filter(o=>o.startsWith(t));if(n.length===0)throw new Error(`Context offload asset not found: ${e}`);if(n.length>1)throw new Error(`Ambiguous context offload asset reference: ${e}`);return n[0]}function qn(r,e,t=6e3){let n=Ga(r,e),o=$n(X(Gn(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==$a||s.version!==1||s.assetId!==n)throw new Error(`Invalid context offload asset: ${e}`);let i=Math.max(200,Math.min(2e4,Math.floor(t)));return{assetId:n,kind:s.event.type,bytes:Buffer.byteLength(o,"utf8"),truncated:o.length>i,content:o.length>i?`${o.slice(0,i)}
17
+ [truncated]`:o}}var Hn={assetId:Vn.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:Vn.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function Bn(r,e){return qn(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as Qn}from"zod";import{chmodSync as Cp,existsSync as qa,mkdirSync as xp,readFileSync as Va,readdirSync as Ha,renameSync as Mp,statSync as Ba,writeFileSync as Pp}from"node:fs";import{join as Un}from"node:path";var Ua="toolnet.skill-memory.v1";function Ja(r,e=Number.MAX_SAFE_INTEGER){let t=new Set,n=[];for(let o of r){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!t.has(i)&&(t.add(i),n.push(s),n.length>=e))break}return n}function Qa(r){return Un(r.rootPath,".toolnet","memory","skills")}function Ya(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===Ua&&t.version===1&&t.projectId===e&&typeof t.id=="string"&&typeof t.task=="string"&&Array.isArray(t.steps)&&Array.isArray(t.verification)&&Array.isArray(t.files)}function Xa(r){let e=Qa(r);if(!qa(e))return[];if(!Ba(e).isDirectory())return[];let t=[];for(let n of Ha(e)){if(!n.endsWith(".json"))continue;let o=Un(e,n);try{let s=JSON.parse(Va(o,"utf8"));Ya(s,r.id)&&t.push(s)}catch{}}return t.sort((n,o)=>{let s=o.createdAt.localeCompare(n.createdAt);return s!==0?s:n.id.localeCompare(o.id)})}function Za(r){return Ja(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function ec(r,e){let t=e.normalize("NFKC").toLowerCase().trim();if(!t)return 0;if(r.id.toLowerCase()===t||r.fingerprint.toLowerCase()===t)return 1e3;let n=[r.title,r.task,r.summary,...r.steps,...r.verification,...r.files].join(`
18
+ `).normalize("NFKC").toLowerCase(),o=0;r.task.normalize("NFKC").toLowerCase().includes(t)&&(o+=40),r.title.normalize("NFKC").toLowerCase().includes(t)&&(o+=30);for(let s of Za(t))n.includes(s)&&(o+=5),r.task.normalize("NFKC").toLowerCase().includes(s)&&(o+=4),r.files.some(i=>i.toLowerCase().includes(s))&&(o+=3);return o}function Jn(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return Xa(r).map(o=>({...o,score:ec(o,e)})).filter(o=>o.score>0).sort((o,s)=>s.score!==o.score?s.score-o.score:s.createdAt.localeCompare(o.createdAt)).slice(0,n)}var Yn={query:Qn.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:Qn.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function Xn(r,e){let t=Jn(r.project,e.query,e.limit??5);return{schema:"toolnet.skill-memory-search.v1",query:e.query,count:t.length,matches:t}}import{z as lo}from"zod";var Zn="wiki/state.v1.json";function tc(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function rc(r,e){let t=JSON.parse(r);if(t.schema!=="toolnet.wiki.v1"||t.version!==1||t.projectId!==e.id||!Array.isArray(t.pages)||!Array.isArray(t.revisions))throw new Error("Invalid ToolNet Wiki state");return t}var C=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Zn);if(!e){let t=tc(this.project);return await this.save(t),t}return rc(e,this.project)}async save(e){await this.storage.put(Zn,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as ro}from"node:crypto";var k=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function Z(r){let e=new Set,t=[];for(let n of r){let o=n.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(o))}return t}function ee(r){let e=r.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new k("Invalid Wiki slug",400);return e}function eo(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(ee(n))}return Z(e)}function nc(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function to(r){return{id:`revision-${ro()}`,pageId:r.id,slug:r.slug,revision:r.revision,title:r.title,...r.summary?{summary:r.summary}:{},content:r.content,tags:[...r.tags],links:[...r.links],createdAt:r.updatedAt}}function L(r){return structuredClone(r)}var x=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async summary(){let e=await this.ensureState(),t=new Set(e.pages.flatMap(n=>n.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:Z(e.pages.flatMap(n=>n.tags)).sort((n,o)=>n.localeCompare(o)),links:e.pages.reduce((n,o)=>n+o.links.length,0),orphanPages:e.pages.filter(n=>n.links.length===0&&!t.has(n.slug)).length,automatedPages:e.pages.filter(n=>n.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return L([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=ee(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new k(`Wiki page not found: ${e}`,404);return L(o)}async createPage(e){return this.mutate(t=>{let n=e.title.trim(),o=e.content.trim();if(!n)throw new k("Wiki title is required",400);let s=ee(e.slug??n);if(t.pages.some(c=>c.slug===s))throw new k(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${ro()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:Z(e.tags??[]),links:eo(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(to(a)),L(a)})}async updatePage(e,t){return this.mutate(n=>{let o=ee(e),s=n.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new k(`Wiki page not found: ${e}`,404);if(t.title!==void 0){let i=t.title.trim();if(!i)throw new k("Wiki title is required",400);s.title=i}if(t.summary!==void 0){let i=t.summary.trim();i?s.summary=i:delete s.summary}return t.content!==void 0&&(s.content=t.content.trim(),s.links=eo(s.content)),t.tags!==void 0&&(s.tags=Z(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(to(s)),L(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return L(n.revisions.filter(o=>o.pageId===t.id).sort((o,s)=>s.revision-o.revision))}async backlinks(e){let t=await this.getPage(e),n=await this.ensureState();return L(n.pages.filter(o=>o.links.includes(t.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(e,t=10){let n=await this.ensureState(),o=Z(nc(e));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(t))),i=[];for(let a of n.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),m=a.tags.map(y=>y.toLowerCase()),p=0;for(let y of o)u===y&&(p+=12),c===y&&(p+=10),c.includes(y)&&(p+=6),u.includes(y)&&(p+=5),m.some(S=>S===y)?p+=5:m.some(S=>S.includes(y))&&(p+=3),l.includes(y)&&(p+=2),d.includes(y)&&(p+=1);p>0&&i.push({page:L(a),score:p})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};import{createHash as oc,randomUUID as no}from"node:crypto";var oo="wiki/governance.v1.json",co="toolnet.knowledge-governance.v1",so=500,te={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function sc(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function yt(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function io(r){return oc("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ic(r){let e=[r.title,r.summary??"",r.content.slice(0,2e3),...r.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function ac(r){let e=r.sourceType==="skill"?.96:r.sourceType==="memory"?.94:.88,t=r.tags.map(n=>n.toLowerCase());return(t.includes("permanent")||t.includes("task"))&&(e+=.03),r.content.length>=200&&(e+=.02),r.content.length<80&&(e-=.05),r.title.length<4&&(e-=.05),sc(e)}function ao(r){let e=new Date().toISOString();return{schema:co,version:1,projectId:r,policy:{...te},reviews:[],audit:[],createdAt:e,updatedAt:e}}function uo(r){let e=r.autoApproveThreshold??te.autoApproveThreshold,t=r.criticalApproveThreshold??te.criticalApproveThreshold,n=r.staleAfterDays??te.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new k("Invalid autoApproveThreshold",400);if(!Number.isFinite(t)||t<.5||t>1)throw new k("Invalid criticalApproveThreshold",400);if(!Number.isInteger(n)||n<1||n>3650)throw new k("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:t,staleAfterDays:n}}var re=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(oo);if(!e){let t=ao(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==co||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:uo(t.policy??te)}}catch{let t=ao(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(oo,JSON.stringify(e,null,2),"application/json")}},ne=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,t,n,o={}){e.audit.push({id:no(),action:t,principal:n,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),e.audit.length>so&&(e.audit=e.audit.slice(-so))}async mutate(e){let t,n=this.queue.then(async()=>{let o=await this.ensureState();t=await e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=n.then(()=>{},()=>{}),await n,t}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,t){return this.mutate(n=>(n.policy=uo({...n.policy,...e}),this.audit(n,"policy:update",t,{metadata:{...n.policy}}),{...n.policy}))}async summary(){let e=await this.ensureState(),t=n=>e.reviews.filter(o=>o.status===n).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:t("pending"),approved:t("approved"),rejected:t("rejected"),superseded:t("superseded"),criticalPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="critical").length,conflictPending:e.reviews.filter(n=>n.status==="pending"&&n.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let t=await this.ensureState();return structuredClone(t.reviews.filter(n=>!e||n.status===e).sort((n,o)=>o.updatedAt.localeCompare(n.updatedAt)))}async auditLog(e=100){let t=await this.ensureState(),n=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(t.audit.slice(-n).reverse())}async assess(e,t){let n=await this.ensureState(),o=ac(e),s=yt(e.title),i=t.filter(l=>l.slug!==e.slug&&yt(l.title)===s&&io(l.content)!==io(e.content)).map(l=>l.slug),a=ic(e),c=[];o<n.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<n.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<n.policy.autoApproveThreshold||a&&o<n.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,t){let n=await this.assess(e,t);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:n,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:n,review:structuredClone(s)};if(!n.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:n.confidence,risk:n.risk}}),{allowed:!0,mode:"auto-approved",assessment:n};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(s)};let i=new Date().toISOString(),a={id:no(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:n.confidence,risk:n.risk,reasons:[...n.reasons],conflicts:[...n.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(a)}})}async markApplied(e,t){await this.mutate(n=>{let o=n.reviews.find(s=>s.sourceKey===e&&s.digest===t&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(n,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:e}))})}async decide(e,t,n){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===e);if(!s)throw new k(`Governance review not found: ${e}`,404);if(s.status!=="pending")throw new k("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=t.principal,s.updatedAt=i,t.note?.trim()&&(s.reviewNote=t.note.trim()),t.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s);if(t.action==="supersede")return s.status="superseded",t.targetReviewId&&(s.supersededBy=t.targetReviewId),this.audit(o,"knowledge:superseded",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:t.targetReviewId}}),structuredClone(s);if(t.action==="merge"){if(!t.targetReviewId)throw new k("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===t.targetReviewId);if(!u)throw new k("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await n.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new k(`Wiki page '${s.slug}' is manually managed`,409);return c?await n.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await n.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let t=await this.ensureState(),n=await e.listPages(),o=Date.now(),s=t.policy.staleAfterDays*864e5,i=n.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of n){let d=yt(l.title),m=a.get(d)??[];m.push(l),a.set(d,m)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(m=>m.slug)})),u=t.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:n.length,automatedPages:n.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:n.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<t.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var mo={query:lo.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:lo.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function po(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new x(new C(t,r.project));await n.initialize();let o=await n.search(e.query,e.limit??5);return{schema:"toolnet.wiki-search.v1",query:e.query,count:o.length,results:o.map(({page:s,score:i})=>({id:s.id,slug:s.slug,title:s.title,summary:s.summary,tags:s.tags,links:s.links,revision:s.revision,updatedAt:s.updatedAt,score:i}))}}import{z as cc}from"zod";var fo={page:cc.string().min(1).max(200).describe("Wiki page slug or page id.")};async function go(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new x(new C(t,r.project));await n.initialize();let o=await n.getPage(e.page),s=await n.backlinks(o.slug);return{schema:"toolnet.wiki-read.v1",page:o,backlinks:s.map(i=>({slug:i.slug,title:i.title}))}}import{z as uc}from"zod";var yo={includePending:uc.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function ho(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new ne(new re(t,r.project));await n.initialize();let o=new x(new C(t,r.project));await o.initialize();let s=await n.summary(),i=await n.quality(o),a=e.includePending?(await n.listReviews("pending")).slice(0,10).map(c=>({id:c.id,sourceType:c.sourceType,title:c.title,confidence:c.confidence,risk:c.risk,reasons:c.reasons})):void 0;return{schema:"toolnet.knowledge-governance-status.v1",summary:s,quality:{stalePages:i.stalePages.length,duplicateTitles:i.duplicateTitles.length,pendingReviews:i.pendingReviews,conflicts:i.conflicts},...a?{pending:a}:{}}}var ko={};function So(r){let e=r.project.id;return{project:{id:e,name:r.project.name,remote:r.project.remote??r.project.name,rootPath:r.project.rootPath},runtime:r.runtime?{phase:r.runtime.phase,dependencies:{memory:{...r.runtime.dependencies.memory},graph:{...r.runtime.dependencies.graph},semantic:{...r.runtime.dependencies.semantic}},metrics:{...r.runtime.metrics},errors:[...r.runtime.errors],dataSource:r.runtime.dataSource,lastUpdatedAt:r.runtime.lastUpdatedAt}:null,storage:r.storage?.name??null,data:{memories:r.memory.exportProject(e).length,graphSymbols:r.graph.allSymbols(e).length,graphEdges:r.graph.allEdges(e).length,semanticAvailable:r.codeSemantic!==void 0}}}function h(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}var mc=["# ToolNet Memory \u2014 Persistent Project Continuity","","ToolNet Memory provides persistent work continuity across coding agents and sessions.","","CONTINUITY RULES:","","1. When the user asks to continue, resume, finish, pick up, or return to previous work,"," call memory_agent_ask BEFORE reconstructing previous work from git, files, or session history.","",'2. Use memory_agent_ask with mode="local" for direct continuity facts such as:'," - current task"," - completed work"," - current/last file"," - TODOs"," - blockers"," - next action","",'3. ToolNet Memory Agent is local-only; use mode="local" for all continuity questions.',"","4. NEVER reconstruct previous work by reading or searching raw agent/session history, including:"," - .toolnet/journal/**, .toolnet/runtime/sources/**, and legacy .toolnet/sessions/**"," - state.json"," - events.jsonl"," - raw transcripts"," - ~/.gemini/antigravity-cli/brain/**"," - another coding agent's internal session history","","5. Do not search the filesystem for the implementation or JSON schema of memory_agent_ask."," Invoke the MCP tool directly.","","6. After ToolNet resolves continuity, inspect the current repository only to verify current truth."," Current repository evidence overrides stale memory.","","7. Do not ask the user to repeat project context already available through ToolNet Memory.","","8. Do not call memory_agent_ask for unrelated coding questions when current context is sufficient.","","9. Large tool/file payloads may be stored outside prompt context."," If the compact graph references a needed asset, call context_offload_read.","","10. Never bulk-load offloaded assets. Read only the minimum asset required."].join("\\n");function pc(r){let e=new lc({name:"toolnet-memory",version:"0.1.0"},{instructions:mc});return e.tool("memory_search","Search relevant long-term memory for the current project.",br,async t=>h(await wr(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Mr,async t=>h(await Pr(r,t))),e.tool("memory_forget","Delete a memory by id.",Ar,async t=>h(await Er(r,t))),e.tool("find_symbol","Find code symbols by exact name.",Rr,async t=>h(await jr(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Ir,async t=>h(await _r(r,t))),e.tool("code_search","Search indexed code symbols and files.",Or,async t=>h(await Lr(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",Dr,async t=>h(await Kr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Vr,async t=>h(await Hr(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Ur,async t=>h(await Jr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>h(await Qr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Xr,async t=>h(await Zr(r,t))),e.tool("semantic_code_search","Legacy-compatible local code search using SQLite FTS5/BM25 lexical ranking. No embeddings or vector database.",tn,async t=>h(await rn(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",$r,async t=>h(await zr(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>h(await Wr(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Gr,async t=>h(await qr(r,t))),e.tool("impact_guard","Analyze blast radius before or after code changes. Maps changed files/lines to symbols, follows reverse dependencies, assigns risk and suggests verification targets.",sn,async t=>h(await an(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",cn,async t=>h(await un(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",ln,async t=>h(await dn(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",mn,async t=>h(await pn(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",yn,async t=>h(await hn(r,t))),e.tool("memory_agent_ask",["Ask ToolNet Memory Agent about previous project work.","CALL THIS TOOL before guessing when the user asks to continue/resume previous work,","mentions a previous agent/session, asks what was unfinished, what file was last touched,","which TODOs are complete, blockers, decisions, or what should happen next.","Use mode=local for continuity questions. Memory Agent is deterministic and local-only; no external AI provider is used.","Do not use it for unrelated coding questions when current repository context is already sufficient.","Returns concise selected memory instead of raw transcripts or full memory dumps.","Short conversational follow-ups are supported using compact ToolNet Memory focus; raw transcripts are never replayed."].join(" "),Fn,async t=>h(await Dn(r,t))),e.tool("context_offload_read",["Read one external ToolNet tool/file asset referenced by the compact context graph.","Use only when needed for the current task.","Never bulk-load all offloaded assets."].join(" "),Hn,async t=>h(await Bn(r,t))),e.tool("skill_memory_search",["Search successful ToolNet project work promoted into reusable Skill Memory SOPs.","Call this before repeating a task that may have been solved successfully before.","Returns compact procedure steps, files and verification evidence.","Raw transcripts are never returned."].join(" "),Yn,async t=>h(await Xn(r,t))),e.tool("wiki_search",["Search the ToolNet project Wiki for durable project knowledge.","Use Wiki before rereading broad project history when a maintained knowledge page may exist.","Returns compact metadata; call wiki_read only for the page needed."].join(" "),mo,async t=>h(await po(r,t))),e.tool("wiki_read",["Read one ToolNet Wiki page by slug or id.","Returns the maintained page plus compact backlinks.","Do not bulk-read unrelated Wiki pages."].join(" "),fo,async t=>h(await go(r,t))),e.tool("toolnet_status",["Inspect ToolNet MCP runtime health.","Returns dependency readiness, degraded state, retry counts,","startup timing, hydration timing, storage source and project data counts."].join(" "),ko,async()=>h(So(r))),e.tool("knowledge_governance_status",["Inspect ToolNet Knowledge Governance health.","Returns review counts, confidence, conflicts, stale knowledge, and optional compact pending reviews.","Use this before trusting or changing important durable project knowledge."].join(" "),yo,async t=>h(await ho(r,t))),e}async function bo(r){let e=pc(r),t=new dc;await e.connect(t)}function wo(){return new Date().toISOString()}function M(r){r.lastUpdatedAt=wo()}function $e(r=Date.now()){return{phase:"starting",dependencies:{memory:{state:"idle",attempts:0},graph:{state:"idle",attempts:0},semantic:{state:"idle",attempts:0}},metrics:{processStartedAtMs:r,hydrationRuns:0,retryCount:0},errors:[],dataSource:"none",lastUpdatedAt:wo()}}function vo(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",M(r)}function Co(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,M(r)}function ze(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,M(r))}function We(r,e){r.dependencies[e].attempts+=1,M(r)}function Ge(r){r.metrics.retryCount+=1,M(r)}function $(r,e,t=Date.now()){let n=r.dependencies[e];n.state="ready",n.lastError=void 0,n.readyAfterMs=t-r.metrics.processStartedAtMs,M(r)}function oe(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),M(r)}function xo(r,e=Date.now()){r.metrics.hydrationFinishedAtMs=e,r.metrics.hydrationStartedAtMs!==void 0&&(r.metrics.hydrationMs=e-r.metrics.hydrationStartedAtMs),r.errors=Object.entries(r.dependencies).filter(([,n])=>n.state==="failed").map(([n,o])=>`${n}: ${o.lastError??"unknown error"}`);let t=Object.values(r.dependencies).every(n=>n.state==="ready");r.phase=t?"ready":"degraded",M(r)}function Mo(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],M(r)}async function qe(r,e){let t=Math.max(1,Math.floor(e.attempts)),n;for(let o=1;o<=t;o+=1){e.onAttempt?.(o);try{return await r()}catch(s){if(n=s,o>=t)break;e.onRetry?.(o,s),e.delayMs>0&&await new Promise(i=>{setTimeout(i,e.delayMs)})}}throw n instanceof Error?n:new Error(String(n??"operation failed"))}function ns(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function Hc(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function Bc(r){let e=r.runtime;return e?{memory:e.dependencies.memory.state==="ready"?"ready":"failed",graph:e.dependencies.graph.state==="ready"?"ready":"failed",semantic:e.dependencies.semantic.state==="ready"?"ready":"failed",errors:[...e.errors]}:{memory:"failed",graph:"failed",semantic:"failed",errors:["runtime unavailable"]}}async function os(r){let e=r.runtime??$e(Date.now());r.runtime=e,Co(e);let t=ns(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=Hc(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await xr(r.project,{timeoutMs:ns(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});o&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(o.memory),$(e,"memory")),e.dependencies.graph.state!=="ready"&&(o.graph&&r.graph.import(o.graph.symbols,o.graph.edges),$(e,"graph")))}try{let[{loadConfig:o},s]=await Promise.all([Promise.resolve().then(()=>(pt(),bn)),Promise.resolve().then(()=>(Jo(),Uo))]),i=o(),a=s.createStorageProvider({provider:i.storage.provider,r2:i.storage.r2,s3:i.storage.s3,huggingface:i.storage.huggingface,localRoot:i.storage.localRoot}),c=s.withStorageRetry(a,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),u=new s.ProjectScopedStorageProvider(c,r.project.id,r.project.name,r.project.remote??r.project.name),l=new s.MemoryStore(u);r.storage=u,r.memoryStore=l;let d=e.dependencies.memory.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",ze(e,"memory");try{let p=await qe(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"memory")},onRetry:()=>{Ge(e)}});r.memory.importRecords(p),$(e,"memory")}catch(p){oe(e,"memory",p)}})(),m=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",ze(e,"graph");try{let p=await qe(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"graph")},onRetry:()=>{Ge(e)}});p&&r.graph.import(p.symbols,p.edges),$(e,"graph")}catch(p){oe(e,"graph",p)}})();if(await Promise.all([d,m]),e.dependencies.semantic.state!=="ready"){ze(e,"semantic");try{let{SemanticCodeEngine:p}=await Promise.resolve().then(()=>(rs(),ts)),y=new p({projectId:r.project.id,rootPath:r.project.rootPath,storage:u,graph:r.graph});await qe(()=>y.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{We(e,"semantic")},onRetry:()=>{Ge(e)}}),r.codeSemantic=y,$(e,"semantic")}catch(p){oe(e,"semantic",p)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&oe(e,s,o)}return xo(e),Bc(r)}function ss(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function Uc(){let r=Date.now(),e=new ke().detect(),t=new pe,n=new Ce(t),o=new xe,s=new Me(o),i=$e(r),a={project:e,memory:t,retrieval:n,graph:o,references:s,runtime:i};await bo(a),vo(i);let c=async()=>{try{await os(a),i.phase==="degraded"&&setTimeout(()=>{c()},ss()).unref()}catch(u){Mo(i,u),setTimeout(()=>{i.phase="degraded",c()},ss()).unref()}};c()}Uc().catch(r=>{console.error(r),process.exit(1)});