toolnet-memory 0.3.15 → 0.3.16

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