toolnet-memory 0.3.3 → 0.3.5
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/agy-hook.js +79 -69
- package/bundle/agy.js +71 -61
- package/bundle/api.js +16 -16
- package/bundle/auto-integrate.js +377 -71
- package/bundle/claude-hook.js +102 -36
- package/bundle/codex-context.js +10 -10
- package/bundle/codex.js +67 -65
- package/bundle/context-runtime.js +30 -30
- package/bundle/context.js +15 -15
- package/bundle/continuity-certify.js +14 -13
- package/bundle/doctor.js +5 -5
- package/bundle/full-index.js +22 -18
- package/bundle/graph-index.js +2 -2
- package/bundle/handoff-refresh.js +7 -7
- package/bundle/init.js +386 -80
- package/bundle/learner.js +1 -1
- package/bundle/mcp.js +19 -19
- package/bundle/memory-agent.js +11 -11
- package/bundle/memory-query.js +5 -5
- package/bundle/opencode.js +442 -121
- package/bundle/project-manual.js +3 -3
- package/bundle/provider.js +5 -2
- package/bundle/recovery-certify.js +21 -20
- package/bundle/runtime.js +4 -4
- package/bundle/semantic.js +5 -5
- package/bundle/service-cli.js +2 -2
- package/bundle/setup.js +376 -70
- package/bundle/snapshot.js +4 -4
- package/bundle/update.js +4 -4
- package/bundle/work-continuity.js +7 -7
- package/package.json +1 -1
package/bundle/mcp.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
var
|
|
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 Da(){let r=process.env.TOOLNET_GLOBAL_ENV??Na(Oa(),".config","toolnet-memory",".env");if(!Ia(r))return;let e=_a(r,"utf8");for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7));let n=o.indexOf("=");if(n<=0)continue;let s=o.slice(0,n).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=La(o.slice(n+1)))}}var Sn=g(()=>{"use strict";Da()});var kn={};ve(kn,{loadConfig:()=>Ka});function ce(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function le(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function Ka(){return{memory:{autoCapture:ce(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ce(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ce(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ce(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:le(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:le(process.env.MEMORY_RERANK_TOP,10),finalContext:le(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:le(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:ce(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:le(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Cn=g(()=>{"use strict";Sn()});var Pn=g(()=>{"use strict"});import{DeleteObjectCommand as Fa,GetObjectCommand as $a,HeadObjectCommand as Ga,ListObjectsV2Command as Ua,PutObjectCommand as Wa,S3Client as za}from"@aws-sdk/client-s3";import{getSignedUrl as Ba}from"@aws-sdk/s3-request-presigner";var de,Et=g(()=>{"use strict";de=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new za({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Wa({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await Ba(this.client,new $a({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`HF download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Ga({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 Fa({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new Ua({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}}});import{access as An,mkdir as Va,readFile as qa,readdir as Ha,rm as Ja,stat as xn,writeFile as Ya}from"node:fs/promises";import{dirname as Qa,join as Xa,relative as Mn,resolve as Za}from"node:path";var z,Rt=g(()=>{"use strict";z=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Za(this.root,t)}async put(e,t){let o=this.path(e);await Va(Qa(o),{recursive:!0}),await Ya(o,t)}async get(e){try{return await qa(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 An(this.path(e)),!0}catch{return!1}}async delete(e){await Ja(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),o=[];try{await An(t)}catch{return o}let n=async i=>{let a=await Ha(i,{withFileTypes:!0});for(let c of a){let d=Xa(i,c.name);if(c.isDirectory()){await n(d);continue}let l=await xn(d);o.push({key:Mn(this.root,d),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await xn(t);return s.isDirectory()?await n(t):o.push({key:Mn(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),o}}});import{DeleteObjectCommand as ec,GetObjectCommand as tc,HeadObjectCommand as rc,ListObjectsV2Command as oc,PutObjectCommand as nc,S3Client as sc}from"@aws-sdk/client-s3";import{getSignedUrl as ic}from"@aws-sdk/s3-request-presigner";var B,jt=g(()=>{"use strict";B=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new sc({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,o="application/octet-stream"){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new nc({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await ic(this.client,new tc({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(t,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`${this.name} download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new rc({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 ec({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new oc({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of n.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return t}}});import{homedir as ac}from"node:os";import{join as cc}from"node:path";function Tt(r,e){return console.warn(e),new z(r)}function lc(r){let e=r.localRoot??cc(ac(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new B({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Tt(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 B({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Tt(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 de({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Tt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new z(e)}var En=g(()=>{"use strict";Et();Rt();jt()});var It,Rn=g(()=>{"use strict";It=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let o=JSON.parse(t);if(!Array.isArray(o))throw new Error("Invalid memory snapshot");return o}async save(e,t){let o=JSON.stringify(t,null,2);await this.storage.put(this.key(e),o,"application/json")}}});var jn=g(()=>{"use strict";Rt()});var Tn=g(()=>{"use strict";Et()});var In=g(()=>{"use strict";jt()});var _t,_n=g(()=>{"use strict";_t=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 o=JSON.parse(t);if(o.version!==1||o.projectId!==e||!Array.isArray(o.records))throw new Error("Invalid vector snapshot");return o}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Ot,On=g(()=>{"use strict";Ot=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 Nt,Nn=g(()=>{"use strict";Nt=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 ue,Lt=g(()=>{"use strict";ue=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 me,Dt=g(()=>{"use strict";me=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 dc(r){return new Promise(e=>setTimeout(e,r))}async function Ln(r,e={}){let t=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,n=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await r()}catch(a){if(s=a,i>=t)break;let c=Math.min(n,o*2**(i-1)),d=Math.floor(Math.random()*Math.max(1,c*.2));await dc(c+d)}throw s}var Dn=g(()=>{"use strict"});function mc(r,e={}){return new Proxy(r,{get(t,o){let n=Reflect.get(t,o,t);return typeof n!="function"?n:uc.has(o)?(...s)=>Ln(()=>Promise.resolve(n.apply(t,s)),e):n.bind(t)}})}var uc,Kn=g(()=>{"use strict";Dn();uc=new Set(["put","get","getText","delete","list"])});function Kt(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 Ft=g(()=>{"use strict"});function $t(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(o)return`${o[1]}memory/records/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),o)return`${o[1]}memory/vectors/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),o)return`${o[1]}code/graph/${o[2]}`;let n=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:e))}var Gt=g(()=>{"use strict"});var Ut,Fn=g(()=>{"use strict";Ft();Gt();Ut=class{constructor(e,t,o,n){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=o,this.folder=Kt(n??o),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),o=t,n=await this.provider.getText(e);if(n){let i;try{i=JSON.parse(n)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(o=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,updatedAt:t};await this.provider.put(e,JSON.stringify(s,null,2)+`
|
|
3
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e
|
|
4
|
-
`).trim();if(
|
|
5
|
-
`)),ds=await n.embedMany(ls);for(let A=0;A<D.length;A++){let I=D[A],K=ds[A];if(!(!I||!K||K.length===0)){if(O===void 0&&(O=K.length),K.length!==O){console.warn(`[code-semantic] skip dimension mismatch: ${K.length} != ${O}`);continue}this.vectors.upsert({id:I.id,projectId:e,vector:K,metadata:{contentHash:I.contentHash,filePath:I.filePath,symbolName:I.symbolName,symbolType:I.symbolType,startLine:I.startLine,endLine:I.endLine}}),M++}}}let it=this.vectors.exportProject(e),Xt=M>0||b>0||!p||p.model!==i;return Xt&&await c.save({version:1,projectId:e,model:i,dimensions:it[0]?.vector.length??O??0,updatedAt:new Date().toISOString(),records:it}),{chunks:d.length,vectorsLoaded:f,vectorsIndexed:M,vectorsRemoved:b,totalVectors:it.length,savedChunks:m,savedVectors:Xt}}async search(e,t=8){let o=await this.options.embeddings.embed(e),n=this.vectors.search(this.options.projectId,o,Math.max(t*4,20)),s=new Set($(e)),i=[];for(let a of n){let c=this.chunks.get(a.id);if(!c)continue;let d=new Set($([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),l=0;for(let b of s)d.has(b)&&l++;let m=s.size===0?0:l/s.size,p=Math.max(0,a.score),f=Yn(c.filePath,e),y=(p*.75+m*.25)*f;i.push({chunk:c,score:y,vectorScore:p,lexicalScore:m})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}}});var es=g(()=>{"use strict"});var pe,Ht=g(()=>{"use strict";pe=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),n=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,s=await fetch(n,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!s.ok)throw new Error(`Gemini embedding failed: ${s.status} ${await s.text()}`);let a=(await s.json()).embedding?.values;if(!Array.isArray(a)||a.length===0)throw new Error("Gemini embedding returned invalid response");return a}async embedMany(e){let t=[];for(let o of e)t.push(await this.embed(o));return t}}});import{createHash as hc}from"node:crypto";function vc(r){let e=Math.sqrt(r.reduce((t,o)=>t+o*o,0));return e===0?r:r.map(t=>t/e)}var fe,Jt=g(()=>{"use strict";fe=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),o=e.toLowerCase().split(/\s+/).filter(Boolean);for(let n of o){let i=hc("sha256").update(n).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return vc(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}}});var ge,Yt=g(()=>{"use strict";ge=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),o=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:e})});if(!o.ok)throw new Error(`Embedding failed: ${o.status} ${await o.text()}`);let s=(await o.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!s||s.length!==e.length||s.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return s}}});function wc(r){if(!Array.isArray(r))throw new Error("Invalid embedding");if(r.length>0&&typeof r[0]=="number")return r;if(r.length>0&&Array.isArray(r[0])){let e=r;if(e.length===0)return[];let t=e[0].length,o=new Array(t).fill(0);for(let n of e)for(let s=0;s<t;s++)o[s]+=n[s]??0;for(let n=0;n<t;n++)o[n]/=e.length;return o}throw new Error("Unsupported embedding shape")}var ye,Qt=g(()=>{"use strict";ye=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,o=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!o.ok)throw new Error(`HF embedding failed: ${o.status} ${await o.text()}`);let n=await o.json();if(!Array.isArray(n))throw new Error("HF embedding returned invalid response");return n.map(s=>wc(s))}}});function bc(r){return`https://api.cloudflare.com/client/v4/accounts/${r}/ai/v1`}function Sc(){let r=X().embedding;if(r.provider==="local")return null;if(r.provider==="huggingface")return!r.apiKey||!r.model?null:new ye({token:r.apiKey,model:r.model});if(r.provider==="gemini")return!r.apiKey||!r.model?null:new pe({apiKey:r.apiKey,model:r.model,baseUrl:r.baseUrl});let e=r.baseUrl;return r.provider==="cloudflare"&&!e&&r.accountId&&(e=bc(r.accountId)),e&&r.model?new ge({apiKey:r.apiKey,baseUrl:e,model:r.model}):null}function kc(){return new nt(Sc())}var nt,ts=g(()=>{"use strict";Be();Ht();Jt();Yt();Qt();nt=class{constructor(e,t=new fe){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}}});var rs={};ve(rs,{GeminiEmbeddingProvider:()=>pe,HashEmbeddingProvider:()=>fe,HuggingFaceEmbeddingProvider:()=>ye,OpenAiCompatibleEmbeddingProvider:()=>ge,ResilientEmbeddingProvider:()=>nt,createEmbeddingProvider:()=>kc});var os=g(()=>{"use strict";es();ts();Qt();Jt();Yt();Ht()});import"dotenv/config";import{randomUUID as Ms}from"node:crypto";var ms={critical:100,high:75,normal:50,temporary:20};function Zt(r){return ms[r]}function er(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"}at();var fs=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),gs=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 rr(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!gs.has(e)))}function ys(r,e){let t=rr(r),o=rr(e);if(t.size===0||o.size===0)return 0;let n=0;for(let i of t)o.has(i)&&n++;let s=new Set([...t,...o]).size;return n/s}function or(r){return new Set(r.tags.filter(e=>!fs.has(e.toLowerCase())))}var be=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let o=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,n=or(e);return t.filter(s=>{if(s.id===e.id||s.projectId!==e.projectId||s.type!==e.type||s.metadata?.supersededBy)return!1;let i=typeof s.metadata?.topic=="string"?s.metadata.topic:void 0;if(o&&i&&o===i)return!0;let a=or(s);for(let c of n)if(a.has(c))return!0;return ys(e.content,s.content)>=.6})}};var hs=new Set(["code","decision","rule","todo","summary"]);function vs(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function nr(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 ws(r,e){let t=nr(e)-nr(r);if(t!==0)return t;let o=e.importanceScore-r.importanceScore;if(o!==0)return o;let n=e.updatedAt.localeCompare(r.updatedAt);if(n!==0)return n;let s=e.createdAt.localeCompare(r.createdAt);return s!==0?s:r.id.localeCompare(e.id)}function sr(r){let e=new Set,t=[];for(let o of r){let n=o.trim();if(!n)continue;let s=n.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(n))}return t}function ir(r){let e=new Map;for(let n of r){if(!hs.has(n.type)||n.metadata?.supersededBy)continue;let s=vs(n.content);if(!s)continue;let i=[n.projectId,n.type,s].join("\0"),a=e.get(i)??[];a.push(n),e.set(i,a)}let t=[],o=0;for(let n of e.values()){if(n.length<2)continue;let s=[...n].sort(ws),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:sr(s.flatMap(c=>c.tags)),mergedSources:sr(s.map(c=>c.source))}),o+=a.length}return{groups:t,duplicates:o}}function ct(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 bs(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function Ss(r){let e=ct(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 ks(r){return ct(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function Cs(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 ar(r,e=Date.now()){let t=50,o=[],n=ct(r);switch(n==="permanent"?(t+=25,o.push("permanent project knowledge")):n==="task"?(t+=15,o.push("active task knowledge")):n==="session"?(t+=2,o.push("session-scoped knowledge")):n==="transient"&&(t-=25,o.push("transient knowledge")),r.importance){case"critical":t+=25,o.push("critical importance");break;case"high":t+=15,o.push("high importance");break;case"normal":break;case"temporary":t-=15,o.push("temporary importance");break}(r.type==="rule"||r.type==="decision")&&(t+=10,o.push("durable knowledge type"));let s=r.content.trim().length;s<12?(t-=30,o.push("very short content")):s<30?(t-=10,o.push("limited context")):s<=1200?(t+=8,o.push("useful context density")):s>5e3&&(t-=15,o.push("excessively large memory")),Cs(r.content)&&(t-=35,o.push("matches transient/noise pattern"));let i=r.metadata?.consolidation;i&&typeof i=="object"&&Array.isArray(i.sources)&&i.sources.length>1&&(t+=10,o.push("confirmed across multiple sources"));let a=bs(r,e)>=Ss(r);a&&(t-=15,o.push("stale for lifecycle class"));let c=ks(r);t=Math.max(0,Math.min(100,Math.round(t)));let d;t>=80?d="trusted":t>=55?d="useful":t>=30?d="weak":d="noise";let l=r.importance==="temporary"||r.type==="activity"||n==="transient";return{score:t,tier:d,stale:a,protected:c,pruneEligible:!c&&(d==="noise"&&l||a&&(d==="noise"||d==="weak")),reasons:o}}var Ps={critical:100,high:75,normal:50,temporary:20},As={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function cr(r,e,t=new Date){let o;if(e==="temporary"&&(o=30),r==="activity"&&(o=Math.min(o??14,14)),r==="summary"&&(o=Math.min(o??30,30)),!!o)return new Date(t.getTime()+o*864e5).toISOString()}function lt(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function xs(r){return!!r.metadata?.supersededBy}function dt(r,e=Date.now()){return!lt(r,e)&&!xs(r)}function V(r,e=Date.now()){if(!dt(r,e))return 0;let t=Ps[r.importance];if(r.importance==="critical")return t;let o=As[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/o);return t*i}var Se=class{memories=new Map;sanitizer=new F;conflicts=new be;remember(e){let t=new Date().toISOString(),o=this.sanitizer.sanitize(e.content.trim()).text,n=e.importance??er(e.type,o),s={id:Ms(),projectId:e.projectId,type:e.type,content:o,importance:n,importanceScore:Zt(n),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??cr(e.type,n,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(s,this.list(e.projectId));if(i.length){s.metadata={...s.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let o of e)o?.id&&(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,o)=>o.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>dt(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(o=>o.type===t)}search(e){let t=e.query.trim().toLowerCase(),o=e.limit??10,n=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=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=n.filter(l=>i.includes(l)).length,c=n.length===0?0:a/n.length,d=V(s)/500;return{memory:s,score:c+d,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,o)}consolidate(e,t=Date.now()){let o=ir(this.list(e)),n=[],s=0;for(let i of o.groups){let a=this.memories.get(i.canonicalId);if(a){a.tags=i.mergedTags,a.metadata={...a.metadata??{},consolidation:{version:1,consolidatedAt:new Date(t).toISOString(),mergedIds:i.duplicateIds,sources:i.mergedSources}},this.memories.set(a.id,a),n.push(a.id);for(let c of i.duplicateIds)this.memories.delete(c)&&(s+=1)}}return{groupsConsolidated:n.length,duplicatesRemoved:s,canonicalIds:n}}reviewLifecycle(e,t=Date.now()){let o={reviewed:0,trusted:0,useful:0,weak:0,noise:0,stale:0,protected:0,pruned:0};for(let n of this.list(e)){let s=ar(n,t);o.reviewed+=1,o[s.tier]+=1,s.stale&&(o.stale+=1),s.protected&&(o.protected+=1),n.metadata={...n.metadata??{},lifecycle:{version:1,reviewedAt:new Date(t).toISOString(),qualityScore:s.score,tier:s.tier,stale:s.stale,protected:s.protected,reasons:s.reasons}},this.memories.set(n.id,n),s.pruneEligible&&this.memories.delete(n.id)&&(o.pruned+=1)}return o}pruneExpired(e,t=Date.now()){let o=0;for(let[n,s]of this.memories)s.projectId===e&<(s,t)&&(this.memories.delete(n),o++);return o}pruneSuperseded(e,t=30,o=Date.now()){let n=0,s=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;o-new Date(c).getTime()>=s&&(this.memories.delete(i),n++)}return n}clearProject(e){let t=0;for(let[o,n]of this.memories)n.projectId===e&&(this.memories.delete(o),t++);return t}};import{createHash as Es}from"node:crypto";import{existsSync as ut,mkdirSync as Rs,readFileSync as js,renameSync as Ts,writeFileSync as Is}from"node:fs";import{basename as _s,dirname as ke,join as Pe,parse as ur,resolve as q}from"node:path";var mr=".toolnet",Os="project.json";function Ns(r){return Es("sha256").update(r).digest("hex").slice(0,16)}function mt(r){return Pe(r,mr,Os)}function Ls(r){return ut(mt(r))}function Ds(r,e){let t=q(r),o=ur(t).root;for(;;){if(Ls(t))return t;if(t===o||e&&t===q(e))break;let n=ke(t);if(n===t)break;t=n}return null}function Ks(r){let e=q(r),t=ur(e).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(s=>ut(Pe(e,s))))return e;if(e===t)break;let n=ke(e);if(n===e)break;e=n}return q(r)}function Fs(r){let e;try{e=JSON.parse(js(r,"utf8"))}catch(n){throw new Error(`Invalid ToolNet project manifest: ${r}: ${n instanceof Error?n.message:String(n)}`)}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 o=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:ke(ke(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:o,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:o,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 lr(r,e){let t=Pe(r,mr);Rs(t,{recursive:!0});let o=mt(r),n=`${o}.tmp-${process.pid}`;Is(n,JSON.stringify(e,null,2)+`
|
|
6
|
-
`,{encoding:"utf8",mode:384}),
|
|
7
|
-
`)}};var
|
|
1
|
+
var fs=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 ke=(r,e)=>{for(var t in e)fs(r,t,{get:e[t],enumerable:!0})};var ys,be,rr=y(()=>{"use strict";ys=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],be=class{scan(e){let t=[];for(let n of ys){let o=new RegExp(n.regex.source,n.regex.flags);for(let s of e.matchAll(o))t.push({type:n.type,value:s[0]})}return t}hasSecrets(e){return this.scan(e).length>0}}});var _,ve=y(()=>{"use strict";rr();_=class{scanner=new be;sanitize(e){let t=e,n=this.scanner.scan(e),o=new Set;for(let s of n)o.add(s.type),t=t.split(s.value).join(`[REDACTED:${s.type}]`);return{text:t,redacted:n.length,secretTypes:[...o]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[n,o]of Object.entries(e)){let s=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")?t[n]="[REDACTED]":t[n]=this.sanitizeValue(o)}return t}return e}}});function $(r){return r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var pt=y(()=>{"use strict"});import{existsSync as wi,readFileSync as Ci}from"node:fs";import{homedir as xi}from"node:os";import{join as Mi}from"node:path";function Pi(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 Ai(){let r=process.env.TOOLNET_GLOBAL_ENV??Mi(xi(),".config","toolnet-memory",".env");if(!wi(r))return;let e=Ci(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]=Pi(n.slice(o+1)))}}var yn=y(()=>{"use strict";Ai()});var kn={};ke(kn,{loadConfig:()=>hn});function J(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function Y(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function hn(){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:Y(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Y(process.env.MEMORY_RERANK_TOP,10),finalContext:Y(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Y(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:Y(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}var Ct=y(()=>{"use strict";yn()});function L(r){let e=xn.find(t=>t.id===r);if(!e)throw new Error(`Unsupported AI provider: ${r}`);return e}function X(r){return xn.some(e=>e.id===r)}var xn,xt=y(()=>{"use strict";xn=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}]});function d(r){return process.env[r]?.trim()||void 0}function k(...r){return r.find(e=>!!e?.trim())}function Mn(){if(d("GROQ_API_KEY"))return"groq";if(d("DEEPSEEK_API_KEY"))return"deepseek";if(d("NVIDIA_API_KEY")||d("NVIDIA_NIM_API_KEY"))return"nvidia";if(d("OPENROUTER_API_KEY"))return"openrouter";if(d("ALIBABA_API_KEY")||d("DASHSCOPE_API_KEY"))return"alibaba";if(d("GEMINI_API_KEY")||d("GOOGLE_API_KEY"))return"gemini";if(d("CLOUDFLARE_API_TOKEN")&&d("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(d("HF_TOKEN"))return"huggingface";if(d("OLLAMA_MODEL")||d("OLLAMA_BASE_URL"))return"ollama"}function Pn(){let r=d("TOOLNET_LLM_PROVIDER");return r&&X(r)?r:Mn()??"openai-compatible"}function qe(r){let e=L(r);switch(r){case"alibaba":return{provider:r,apiKey:k(d("ALIBABA_API_KEY"),d("DASHSCOPE_API_KEY")),baseUrl:k(d("ALIBABA_BASE_URL"),d("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:k(d("ALIBABA_MODEL"),d("DASHSCOPE_MODEL"))};case"openrouter":return{provider:r,apiKey:d("OPENROUTER_API_KEY"),baseUrl:k(d("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:d("OPENROUTER_MODEL")};case"groq":return{provider:r,apiKey:d("GROQ_API_KEY"),baseUrl:k(d("GROQ_BASE_URL"),e.defaultBaseUrl),model:d("GROQ_MODEL")};case"deepseek":return{provider:r,apiKey:d("DEEPSEEK_API_KEY"),baseUrl:k(d("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:k(d("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:r,apiKey:k(d("NVIDIA_API_KEY"),d("NVIDIA_NIM_API_KEY")),baseUrl:k(d("NVIDIA_BASE_URL"),d("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:k(d("NVIDIA_MODEL"),d("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:r,apiKey:k(d("GEMINI_API_KEY"),d("GOOGLE_API_KEY")),baseUrl:k(d("GEMINI_BASE_URL"),e.defaultBaseUrl),model:d("GEMINI_MODEL")};case"huggingface":return{provider:r,apiKey:d("HF_TOKEN"),baseUrl:k(d("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:k(d("HF_LLM_MODEL"),d("HF_MODEL"))};case"ollama":return{provider:r,apiKey:d("OLLAMA_API_KEY"),baseUrl:k(d("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:d("OLLAMA_MODEL")};case"cloudflare":return{provider:r,accountId:d("CLOUDFLARE_ACCOUNT_ID"),apiKey:d("CLOUDFLARE_API_TOKEN"),baseUrl:d("CLOUDFLARE_AI_BASE_URL"),model:d("CLOUDFLARE_MODEL")};case"custom":return{provider:r,apiKey:d("CUSTOM_AI_API_KEY"),baseUrl:d("CUSTOM_AI_BASE_URL"),model:d("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:k(d("OPENAI_API_KEY"),d("MODEL_API_KEY")),baseUrl:k(d("OPENAI_BASE_URL"),d("MODEL_BASE_URL")),model:k(d("OPENAI_MODEL"),d("MODEL_NAME"))}}}function Xi(){let r=d("TOOLNET_LLM_PROVIDER"),e=r&&X(r)?r:Pn(),t=L(e),n=qe(e);return{provider:e,apiKey:k(d("TOOLNET_LLM_API_KEY"),n.apiKey),baseUrl:k(d("TOOLNET_LLM_BASE_URL"),n.baseUrl,t.defaultBaseUrl),model:k(d("TOOLNET_LLM_MODEL"),n.model,t.defaultModel),accountId:k(d("TOOLNET_LLM_ACCOUNT_ID"),n.accountId)}}function Zi(){let r=d("TOOLNET_EMBEDDING_PROVIDER");return r==="local"?"local":r&&X(r)?r:d("HF_TOKEN")||d("HF_EMBEDDING_MODEL")?"huggingface":"local"}function ea(){let r=Zi();if(r==="local")return{provider:"local",model:k(d("TOOLNET_EMBEDDING_MODEL"),d("LOCAL_EMBEDDING_MODEL"))};let e=L(r),t,n,o,s;switch(r){case"huggingface":t=d("HF_TOKEN"),n=d("HF_INFERENCE_BASE_URL"),o=d("HF_EMBEDDING_MODEL");break;case"openai-compatible":t=d("OPENAI_API_KEY"),n=d("OPENAI_BASE_URL"),o=d("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":t=d("CLOUDFLARE_API_TOKEN"),n=d("CLOUDFLARE_AI_BASE_URL"),o=d("CLOUDFLARE_EMBEDDING_MODEL"),s=d("CLOUDFLARE_ACCOUNT_ID");break;default:t=qe(r).apiKey,n=qe(r).baseUrl,o=d(`${r.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let i=k(d("TOOLNET_EMBEDDING_ACCOUNT_ID"),s),a=k(d("TOOLNET_EMBEDDING_BASE_URL"),n,e.defaultBaseUrl),c=r==="cloudflare"&&!a&&i?`https://api.cloudflare.com/client/v4/accounts/${i}/ai/v1`:a;return{provider:r,apiKey:k(d("TOOLNET_EMBEDDING_API_KEY"),t),baseUrl:c,model:k(d("TOOLNET_EMBEDDING_MODEL"),o),accountId:i}}function ee(){let r=Xi(),e=ea();return{llm:r,embedding:e,legacy:{llm:!d("TOOLNET_LLM_PROVIDER")&&!!Mn(),embedding:!d("TOOLNET_EMBEDDING_PROVIDER")&&!!(d("HF_TOKEN")||d("HF_EMBEDDING_MODEL"))}}}function An(r=Pn()){let e=ee().llm;if(r===e.provider)return{id:r,apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,accountId:e.accountId};let t=qe(r);return{id:r,apiKey:t.apiKey,baseUrl:t.baseUrl,model:t.model,accountId:t.accountId}}function Z(r,e){return d(`TOOLNET_LLM_FALLBACK_${r}_${e}`)}function En(){let r=[];for(let e of[1,2]){let t=Z(e,"PROVIDER");if(!t||!X(t))continue;let n=L(t);r.push({slot:e,config:{provider:t,apiKey:Z(e,"API_KEY"),baseUrl:k(Z(e,"BASE_URL"),n.defaultBaseUrl),model:k(Z(e,"MODEL"),n.defaultModel),accountId:Z(e,"ACCOUNT_ID")}})}return r}function Rn(){let r=d("TOOLNET_LLM_FALLBACK_COOLDOWN_MS"),e=d("TOOLNET_LLM_MAX_RETRIES"),t=Number(r??6e4),n=Number(e??1);return{cooldownMs:Number.isFinite(t)&&t>=0?t:6e4,maxRetries:Number.isFinite(n)&&n>=0?Math.floor(n):1}}var Be=y(()=>{"use strict";xt()});var Ao=y(()=>{"use strict"});import{DeleteObjectCommand as Ha,GetObjectCommand as Ja,HeadObjectCommand as Ya,ListObjectsV2Command as Qa,PutObjectCommand as Xa,S3Client as Za}from"@aws-sdk/client-s3";import{getSignedUrl as ec}from"@aws-sdk/s3-request-presigner";var ue,Rt=y(()=>{"use strict";ue=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Za({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 Xa({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await ec(this.client,new Ja({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 Ya({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 Ha({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Qa({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 tc,readFile as rc,readdir as nc,rm as oc,stat as Ro,writeFile as sc}from"node:fs/promises";import{dirname as ic,join as ac,relative as Io,resolve as cc}from"node:path";var W,It=y(()=>{"use strict";W=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return cc(this.root,t)}async put(e,t){let n=this.path(e);await tc(ic(n),{recursive:!0}),await sc(n,t)}async get(e){try{return await rc(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 oc(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 nc(i,{withFileTypes:!0});for(let c of a){let u=ac(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Ro(u);n.push({key:Io(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Ro(t);return s.isDirectory()?await o(t):n.push({key:Io(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),n}}});import{DeleteObjectCommand as lc,GetObjectCommand as uc,HeadObjectCommand as dc,ListObjectsV2Command as mc,PutObjectCommand as pc,S3Client as fc}from"@aws-sdk/client-s3";import{getSignedUrl as gc}from"@aws-sdk/s3-request-presigner";var q,Tt=y(()=>{"use strict";q=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new fc({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 pc({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await gc(this.client,new uc({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 dc({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 lc({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new mc({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 yc}from"node:os";import{join as hc}from"node:path";function jt(r,e){return console.warn(e),new W(r)}function kc(r){let e=r.localRoot??hc(yc(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new q({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):jt(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 q({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):jt(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 ue({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):jt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new W(e)}var To=y(()=>{"use strict";Rt();It();Tt()});var _t,jo=y(()=>{"use strict";_t=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"memories","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return[];let 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 _o=y(()=>{"use strict";It()});var Oo=y(()=>{"use strict";Rt()});var No=y(()=>{"use strict";Tt()});var Ot,Lo=y(()=>{"use strict";Ot=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"vectors","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));if(!t)return null;let n=JSON.parse(t);if(n.version!==1||n.projectId!==e||!Array.isArray(n.records))throw new Error("Invalid vector snapshot");return n}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}}});var Nt,Do=y(()=>{"use strict";Nt=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 Lt,Ko=y(()=>{"use strict";Lt=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 de,Dt=y(()=>{"use strict";de=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 me,Kt=y(()=>{"use strict";me=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 bc(r){return new Promise(e=>setTimeout(e,r))}async function Fo(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 bc(c+u)}throw s}var $o=y(()=>{"use strict"});function Sc(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:vc.has(n)?(...s)=>Fo(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}var vc,Go=y(()=>{"use strict";$o();vc=new Set(["put","get","getText","delete","list"])});function Ft(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 $t=y(()=>{"use strict"});function Gt(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 zt=y(()=>{"use strict"});var Ut,zo=y(()=>{"use strict";$t();zt();Ut=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=Ft(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=Gt(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 Uo=y(()=>{"use strict";$t();zo();zt()});var Wt,Wo=y(()=>{"use strict";Wt=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 qt,qo=y(()=>{"use strict";qt=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 Bt,Bo=y(()=>{"use strict";Bt=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 Vt,Vo=y(()=>{"use strict";Vt=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 Ho={};ke(Ho,{HuggingFaceStorageProvider:()=>ue,LocalStorageProvider:()=>W,MemoryStore:()=>_t,PersistentArchitectureStore:()=>qt,PersistentCodeAnalysisStore:()=>Bt,PersistentCodeChunkStore:()=>de,PersistentCodeGraphStore:()=>Nt,PersistentCodeManifestStore:()=>Lt,PersistentCodeVectorStore:()=>me,PersistentTypeResolutionStore:()=>Wt,PersistentVectorStore:()=>Ot,PersistentVisualizationStore:()=>Vt,ProjectScopedStorageProvider:()=>Ut,S3StorageProvider:()=>q,createStorageProvider:()=>kc,mapProjectStoragePath:()=>Gt,sanitizeProjectFolder:()=>Ft,withStorageRetry:()=>Sc});var Jo=y(()=>{"use strict";Ao();To();jo();_o();Oo();No();Lo();Do();Ko();Dt();Kt();Go();Uo();Wo();qo();Bo();Vo()});import{createHash as wc}from"node:crypto";import{readFile as Cc}from"node:fs/promises";import{join as xc}from"node:path";function Yo(r){return wc("sha256").update(r).digest("hex")}var nt,Qo=y(()=>{"use strict";ve();nt=class{sanitizer=new _;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 m;try{m=await Cc(xc(t,u),"utf8")}catch{continue}let p=m.split(/\r?\n/),f=l.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(f.length>0)for(let h of f)c.push(...this.chunkRange({projectId:e,filePath:u,lines:p,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:s,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:u,lines:p,startLine:1,endLine:Math.max(1,p.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=[],m=c,p=0;for(;m<=u;){let f=Math.min(u,m+i-1),h=o.slice(m-1,f).join(`
|
|
4
|
+
`).trim();if(h){let v=this.sanitizer.sanitize(h).text,P=Yo(v),A=[t,n,s?.id??"file",String(p),P].join(":");l.push({id:Yo(A).slice(0,32),projectId:t,filePath:n,symbolId:s?.id,symbolName:s?.qualifiedName??s?.name,symbolType:s?.type,startLine:m,endLine:f,content:v,contentHash:P})}if(f>=u)break;m=f-a+1,p++}return l}}});function Mc(r,e){if(r.length===0||e.length===0||r.length!==e.length)return 0;let t=0,n=0,o=0;for(let s=0;s<r.length;s++){let i=r[s]??0,a=e[s]??0;t+=i*a,n+=i*i,o+=a*a}return n===0||o===0?0:t/(Math.sqrt(n)*Math.sqrt(o))}var ot,Xo=y(()=>{"use strict";ot=class{records=new Map;upsert(e){this.records.set(e.id,e)}get(e){return this.records.get(e)}has(e){return this.records.has(e)}remove(e){return this.records.delete(e)}clearProject(e){let t=0;for(let[n,o]of this.records)o.projectId===e&&(this.records.delete(n),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let n of e)!n?.id||!n?.projectId||!Array.isArray(n.vector)||(this.records.set(n.id,n),t++);return t}search(e,t,n=10){let o=[];for(let s of this.records.values()){if(s.projectId!==e)continue;let i=Mc(t,s.vector);o.push({id:s.id,score:i,metadata:s.metadata})}return o.sort((s,i)=>i.score-s.score).slice(0,n)}size(){return this.records.size}}});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=y(()=>{"use strict"});var ts={};ke(ts,{SemanticCodeEngine:()=>Ht});var Ht,rs=y(()=>{"use strict";Dt();Kt();Qo();Xo();pt();es();Ht=class{constructor(e){this.options=e}options;vectors=new ot;chunks=new Map;async initialize(){let{projectId:e,rootPath:t,storage:n,embeddings:o,graph:s,model:i}=this.options,a=new de(n),c=new me(n),u=await new nt().build(e,t,s.allSymbols(e));this.chunks.clear();for(let w of u)this.chunks.set(w.id,w);let l=await a.load(e),m=!l||l.chunks.length!==u.length||l.chunks.some(w=>!this.chunks.has(w.id));m&&await a.save({version:1,projectId:e,updatedAt:new Date().toISOString(),chunks:u});let p=await c.load(e),f=0;p&&p.model===i&&(f=this.vectors.importRecords(p.records));let h=new Set(u.map(w=>w.id)),v=0;for(let w of this.vectors.exportProject(e))h.has(w.id)||this.vectors.remove(w.id)&&v++;let P=u.filter(w=>{let K=this.vectors.get(w.id);return K?K.metadata?.contentHash!==w.contentHash:!0}),A=0,he=8,N=this.vectors.exportProject(e)[0]?.vector.length;for(let w=0;w<P.length;w+=he){let K=P.slice(w,w+he),ms=K.map(M=>[`file: ${M.filePath}`,M.symbolName?`symbol: ${M.symbolName}`:"",M.symbolType?`type: ${M.symbolType}`:"",M.content].filter(Boolean).join(`
|
|
5
|
+
`)),ps=await o.embedMany(ms);for(let M=0;M<K.length;M++){let j=K[M],F=ps[M];if(!(!j||!F||F.length===0)){if(N===void 0&&(N=F.length),F.length!==N){console.warn(`[code-semantic] skip dimension mismatch: ${F.length} != ${N}`);continue}this.vectors.upsert({id:j.id,projectId:e,vector:F,metadata:{contentHash:j.contentHash,filePath:j.filePath,symbolName:j.symbolName,symbolType:j.symbolType,startLine:j.startLine,endLine:j.endLine}}),A++}}}let at=this.vectors.exportProject(e),Zt=A>0||v>0||!p||p.model!==i;return Zt&&await c.save({version:1,projectId:e,model:i,dimensions:at[0]?.vector.length??N??0,updatedAt:new Date().toISOString(),records:at}),{chunks:u.length,vectorsLoaded:f,vectorsIndexed:A,vectorsRemoved:v,totalVectors:at.length,savedChunks:m,savedVectors:Zt}}async search(e,t=8){let n=await this.options.embeddings.embed(e),o=this.vectors.search(this.options.projectId,n,Math.max(t*4,20)),s=new Set($(e)),i=[];for(let a of o){let c=this.chunks.get(a.id);if(!c)continue;let u=new Set($([c.filePath,c.symbolName??"",c.symbolType??"",c.content].join(" "))),l=0;for(let v of s)u.has(v)&&l++;let m=s.size===0?0:l/s.size,p=Math.max(0,a.score),f=Zo(c.filePath,e),h=(p*.75+m*.25)*f;i.push({chunk:c,score:h,vectorScore:p,lexicalScore:m})}return i.sort((a,c)=>c.score-a.score).slice(0,t)}size(){return this.chunks.size}}});var ns=y(()=>{"use strict"});var pe,Jt=y(()=>{"use strict";pe=class{constructor(e){this.options=e}options;name="gemini";async embed(e){let t=this.options.model.replace(/^models\//,""),o=`${this.options.baseUrl?.replace(/\/+$/,"")||"https://generativelanguage.googleapis.com/v1beta"}/models/${encodeURIComponent(t)}:embedContent?key=${encodeURIComponent(this.options.apiKey)}`,s=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:`models/${t}`,content:{parts:[{text:e}]}})});if(!s.ok)throw new Error(`Gemini embedding failed: ${s.status} ${await s.text()}`);let a=(await s.json()).embedding?.values;if(!Array.isArray(a)||a.length===0)throw new Error("Gemini embedding returned invalid response");return a}async embedMany(e){let t=[];for(let n of e)t.push(await this.embed(n));return t}}});import{createHash as Pc}from"node:crypto";function Ac(r){let e=Math.sqrt(r.reduce((t,n)=>t+n*n,0));return e===0?r:r.map(t=>t/e)}var fe,Yt=y(()=>{"use strict";fe=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),n=e.toLowerCase().split(/\s+/).filter(Boolean);for(let o of n){let i=Pc("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return Ac(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}}});var ge,Qt=y(()=>{"use strict";ge=class{constructor(e){this.options=e;this.dimensions=e.dimensions}options;name="openai-compatible";dimensions;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=this.options.baseUrl.replace(/\/+$/,""),n=await fetch(`${t}/embeddings`,{method:"POST",headers:{"content-type":"application/json",...this.options.apiKey?{authorization:`Bearer ${this.options.apiKey}`}:{}},body:JSON.stringify({model:this.options.model,input:e})});if(!n.ok)throw new Error(`Embedding failed: ${n.status} ${await n.text()}`);let s=(await n.json()).data?.sort((i,a)=>(i.index??0)-(a.index??0)).map(i=>i.embedding);if(!s||s.length!==e.length||s.some(i=>!Array.isArray(i)))throw new Error("Embedding provider returned invalid response");return s}}});function Ec(r){if(!Array.isArray(r))throw new Error("Invalid embedding");if(r.length>0&&typeof r[0]=="number")return r;if(r.length>0&&Array.isArray(r[0])){let e=r;if(e.length===0)return[];let t=e[0].length,n=new Array(t).fill(0);for(let o of e)for(let s=0;s<t;s++)n[s]+=o[s]??0;for(let o=0;o<t;o++)n[o]/=e.length;return n}throw new Error("Unsupported embedding shape")}var ye,Xt=y(()=>{"use strict";ye=class{constructor(e){this.options=e}options;name="huggingface";dimensions=384;async embed(e){let[t]=await this.embedMany([e]);return t}async embedMany(e){if(e.length===0)return[];let t=`https://router.huggingface.co/hf-inference/models/${this.options.model}/pipeline/feature-extraction`,n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.options.token}`,"Content-Type":"application/json"},body:JSON.stringify({inputs:e,options:{wait_for_model:!0}})});if(!n.ok)throw new Error(`HF embedding failed: ${n.status} ${await n.text()}`);let o=await n.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(s=>Ec(s))}}});function Rc(r){return`https://api.cloudflare.com/client/v4/accounts/${r}/ai/v1`}function Ic(){let r=ee().embedding;if(r.provider==="local")return null;if(r.provider==="huggingface")return!r.apiKey||!r.model?null:new ye({token:r.apiKey,model:r.model});if(r.provider==="gemini")return!r.apiKey||!r.model?null:new pe({apiKey:r.apiKey,model:r.model,baseUrl:r.baseUrl});let e=r.baseUrl;return r.provider==="cloudflare"&&!e&&r.accountId&&(e=Rc(r.accountId)),e&&r.model?new ge({apiKey:r.apiKey,baseUrl:e,model:r.model}):null}function Tc(){return new st(Ic())}var st,os=y(()=>{"use strict";Be();Jt();Yt();Qt();Xt();st=class{constructor(e,t=new fe){this.primary=e;this.fallback=t}primary;fallback;name="resilient";async embed(e){if(this.primary)try{return await this.primary.embed(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embed(e)}async embedMany(e){if(this.primary)try{return await this.primary.embedMany(e)}catch(t){console.warn("[embedding] primary failed, fallback enabled:",t instanceof Error?t.message:t)}return this.fallback.embedMany(e)}}});var ss={};ke(ss,{GeminiEmbeddingProvider:()=>pe,HashEmbeddingProvider:()=>fe,HuggingFaceEmbeddingProvider:()=>ye,OpenAiCompatibleEmbeddingProvider:()=>ge,ResilientEmbeddingProvider:()=>st,createEmbeddingProvider:()=>Tc});var is=y(()=>{"use strict";ns();os();Xt();Yt();Qt();Jt()});import"dotenv/config";import{randomUUID as Is}from"node:crypto";var gs={critical:100,high:75,normal:50,temporary:20};function er(r){return gs[r]}function tr(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"}ve();var hs=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),ks=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 nr(r){return new Set(r.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!ks.has(e)))}function bs(r,e){let t=nr(r),n=nr(e);if(t.size===0||n.size===0)return 0;let o=0;for(let i of t)n.has(i)&&o++;let s=new Set([...t,...n]).size;return o/s}function or(r){return new Set(r.tags.filter(e=>!hs.has(e.toLowerCase())))}var Se=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let n=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,o=or(e);return t.filter(s=>{if(s.id===e.id||s.projectId!==e.projectId||s.type!==e.type||s.metadata?.supersededBy)return!1;let i=typeof s.metadata?.topic=="string"?s.metadata.topic:void 0;if(n&&i&&n===i)return!0;let a=or(s);for(let c of o)if(a.has(c))return!0;return bs(e.content,s.content)>=.6})}};var vs=new Set(["code","decision","rule","todo","summary"]);function Ss(r){return r.normalize("NFKC").toLowerCase().replace(/[“”"'`]/gu,"").replace(/[.!?]+$/gu,"").replace(/\s+/gu," ").trim()}function sr(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 ws(r,e){let t=sr(e)-sr(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 ir(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 ar(r){let e=new Map;for(let o of r){if(!vs.has(o.type)||o.metadata?.supersededBy)continue;let s=Ss(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(ws),i=s[0];if(!i)continue;let a=s.slice(1);t.push({canonicalId:i.id,duplicateIds:a.map(c=>c.id),mergedTags:ir(s.flatMap(c=>c.tags)),mergedSources:ir(s.map(c=>c.source))}),n+=a.length}return{groups:t,duplicates:n}}function ct(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 Cs(r,e){let t=new Date(r.updatedAt).getTime();return Number.isFinite(t)?Math.max(0,(e-t)/864e5):0}function xs(r){let e=ct(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 Ms(r){return ct(r)==="permanent"||r.type==="rule"||r.type==="decision"||r.importance==="critical"}function Ps(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 cr(r,e=Date.now()){let t=50,n=[],o=ct(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")),Ps(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=Cs(r,e)>=xs(r);a&&(t-=15,n.push("stale for lifecycle class"));let c=Ms(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 As={critical:100,high:75,normal:50,temporary:20},Es={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function lr(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 lt(r,e=Date.now()){return r.expiresAt?new Date(r.expiresAt).getTime()<=e:!1}function Rs(r){return!!r.metadata?.supersededBy}function ut(r,e=Date.now()){return!lt(r,e)&&!Rs(r)}function B(r,e=Date.now()){if(!ut(r,e))return 0;let t=As[r.importance];if(r.importance==="critical")return t;let n=Es[r.type]??180,s=Math.max(0,e-new Date(r.updatedAt).getTime())/864e5,i=Math.pow(.5,s/n);return t*i}var we=class{memories=new Map;sanitizer=new _;conflicts=new Se;remember(e){let t=new Date().toISOString(),n=this.sanitizer.sanitize(e.content.trim()).text,o=e.importance??tr(e.type,n),s={id:Is(),projectId:e.projectId,type:e.type,content:n,importance:o,importanceScore:er(o),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??lr(e.type,o,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(s,this.list(e.projectId));if(i.length){s.metadata={...s.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:s.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(s.id,s),s}importRecords(e){let t=0;for(let n of e)n?.id&&(this.memories.set(n.id,n),t++);return t}exportProject(e){return this.listAll(e)}get(e){return this.memories.get(e)}delete(e){return this.memories.delete(e)}listAll(e){return[...this.memories.values()].filter(t=>t.projectId===e).sort((t,n)=>n.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>ut(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(n=>n.type===t)}search(e){let t=e.query.trim().toLowerCase(),n=e.limit??10,o=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(s=>{if(e.types&&!e.types.includes(s.type))return!1;let i=B(s);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>s.tags.includes(c)))}).map(s=>{let i=s.content.toLowerCase(),a=o.filter(l=>i.includes(l)).length,c=o.length===0?0:a/o.length,u=B(s)/500;return{memory:s,score:c+u,source:"memory"}}).filter(s=>t.length===0||s.score>0).sort((s,i)=>i.score-s.score).slice(0,n)}consolidate(e,t=Date.now()){let n=ar(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=cr(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&<(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 Ts}from"node:crypto";import{existsSync as dt,mkdirSync as js,readFileSync as _s,renameSync as Os,writeFileSync as Ns}from"node:fs";import{basename as Ls,dirname as Ce,join as Me,parse as mr,resolve as V}from"node:path";var pr=".toolnet",Ds="project.json";function Ks(r){return Ts("sha256").update(r).digest("hex").slice(0,16)}function mt(r){return Me(r,pr,Ds)}function Fs(r){return dt(mt(r))}function $s(r,e){let t=V(r),n=mr(t).root;for(;;){if(Fs(t))return t;if(t===n||e&&t===V(e))break;let o=Ce(t);if(o===t)break;t=o}return null}function Gs(r){let e=V(r),t=mr(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(s=>dt(Me(e,s))))return e;if(e===t)break;let o=Ce(e);if(o===e)break;e=o}return V(r)}function zs(r){let e;try{e=JSON.parse(_s(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:Ce(Ce(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 ur(r,e){let t=Me(r,pr);js(t,{recursive:!0});let n=mt(r),o=`${n}.tmp-${process.pid}`;Ns(o,JSON.stringify(e,null,2)+`
|
|
6
|
+
`,{encoding:"utf8",mode:384}),Os(o,n)}function dr(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 xe=class{detect(e=process.cwd()){let t=V(e),n=Gs(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>dt(Me(n,l))),i=$s(t,s?n:void 0);if(i){let l=mt(i),m=zs(l);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),ur(i,m)),dr(m,i)}let a=new Date().toISOString(),c=Ls(n),u={version:1,id:Ks(n),name:c,remote:c,rootPath:n,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return ur(n,u),dr(u,n)}};pt();var Pe=class{score(e,t){let n=$(e),o=$([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 fr(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 gr(r){return B(r)/100}var Us={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function yr(r){return Us[r]??.4}var Ae=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 Ee=class{bm25=new Pe;analyzer=new Ae;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=fr(c),m=gr(c),p=yr(c.type);i.preferredTypes.includes(c.type)&&(p=Math.min(1,p+.25));let f=u*.55+m*.2+l*.15+p*.1;u<=0||f<s||a.push({memory:c,score:f,scores:{keyword:u,recency:l,importance:m,type:p}})}return a.sort((c,u)=>u.score-c.score).slice(0,o)}};var Re=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(`
|
|
7
|
+
`)}};var Ie=class{constructor(e){this.memory=e}memory;searcher=new Ee;contextBuilder=new Re;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 Te=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 je=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 Wa}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as qa}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as hr}from"zod";var kr={query:hr.string(),limit:hr.number().int().min(1).max(20).optional()};async function br(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 H}from"zod";import{createConnection as Bs}from"node:net";import{homedir as Ws}from"node:os";import{join as qs}from"node:path";function vr(){return process.env.TOOLNET_SERVICE_SOCKET??qs(Ws(),".toolnet","run","service.sock")}function Sr(r,e={}){let t=e.socketPath??vr(),n=e.timeoutMs??1e3;return new Promise((o,s)=>{let i=Bs({path:t}),a="",c=!1,u=m=>{c||(c=!0,clearTimeout(l),i.destroy(),m())},l=setTimeout(()=>{u(()=>{s(new Error(`ToolNet service timeout after ${n}ms`))})},n);i.setEncoding("utf8"),i.once("connect",()=>{i.write(`${JSON.stringify(r)}
|
|
8
8
|
`)}),i.on("data",m=>{a+=m;let p=a.indexOf(`
|
|
9
|
-
`);if(p===-1)return;let f=a.slice(0,p).trim();d(()=>{try{n(JSON.parse(f))}catch(y){s(y instanceof Error?y:new Error(String(y)))}})}),i.once("error",m=>{d(()=>{s(m)})}),i.once("end",()=>{c||d(()=>{s(new Error("ToolNet service closed without response"))})})})}async function zs(r,e={}){let t=await br({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 Sr(r,e={}){try{return await zs(r,e)}catch{return null}}async function Ie(r,e={}){try{let t=await br({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var kr={type:H.enum(["activity","decision","rule","todo","summary"]),content:H.string().min(1),tags:H.array(H.string()).optional(),importance:H.enum(["critical","high","normal","temporary"]).optional()};async function Cr(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)),Ie(r.project),t}import{z as Bs}from"zod";var Pr={id:Bs.string().min(1)};async function Ar(r,e){let t=r.memory.delete(e.id);return t&&r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),t&&Ie(r.project),{deleted:t}}import{z as Vs}from"zod";var xr={name:Vs.string().min(1)};async function Mr(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as qs}from"zod";var _e=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Er=new Set(["CALLS","CALL_REFERENCE"]),P=class{constructor(e){this.graph=e}graph;findSymbols(e,t){let o=t.trim().toLowerCase();return o?this.graph.allSymbols(e).filter(n=>n.name.toLowerCase().includes(o)||(n.qualifiedName?.toLowerCase().includes(o)??!1)||n.filePath.toLowerCase().includes(o)).sort((n,s)=>{let i=n.name.toLowerCase()===o,a=s.name.toLowerCase()===o;return i!==a?i?-1:1:n.filePath.localeCompare(s.filePath)}):[]}callers(e,t){return this.relatedIncoming(e,t,Er)}callees(e,t){return this.relatedOutgoing(e,t,Er)}dependents(e,t){return this.relatedIncoming(e,t,_e)}dependencies(e,t){return this.relatedOutgoing(e,t,_e)}neighborhood(e,t,o=1){let n=this.graph.getSymbol(t);return!n||n.projectId!==e?null:{center:n,incoming:this.walk(e,t,"incoming",o),outgoing:this.walk(e,t,"outgoing",o)}}shortestPath(e,t,o,n=12){let s=this.graph.getSymbol(t),i=this.graph.getSymbol(o);if(!s||!i||s.projectId!==e||i.projectId!==e)return{found:!1,distance:-1,symbols:[],edges:[]};if(t===o)return{found:!0,distance:0,symbols:[s],edges:[]};let a=this.graph.allEdges(e).filter(p=>_e.has(p.type)),c=new Map;for(let p of a){let f=c.get(p.from)??[];f.push(p),c.set(p.from,f)}let d=[{id:t,depth:0}],l=new Set([t]),m=new Map;for(;d.length>0;){let p=d.shift();if(!(p.depth>=n)){for(let f of c.get(p.id)??[])if(!l.has(f.to)){if(l.add(f.to),m.set(f.to,{node:p.id,edge:f}),f.to===o)return this.buildPath(t,o,m);d.push({id:f.to,depth:p.depth+1})}}}return{found:!1,distance:-1,symbols:[],edges:[]}}buildPath(e,t,o){let n=[t],s=[],i=t;for(;i!==e;){let c=o.get(i);if(!c)return{found:!1,distance:-1,symbols:[],edges:[]};s.push(c.edge),i=c.node,n.push(i)}n.reverse(),s.reverse();let a=n.map(c=>this.graph.getSymbol(c)).filter(c=>!!c);return{found:!0,distance:s.length,symbols:a,edges:s}}walk(e,t,o,n){let s=this.graph.allEdges(e).filter(d=>_e.has(d.type)),i=[{id:t,depth:0}],a=new Set([t]),c=[];for(;i.length>0;){let d=i.shift();if(!(d.depth>=n))for(let l of s){if(!(o==="incoming"?l.to===d.id:l.from===d.id))continue;let p=o==="incoming"?l.from:l.to;if(a.has(p))continue;let f=this.graph.getSymbol(p);f&&(a.add(p),c.push({symbol:f,depth:d.depth+1,via:l}),i.push({id:p,depth:d.depth+1}))}}return c}relatedIncoming(e,t,o){return[...new Set(this.graph.allEdges(e).filter(s=>s.to===t&&o.has(s.type)).map(s=>s.from))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}relatedOutgoing(e,t,o){return[...new Set(this.graph.allEdges(e).filter(s=>s.from===t&&o.has(s.type)).map(s=>s.to))].map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function E(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let o=new P(r.graph),n=o.findSymbols(r.project.id,e).find(s=>s.name===e||s.qualifiedName===e);return n||(o.findSymbols(r.project.id,e)[0]??null)}function C(r){return{id:r.id,name:r.name,qualifiedName:r.qualifiedName,type:r.type,filePath:r.filePath,startLine:r.startLine,endLine:r.endLine}}var Rr={symbolId:qs.string().min(1)};async function jr(r,e){let t=E(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let n=new P(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:C(t),count:n.length,callers:n.map(C)}}import{z as Tr}from"zod";var Ir={query:Tr.string().min(1),limit:Tr.number().int().min(1).max(50).optional()};async function _r(r,e){let t=e.query.toLowerCase(),o=e.limit??20;return r.graph.allSymbols(r.project.id).filter(n=>n.name.toLowerCase().includes(t)||n.qualifiedName?.toLowerCase().includes(t)||n.filePath.toLowerCase().includes(t)).slice(0,o)}import{z as Or}from"zod";function Oe(r,e){let t=r.allSymbols(e),o=r.allEdges(e),n=i=>t.filter(a=>a.type===i).length,s=i=>o.filter(a=>a.type===i).length;return{files:n("file"),classes:n("class"),interfaces:n("interface"),functions:n("function"),methods:n("method"),properties:n("property"),routes:n("route"),symbols:t.length,edges:o.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 Nr={query:Or.string().optional(),memoryLimit:Or.number().int().min(1).max(20).optional()};async function Lr(r,e){let t=Oe(r.graph,r.project.id),o=r.memory.recent(r.project.id,5),n=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:o,relevant:n.map(s=>s.memory)}}import{z as Js}from"zod";var Hs=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],_=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",o){let n=new Date().toISOString(),s=n.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,s),c=[];for(let l of Hs){let m=`${i}/${l}`,p=await this.storage.get(m);p&&(await this.storage.put(`${a}/${l}`,p,"application/json"),c.push(l))}if(c.length===0)return null;let d={version:1,id:s,projectId:e,createdAt:n,reason:t,objects:c,metadata:o};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(d,null,2),"application/json"),d}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),n=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),s=[];for(let i of n){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 o=this.snapshotPrefix(e,t),n=await this.storage.getText(`${o}/snapshot.json`);if(!n)throw new Error(`Snapshot not found: ${t}`);let s=JSON.parse(n);if(s.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of s.objects){let d=await this.storage.get(`${o}/${c}`);d&&(await this.storage.put(`${i}/${c}`,d,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let o=this.snapshotPrefix(e,t),n=await this.storage.list(o);for(let s of n)await this.storage.delete(s.key);return n.length}async prune(e,t=10){let n=(await this.list(e)).slice(t),s=0;for(let i of n)await this.remove(e,i.id),s++;return s}};var Dr={reason:Js.string().optional()};async function Kr(r,e){if(!r.storage)throw new Error("Storage unavailable");return new _(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function Fr(r){if(!r.storage)throw new Error("Storage unavailable");return new _(r.storage).list(r.project.id)}import{z as Ys}from"zod";var $r={snapshotId:Ys.string().min(1)};async function Gr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new _(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as ft}from"zod";var Ne=class{constructor(e){this.graph=e}graph;callees(e,t,o=3){return this.walk(e,t,"out",o)}callers(e,t,o=3){return this.walk(e,t,"in",o)}walk(e,t,o,n){let s=[],i=new Set([t]),a=[{id:t,depth:0}],c=this.graph.allEdges(e).filter(d=>d.type==="CALLS"||d.type==="CALL_REFERENCE");for(;a.length;){let d=a.shift();if(d.depth>=n)continue;let l=o==="out"?c.filter(m=>m.from===d.id):c.filter(m=>m.to===d.id);for(let m of l){let p=o==="out"?m.to:m.from;if(i.has(p))continue;i.add(p);let f=this.graph.getSymbol(p);if(!f)continue;let y=d.depth+1;s.push({symbol:f,depth:y}),a.push({id:p,depth:y})}}return s}};var Ur={symbolId:ft.string().min(1),direction:ft.enum(["callers","callees"]).optional(),depth:ft.number().int().min(1).max(10).optional()};async function Wr(r,e){let t=new Ne(r.graph),o=e.direction??"callees",n=e.depth??3,s=o==="callers"?t.callers(r.project.id,e.symbolId,n):t.callees(r.project.id,e.symbolId,n);return{direction:o,depth:n,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 zr}from"zod";var Le=class{constructor(e){this.graph=e}graph;analyze(e,t,o=4){let n=this.graph.allEdges(e),s=new Set([t]),i=[{id:t,depth:0}],a=[];for(;i.length;){let c=i.shift();if(c.depth>=o)continue;let d=n.filter(l=>l.to===c.id&&["CALLS","IMPORTS","INHERITS","IMPLEMENTS"].includes(l.type));for(let l of d){if(s.has(l.from))continue;s.add(l.from);let m=this.graph.getSymbol(l.from);if(!m)continue;let p=c.depth+1;a.push({symbol:m,depth:p,relation:l.type}),i.push({id:l.from,depth:p})}}return a}};var Br={symbolId:zr.string().min(1),depth:zr.number().int().min(1).max(10).optional()};async function Vr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let n=new Le(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:n.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:Oe(r.graph,r.project.id)}}import{z as Hr}from"zod";var Qs=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),De=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e).filter(i=>Qs.has(i.type)),n=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,d=0,l=0;for(let m of o){let p=n.get(m.from),f=n.get(m.to);!p||!f||p.filePath===f.filePath||(p.filePath===i&&(a.add(f.filePath),d++),f.filePath===i&&(c.add(p.filePath),l++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:d,incomingEdges:l}})}};var Jr={filePath:Hr.string().min(1),direction:Hr.enum(["dependencies","dependents","both"]).optional()};async function Yr(r,e){let o=new De(r.graph).analyze(r.project.id).find(c=>c.filePath===e.filePath);if(!o)return{found:!1,filePath:e.filePath,dependencies:[],dependents:[]};let n=r.graph.allSymbols(r.project.id).filter(c=>c.type==="file"),s=new Map(n.map(c=>[c.filePath,c])),i=c=>({id:s.get(c)?.id??c,filePath:c}),a=e.direction??"both";return{found:!0,filePath:o.filePath,outgoingEdges:o.outgoingEdges,incomingEdges:o.incomingEdges,dependencies:a==="dependents"?[]:o.dependencies.map(i),dependents:a==="dependencies"?[]:o.dependents.map(i)}}import{z as Qr}from"zod";var Xr={query:Qr.string().min(1),limit:Qr.number().int().min(1).max(20).optional()};async function Zr(r,e){return r.codeSemantic?{available:!0,results:(await r.codeSemantic.search(e.query,e.limit??8)).map(o=>({id:o.chunk.id,filePath:o.chunk.filePath,symbol:o.chunk.symbolName,symbolType:o.chunk.symbolType,startLine:o.chunk.startLine,endLine:o.chunk.endLine,score:o.score,vectorScore:o.vectorScore,lexicalScore:o.lexicalScore,content:o.chunk.content}))}:{available:!1,results:[]}}import{z as yt}from"zod";import{execFile as Xs}from"node:child_process";import{promisify as Zs}from"node:util";var gt=Zs(Xs);function ei(r){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let o of r.matchAll(t)){let n=Number(o[1]),s=Number(o[2]??1);e.push({startLine:n,endLine:Math.max(n,n+s-1)})}return e}function ti(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function eo(r){let e="";try{e=(await gt("git",["diff","HEAD","--name-status","--no-renames"],{cwd:r,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let o of e.split(/\r?\n/).filter(Boolean)){let[n,...s]=o.split(" "),i=s.at(-1);if(!i)continue;let a="";try{a=(await gt("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:ti(n),ranges:ei(a)})}try{let o=await gt("git",["ls-files","--others","--exclude-standard"],{cwd:r});for(let n of o.stdout.split(/\r?\n/).filter(Boolean))t.some(s=>s.filePath===n)||t.push({filePath:n,status:"added",ranges:[]})}catch{}return t}function ri(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var Ke=class{constructor(e){this.graph=e}graph;map(e,t){let o=this.graph.allSymbols(e),n=[];for(let s of t){let i=o.filter(d=>d.filePath===s.filePath),c=i.filter(d=>d.type!=="file").filter(d=>ri(d,s));if(c.length===0){let d=i.find(l=>l.type==="file");d&&n.push({symbol:d,fileStatus:s.status,direct:!0});continue}for(let d of c)n.push({symbol:d,fileStatus:s.status,direct:!0})}return n}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var oi={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function ni(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function to(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var Fe=class{constructor(e){this.graph=e}graph;analyze(e,t,o=4){let n=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 m=new Set([l.symbol.id]),p=[{id:l.symbol.id,depth:0}];for(;p.length;){let f=p.shift();if(f.depth>=o)continue;let y=n.filter(b=>b.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(b.type));for(let b of y){if(m.has(b.from))continue;m.add(b.from);let x=this.graph.getSymbol(b.from);if(!x)continue;let M=f.depth+1,he=`${l.symbol.id}:${x.id}`;s.set(he,{symbol:x,relation:b.type,depth:M,sourceSymbolId:l.symbol.id});let O=oi[b.type]??1;i+=Math.max(1,O-(M-1)),p.push({id:x.id,depth:M})}}}let a=[...s.values()].sort((l,m)=>l.depth-m.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],d=c.filter(to);return d.length===0&&d.push(...c.filter(l=>!to(l)).slice(0,10)),{risk:ni(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:d}}};var $e=class{constructor(e){this.graph=e;this.mapper=new Ke(e),this.blast=new Fe(e)}graph;mapper;blast;async analyzeGitDiff(e,t,o={}){let n=await eo(t),s=this.mapper.map(e,n),i=this.blast.analyze(e,s,o.maxDepth??4);return{mode:"git_diff",changes:n,...i}}analyzeFile(e,t,o={}){let n=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,n,o.maxDepth??4)}}};var ro={mode:yt.enum(["git_diff","file"]).optional(),filePath:yt.string().optional(),depth:yt.number().int().min(1).max(10).optional()};async function oo(r,e){let t=new $e(r.graph);if((e.mode??(e.filePath?"file":"git_diff"))==="file"){if(!e.filePath)throw new Error("filePath is required when mode=file");return t.analyzeFile(r.project.id,e.filePath,{maxDepth:e.depth})}return t.analyzeGitDiff(r.project.id,r.project.rootPath,{maxDepth:e.depth})}import{z as si}from"zod";var no={symbol:si.string().min(1)};async function so(r,e){let t=E(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let n=new P(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:C(t),count:n.length,dependents:n.map(C)}}import{z as ht}from"zod";var io={from:ht.string().min(1),to:ht.string().min(1),maxDepth:ht.number().int().min(1).max(30).optional()};async function ao(r,e){let t=E(r,e.from),o=E(r,e.to);if(!t||!o)return{found:!1,fromFound:!!t,toFound:!!o,path:[],edges:[]};let s=new P(r.graph).shortestPath(r.project.id,t.id,o.id,e.maxDepth??12);return{found:s.found,distance:s.distance,from:C(t),to:C(o),path:s.symbols.map(C),edges:s.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as vt}from"zod";var co={symbol:vt.string().min(1),depth:vt.number().int().min(1).max(5).optional(),limit:vt.number().int().min(1).max(200).optional()};async function lo(r,e){let t=E(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let n=new P(r.graph).neighborhood(r.project.id,t.id,e.depth??1);if(!n)return{found:!1,query:e.symbol};let s=e.limit??50;return{found:!0,center:C(n.center),incomingCount:n.incoming.length,outgoingCount:n.outgoing.length,incoming:n.incoming.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:C(i.symbol)})),outgoing:n.outgoing.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:C(i.symbol)}))}}import{z as bt}from"zod";function ii(r){return r.replaceAll("\\","/").toLowerCase()}var Ge=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e),n=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,o);a&&n.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 n){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 o=ii(e.filePath),n=[];if(e.type==="route")return{kind:"route",score:100,reasons:["HTTP route"]};let s=null,i=0;if(o.startsWith("bin/"))s="cli",i=100,n.push("bin executable");else if(/(^|\/)(cli)\.[^.]+$/.test(o))s="cli",i=90,n.push("CLI entry file");else if(/(^|\/)(main|server)\.[^.]+$/.test(o))s="main",i=90,n.push("main/server file");else if(o.includes("/runtime/")&&/(^|\/)(bootstrap|index)\.[^.]+$/.test(o))s="runtime",i=75,n.push("runtime bootstrap");else if(/(^|\/)index\.[^.]+$/.test(o)){let c=t.filter(l=>l.to===e.id&&l.type!=="DEFINES").length,d=t.filter(l=>l.from===e.id&&l.type!=="DEFINES").length;(o.startsWith("packages/")||c===0||d>0)&&(s="package",i=o.startsWith("packages/")?70:55,n.push("package/public index"))}return s?(t.filter(c=>c.to===e.id&&c.type!=="DEFINES").length===0&&(i+=10,n.push("no incoming dependency")),{kind:s,score:i,reasons:n}):null}};var uo=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function wt(r){return r.replaceAll("\\","/").toLowerCase()}function ai(r){let e=wt(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function ci(r){let e=wt(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var Ue=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),o=this.graph.allEdges(e),n=new Set(new Ge(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||ai(i.filePath)||n.has(i.id)||ci(i)||o.filter(f=>f.to===i.id&&uo.has(f.type)).length>0)continue;let c=o.filter(f=>f.from===i.id&&uo.has(f.type)),d=["no incoming usage edge"],l=50;(i.type==="function"||i.type==="method")&&(l+=20,d.push("callable symbol")),i.type==="property"&&(l-=15),c.length===0&&(l+=10,d.push("no outgoing dependency")),wt(i.filePath).includes("/internal/")&&(l+=10,d.push("internal implementation")),i.name.startsWith("_")&&(l+=5);let p=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:p,score:l,reasons:d})}return s.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var po={confidence:bt.enum(["high","medium","low","all"]).optional(),filePath:bt.string().min(1).optional(),limit:bt.number().int().min(1).max(500).optional()},mo={high:3,medium:2,low:1};async function fo(r,e){let o=new Ue(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=mo[e.confidence];o=o.filter(a=>mo[a.confidence]>=i)}e.filePath&&(o=o.filter(i=>i.filePath===e.filePath));let n=o.length,s=e.limit??100;return{total:n,high:o.filter(i=>i.confidence==="high").length,medium:o.filter(i=>i.confidence==="medium").length,low:o.filter(i=>i.confidence==="low").length,warning:"Dead-code results are candidates only. Verify before deleting code.",candidates:o.slice(0,s)}}import{z as To}from"zod";import{existsSync as vi,readFileSync as wi}from"node:fs";import{join as bi}from"node:path";import{existsSync as li,mkdirSync as eu,readFileSync as di,renameSync as tu,writeFileSync as ru}from"node:fs";import{dirname as nu,join as ui}from"node:path";function mi(r){return ui(r.rootPath,".toolnet","work","current.json")}function St(r){let e=mi(r);if(!li(e))return null;try{let t=JSON.parse(di(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as pi,mkdirSync as au,readFileSync as fi,renameSync as cu,writeFileSync as lu}from"node:fs";import{dirname as uu,join as gi}from"node:path";function yi(r){return gi(r.rootPath,".toolnet","context","session-origin.json")}function kt(r){let e=yi(r);if(!pi(e))return null;try{let t=JSON.parse(fi(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function hi(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function We(r){let e=hi(r),t=/(?:agent trước|previous agent|ai trước|phiên trước)/u.test(e),o=/(?:đ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&&o?"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"}var Si={previous_agent:{previous_agent:100,task:35,phase:25},current_task:{task:100,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,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,next_action:95,file:90,blocker:85,previous_agent:80,phase:75,completed:60,todo:60,decision:55,progress:50,test:45,goal:35}},ki={handoff:18,"session-origin":14,"work-state":8};function Ci(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function h(r,e){let t=e.value.replace(/\s+/g," ").trim();t&&r.push({...e,value:t,score:0})}function Pi(r){let e=bi(r.rootPath,".toolnet","work","handoff-latest.json");if(!vi(e))return null;try{let o=JSON.parse(wi(e,"utf8")).continuity;return o?.schema!=="toolnet.handoff.v2"||o.project.id!==r.id?null:o}catch{return null}}function Ai(r){let e=Pi(r);if(!e)return[];let t=[];h(t,{kind:"previous_agent",value:e.source.agent,source:"handoff"}),e.goal&&h(t,{kind:"goal",value:e.goal,source:"handoff"}),e.current.phase&&h(t,{kind:"phase",value:e.current.phase.title,source:"handoff"}),e.current.task&&h(t,{kind:"task",value:e.current.task.title,source:"handoff"}),e.files.current&&h(t,{kind:"file",value:e.files.current,source:"handoff"}),e.nextAction&&h(t,{kind:"next_action",value:e.nextAction,source:"handoff"});for(let o of e.blockers)h(t,{kind:"blocker",value:o,source:"handoff"});for(let o of e.decisions)h(t,{kind:"decision",value:o,source:"handoff"});for(let o of e.completed.tasks)h(t,{kind:"completed",value:o,source:"handoff"});for(let o of e.remaining.todos)h(t,{kind:"todo",value:o,source:"handoff"});return h(t,{kind:"test",value:`Test status: ${e.tests.status}`,source:"handoff"}),h(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"handoff"}),t}function xi(r){let e=kt(r);if(!e)return[];let t=[];return h(t,{kind:"previous_agent",value:e.agent,source:"session-origin"}),e.currentPhase&&h(t,{kind:"phase",value:e.currentPhase,source:"session-origin"}),e.currentTask&&h(t,{kind:"task",value:e.currentTask,source:"session-origin"}),e.lastTouchedFile&&h(t,{kind:"file",value:e.lastTouchedFile,source:"session-origin"}),e.latestNextAction&&h(t,{kind:"next_action",value:e.latestNextAction,source:"session-origin"}),e.latestBlocker&&h(t,{kind:"blocker",value:e.latestBlocker,source:"session-origin"}),e.latestDecision&&h(t,{kind:"decision",value:e.latestDecision,source:"session-origin"}),t}function Mi(r){let e=St(r);if(!e)return[];let t=[];e.goal&&h(t,{kind:"goal",value:e.goal,source:"work-state"}),e.currentPhase&&h(t,{kind:"phase",value:e.currentPhase.title,source:"work-state"}),e.currentTask&&h(t,{kind:"task",value:e.currentTask.title,source:"work-state"});let o=e.filesTouched.at(-1);o&&h(t,{kind:"file",value:o,source:"work-state"});for(let n of e.nextActions.slice(0,5))h(t,{kind:"next_action",value:n,source:"work-state"});for(let n of e.blockers.slice(-5))h(t,{kind:"blocker",value:n,source:"work-state"});for(let n of e.decisions.slice(-5))h(t,{kind:"decision",value:n,source:"work-state"});for(let n of e.tasks.filter(s=>s.status==="completed").slice(-8))h(t,{kind:"completed",value:n.title,source:"work-state"});for(let n of e.tasks.filter(s=>s.status!=="completed"&&s.status!=="cancelled").slice(0,8))h(t,{kind:"todo",value:n.title,source:"work-state"});for(let n of e.tests.slice(-5))h(t,{kind:"test",value:n,source:"work-state"});return h(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"work-state"}),t}function Ei(r,e){let t=Si[r];return e.map((o,n)=>({...o,score:(t[o.kind]??10)+ki[o.source]+Math.max(0,5-n*.01)}))}function Ri(r){let e=new Map;for(let t of r){let o=`${t.kind}:${Ci(t.value)}`,n=e.get(o);(!n||t.score>n.score)&&e.set(o,t)}return[...e.values()]}function G(r,e,t={}){let o=We(e),n=[...Ai(r),...xi(r),...Mi(r)],s=Ri(Ei(o,n)).sort((l,m)=>m.score-l.score),i=Math.max(1,t.maxFacts??12),a=Math.max(300,t.maxChars??3200),c=[],d=0;for(let l of s){if(c.length>=i)break;let m=l.kind.length+l.value.length+l.source.length+16;c.length>0&&d+m>a||(c.push(l),d+=m)}return{intent:o,facts:c,context:{project:{id:r.id,name:r.name},intent:o,selectedFacts:c.map(l=>({kind:l.kind,value:l.value,source:l.source}))},stats:{candidates:n.length,selected:c.length,chars:d}}}var go={previous_agent:"Agent tr\u01B0\u1EDBc",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",completed:"\u0110\xE3 ho\xE0n th\xE0nh",test:"Test",progress:"Ti\u1EBFn \u0111\u1ED9"},yo=["previous_agent","phase","task","file","todo","next_action","blocker","decision","completed","test","progress","goal"],ji={previous_agent:["previous_agent"],current_task:["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:yo};function Ti(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 Ii(r){let e=r.filter(t=>t.source==="handoff");return e.length>0?e:r}function _i(r){let e=new Set,t=[];for(let o of r){let n=`${o.kind}:${o.value.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}`;e.has(n)||(e.add(n),t.push(o))}return t}function ho(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function Oi(r,e){let t=[];for(let o of e){let n=r.filter(s=>s.kind===o).slice(0,ho(o));for(let s of n)t.push(`${go[o]}: ${s.value}`)}return t.join(`
|
|
10
|
-
`)}function
|
|
11
|
-
`)}function
|
|
9
|
+
`);if(p===-1)return;let f=a.slice(0,p).trim();u(()=>{try{o(JSON.parse(f))}catch(h){s(h instanceof Error?h:new Error(String(h)))}})}),i.once("error",m=>{u(()=>{s(m)})}),i.once("end",()=>{c||u(()=>{s(new Error("ToolNet service closed without response"))})})})}async function Vs(r,e={}){let t=await Sr({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 wr(r,e={}){try{return await Vs(r,e)}catch{return null}}async function _e(r,e={}){try{let t=await Sr({type:"invalidate",project:r},{timeoutMs:250,...e});return t.ok&&t.type==="invalidate"}catch{return!1}}var Cr={type:H.enum(["activity","decision","rule","todo","summary"]),content:H.string().min(1),tags:H.array(H.string()).optional(),importance:H.enum(["critical","high","normal","temporary"]).optional()};async function xr(r,e){let t=r.memory.remember({projectId:r.project.id,type:e.type,content:e.content,tags:e.tags,importance:e.importance,source:"mcp"});return r.memoryStore&&await r.memoryStore.save(r.project.id,r.memory.exportProject(r.project.id)),_e(r.project),t}import{z as Hs}from"zod";var Mr={id:Hs.string().min(1)};async function Pr(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&&_e(r.project),{deleted:t}}import{z as Js}from"zod";var Ar={name:Js.string().min(1)};async function Er(r,e){return r.graph.findByName(r.project.id,e.name)}import{z as Ys}from"zod";var Oe=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Rr=new Set(["CALLS","CALL_REFERENCE"]),x=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,Rr)}callees(e,t){return this.relatedOutgoing(e,t,Rr)}dependents(e,t){return this.relatedIncoming(e,t,Oe)}dependencies(e,t){return this.relatedOutgoing(e,t,Oe)}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(p=>Oe.has(p.type)),c=new Map;for(let p of a){let f=c.get(p.from)??[];f.push(p),c.set(p.from,f)}let u=[{id:t,depth:0}],l=new Set([t]),m=new Map;for(;u.length>0;){let p=u.shift();if(!(p.depth>=o)){for(let f of c.get(p.id)??[])if(!l.has(f.to)){if(l.add(f.to),m.set(f.to,{node:p.id,edge:f}),f.to===n)return this.buildPath(t,n,m);u.push({id:f.to,depth:p.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=>Oe.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 p=n==="incoming"?l.from:l.to;if(a.has(p))continue;let f=this.graph.getSymbol(p);f&&(a.add(p),c.push({symbol:f,depth:u.depth+1,via:l}),i.push({id:p,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 E(r,e){let t=r.graph.getSymbol(e);if(t&&t.projectId===r.project.id)return t;let n=new x(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 C(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:Ys.string().min(1)};async function Tr(r,e){let t=E(r,e.symbolId);if(!t)return{found:!1,query:e.symbolId,callers:[]};let o=new x(r.graph).callers(r.project.id,t.id);return{found:!0,symbol:C(t),count:o.length,callers:o.map(C)}}import{z as jr}from"zod";var _r={query:jr.string().min(1),limit:jr.number().int().min(1).max(50).optional()};async function Or(r,e){let t=e.query.toLowerCase(),n=e.limit??20;return r.graph.allSymbols(r.project.id).filter(o=>o.name.toLowerCase().includes(t)||o.qualifiedName?.toLowerCase().includes(t)||o.filePath.toLowerCase().includes(t)).slice(0,n)}import{z as Nr}from"zod";function Ne(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 Lr={query:Nr.string().optional(),memoryLimit:Nr.number().int().min(1).max(20).optional()};async function Dr(r,e){let t=Ne(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 Xs}from"zod";var Qs=["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"],O=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 Qs){let m=`${i}/${l}`,p=await this.storage.get(m);p&&(await this.storage.put(`${a}/${l}`,p,"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 Kr={reason:Xs.string().optional()};async function Fr(r,e){if(!r.storage)throw new Error("Storage unavailable");return new O(r.storage).create(r.project.id,e.reason??"manual-mcp")}async function $r(r){if(!r.storage)throw new Error("Storage unavailable");return new O(r.storage).list(r.project.id)}import{z as Zs}from"zod";var Gr={snapshotId:Zs.string().min(1)};async function zr(r,e){if(!r.storage)throw new Error("Storage unavailable");let t=new O(r.storage);return await t.create(r.project.id,"before-rollback"),t.restore(r.project.id,e.snapshotId)}import{z as ft}from"zod";var Le=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(m=>m.from===u.id):c.filter(m=>m.to===u.id);for(let m of l){let p=n==="out"?m.to:m.from;if(i.has(p))continue;i.add(p);let f=this.graph.getSymbol(p);if(!f)continue;let h=u.depth+1;s.push({symbol:f,depth:h}),a.push({id:p,depth:h})}}return s}};var Ur={symbolId:ft.string().min(1),direction:ft.enum(["callers","callees"]).optional(),depth:ft.number().int().min(1).max(10).optional()};async function Wr(r,e){let t=new Le(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 qr}from"zod";var De=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 m=this.graph.getSymbol(l.from);if(!m)continue;let p=c.depth+1;a.push({symbol:m,depth:p,relation:l.type}),i.push({id:l.from,depth:p})}}return a}};var Br={symbolId:qr.string().min(1),depth:qr.number().int().min(1).max(10).optional()};async function Vr(r,e){let t=r.graph.getSymbol(e.symbolId);if(!t)return{found:!1,impacts:[]};let o=new De(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 Hr(r){return{project:{id:r.project.id,name:r.project.name,rootPath:r.project.rootPath},architecture:Ne(r.graph,r.project.id)}}import{z as Jr}from"zod";var ei=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE"]),Ke=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e).filter(i=>ei.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 m of n){let p=o.get(m.from),f=o.get(m.to);!p||!f||p.filePath===f.filePath||(p.filePath===i&&(a.add(f.filePath),u++),f.filePath===i&&(c.add(p.filePath),l++))}return{filePath:i,dependencies:[...a].sort(),dependents:[...c].sort(),outgoingEdges:u,incomingEdges:l}})}};var Yr={filePath:Jr.string().min(1),direction:Jr.enum(["dependencies","dependents","both"]).optional()};async function Qr(r,e){let n=new Ke(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 Xr}from"zod";var Zr={query:Xr.string().min(1),limit:Xr.number().int().min(1).max(20).optional()};async function en(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 yt}from"zod";import{execFile as ti}from"node:child_process";import{promisify as ri}from"node:util";var gt=ri(ti);function ni(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 oi(r){return r.startsWith("A")?"added":r.startsWith("D")?"deleted":r.startsWith("R")?"renamed":"modified"}async function tn(r){let e="";try{e=(await gt("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 gt("git",["diff","HEAD","--unified=0","--",i],{cwd:r,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:oi(o),ranges:ni(a)})}try{let n=await gt("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 si(r,e){return e.ranges.length===0?!0:typeof r.startLine!="number"||typeof r.endLine!="number"?!1:e.ranges.some(t=>r.startLine<=t.endLine&&r.endLine>=t.startLine)}var Fe=class{constructor(e){this.graph=e}graph;map(e,t){let n=this.graph.allSymbols(e),o=[];for(let s of t){let i=n.filter(u=>u.filePath===s.filePath),c=i.filter(u=>u.type!=="file").filter(u=>si(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 ii={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function ai(r){return r>=30?"CRITICAL":r>=16?"HIGH":r>=6?"MEDIUM":"LOW"}function rn(r){let e=r.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var $e=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 m=new Set([l.symbol.id]),p=[{id:l.symbol.id,depth:0}];for(;p.length;){let f=p.shift();if(f.depth>=n)continue;let h=o.filter(v=>v.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(v.type));for(let v of h){if(m.has(v.from))continue;m.add(v.from);let P=this.graph.getSymbol(v.from);if(!P)continue;let A=f.depth+1,he=`${l.symbol.id}:${P.id}`;s.set(he,{symbol:P,relation:v.type,depth:A,sourceSymbolId:l.symbol.id});let N=ii[v.type]??1;i+=Math.max(1,N-(A-1)),p.push({id:P.id,depth:A})}}}let a=[...s.values()].sort((l,m)=>l.depth-m.depth),c=[...new Set(a.map(l=>l.symbol.filePath))],u=c.filter(rn);return u.length===0&&u.push(...c.filter(l=>!rn(l)).slice(0,10)),{risk:ai(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:u}}};var Ge=class{constructor(e){this.graph=e;this.mapper=new Fe(e),this.blast=new $e(e)}graph;mapper;blast;async analyzeGitDiff(e,t,n={}){let o=await tn(t),s=this.mapper.map(e,o),i=this.blast.analyze(e,s,n.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,n={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,n.maxDepth??4)}}};var nn={mode:yt.enum(["git_diff","file"]).optional(),filePath:yt.string().optional(),depth:yt.number().int().min(1).max(10).optional()};async function on(r,e){let t=new Ge(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 ci}from"zod";var sn={symbol:ci.string().min(1)};async function an(r,e){let t=E(r,e.symbol);if(!t)return{found:!1,query:e.symbol,dependents:[]};let o=new x(r.graph).dependents(r.project.id,t.id);return{found:!0,symbol:C(t),count:o.length,dependents:o.map(C)}}import{z as ht}from"zod";var cn={from:ht.string().min(1),to:ht.string().min(1),maxDepth:ht.number().int().min(1).max(30).optional()};async function ln(r,e){let t=E(r,e.from),n=E(r,e.to);if(!t||!n)return{found:!1,fromFound:!!t,toFound:!!n,path:[],edges:[]};let s=new x(r.graph).shortestPath(r.project.id,t.id,n.id,e.maxDepth??12);return{found:s.found,distance:s.distance,from:C(t),to:C(n),path:s.symbols.map(C),edges:s.edges.map(i=>({id:i.id,type:i.type,from:i.from,to:i.to,metadata:i.metadata}))}}import{z as kt}from"zod";var un={symbol:kt.string().min(1),depth:kt.number().int().min(1).max(5).optional(),limit:kt.number().int().min(1).max(200).optional()};async function dn(r,e){let t=E(r,e.symbol);if(!t)return{found:!1,query:e.symbol};let o=new x(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:C(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:C(i.symbol)})),outgoing:o.outgoing.slice(0,s).map(i=>({depth:i.depth,via:i.via?.type,symbol:C(i.symbol)}))}}import{z as vt}from"zod";function li(r){return r.replaceAll("\\","/").toLowerCase()}var ze=class{constructor(e){this.graph=e}graph;detect(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=[];for(let i of t){if(i.type!=="route"&&i.type!=="file")continue;let a=this.classify(i,n);a&&o.push({symbolId:i.id,filePath:i.filePath,name:i.name,kind:a.kind,score:a.score,reasons:a.reasons})}let s=new Map;for(let i of o){let a=i.kind==="route"?i.symbolId:i.filePath,c=s.get(a);(!c||i.score>c.score)&&s.set(a,i)}return[...s.values()].sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath))}classify(e,t){let n=li(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 mn=new Set(["CALLS","CALL_REFERENCE","IMPORTS","USES_TYPE","WRITES","INHERITS","IMPLEMENTS","ROUTE","TESTS"]);function bt(r){return r.replaceAll("\\","/").toLowerCase()}function ui(r){let e=bt(r);return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}function di(r){let e=bt(r.filePath);return e.startsWith("bin/")||/(^|\/)index\.[^.]+$/.test(e)||/(^|\/)(main|server|cli)\.[^.]+$/.test(e)}var Ue=class{constructor(e){this.graph=e}graph;analyze(e){let t=this.graph.allSymbols(e),n=this.graph.allEdges(e),o=new Set(new ze(this.graph).detect(e).map(i=>i.symbolId)),s=[];for(let i of t){if(!["function","method","class","interface","property"].includes(i.type)||ui(i.filePath)||o.has(i.id)||di(i)||n.filter(f=>f.to===i.id&&mn.has(f.type)).length>0)continue;let c=n.filter(f=>f.from===i.id&&mn.has(f.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")),bt(i.filePath).includes("/internal/")&&(l+=10,u.push("internal implementation")),i.name.startsWith("_")&&(l+=5);let p=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:p,score:l,reasons:u})}return s.sort((i,a)=>a.score-i.score||i.filePath.localeCompare(a.filePath)||i.name.localeCompare(a.name))}};var fn={confidence:vt.enum(["high","medium","low","all"]).optional(),filePath:vt.string().min(1).optional(),limit:vt.number().int().min(1).max(500).optional()},pn={high:3,medium:2,low:1};async function gn(r,e){let n=new Ue(r.graph).analyze(r.project.id);if(e.confidence&&e.confidence!=="all"){let i=pn[e.confidence];n=n.filter(a=>pn[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 Dn}from"zod";import{existsSync as _i,readFileSync as Oi}from"node:fs";import{join as Ni}from"node:path";import{existsSync as mi,mkdirSync as ld,readFileSync as pi,renameSync as ud,writeFileSync as dd}from"node:fs";import{dirname as pd,join as fi}from"node:path";function gi(r){return fi(r.rootPath,".toolnet","work","current.json")}function St(r){let e=gi(r);if(!mi(e))return null;try{let t=JSON.parse(pi(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}import{existsSync as yi,mkdirSync as yd,readFileSync as hi,renameSync as hd,writeFileSync as kd}from"node:fs";import{dirname as vd,join as ki}from"node:path";function bi(r){return ki(r.rootPath,".toolnet","context","session-origin.json")}function wt(r){let e=bi(r);if(!yi(e))return null;try{let t=JSON.parse(hi(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function vi(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function We(r){let e=vi(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 Ei,mkdirSync as im,readFileSync as Ri}from"node:fs";import{join as bn}from"node:path";ve();Ct();var Hd=new _;function Ii(r){return bn(r.rootPath,".toolnet","memory","checkpoints")}function Ti(r){return bn(Ii(r),"latest.json")}function ji(r){let e=Ti(r);if(!Ei(e))return null;try{let t=JSON.parse(Ri(e,"utf8"));return t.schema!=="toolnet.memory.checkpoint.v1"||t.project.id!==r.id?null:t}catch{return null}}function vn(r){return ji(r)}var Li={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}},Di={checkpoint:20,handoff:18,"session-origin":14,"work-state":8};function Ki(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim()}function g(r,e){let t=e.value.replace(/\s+/g," ").trim();t&&r.push({...e,value:t,score:0})}function Fi(r){let e=Ni(r.rootPath,".toolnet","work","handoff-latest.json");if(!_i(e))return null;try{let n=JSON.parse(Oi(e,"utf8")).continuity;return n?.schema!=="toolnet.handoff.v2"||n.project.id!==r.id?null:n}catch{return null}}function $i(r){let e=vn(r);if(!e)return[];let t=[];e.request&&g(t,{kind:"request",value:e.request,source:"checkpoint"}),e.activity&&g(t,{kind:"activity",value:e.activity,source:"checkpoint"}),e.current.phase&&g(t,{kind:"phase",value:e.current.phase.title,source:"checkpoint"}),e.current.task&&g(t,{kind:"task",value:e.current.task.title,source:"checkpoint"});let n=e.files.active.at(-1);n&&g(t,{kind:"file",value:n,source:"checkpoint"});for(let o of e.nextActions)g(t,{kind:"next_action",value:o,source:"checkpoint"});for(let o of e.blockers)g(t,{kind:"blocker",value:o,source:"checkpoint"});for(let o of e.completed.tasks)g(t,{kind:"completed",value:o,source:"checkpoint"});for(let o of e.remaining.tasks)g(t,{kind:"todo",value:o,source:"checkpoint"});for(let o of e.durableFacts)g(t,{kind:o.kind,value:o.content,source:"checkpoint"});return t}function Gi(r){let e=Fi(r);if(!e)return[];let t=[];g(t,{kind:"previous_agent",value:e.source.agent,source:"handoff"}),e.request&&g(t,{kind:"request",value:e.request,source:"handoff"}),e.activity&&g(t,{kind:"activity",value:e.activity,source:"handoff"}),e.goal&&g(t,{kind:"goal",value:e.goal,source:"handoff"}),e.current.phase&&g(t,{kind:"phase",value:e.current.phase.title,source:"handoff"}),e.current.task&&g(t,{kind:"task",value:e.current.task.title,source:"handoff"}),e.files.current&&g(t,{kind:"file",value:e.files.current,source:"handoff"}),e.nextAction&&g(t,{kind:"next_action",value:e.nextAction,source:"handoff"});for(let n of e.blockers)g(t,{kind:"blocker",value:n,source:"handoff"});for(let n of e.decisions)g(t,{kind:"decision",value:n,source:"handoff"});for(let n of e.completed.tasks)g(t,{kind:"completed",value:n,source:"handoff"});for(let n of e.remaining.todos)g(t,{kind:"todo",value:n,source:"handoff"});return g(t,{kind:"test",value:`Test status: ${e.tests.status}`,source:"handoff"}),g(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"handoff"}),t}function zi(r){let e=wt(r);if(!e)return[];let t=[];return g(t,{kind:"previous_agent",value:e.agent,source:"session-origin"}),e.currentPhase&&g(t,{kind:"phase",value:e.currentPhase,source:"session-origin"}),e.currentTask&&g(t,{kind:"task",value:e.currentTask,source:"session-origin"}),e.lastTouchedFile&&g(t,{kind:"file",value:e.lastTouchedFile,source:"session-origin"}),e.latestNextAction&&g(t,{kind:"next_action",value:e.latestNextAction,source:"session-origin"}),e.latestBlocker&&g(t,{kind:"blocker",value:e.latestBlocker,source:"session-origin"}),e.latestDecision&&g(t,{kind:"decision",value:e.latestDecision,source:"session-origin"}),t}function Ui(r){let e=St(r);if(!e)return[];let t=[];e.currentRequest&&g(t,{kind:"request",value:e.currentRequest,source:"work-state"}),e.currentActivity&&g(t,{kind:"activity",value:e.currentActivity,source:"work-state"}),e.goal&&g(t,{kind:"goal",value:e.goal,source:"work-state"}),e.currentPhase&&g(t,{kind:"phase",value:e.currentPhase.title,source:"work-state"}),e.currentTask&&g(t,{kind:"task",value:e.currentTask.title,source:"work-state"});let n=e.activeFiles?.at(-1)??e.filesTouched.at(-1);n&&g(t,{kind:"file",value:n,source:"work-state"});for(let o of e.nextActions.slice(0,5))g(t,{kind:"next_action",value:o,source:"work-state"});for(let o of e.blockers.slice(-5))g(t,{kind:"blocker",value:o,source:"work-state"});for(let o of e.decisions.slice(-5))g(t,{kind:"decision",value:o,source:"work-state"});for(let o of e.tasks.filter(s=>s.status==="completed").slice(-8))g(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))g(t,{kind:"todo",value:o.title,source:"work-state"});for(let o of e.tests.slice(-5))g(t,{kind:"test",value:o,source:"work-state"});return g(t,{kind:"progress",value:`${e.progress.tasksCompleted}/${e.progress.tasksTotal} tasks completed; ${e.progress.blocked} blocked`,source:"work-state"}),t}function Wi(r,e){let t=Li[r];return e.map((n,o)=>({...n,score:(t[n.kind]??10)+Di[n.source]+Math.max(0,5-o*.01)}))}function qi(r){let e=new Map;for(let t of r){let n=`${t.kind}:${Ki(t.value)}`,o=e.get(n);(!o||t.score>o.score)&&e.set(n,t)}return[...e.values()]}function G(r,e,t={}){let n=We(e),o=[...$i(r),...Gi(r),...zi(r),...Ui(r)],s=qi(Wi(n,o)).sort((l,m)=>m.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 m=l.kind.length+l.value.length+l.source.length+16;c.length>0&&u+m>a||(c.push(l),u+=m)}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 Sn={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"},wn=["previous_agent","request","activity","phase","task","file","todo","next_action","blocker","decision","rule","architecture","fix","completed","test","progress","goal"],Bi={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:wn};function Vi(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 Hi(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 Ji(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 Cn(r){switch(r){case"todo":case"blocker":case"decision":case"completed":return 3;default:return 1}}function Yi(r,e){let t=[];for(let n of e){let o=r.filter(s=>s.kind===n).slice(0,Cn(n));for(let s of o)t.push(`${Sn[n]}: ${s.value}`)}return t.join(`
|
|
10
|
+
`)}function Qi(r,e){let t=Bi[e]??wn,n=[];for(let o of t){let s=r.filter(i=>i.kind===o).slice(0,Cn(o));for(let i of s)n.push(`${Sn[o]}: ${i.value}`)}return n.join(`
|
|
11
|
+
`)}function Q(r,e){let t=G(r,e,{maxFacts:32,maxChars:6400}),n=Ji(Hi(t.facts)),o=Vi(e)?Yi(n,["todo","task","next_action","file"]):Qi(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"}}Be();var te=class extends Error{status;constructor(e,t){super(e),this.name="AiHttpError",this.status=t}};async function z(r,e,t=3e4){let n=new AbortController,o=setTimeout(()=>n.abort(),t);o.unref?.();try{let s=await fetch(r,{...e,signal:n.signal}),i=await s.text();if(!s.ok){let a=i;try{let c=JSON.parse(i);a=c.error?.message??c.message??i}catch{}throw new te(a||`HTTP ${s.status}`,s.status)}return i.trim()?JSON.parse(i):{}}finally{clearTimeout(o)}}function Ve(r,e){return`${r.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}Be();xt();var He=class{constructor(e){this.config=e}config;id="cloudflare";model(){let e=this.config.model?.trim();if(!e)throw new Error("cloudflare: MODEL is not configured");return e}async generate(e){let t=this.config.accountId?.trim(),n=this.config.apiKey?.trim();if(!t)throw new Error("cloudflare: ACCOUNT ID is not configured");if(!n)throw new Error("cloudflare: API TOKEN is not configured");let o=this.model(),i=`${(this.config.baseUrl?.trim()||`https://api.cloudflare.com/client/v4/accounts/${t}/ai/run`).replace(/\/+$/,"")}/${o}`,a=await z(i,{method:"POST",headers:{authorization:`Bearer ${n}`,"content-type":"application/json",...this.config.headers},body:JSON.stringify({messages:e.messages,temperature:e.temperature,max_tokens:e.maxTokens})}),c=a.result?.response?.trim();if(!c)throw new Error(a.errors?.[0]?.message??"cloudflare: empty model response");return{text:c,provider:"cloudflare",model:o}}async healthCheck(){let e=Date.now();try{return{ok:!0,provider:"cloudflare",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-e}}catch(t){return{ok:!1,provider:"cloudflare",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-e}}}};var Je=class{constructor(e){this.config=e}config;id="gemini";model(){let e=this.config.model?.trim();if(!e)throw new Error("gemini: MODEL is not configured");return e.replace(/^models\//,"")}async generate(e){let t=this.config.apiKey?.trim();if(!t)throw new Error("gemini: API KEY is not configured");let n=this.config.baseUrl?.trim()||"https://generativelanguage.googleapis.com/v1beta",o=this.model(),s=e.messages.filter(l=>l.role==="system"),i=e.messages.filter(l=>l.role!=="system").map(l=>({role:l.role==="assistant"?"model":"user",parts:[{text:l.content}]})),a=`${Ve(n,`models/${encodeURIComponent(o)}:generateContent`)}?key=${encodeURIComponent(t)}`,c=await z(a,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...s.length?{systemInstruction:{parts:[{text:s.map(l=>l.content).join(`
|
|
12
12
|
|
|
13
|
-
`)}]}}:{},contents:i,generationConfig:{temperature:e.temperature,maxOutputTokens:e.maxTokens}})}),
|
|
14
|
-
[truncated]`}function
|
|
13
|
+
`)}]}}:{},contents:i,generationConfig:{temperature:e.temperature,maxOutputTokens:e.maxTokens}})}),u=c.candidates?.[0]?.content?.parts?.map(l=>l.text??"").join("").trim();if(!u)throw new Error("gemini: empty model response");return{text:u,provider:"gemini",model:o,usage:c.usageMetadata?{inputTokens:c.usageMetadata.promptTokenCount,outputTokens:c.usageMetadata.candidatesTokenCount,totalTokens:c.usageMetadata.totalTokenCount}:void 0}}async healthCheck(){let e=Date.now();try{return{ok:!0,provider:"gemini",model:(await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8})).model,message:"Provider reachable",latencyMs:Date.now()-e}}catch(t){return{ok:!1,provider:"gemini",model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-e}}}};var Ye=class{constructor(e){this.config=e;this.id=e.id}config;id;baseUrl(){let e=this.config.baseUrl?.trim();if(!e)throw new Error(`${this.id}: BASE URL is not configured`);return e}model(){let e=this.config.model?.trim();if(!e)throw new Error(`${this.id}: MODEL is not configured`);return e}headers(){let e={"content-type":"application/json",...this.config.headers};return this.config.apiKey&&(e.authorization=`Bearer ${this.config.apiKey}`),e}async generate(e){let t=this.model(),n=await z(Ve(this.baseUrl(),"chat/completions"),{method:"POST",headers:this.headers(),body:JSON.stringify({model:t,messages:e.messages,temperature:e.temperature,max_tokens:e.maxTokens,...this.id==="alibaba"?{enable_thinking:!1}:{}})}),o=n.choices?.[0]?.message?.content?.trim();if(!o)throw new Error(`${this.id}: empty model response`);return{text:o,provider:this.id,model:t,usage:n.usage?{inputTokens:n.usage.prompt_tokens,outputTokens:n.usage.completion_tokens,totalTokens:n.usage.total_tokens}:void 0}}async healthCheck(){let e=Date.now();try{let t=await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8});return{ok:!0,provider:this.id,model:t.model,message:"Provider reachable",latencyMs:Date.now()-e}}catch(t){return{ok:!1,provider:this.id,model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-e}}}};function In(r=An()){switch(L(r.id).transport){case"gemini":return new Je(r);case"cloudflare":return new He(r);default:return new Ye(r)}}function ta(r){return new Promise(e=>{setTimeout(e,r)})}function ra(r){if(r instanceof te){let t=r.status;return t===void 0||t===408||t===409||t===425||t===429?!0:t>=500}if(!(r instanceof Error))return!0;let e=r.message.toLowerCase();return e.includes("401")||e.includes("403")||e.includes("400")||e.includes("invalid api key")||e.includes("unauthorized")||e.includes("forbidden")?!1:e.includes("timeout")||e.includes("timed out")||e.includes("abort")||e.includes("network")||e.includes("fetch failed")||e.includes("econnreset")||e.includes("econnrefused")||e.includes("429")||e.includes("rate limit")||e.includes("500")||e.includes("502")||e.includes("503")||e.includes("504")}var Qe=class{id;config;providers;states=new Map;cooldownMs;maxRetries;constructor(e,t=[],n={}){this.id=e.config.id,this.config=e.config,this.cooldownMs=n.cooldownMs??6e4,this.maxRetries=Math.max(0,n.maxRetries??1),this.providers=[e,...t].map(o=>({provider:In(o.config),label:o.label}))}key(e){let t=this.providers[e];return`${e}:${t.provider.id}:${t.provider.config.model??""}`}state(e){let t=this.key(e),n=this.states.get(t);return n||(n={failures:0,cooldownUntil:0},this.states.set(t,n)),n}available(e){return this.state(e).cooldownUntil<=Date.now()}success(e){let t=this.state(e);t.failures=0,t.cooldownUntil=0,t.lastError=void 0}fail(e,t){let n=this.state(e);n.failures+=1,n.lastError=t instanceof Error?t.message:String(t),n.cooldownUntil=Date.now()+this.cooldownMs}async generate(e){let t=[];for(let n=0;n<this.providers.length;n+=1){if(!this.available(n)){t.push(`${this.providers[n].label}: cooldown`);continue}let o=this.providers[n];for(let s=0;s<=this.maxRetries;s+=1)try{let i=await o.provider.generate(e);return this.success(n),i}catch(i){let a=i instanceof Error?i.message:String(i),c=ra(i);if(t.push(`${o.label}: ${a}`),!c)throw i;if(s<this.maxRetries){await ta(Math.min(250*2**s,2e3));continue}this.fail(n,i)}}throw new Error(`All ToolNet LLM providers failed: ${t.join(" | ")}`)}async healthCheck(){let e=Date.now();try{let t=await this.generate({messages:[{role:"user",content:"Reply exactly: OK"}],temperature:0,maxTokens:8});return{ok:!0,provider:t.provider,model:t.model,message:"Fallback chain reachable",latencyMs:Date.now()-e}}catch(t){return{ok:!1,provider:this.id,model:this.config.model,message:t instanceof Error?t.message:String(t),latencyMs:Date.now()-e}}}status(){return this.providers.map((e,t)=>{let n=this.state(t);return{position:t,provider:e.provider.id,model:e.provider.config.model,cooldown:n.cooldownUntil>Date.now(),cooldownUntil:n.cooldownUntil||void 0,failures:n.failures,lastError:n.lastError}})}};function Tn(){let r=ee(),e=En();return new Qe({label:`Primary (${r.llm.provider})`,config:{id:r.llm.provider,apiKey:r.llm.apiKey,baseUrl:r.llm.baseUrl,model:r.llm.model,accountId:r.llm.accountId}},e.map(t=>({label:`Fallback ${t.slot} (${t.config.provider})`,config:{id:t.config.provider,apiKey:t.config.apiKey,baseUrl:t.config.baseUrl,model:t.config.model,accountId:t.config.accountId}})),Rn())}var Mt=class{constructor(e=Tn()){this.provider=e}provider;get activeProvider(){return this.provider}setProvider(e){this.provider=e}generate(e){return this.provider.generate(e)}};function jn(){return new Mt(Tn())}function na(r,e){let t=JSON.stringify(r,null,2);return t.length<=e?t:t.slice(0,e)+`
|
|
14
|
+
[truncated]`}function oa(r,e){let t=Q(r,e),n=G(r,e,{maxFacts:12,maxChars:3200});return na({project:n.context.project,intent:n.intent,directAnswer:t.answer,selectedMemory:n.context.selectedFacts,retrievalStats:n.stats},4200)}async function _n(r,e,t={}){let n=Q(r,e),o=oa(r,e),s=t.router??jn();try{let i=await s.generate({temperature:.1,maxTokens:450,messages:[{role:"system",content:`
|
|
15
15
|
You are ToolNet Memory Agent.
|
|
16
16
|
|
|
17
17
|
You are NOT the coding agent.
|
|
@@ -45,12 +45,12 @@ ${e}
|
|
|
45
45
|
|
|
46
46
|
ToolNet selected memory:
|
|
47
47
|
|
|
48
|
-
${
|
|
48
|
+
${o}
|
|
49
49
|
|
|
50
50
|
Answer the coding agent directly.
|
|
51
|
-
`.trim()}]}),a=i.text.trim();return a?{answer:a,provider:i.provider,model:i.model,usedAi:!0}:{answer:
|
|
52
|
-
`,{encoding:"utf8",mode:384}),
|
|
53
|
-
`)}function
|
|
54
|
-
`):e.trim(),c=We(e),l=G(r,a,{maxFacts:8,maxChars:1800}).facts.map(p=>({kind:p.kind,value:p.value,source:p.source})),m=
|
|
55
|
-
[truncated]`:
|
|
56
|
-
`).normalize("NFKC").toLowerCase(),n=0;r.task.normalize("NFKC").toLowerCase().includes(t)&&(n+=40),r.title.normalize("NFKC").toLowerCase().includes(t)&&(n+=30);for(let s of ha(t))o.includes(s)&&(n+=5),r.task.normalize("NFKC").toLowerCase().includes(s)&&(n+=4),r.files.some(i=>i.toLowerCase().includes(s))&&(n+=3);return n}function zo(r,e,t=5){let o=Math.max(1,Math.min(10,Math.floor(t)));return ya(r).map(n=>({...n,score:va(n,e)})).filter(n=>n.score>0).sort((n,s)=>s.score!==n.score?s.score-n.score:s.createdAt.localeCompare(n.createdAt)).slice(0,o)}var Vo={query:Bo.string().min(2).max(500).describe("Task, problem, file, command or workflow to match against successful reusable Skill Memory SOPs."),limit:Bo.number().int().min(1).max(10).optional().describe("Maximum matching reusable SOPs to return. Default 5.")};async function qo(r,e){let t=zo(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 sn}from"zod";var Ho="wiki/state.v1.json";function wa(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function ba(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 R=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Ho);if(!e){let t=wa(this.project);return await this.save(t),t}return ba(e,this.project)}async save(e){await this.storage.put(Ho,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as Qo}from"node:crypto";var S=class extends Error{constructor(t,o){super(t);this.statusCode=o}statusCode};function re(r){let e=new Set,t=[];for(let o of r){let n=o.replace(/\s+/gu," ").trim();if(!n)continue;let s=n.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),t.push(n))}return t}function oe(r){let e=r.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new S("Invalid Wiki slug",400);return e}function Jo(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let o=t[1]?.trim();o&&e.push(oe(o))}return re(e)}function Sa(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function Yo(r){return{id:`revision-${Qo()}`,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 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}async mutate(e){let t,o=this.queue.then(async()=>{let n=await this.ensureState();t=e(n),n.updatedAt=new Date().toISOString(),await this.store.save(n)});return this.queue=o.then(()=>{},()=>{}),await o,t}async summary(){let e=await this.ensureState(),t=new Set(e.pages.flatMap(o=>o.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:re(e.pages.flatMap(o=>o.tags)).sort((o,n)=>o.localeCompare(n)),links:e.pages.reduce((o,n)=>o+n.links.length,0),orphanPages:e.pages.filter(o=>o.links.length===0&&!t.has(o.slug)).length,automatedPages:e.pages.filter(o=>o.tags.some(n=>n.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return L([...e.pages].sort((t,o)=>t.title.localeCompare(o.title)))}async getPage(e){let t=await this.ensureState(),o=oe(e),n=t.pages.find(s=>s.slug===o||s.id===e);if(!n)throw new S(`Wiki page not found: ${e}`,404);return L(n)}async createPage(e){return this.mutate(t=>{let o=e.title.trim(),n=e.content.trim();if(!o)throw new S("Wiki title is required",400);let s=oe(e.slug??o);if(t.pages.some(c=>c.slug===s))throw new S(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${Qo()}`,slug:s,title:o,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:n,tags:re(e.tags??[]),links:Jo(n),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(Yo(a)),L(a)})}async updatePage(e,t){return this.mutate(o=>{let n=oe(e),s=o.pages.find(i=>i.slug===n||i.id===e);if(!s)throw new S(`Wiki page not found: ${e}`,404);if(t.title!==void 0){let i=t.title.trim();if(!i)throw new S("Wiki title is required",400);s.title=i}if(t.summary!==void 0){let i=t.summary.trim();i?s.summary=i:delete s.summary}return t.content!==void 0&&(s.content=t.content.trim(),s.links=Jo(s.content)),t.tags!==void 0&&(s.tags=re(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),o.revisions.push(Yo(s)),L(s)})}async history(e){let t=await this.getPage(e),o=await this.ensureState();return L(o.revisions.filter(n=>n.pageId===t.id).sort((n,s)=>s.revision-n.revision))}async backlinks(e){let t=await this.getPage(e),o=await this.ensureState();return L(o.pages.filter(n=>n.links.includes(t.slug)).sort((n,s)=>n.title.localeCompare(s.title)))}async search(e,t=10){let o=await this.ensureState(),n=re(Sa(e));if(n.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(t))),i=[];for(let a of o.pages){let c=a.title.toLowerCase(),d=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",m=a.content.toLowerCase(),p=a.tags.map(y=>y.toLowerCase()),f=0;for(let y of n)d===y&&(f+=12),c===y&&(f+=10),c.includes(y)&&(f+=6),d.includes(y)&&(f+=5),p.some(b=>b===y)?f+=5:p.some(b=>b.includes(y))&&(f+=3),l.includes(y)&&(f+=2),m.includes(y)&&(f+=1);f>0&&i.push({page:L(a),score:f})}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 Xo}from"node:crypto";var Zo="wiki/governance.v1.json",on="toolnet.knowledge-governance.v1",en=500,ne={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Ca(r,e=0,t=1){return Math.max(e,Math.min(t,r))}function Mt(r){return r.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function tn(r){return ka("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Pa(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 Aa(r){let e=r.sourceType==="skill"?.96:r.sourceType==="memory"?.94:.88,t=r.tags.map(o=>o.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),Ca(e)}function rn(r){let e=new Date().toISOString();return{schema:on,version:1,projectId:r,policy:{...ne},reviews:[],audit:[],createdAt:e,updatedAt:e}}function nn(r){let e=r.autoApproveThreshold??ne.autoApproveThreshold,t=r.criticalApproveThreshold??ne.criticalApproveThreshold,o=r.staleAfterDays??ne.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new S("Invalid autoApproveThreshold",400);if(!Number.isFinite(t)||t<.5||t>1)throw new S("Invalid criticalApproveThreshold",400);if(!Number.isInteger(o)||o<1||o>3650)throw new S("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:t,staleAfterDays:o}}var se=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(Zo);if(!e){let t=rn(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==on||t.version!==1||t.projectId!==this.project.id||!Array.isArray(t.reviews)||!Array.isArray(t.audit))throw new Error("invalid");return{...t,policy:nn(t.policy??ne)}}catch{let t=rn(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(Zo,JSON.stringify(e,null,2),"application/json")}},ie=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,t,o,n={}){e.audit.push({id:Xo(),action:t,principal:o,...n.reviewId?{reviewId:n.reviewId}:{},...n.sourceKey?{sourceKey:n.sourceKey}:{},timestamp:new Date().toISOString(),...n.metadata?{metadata:n.metadata}:{}}),e.audit.length>en&&(e.audit=e.audit.slice(-en))}async mutate(e){let t,o=this.queue.then(async()=>{let n=await this.ensureState();t=await e(n),n.updatedAt=new Date().toISOString(),await this.store.save(n)});return this.queue=o.then(()=>{},()=>{}),await o,t}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,t){return this.mutate(o=>(o.policy=nn({...o.policy,...e}),this.audit(o,"policy:update",t,{metadata:{...o.policy}}),{...o.policy}))}async summary(){let e=await this.ensureState(),t=o=>e.reviews.filter(n=>n.status===o).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(o=>o.status==="pending"&&o.risk==="critical").length,conflictPending:e.reviews.filter(o=>o.status==="pending"&&o.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(o=>!e||o.status===e).sort((o,n)=>n.updatedAt.localeCompare(o.updatedAt)))}async auditLog(e=100){let t=await this.ensureState(),o=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(t.audit.slice(-o).reverse())}async assess(e,t){let o=await this.ensureState(),n=Aa(e),s=Mt(e.title),i=t.filter(l=>l.slug!==e.slug&&Mt(l.title)===s&&tn(l.content)!==tn(e.content)).map(l=>l.slug),a=Pa(e),c=[];n<o.policy.autoApproveThreshold&&c.push(`confidence:${n.toFixed(2)}`),a&&n<o.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let d=i.length>0?"conflict":a?"critical":"normal";return{confidence:n,risk:d,requiresReview:i.length>0||n<o.policy.autoApproveThreshold||a&&n<o.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,t){let o=await this.assess(e,t);return this.mutate(n=>{let s=n.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:o,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:o,review:structuredClone(s)};if(!o.requiresReview)return this.audit(n,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:o.confidence,risk:o.risk}}),{allowed:!0,mode:"auto-approved",assessment:o};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:o,review:structuredClone(s)};let i=new Date().toISOString(),a={id:Xo(),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:o.confidence,risk:o.risk,reasons:[...o.reasons],conflicts:[...o.conflicts],status:"pending",createdAt:i,updatedAt:i};return n.reviews.push(a),this.audit(n,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:o,review:structuredClone(a)}})}async markApplied(e,t){await this.mutate(o=>{let n=o.reviews.find(s=>s.sourceKey===e&&s.digest===t&&s.status==="approved");n&&(n.appliedAt=new Date().toISOString(),n.updatedAt=n.appliedAt,this.audit(o,"knowledge:applied",n.reviewedBy??"system",{reviewId:n.id,sourceKey:e}))})}async decide(e,t,o){return this.mutate(async n=>{let s=n.reviews.find(d=>d.id===e);if(!s)throw new S(`Governance review not found: ${e}`,404);if(s.status!=="pending")throw new S("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=t.principal,s.updatedAt=i,t.note?.trim()&&(s.reviewNote=t.note.trim()),t.action==="reject")return s.status="rejected",this.audit(n,"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(n,"knowledge:superseded",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:t.targetReviewId}}),structuredClone(s);if(t.action==="merge"){if(!t.targetReviewId)throw new S("targetReviewId is required for merge",400);let d=n.reviews.find(l=>l.id===t.targetReviewId);if(!d)throw new S("Merge target review not found",404);return s.status="superseded",s.mergedInto=d.id,this.audit(n,"knowledge:merged",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:d.id}}),structuredClone(s)}s.status="approved";let c=(await o.listPages()).find(d=>d.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new S(`Wiki page '${s.slug}' is manually managed`,409);return c?await o.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await o.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(n,"knowledge:approved",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let t=await this.ensureState(),o=await e.listPages(),n=Date.now(),s=t.policy.staleAfterDays*864e5,i=o.map(l=>{let m=n-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(m/864e5)),stale:Number.isFinite(m)&&m>s}}).filter(l=>l.stale).map(({stale:l,...m})=>m),a=new Map;for(let l of o){let m=Mt(l.title),p=a.get(m)??[];p.push(l),a.set(m,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,m])=>({title:l,pages:m.map(p=>p.slug)})),d=t.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:o.length,automatedPages:o.filter(l=>l.tags.some(m=>m.startsWith("toolnet-auto-"))).length,manualPages:o.filter(l=>!l.tags.some(m=>m.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:d.length,lowConfidenceReviews:d.filter(l=>l.confidence<t.policy.autoApproveThreshold).length,conflicts:d.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var an={query:sn.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:sn.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function cn(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let o=new j(new R(t,r.project));await o.initialize();let n=await o.search(e.query,e.limit??5);return{schema:"toolnet.wiki-search.v1",query:e.query,count:n.length,results:n.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 xa}from"zod";var ln={page:xa.string().min(1).max(200).describe("Wiki page slug or page id.")};async function dn(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let o=new j(new R(t,r.project));await o.initialize();let n=await o.getPage(e.page),s=await o.backlinks(n.slug);return{schema:"toolnet.wiki-read.v1",page:n,backlinks:s.map(i=>({slug:i.slug,title:i.title}))}}import{z as Ma}from"zod";var un={includePending:Ma.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function mn(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let o=new ie(new se(t,r.project));await o.initialize();let n=new j(new R(t,r.project));await n.initialize();let s=await o.summary(),i=await o.quality(n),a=e.includePending?(await o.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 pn={};function fn(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 w(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}var ja=["# 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. Use mode="ai" only when the continuity question is ambiguous or requires synthesis.',"","4. NEVER reconstruct previous work by reading or searching raw agent/session history, including:"," - .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 Ta(r){let e=new Ea({name:"toolnet-memory",version:"0.1.0"},{instructions:ja});return e.tool("memory_search","Search relevant long-term memory for the current project.",hr,async t=>w(await vr(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",kr,async t=>w(await Cr(r,t))),e.tool("memory_forget","Delete a memory by id.",Pr,async t=>w(await Ar(r,t))),e.tool("find_symbol","Find code symbols by exact name.",xr,async t=>w(await Mr(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Rr,async t=>w(await jr(r,t))),e.tool("code_search","Search indexed code symbols and files.",Ir,async t=>w(await _r(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",Nr,async t=>w(await Lr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Ur,async t=>w(await Wr(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Br,async t=>w(await Vr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>w(await qr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Jr,async t=>w(await Yr(r,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Xr,async t=>w(await Zr(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Dr,async t=>w(await Kr(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>w(await Fr(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",$r,async t=>w(await Gr(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.",ro,async t=>w(await oo(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",no,async t=>w(await so(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",io,async t=>w(await ao(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",co,async t=>w(await lo(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",po,async t=>w(await fo(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(" "),Io,async t=>w(await _o(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(" "),Go,async t=>w(await Uo(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(" "),Vo,async t=>w(await qo(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(" "),an,async t=>w(await cn(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(" "),ln,async t=>w(await dn(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(" "),pn,async()=>w(fn(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(" "),un,async t=>w(await mn(r,t))),e}async function gn(r){let e=Ta(r),t=new Ra;await e.connect(t)}function yn(){return new Date().toISOString()}function T(r){r.lastUpdatedAt=yn()}function Qe(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:yn()}}function hn(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",T(r)}function vn(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,T(r)}function Xe(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,T(r))}function Ze(r,e){r.dependencies[e].attempts+=1,T(r)}function et(r){r.metrics.retryCount+=1,T(r)}function W(r,e,t=Date.now()){let o=r.dependencies[e];o.state="ready",o.lastError=void 0,o.readyAfterMs=t-r.metrics.processStartedAtMs,T(r)}function ae(r,e,t){let o=r.dependencies[e];o.state="failed",o.lastError=t instanceof Error?t.message:String(t),T(r)}function wn(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(([,o])=>o.state==="failed").map(([o,n])=>`${o}: ${n.lastError??"unknown error"}`);let t=Object.values(r.dependencies).every(o=>o.state==="ready");r.phase=t?"ready":"degraded",T(r)}function bn(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],T(r)}async function tt(r,e){let t=Math.max(1,Math.floor(e.attempts)),o;for(let n=1;n<=t;n+=1){e.onAttempt?.(n);try{return await r()}catch(s){if(o=s,n>=t)break;e.onRetry?.(n,s),e.delayMs>0&&await new Promise(i=>{setTimeout(i,e.delayMs)})}}throw o instanceof Error?o:new Error(String(o??"operation failed"))}function ns(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function Cc(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function Pc(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 ss(r){let e=r.runtime??Qe(Date.now());r.runtime=e,vn(e);let t=ns(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),o=Cc(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let n=await Sr(r.project,{timeoutMs:ns(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});n&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(n.memory),W(e,"memory")),e.dependencies.graph.state!=="ready"&&(n.graph&&r.graph.import(n.graph.symbols,n.graph.edges),W(e,"graph")))}try{let[{loadConfig:n},s]=await Promise.all([Promise.resolve().then(()=>(Cn(),kn)),Promise.resolve().then(()=>(Vn(),Bn))]),i=n(),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)}),d=new s.ProjectScopedStorageProvider(c,r.project.id,r.project.name,r.project.remote??r.project.name),l=new s.MemoryStore(d);r.storage=d,r.memoryStore=l;let m=e.dependencies.memory.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Xe(e,"memory");try{let f=await tt(()=>l.load(r.project.id),{attempts:t,delayMs:o,onAttempt:()=>{Ze(e,"memory")},onRetry:()=>{et(e)}});r.memory.importRecords(f),W(e,"memory")}catch(f){ae(e,"memory",f)}})(),p=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Xe(e,"graph");try{let f=await tt(()=>new s.PersistentCodeGraphStore(d).load(r.project.id),{attempts:t,delayMs:o,onAttempt:()=>{Ze(e,"graph")},onRetry:()=>{et(e)}});f&&r.graph.import(f.symbols,f.edges),W(e,"graph")}catch(f){ae(e,"graph",f)}})();if(await Promise.all([m,p]),e.dependencies.semantic.state!=="ready"){Xe(e,"semantic");try{let[{SemanticCodeEngine:f},{createEmbeddingProvider:y}]=await Promise.all([Promise.resolve().then(()=>(Zn(),Xn)),Promise.resolve().then(()=>(os(),rs))]),b=new f({projectId:r.project.id,rootPath:r.project.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:d,embeddings:y(),graph:r.graph});await tt(()=>b.initialize(),{attempts:t,delayMs:o,onAttempt:()=>{Ze(e,"semantic")},onRetry:()=>{et(e)}}),r.codeSemantic=b,W(e,"semantic")}catch(f){ae(e,"semantic",f)}}}catch(n){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&ae(e,s,n)}return wn(e),Pc(r)}import{closeSync as Ac,mkdirSync as xc,openSync as Mc,readFileSync as Ec,unlinkSync as is,writeFileSync as Rc}from"node:fs";import{tmpdir as jc}from"node:os";import{join as as}from"node:path";function Tc(r){try{return process.kill(r,0),!0}catch(e){return e?.code==="EPERM"}}var st=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=as(jc(),"toolnet-memory-locks");xc(t,{recursive:!0});let o=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=as(t,`${o}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Mc(this.path,"wx");Rc(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Ac(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let o=!0;try{let n=JSON.parse(Ec(this.path,"utf8"));Number.isInteger(n.pid)&&Tc(n.pid)&&(o=!1)}catch{o=!0}if(!o)throw new Error("ToolNet Memory is already running for this project");try{is(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{is(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};function cs(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function Ic(){let r=Date.now(),e=new Ce().detect(),t=new st(e.id);await t.acquire();let o=()=>{t.release().finally(()=>process.exit(0))};process.once("SIGINT",o),process.once("SIGTERM",o);let n=new Se,s=new Re(n),i=new je,a=new Te(i),c=Qe(r),d={project:e,memory:n,retrieval:s,graph:i,references:a,runtime:c};await gn(d),hn(c);let l=async()=>{try{await ss(d),c.phase==="degraded"&&setTimeout(()=>{l()},cs()).unref()}catch(m){bn(c,m),setTimeout(()=>{c.phase="degraded",l()},cs()).unref()}};l()}Ic().catch(r=>{console.error(r),process.exit(1)});
|
|
51
|
+
`.trim()}]}),a=i.text.trim();return a?{answer:a,provider:i.provider,model:i.model,usedAi:!0}:{answer:n.answer,usedAi:!1}}catch{return{answer:n.answer,usedAi:!1}}}import{existsSync as sa,mkdirSync as ia,readFileSync as aa,renameSync as ca,rmSync as la,writeFileSync as ua}from"node:fs";import{join as On}from"node:path";var da=720*60*1e3;function Nn(r){return On(r.rootPath,".toolnet","context","memory-agent-conversation.json")}function re(r){return r.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim()}function ma(r){let e=re(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 pa(r){if(ma(r))return!1;let e=re(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 fa(r,e,t){let n=Nn(r);if(!sa(n))return null;try{let o=JSON.parse(aa(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 ga(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,re(s)].join(":");if(!t.has(i)&&(t.add(i),n.push({...o,value:s}),n.length>=e))break}return n}function ya(r,e){let t=Nn(r),n=On(r.rootPath,".toolnet","context");ia(n,{recursive:!0,mode:448});let o=`${t}.${process.pid}.tmp`;try{ua(o,JSON.stringify(e,null,2)+`
|
|
52
|
+
`,{encoding:"utf8",mode:384}),ca(o,t)}finally{la(o,{force:!0})}}function ha(r){return r.focus.slice(0,8).map(e=>`- ${e.kind}: ${e.value}`).join(`
|
|
53
|
+
`)}function ka(r,e){return r.priorFocus.find(t=>t.kind===e)?.value}function Pt(r){if(!r.usedPriorFocus||r.currentIntent!=="summary"||r.priorFocus.length===0)return null;let e=re(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=ka(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 ba(r){let e=re(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 Ln(r,e,t={}){let n=t.now??Date.now(),o=t.maxAgeMs??da,s=fa(r,n,o),i=!!(s&&s.focus.length>0&&pa(e)&&!ba(e)),a=i&&s?[e.trim(),"","Previous ToolNet Memory conversation focus:",ha(s),"","Use the compact focus only to resolve the current follow-up question.","Do not reconstruct or request raw session transcripts."].join(`
|
|
54
|
+
`):e.trim(),c=We(e),l=G(r,a,{maxFacts:8,maxChars:1800}).facts.map(p=>({kind:p.kind,value:p.value,source:p.source})),m=ga(i&&s?[...l,...s.focus]:l);return ya(r,{schema:"toolnet.memory-conversation.v1",version:1,projectId:r.id,updatedAt:new Date(n).toISOString(),lastIntent:c,focus:m}),{question:a,originalQuestion:e,usedPriorFocus:i,previousIntent:s?.lastIntent,currentIntent:c,priorFocus:s?.focus??[],focusCount:m.length}}var Kn={question:Dn.string().min(2).max(4e3).describe("Question about previous project work, unfinished tasks, handoff, blockers, decisions, files or next actions."),mode:Dn.enum(["ai","local"]).optional().describe("ai uses ToolNet Memory Agent with configured LLM fallback chain. local returns deterministic local memory only.")};async function Fn(r,e){let t=Ln(r.project,e.question);if(e.mode==="local"){let o=Pt(t);if(o)return{answer:o.answer,mode:"local",usedAi:!1,source:o.source,intent:o.intent};let s=Q(r.project,t.originalQuestion);return{answer:s.answer,mode:"local",usedAi:!1,source:s.source,intent:s.intent}}let n=await _n(r.project,t.question);if(!n.usedAi){let o=Pt(t);if(o)return{answer:o.answer,mode:"ai",usedAi:!1,provider:n.provider,model:n.model}}return{answer:n.answer,mode:"ai",usedAi:n.usedAi,provider:n.provider,model:n.model}}import{z as Bn}from"zod";import{chmodSync as np,existsSync as $n,mkdirSync as op,readFileSync as Gn,renameSync as sp,writeFileSync as ip}from"node:fs";import{dirname as cp,join as ne}from"node:path";var zn="toolnet.context-offload.v1",va="toolnet.context-offload-asset.v1";function Un(r){return ne(r,".toolnet","offload")}function Wn(r){return ne(Un(r),"assets")}function Sa(r){return ne(Un(r),"graph.json")}function At(){return{schema:zn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function wa(r){let e=Sa(r);if(!$n(e))return At();try{let t=JSON.parse(Gn(e,"utf8"));return t.schema!==zn||t.version!==1||!Array.isArray(t.nodes)?At():t}catch{return At()}}function Ca(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&&$n(ne(Wn(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=Ca(r,e),o=Gn(ne(Wn(r),`${n}.json`),"utf8"),s=JSON.parse(o);if(s.schema!==va||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)}
|
|
55
|
+
[truncated]`:o}}var Vn={assetId:Bn.string().regex(/^[a-f0-9]{8,64}$/iu).describe("Asset reference from the ToolNet Context Offload Graph."),maxChars:Bn.number().int().min(200).max(2e4).optional().describe("Maximum asset characters to return. Defaults to 6000.")};async function Hn(r,e){return qn(r.project.rootPath,e.assetId,e.maxChars??6e3)}import{z as Qn}from"zod";import{chmodSync as fp,existsSync as xa,mkdirSync as gp,readFileSync as Ma,readdirSync as Pa,renameSync as yp,statSync as Aa,writeFileSync as hp}from"node:fs";import{join as Jn}from"node:path";var Ea="toolnet.skill-memory.v1";function Ra(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 Ia(r){return Jn(r.rootPath,".toolnet","memory","skills")}function Ta(r,e){if(!r||typeof r!="object")return!1;let t=r;return t.schema===Ea&&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 ja(r){let e=Ia(r);if(!xa(e))return[];if(!Aa(e).isDirectory())return[];let t=[];for(let n of Pa(e)){if(!n.endsWith(".json"))continue;let o=Jn(e,n);try{let s=JSON.parse(Ma(o,"utf8"));Ta(s,r.id)&&t.push(s)}catch{}}return t.sort((n,o)=>{let s=o.createdAt.localeCompare(n.createdAt);return s!==0?s:n.id.localeCompare(o.id)})}function _a(r){return Ra(r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_./-]+/gu).filter(e=>e.length>=2),32)}function Oa(r,e){let t=e.normalize("NFKC").toLowerCase().trim();if(!t)return 0;if(r.id.toLowerCase()===t||r.fingerprint.toLowerCase()===t)return 1e3;let n=[r.title,r.task,r.summary,...r.steps,...r.verification,...r.files].join(`
|
|
56
|
+
`).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 _a(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 Yn(r,e,t=5){let n=Math.max(1,Math.min(10,Math.floor(t)));return ja(r).map(o=>({...o,score:Oa(o,e)})).filter(o=>o.score>0).sort((o,s)=>s.score!==o.score?s.score-o.score:s.createdAt.localeCompare(o.createdAt)).slice(0,n)}var Xn={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 Zn(r,e){let t=Yn(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 mo}from"zod";var eo="wiki/state.v1.json";function Na(r){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:r.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function La(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 R=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(eo);if(!e){let t=Na(this.project);return await this.save(t),t}return La(e,this.project)}async save(e){await this.storage.put(eo,JSON.stringify(e,null,2),"application/json")}};import{randomUUID as no}from"node:crypto";var S=class extends Error{constructor(t,n){super(t);this.statusCode=n}statusCode};function oe(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 se(r){let e=r.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new S("Invalid Wiki slug",400);return e}function to(r){let e=[];for(let t of r.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let n=t[1]?.trim();n&&e.push(se(n))}return oe(e)}function Da(r){return r.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function ro(r){return{id:`revision-${no()}`,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 D(r){return structuredClone(r)}var I=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:oe(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 D([...e.pages].sort((t,n)=>t.title.localeCompare(n.title)))}async getPage(e){let t=await this.ensureState(),n=se(e),o=t.pages.find(s=>s.slug===n||s.id===e);if(!o)throw new S(`Wiki page not found: ${e}`,404);return D(o)}async createPage(e){return this.mutate(t=>{let n=e.title.trim(),o=e.content.trim();if(!n)throw new S("Wiki title is required",400);let s=se(e.slug??n);if(t.pages.some(c=>c.slug===s))throw new S(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${no()}`,slug:s,title:n,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:oe(e.tags??[]),links:to(o),revision:1,createdAt:i,updatedAt:i};return t.pages.push(a),t.revisions.push(ro(a)),D(a)})}async updatePage(e,t){return this.mutate(n=>{let o=se(e),s=n.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new S(`Wiki page not found: ${e}`,404);if(t.title!==void 0){let i=t.title.trim();if(!i)throw new S("Wiki title is required",400);s.title=i}if(t.summary!==void 0){let i=t.summary.trim();i?s.summary=i:delete s.summary}return t.content!==void 0&&(s.content=t.content.trim(),s.links=to(s.content)),t.tags!==void 0&&(s.tags=oe(t.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),n.revisions.push(ro(s)),D(s)})}async history(e){let t=await this.getPage(e),n=await this.ensureState();return D(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 D(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=oe(Da(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()??"",m=a.content.toLowerCase(),p=a.tags.map(h=>h.toLowerCase()),f=0;for(let h of o)u===h&&(f+=12),c===h&&(f+=10),c.includes(h)&&(f+=6),u.includes(h)&&(f+=5),p.some(v=>v===h)?f+=5:p.some(v=>v.includes(h))&&(f+=3),l.includes(h)&&(f+=2),m.includes(h)&&(f+=1);f>0&&i.push({page:D(a),score:f})}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 oo}from"node:crypto";var so="wiki/governance.v1.json",lo="toolnet.knowledge-governance.v1",io=500,ie={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Fa(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 ao(r){return Ka("sha256").update(r.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function $a(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 Ga(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),Fa(e)}function co(r){let e=new Date().toISOString();return{schema:lo,version:1,projectId:r,policy:{...ie},reviews:[],audit:[],createdAt:e,updatedAt:e}}function uo(r){let e=r.autoApproveThreshold??ie.autoApproveThreshold,t=r.criticalApproveThreshold??ie.criticalApproveThreshold,n=r.staleAfterDays??ie.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new S("Invalid autoApproveThreshold",400);if(!Number.isFinite(t)||t<.5||t>1)throw new S("Invalid criticalApproveThreshold",400);if(!Number.isInteger(n)||n<1||n>3650)throw new S("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:t,staleAfterDays:n}}var ae=class{constructor(e,t){this.storage=e;this.project=t}storage;project;async load(){let e=await this.storage.getText(so);if(!e){let t=co(this.project.id);return await this.save(t),t}try{let t=JSON.parse(e);if(t.schema!==lo||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??ie)}}catch{let t=co(this.project.id);return await this.save(t),t}}async save(e){await this.storage.put(so,JSON.stringify(e,null,2),"application/json")}},ce=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:oo(),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>io&&(e.audit=e.audit.slice(-io))}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=Ga(e),s=Et(e.title),i=t.filter(l=>l.slug!==e.slug&&Et(l.title)===s&&ao(l.content)!==ao(e.content)).map(l=>l.slug),a=$a(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:oo(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:n.confidence,risk:n.risk,reasons:[...n.reasons],conflicts:[...n.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:n,review:structuredClone(a)}})}async markApplied(e,t){await this.mutate(n=>{let o=n.reviews.find(s=>s.sourceKey===e&&s.digest===t&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(n,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:e}))})}async decide(e,t,n){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===e);if(!s)throw new S(`Governance review not found: ${e}`,404);if(s.status!=="pending")throw new S("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=t.principal,s.updatedAt=i,t.note?.trim()&&(s.reviewNote=t.note.trim()),t.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s);if(t.action==="supersede")return s.status="superseded",t.targetReviewId&&(s.supersededBy=t.targetReviewId),this.audit(o,"knowledge:superseded",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:t.targetReviewId}}),structuredClone(s);if(t.action==="merge"){if(!t.targetReviewId)throw new S("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===t.targetReviewId);if(!u)throw new S("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",t.principal,{reviewId:e,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await n.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new S(`Wiki page '${s.slug}' is manually managed`,409);return c?await n.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await n.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",t.principal,{reviewId:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let t=await this.ensureState(),n=await e.listPages(),o=Date.now(),s=t.policy.staleAfterDays*864e5,i=n.map(l=>{let m=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(m/864e5)),stale:Number.isFinite(m)&&m>s}}).filter(l=>l.stale).map(({stale:l,...m})=>m),a=new Map;for(let l of n){let m=Et(l.title),p=a.get(m)??[];p.push(l),a.set(m,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,m])=>({title:l,pages:m.map(p=>p.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(m=>m.startsWith("toolnet-auto-"))).length,manualPages:n.filter(l=>!l.tags.some(m=>m.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 po={query:mo.string().min(2).max(500).describe("Knowledge topic or project concept to search in ToolNet Wiki."),limit:mo.number().int().min(1).max(10).optional().describe("Maximum Wiki matches. Default 5.")};async function fo(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new I(new R(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 za}from"zod";var go={page:za.string().min(1).max(200).describe("Wiki page slug or page id.")};async function yo(r,e){let t=r.storage;if(!t)throw new Error("Wiki storage unavailable");let n=new I(new R(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 Ua}from"zod";var ho={includePending:Ua.boolean().optional().describe("Include compact pending-review metadata. Default false.")};async function ko(r,e){let t=r.storage;if(!t)throw new Error("Knowledge Governance storage unavailable");let n=new ce(new ae(t,r.project));await n.initialize();let o=new I(new R(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 bo={};function vo(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 b(r){return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}var Ba=["# 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. Use mode="ai" only when the continuity question is ambiguous or requires synthesis.',"","4. NEVER reconstruct previous work by reading or searching raw agent/session history, including:"," - .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 Va(r){let e=new Wa({name:"toolnet-memory",version:"0.1.0"},{instructions:Ba});return e.tool("memory_search","Search relevant long-term memory for the current project.",kr,async t=>b(await br(r,t))),e.tool("memory_save","Save an important memory, decision, rule, TODO or summary.",Cr,async t=>b(await xr(r,t))),e.tool("memory_forget","Delete a memory by id.",Mr,async t=>b(await Pr(r,t))),e.tool("find_symbol","Find code symbols by exact name.",Ar,async t=>b(await Er(r,t))),e.tool("find_callers","Find functions or methods calling a symbol.",Ir,async t=>b(await Tr(r,t))),e.tool("code_search","Search indexed code symbols and files.",_r,async t=>b(await Or(r,t))),e.tool("project_context","Get compact project architecture, recent memory and relevant context.",Lr,async t=>b(await Dr(r,t))),e.tool("trace_calls","Trace callers or callees through the code call graph.",Ur,async t=>b(await Wr(r,t))),e.tool("analyze_impact","Analyze what code can be affected if a symbol changes.",Br,async t=>b(await Vr(r,t))),e.tool("get_architecture","Get compact architecture statistics for the indexed project.",{},async()=>b(await Hr(r))),e.tool("find_dependencies","Find direct file dependencies and reverse dependents.",Yr,async t=>b(await Qr(r,t))),e.tool("semantic_code_search","Search source code by semantic meaning, not only exact symbol names.",Zr,async t=>b(await en(r,t))),e.tool("snapshot_create","Create a safe versioned snapshot of project memory, vectors and graph.",Kr,async t=>b(await Fr(r,t))),e.tool("snapshot_list","List available ToolNet Memory snapshots.",{},async()=>b(await $r(r))),e.tool("snapshot_restore","Restore a previous ToolNet Memory snapshot. A safety snapshot is created first.",Gr,async t=>b(await zr(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.",nn,async t=>b(await on(r,t))),e.tool("graph_dependents","Find code symbols that depend on a symbol through calls, imports, type usage, writes, inheritance or implementation relationships.",sn,async t=>b(await an(r,t))),e.tool("graph_path","Find the shortest dependency path between two code symbols.",cn,async t=>b(await ln(r,t))),e.tool("graph_neighborhood","Explore incoming and outgoing dependency relationships around a code symbol.",un,async t=>b(await dn(r,t))),e.tool("dead_code","Find likely unused code. Results are candidates and must be verified before deletion.",fn,async t=>b(await gn(r,t))),e.tool("memory_agent_ask",["Ask ToolNet Memory Agent about previous project work.","CALL THIS TOOL before guessing when the user asks to continue/resume previous work,","mentions a previous agent/session, asks what was unfinished, what file was last touched,","which TODOs are complete, blockers, decisions, or what should happen next.","Use mode=local for 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(" "),Kn,async t=>b(await Fn(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(" "),Vn,async t=>b(await Hn(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(" "),Xn,async t=>b(await Zn(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(" "),po,async t=>b(await fo(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(" "),go,async t=>b(await yo(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(" "),bo,async()=>b(vo(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(" "),ho,async t=>b(await ko(r,t))),e}async function So(r){let e=Va(r),t=new qa;await e.connect(t)}function wo(){return new Date().toISOString()}function T(r){r.lastUpdatedAt=wo()}function Xe(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 Co(r,e=Date.now()){r.metrics.mcpConnectedAtMs=e,r.metrics.startupMs=e-r.metrics.processStartedAtMs,r.phase="hydrating",T(r)}function xo(r,e=Date.now()){r.phase="hydrating",r.metrics.hydrationStartedAtMs=e,r.metrics.hydrationRuns+=1,T(r)}function Ze(r,e){r.dependencies[e].state!=="ready"&&(r.dependencies[e].state="loading",r.dependencies[e].lastError=void 0,T(r))}function et(r,e){r.dependencies[e].attempts+=1,T(r)}function tt(r){r.metrics.retryCount+=1,T(r)}function U(r,e,t=Date.now()){let n=r.dependencies[e];n.state="ready",n.lastError=void 0,n.readyAfterMs=t-r.metrics.processStartedAtMs,T(r)}function le(r,e,t){let n=r.dependencies[e];n.state="failed",n.lastError=t instanceof Error?t.message:String(t),T(r)}function Mo(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",T(r)}function Po(r,e){r.phase="failed",r.errors=[e instanceof Error?e.message:String(e)],T(r)}async function rt(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 as(r,e){let t=Number(r);return!Number.isFinite(t)||t<1?e:Math.floor(t)}function jc(r,e){let t=Number(r);return!Number.isFinite(t)||t<0?e:Math.floor(t)}function _c(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 cs(r){let e=r.runtime??Xe(Date.now());r.runtime=e,xo(e);let t=as(process.env.TOOLNET_MCP_HYDRATION_RETRIES,3),n=jc(process.env.TOOLNET_MCP_HYDRATION_RETRY_DELAY_MS,500);if(e.dependencies.memory.state!=="ready"||e.dependencies.graph.state!=="ready"){let o=await wr(r.project,{timeoutMs:as(process.env.TOOLNET_SERVICE_REQUEST_TIMEOUT_MS,1e3)});o&&(e.dataSource="daemon",e.dependencies.memory.state!=="ready"&&(r.memory.importRecords(o.memory),U(e,"memory")),e.dependencies.graph.state!=="ready"&&(o.graph&&r.graph.import(o.graph.symbols,o.graph.edges),U(e,"graph")))}try{let[{loadConfig:o},s]=await Promise.all([Promise.resolve().then(()=>(Ct(),kn)),Promise.resolve().then(()=>(Jo(),Ho))]),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 m=e.dependencies.memory.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Ze(e,"memory");try{let f=await rt(()=>l.load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{et(e,"memory")},onRetry:()=>{tt(e)}});r.memory.importRecords(f),U(e,"memory")}catch(f){le(e,"memory",f)}})(),p=e.dependencies.graph.state==="ready"?Promise.resolve():(async()=>{e.dataSource="embedded",Ze(e,"graph");try{let f=await rt(()=>new s.PersistentCodeGraphStore(u).load(r.project.id),{attempts:t,delayMs:n,onAttempt:()=>{et(e,"graph")},onRetry:()=>{tt(e)}});f&&r.graph.import(f.symbols,f.edges),U(e,"graph")}catch(f){le(e,"graph",f)}})();if(await Promise.all([m,p]),e.dependencies.semantic.state!=="ready"){Ze(e,"semantic");try{let[{SemanticCodeEngine:f},{createEmbeddingProvider:h}]=await Promise.all([Promise.resolve().then(()=>(rs(),ts)),Promise.resolve().then(()=>(is(),ss))]),v=new f({projectId:r.project.id,rootPath:r.project.rootPath,model:process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",storage:u,embeddings:h(),graph:r.graph});await rt(()=>v.initialize(),{attempts:t,delayMs:n,onAttempt:()=>{et(e,"semantic")},onRetry:()=>{tt(e)}}),r.codeSemantic=v,U(e,"semantic")}catch(f){le(e,"semantic",f)}}}catch(o){for(let s of["memory","graph","semantic"])e.dependencies[s].state!=="ready"&&le(e,s,o)}return Mo(e),_c(r)}import{closeSync as Oc,mkdirSync as Nc,openSync as Lc,readFileSync as Dc,unlinkSync as ls,writeFileSync as Kc}from"node:fs";import{tmpdir as Fc}from"node:os";import{join as us}from"node:path";function $c(r){try{return process.kill(r,0),!0}catch(e){return e?.code==="EPERM"}}var it=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=us(Fc(),"toolnet-memory-locks");Nc(t,{recursive:!0});let n=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=us(t,`${n}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Lc(this.path,"wx");Kc(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Oc(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let n=!0;try{let o=JSON.parse(Dc(this.path,"utf8"));Number.isInteger(o.pid)&&$c(o.pid)&&(n=!1)}catch{n=!0}if(!n)throw new Error("ToolNet Memory is already running for this project");try{ls(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{ls(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};function ds(){let r=Number(process.env.TOOLNET_MCP_DEGRADED_RETRY_MS??3e4);return Number.isFinite(r)&&r>=1e3?Math.floor(r):3e4}async function Gc(){let r=Date.now(),e=new xe().detect(),t=new it(e.id);await t.acquire();let n=()=>{t.release().finally(()=>process.exit(0))};process.once("SIGINT",n),process.once("SIGTERM",n);let o=new we,s=new Ie(o),i=new Te,a=new je(i),c=Xe(r),u={project:e,memory:o,retrieval:s,graph:i,references:a,runtime:c};await So(u),Co(c);let l=async()=>{try{await cs(u),c.phase==="degraded"&&setTimeout(()=>{l()},ds()).unref()}catch(m){Po(c,m),setTimeout(()=>{c.phase="degraded",l()},ds()).unref()}};l()}Gc().catch(r=>{console.error(r),process.exit(1)});
|