toolnet-memory 0.2.9 → 0.2.11

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.
@@ -1,7 +1,7 @@
1
- import{readFileSync as $e}from"node:fs";import{existsSync as B,readFileSync as H}from"node:fs";import{homedir as U}from"node:os";import{join as Y}from"node:path";function G(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 W(){let r=process.env.TOOLNET_GLOBAL_ENV??Y(U(),".config","toolnet-memory",".env");if(!B(r))return;let e=H(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]=G(o.slice(n+1)))}}W();function f(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function d(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function b(){return{memory:{autoCapture:f(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:f(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:f(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:f(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:d(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:d(process.env.MEMORY_RERANK_TOP,10),finalContext:d(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:d(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",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:d(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Z}from"node:crypto";import{existsSync as w,mkdirSync as Q,readFileSync as X,renameSync as q,writeFileSync as ee}from"node:fs";import{basename as te,dirname as y,join as j,parse as T,resolve as l}from"node:path";var E=".toolnet",re="project.json";function oe(r){return Z("sha256").update(r).digest("hex").slice(0,16)}function x(r){return j(r,E,re)}function ne(r){return w(x(r))}function se(r,e){let t=l(r),o=T(t).root;for(;;){if(ne(t))return t;if(t===o||e&&t===l(e))break;let n=y(t);if(n===t)break;t=n}return null}function ie(r){let e=l(r),t=T(e).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(s=>w(j(e,s))))return e;if(e===t)break;let n=y(e);if(n===e)break;e=n}return l(r)}function ae(r){let e;try{e=JSON.parse(X(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:y(y(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 M(r,e){let t=j(r,E);Q(t,{recursive:!0});let o=x(r),n=`${o}.tmp-${process.pid}`;ee(n,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),q(n,o)}function k(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 h=class{detect(e=process.cwd()){let t=l(e),o=ie(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>w(j(o,u))),i=se(t,s?o:void 0);if(i){let u=x(i),m=ae(u);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),M(i,m)),k(m,i)}let a=new Date().toISOString(),c=te(o),p={version:1,id:oe(o),name:c,remote:c,rootPath:o,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return M(o,p),k(p,o)}};import{homedir as Pe}from"node:os";import{join as Re}from"node:path";import{DeleteObjectCommand as ce,GetObjectCommand as pe,HeadObjectCommand as ue,ListObjectsV2Command as me,PutObjectCommand as de,S3Client as le}from"@aws-sdk/client-s3";import{getSignedUrl as ge}from"@aws-sdk/s3-request-presigner";var S=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new le({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 de({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let t=await ge(this.client,new pe({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 ue({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 ce({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],o;do{let n=await this.client.send(new me({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 O,mkdir as fe,readFile as ye,readdir as he,rm as je,stat as C,writeFile as Se}from"node:fs/promises";import{dirname as ve,join as we,relative as I,resolve as xe}from"node:path";var g=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return xe(this.root,t)}async put(e,t){let o=this.path(e);await fe(ve(o),{recursive:!0}),await Se(o,t)}async get(e){try{return await ye(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 O(this.path(e)),!0}catch{return!1}}async delete(e){await je(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),o=[];try{await O(t)}catch{return o}let n=async i=>{let a=await he(i,{withFileTypes:!0});for(let c of a){let p=we(i,c.name);if(c.isDirectory()){await n(p);continue}let u=await C(p);o.push({key:I(this.root,p),size:u.size,updatedAt:u.mtime.toISOString()})}},s=await C(t);return s.isDirectory()?await n(t):o.push({key:I(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),o}};function _(r){let e=r.localRoot??Re(Pe(),".toolnet-memory","storage");if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new S({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new g(e))}return new g(e)}function Ae(r){return new Promise(e=>setTimeout(e,r))}async function N(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)),p=Math.floor(Math.random()*Math.max(1,c*.2));await Ae(c+p)}throw s}var be=new Set(["put","get","getText","delete","list"]);function $(r,e={}){return new Proxy(r,{get(t,o){let n=Reflect.get(t,o,t);return typeof n!="function"?n:be.has(o)?(...s)=>N(()=>Promise.resolve(n.apply(t,s)),e):n.bind(t)}})}function z(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}function D(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 v=class{constructor(e,t,o,n){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=o,this.folder=z(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)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=D(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,o){return await this.ensureRegistered(),this.provider.put(this.key(e),t,o)}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))}};import{existsSync as J,mkdirSync as ke,readFileSync as Te,statSync as L,writeFileSync as Ee}from"node:fs";import{dirname as Oe,join as Ce}from"node:path";import{createHash as Me}from"node:crypto";function P(r){return Me("sha256").update(r).digest("hex")}var V=64*1024,Ie=`# ToolNet Project Operating Manual
1
+ import{readFileSync as Ue}from"node:fs";import{existsSync as H,readFileSync as Y}from"node:fs";import{homedir as G}from"node:os";import{join as W}from"node:path";function Z(o){let t=o.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function Q(){let o=process.env.TOOLNET_GLOBAL_ENV??W(G(),".config","toolnet-memory",".env");if(!H(o))return;let t=Y(o,"utf8");for(let e of t.split(/\r?\n/)){let r=e.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let n=r.indexOf("=");if(n<=0)continue;let s=r.slice(0,n).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Z(r.slice(n+1)))}}Q();function m(o,t){return o===void 0?t:["1","true","yes","on"].includes(o.toLowerCase())}function l(o,t){if(!o)return t;let e=Number(o);return Number.isFinite(e)?e:t}function M(){return{memory:{autoCapture:m(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:m(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:m(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:m(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:l(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:l(process.env.MEMORY_RERANK_TOP,10),finalContext:l(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:l(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:m(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:l(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as X}from"node:crypto";import{existsSync as x,mkdirSync as q,readFileSync as ee,renameSync as te,writeFileSync as re}from"node:fs";import{basename as oe,dirname as h,join as j,parse as C,resolve as g}from"node:path";var I=".toolnet",ne="project.json";function se(o){return X("sha256").update(o).digest("hex").slice(0,16)}function P(o){return j(o,I,ne)}function ie(o){return x(P(o))}function ae(o,t){let e=g(o),r=C(e).root;for(;;){if(ie(e))return e;if(e===r||t&&e===g(t))break;let n=h(e);if(n===e)break;e=n}return null}function ce(o){let t=g(o),e=C(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>x(j(t,s))))return t;if(t===e)break;let n=h(t);if(n===t)break;t=n}return g(o)}function pe(o){let t;try{t=JSON.parse(ee(o,"utf8"))}catch(n){throw new Error(`Invalid ToolNet project manifest: ${o}: ${n instanceof Error?n.message:String(n)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let e=t;if(typeof e.id!="string"||!e.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof e.name!="string"||!e.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=new Date().toISOString();return{version:1,id:e.id,name:e.name,remote:typeof e.remote=="string"&&e.remote.trim()?e.remote:e.name,rootPath:typeof e.rootPath=="string"?e.rootPath:h(h(o)),createdAt:typeof e.createdAt=="string"?e.createdAt:r,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:r,graphVersion:typeof e.graphVersion=="number"?e.graphVersion:0,memoryVersion:typeof e.memoryVersion=="number"?e.memoryVersion:0,metadata:e.metadata&&typeof e.metadata=="object"?e.metadata:void 0}}function T(o,t){let e=j(o,I);q(e,{recursive:!0});let r=P(o),n=`${r}.tmp-${process.pid}`;re(n,JSON.stringify(t,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),te(n,r)}function E(o,t){return{id:o.id,name:o.name,remote:o.remote,rootPath:t,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var S=class{detect(t=process.cwd()){let e=g(t),r=ce(e),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>x(j(r,u))),i=ae(e,s?r:void 0);if(i){let u=P(i),d=pe(u);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),T(i,d)),E(d,i)}let a=new Date().toISOString(),c=oe(r),p={version:1,id:se(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return T(r,p),E(p,r)}};import{homedir as Ie}from"node:os";import{join as Oe}from"node:path";import{DeleteObjectCommand as ue,GetObjectCommand as de,HeadObjectCommand as me,ListObjectsV2Command as le,PutObjectCommand as ge,S3Client as fe}from"@aws-sdk/client-s3";import{getSignedUrl as ye}from"@aws-sdk/s3-request-presigner";var v=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new fe({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,e,r="application/octet-stream"){let n=typeof e=="string"?Buffer.from(e,"utf8"):e;await this.client.send(new ge({Bucket:this.bucket,Key:t,Body:n,ContentType:r}))}async get(t){let e=await ye(this.client,new de({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(e,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let e=await this.get(t);return e?Buffer.from(e).toString("utf8"):null}async exists(t){try{return await this.client.send(new me({Bucket:this.bucket,Key:t})),!0}catch(e){if(typeof e=="object"&&e!==null&&"$metadata"in e&&e.$metadata?.httpStatusCode===404)return!1;throw e}}async delete(t){await this.client.send(new ue({Bucket:this.bucket,Key:t}))}async list(t=""){let e=[],r;do{let n=await this.client.send(new le({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of n.Contents??[])s.Key&&e.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=n.IsTruncated?n.NextContinuationToken:void 0}while(r);return e}};import{access as O,mkdir as he,readFile as Se,readdir as je,rm as ve,stat as _,writeFile as we}from"node:fs/promises";import{dirname as xe,join as Pe,relative as N,resolve as be}from"node:path";var f=class{constructor(t){this.root=t}root;name="local";path(t){let e=t.replace(/^\/+/,"");return be(this.root,e)}async put(t,e){let r=this.path(t);await he(xe(r),{recursive:!0}),await we(r,e)}async get(t){try{return await Se(this.path(t))}catch(e){if(typeof e=="object"&&e!==null&&"code"in e&&e.code==="ENOENT")return null;throw e}}async getText(t){let e=await this.get(t);return e?Buffer.from(e).toString("utf8"):null}async exists(t){try{return await O(this.path(t)),!0}catch{return!1}}async delete(t){await ve(this.path(t),{force:!0})}async list(t=""){let e=this.path(t),r=[];try{await O(e)}catch{return r}let n=async i=>{let a=await je(i,{withFileTypes:!0});for(let c of a){let p=Pe(i,c.name);if(c.isDirectory()){await n(p);continue}let u=await _(p);r.push({key:N(this.root,p),size:u.size,updatedAt:u.mtime.toISOString()})}},s=await _(e);return s.isDirectory()?await n(e):r.push({key:N(this.root,e),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as ke,GetObjectCommand as Ae,HeadObjectCommand as Re,ListObjectsV2Command as Me,PutObjectCommand as Te,S3Client as Ee}from"@aws-sdk/client-s3";import{getSignedUrl as Ce}from"@aws-sdk/s3-request-presigner";var y=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Ee({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,e,r="application/octet-stream"){let n=typeof e=="string"?Buffer.from(e,"utf8"):e;await this.client.send(new Te({Bucket:this.bucket,Key:t,Body:n,ContentType:r}))}async get(t){let e=await Ce(this.client,new Ae({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(e,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let e=await this.get(t);return e?Buffer.from(e).toString("utf8"):null}async exists(t){try{return await this.client.send(new Re({Bucket:this.bucket,Key:t})),!0}catch(e){if(typeof e=="object"&&e!==null&&"$metadata"in e&&e.$metadata?.httpStatusCode===404)return!1;throw e}}async delete(t){await this.client.send(new ke({Bucket:this.bucket,Key:t}))}async list(t=""){let e=[],r;do{let n=await this.client.send(new Me({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of n.Contents??[])s.Key&&e.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=n.IsTruncated?n.NextContinuationToken:void 0}while(r);return e}};function b(o,t){return console.warn(t),new f(o)}function $(o){let t=o.localRoot??Oe(Ie(),".toolnet-memory","storage");if(o.provider==="r2"){let e=o.r2;return e?.accountId&&e.bucket&&e.accessKeyId&&e.secretAccessKey?new y({name:"r2",endpoint:`https://${e.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:e.bucket,forcePathStyle:!0,accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}):b(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(o.provider==="s3"){let e=o.s3;return e?.bucket&&e.accessKeyId&&e.secretAccessKey?new y({name:"s3",endpoint:e.endpoint,region:e.region??"us-east-1",bucket:e.bucket,forcePathStyle:e.forcePathStyle??!1,accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}):b(t,"[storage] S3 credentials missing. Using local fallback.")}if(o.provider==="huggingface"){let e=o.huggingface;return e?.namespace&&e.bucket&&e.accessKeyId&&e.secretAccessKey?new v({namespace:e.namespace,bucket:e.bucket,accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}):b(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new f(t)}function _e(o){return new Promise(t=>setTimeout(t,o))}async function K(o,t={}){let e=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,n=t.maxDelayMs??2e3,s;for(let i=1;i<=e;i++)try{return await o()}catch(a){if(s=a,i>=e)break;let c=Math.min(n,r*2**(i-1)),p=Math.floor(Math.random()*Math.max(1,c*.2));await _e(c+p)}throw s}var Ne=new Set(["put","get","getText","delete","list"]);function D(o,t={}){return new Proxy(o,{get(e,r){let n=Reflect.get(e,r,e);return typeof n!="function"?n:Ne.has(r)?(...s)=>K(()=>Promise.resolve(n.apply(e,s)),t):n.bind(e)}})}function z(o){let t=o.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function L(o){let t=o.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let e=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(e)return`${e[1]}memory/records/${e[2]}`;if(e=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),e)return`${e[1]}memory/vectors/${e[2]}`;if(e=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),e)return`${e[1]}code/graph/${e[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:t))}var w=class{constructor(t,e,r,n){this.provider=t;this.name=t.name,this.projectId=e,this.projectName=r,this.folder=z(n??r),this.sourcePrefix=`projects/${e}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,e=new Date().toISOString(),r=e,n=await this.provider.getText(t);if(n){let i;try{i=JSON.parse(n)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${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"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:e};await this.provider.put(t,JSON.stringify(s,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=L(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,e,r){return await this.ensureRegistered(),this.provider.put(this.key(t),e,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{existsSync as J,mkdirSync as Ke,readFileSync as De,statSync as V,writeFileSync as ze}from"node:fs";import{dirname as Le,join as Ve}from"node:path";import{createHash as $e}from"node:crypto";function k(o){return $e("sha256").update(o).digest("hex")}var B=64*1024,Be=`# ToolNet Project Operating Manual
5
5
 
6
6
  This file contains persistent instructions for AI agents working on this project.
7
7
 
@@ -44,11 +44,11 @@ Things an AI agent should always remember.
44
44
  <!--
45
45
  - [advisory] Prefer small focused files.
46
46
  -->
47
- `;function K(r){return Ce(r.rootPath,".toolnet","PROJECT.md")}function _e(r){return r.normalize("NFKC").replace(/\s+/g," ").trim()}function Ne(r){let e=[],t=new Set,o=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,n;for(;n=o.exec(r);){let s=n[1].toLowerCase(),i=_e(n[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;t.has(a)||(t.add(a),e.push({id:P(a).slice(0,24),mode:s,text:i,source:"manual"}))}return e}function R(r){let e=K(r);return J(e)||(ke(Oe(e),{recursive:!0}),Ee(e,Ie,{encoding:"utf8",mode:384})),e}function A(r,e=!1){let t=e?R(r):K(r);if(!J(t))return null;if(L(t).size>V)throw new Error(`PROJECT.md exceeds ${V} bytes`);let n=Te(t,"utf8");return{path:t,content:n,digest:P(n),rules:Ne(n),bytes:Buffer.byteLength(n,"utf8"),updatedAt:new Date(L(t).mtimeMs).toISOString()}}async function F(r,e){let t=A(r,!0);if(!t)throw new Error("Project manual unavailable");let o=`projects/${r.id}/project`;return await e.put(`${o}/manual.md`,t.content,"text/markdown"),await e.put(`${o}/manual.json`,JSON.stringify({version:1,projectId:r.id,projectName:r.name,digest:t.digest,bytes:t.bytes,ruleCount:t.rules.length,enforceRules:t.rules.filter(n=>n.mode==="enforce").length,advisoryRules:t.rules.filter(n=>n.mode==="advisory").length,updatedAt:t.updatedAt},null,2)+`
48
- `,"application/json"),t}function ze(r,e){let t=r.indexOf(e);return t>=0?r[t+1]:void 0}function De(r){let e=b(),t=$(_({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new v(t,r.id,r.name,r.remote??r.name)}async function Le(){let[r="help",...e]=process.argv.slice(2),t=new h().detect(ze(e,"--project")??process.cwd());if(r==="init"){let o=R(t);console.log(`\u2705 Project manual: ${o}`);return}if(r==="show"){let o=A(t,!1);if(!o){console.log("No .toolnet/PROJECT.md yet.");return}process.stdout.write($e(o.path,"utf8"));return}if(r==="sync"){let o=await F(t,De(t));console.log(JSON.stringify({project:t.name,path:o.path,digest:o.digest,bytes:o.bytes,rules:o.rules.length,enforce:o.rules.filter(n=>n.mode==="enforce").length,advisory:o.rules.filter(n=>n.mode==="advisory").length},null,2));return}console.log(`Project Manual
47
+ `;function F(o){return Ve(o.rootPath,".toolnet","PROJECT.md")}function Je(o){return o.normalize("NFKC").replace(/\s+/g," ").trim()}function Fe(o){let t=[],e=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,n;for(;n=r.exec(o);){let s=n[1].toLowerCase(),i=Je(n[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;e.has(a)||(e.add(a),t.push({id:k(a).slice(0,24),mode:s,text:i,source:"manual"}))}return t}function A(o){let t=F(o);return J(t)||(Ke(Le(t),{recursive:!0}),ze(t,Be,{encoding:"utf8",mode:384})),t}function R(o,t=!1){let e=t?A(o):F(o);if(!J(e))return null;if(V(e).size>B)throw new Error(`PROJECT.md exceeds ${B} bytes`);let n=De(e,"utf8");return{path:e,content:n,digest:k(n),rules:Fe(n),bytes:Buffer.byteLength(n,"utf8"),updatedAt:new Date(V(e).mtimeMs).toISOString()}}async function U(o,t){let e=R(o,!0);if(!e)throw new Error("Project manual unavailable");let r=`projects/${o.id}/project`;return await t.put(`${r}/manual.md`,e.content,"text/markdown"),await t.put(`${r}/manual.json`,JSON.stringify({version:1,projectId:o.id,projectName:o.name,digest:e.digest,bytes:e.bytes,ruleCount:e.rules.length,enforceRules:e.rules.filter(n=>n.mode==="enforce").length,advisoryRules:e.rules.filter(n=>n.mode==="advisory").length,updatedAt:e.updatedAt},null,2)+`
48
+ `,"application/json"),e}function He(o,t){let e=o.indexOf(t);return e>=0?o[e+1]:void 0}function Ye(o){let t=M(),e=D($({provider:t.storage.provider,huggingface:t.storage.huggingface,localRoot:t.storage.localRoot}),{attempts:3});return new w(e,o.id,o.name,o.remote??o.name)}async function Ge(){let[o="help",...t]=process.argv.slice(2),e=new S().detect(He(t,"--project")??process.cwd());if(o==="init"){let r=A(e);console.log(`\u2705 Project manual: ${r}`);return}if(o==="show"){let r=R(e,!1);if(!r){console.log("No .toolnet/PROJECT.md yet.");return}process.stdout.write(Ue(r.path,"utf8"));return}if(o==="sync"){let r=await U(e,Ye(e));console.log(JSON.stringify({project:e.name,path:r.path,digest:r.digest,bytes:r.bytes,rules:r.rules.length,enforce:r.rules.filter(n=>n.mode==="enforce").length,advisory:r.rules.filter(n=>n.mode==="advisory").length},null,2));return}console.log(`Project Manual
49
49
 
50
50
  Commands:
51
51
  init [--project PATH]
52
52
  show [--project PATH]
53
53
  sync [--project PATH]
54
- `)}Le().catch(r=>{console.error(r instanceof Error?r.message:r),process.exit(1)});
54
+ `)}Ge().catch(o=>{console.error(o instanceof Error?o.message:o),process.exit(1)});
package/bundle/runtime.js CHANGED
@@ -1,11 +1,11 @@
1
- import{randomUUID as Ot}from"node:crypto";var Rt={critical:100,high:75,normal:50,temporary:20};function Ke(o){return Rt[o]}function We(o,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":o==="rule"||o==="decision"?"high":o==="todo"?"normal":o==="activity"||o==="summary"?"temporary":"normal"}var kt=[{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}],G=class{scan(e){let t=[];for(let r of kt){let s=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(s))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var R=class{scanner=new G;sanitize(e){let t=e,r=this.scanner.scan(e),s=new Set;for(let n of r)s.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...s]}}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[r,s]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(s)}return t}return e}};var Tt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),Mt=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 Ve(o){return new Set(o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!Mt.has(e)))}function It(o,e){let t=Ve(o),r=Ve(e);if(t.size===0||r.size===0)return 0;let s=0;for(let i of t)r.has(i)&&s++;let n=new Set([...t,...r]).size;return s/n}function Ue(o){return new Set(o.tags.filter(e=>!Tt.has(e.toLowerCase())))}var D=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,s=Ue(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=Ue(n);for(let c of s)if(a.has(c))return!0;return It(e.content,n.content)>=.6})}};var At={critical:100,high:75,normal:50,temporary:20},Lt={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function qe(o,e,t=new Date){let r;if(e==="temporary"&&(r=30),o==="activity"&&(r=Math.min(r??14,14)),o==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Re(o,e=Date.now()){return o.expiresAt?new Date(o.expiresAt).getTime()<=e:!1}function Nt(o){return!!o.metadata?.supersededBy}function ke(o,e=Date.now()){return!Re(o,e)&&!Nt(o)}function I(o,e=Date.now()){if(!ke(o,e))return 0;let t=At[o.importance];if(o.importance==="critical")return t;let r=Lt[o.type]??180,n=Math.max(0,e-new Date(o.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var k=class{memories=new Map;sanitizer=new R;conflicts=new D;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,s=e.importance??We(e.type,r),n={id:Ot(),projectId:e.projectId,type:e.type,content:r,importance:s,importanceScore:Ke(s),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??qe(e.type,s,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),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,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>ke(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,s=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=I(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=s.filter(p=>i.includes(p)).length,c=s.length===0?0:a/s.length,l=I(n)/500;return{memory:n,score:c+l,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[s,n]of this.memories)n.projectId===e&&Re(n,t)&&(this.memories.delete(s),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let s=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),s++)}return s}clearProject(e){let t=0;for(let[r,s]of this.memories)s.projectId===e&&(this.memories.delete(r),t++);return t}};var z=class{constructor(e){this.memory=e}memory;run(e){let t=this.memory.pruneExpired(e),r=this.memory.pruneSuperseded(e,30);return{expiredRemoved:t,supersededRemoved:r,active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Te(o){return[...new Set(o.filter(Boolean))]}var B=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,s=t.maxItems??50,n=t.retentionDays??90,i=this.memory.byType(e,"activity").slice(0,s);if(i.length<r)return{scanned:i.length,consolidated:0,summaryCreated:!1};let a=this.buildSummary(i),c=new Date,l=new Date(c.getTime()+n*864e5).toISOString(),p=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:l,metadata:{consolidatedFrom:i.map(u=>u.id),itemCount:i.length}}),d=c.toISOString();for(let u of i){let f=this.memory.get(u.id);f&&(f.updatedAt=d,f.metadata={...f.metadata??{},consolidated:!0,supersededBy:p.id,supersededAt:d})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:p.id}}buildSummary(e){let t=Te(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Te(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),s=Te(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),n=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&n.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&n.push(`- Commands: ${r.slice(0,10).join("; ")}`),s.length&&n.push(`- Errors: ${s.slice(0,10).join("; ")}`),n.join(`
2
- `)}};function H(o){return o.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var K=class{score(e,t){let r=H(e),s=H([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function Je(o,e=Date.now()){let t=o.updatedAt??o.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let s=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*s/30)}function Ye(o){return I(o)/100}var Ft={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function Ze(o){return Ft[o]??.4}var W=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var V=class{bm25=new K;analyzer=new W;search(e,t,r={}){let s=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=Je(c),d=Ye(c),u=Ze(c.type);i.preferredTypes.includes(c.type)&&(u=Math.min(1,u+.25));let f=l*.55+d*.2+p*.15+u*.1;l<=0||f<n||a.push({memory:c,score:f,scores:{keyword:l,recency:p,importance:d,type:u}})}return a.sort((c,l)=>l.score-c.score).slice(0,s)}};var U=class{build(e,t=6e3){let r=[],s=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(s+a.length>t)break;r.push(a),s+=a.length}return r.join(`
3
- `)}};var q=class{constructor(e){this.memory=e}memory;searcher=new V;contextBuilder=new U;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let s=this.search(e,t,r);return this.contextBuilder.build(s)}};var J=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`,r=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(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let s=await r.json();if(!Array.isArray(s))throw new Error("HF embedding returned invalid response");return s.map(n=>$t(n))}};function $t(o){if(!Array.isArray(o))throw new Error("Invalid embedding");if(o.length>0&&typeof o[0]=="number")return o;if(o.length>0&&Array.isArray(o[0])){let e=o;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let s of e)for(let n=0;n<t;n++)r[n]+=s[n]??0;for(let s=0;s<t;s++)r[s]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as _t}from"node:crypto";var Y=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let s of r){let i=_t("sha256").update(s).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return Gt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function Gt(o){let e=Math.sqrt(o.reduce((t,r)=>t+r*r,0));return e===0?o:o.map(t=>t/e)}var Me=class{constructor(e,t=new Y){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)}};function Ie(){let o=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=o?new J({token:o,model:e}):null;return new Me(t)}import{readdir as Ht}from"node:fs/promises";import{extname as Kt,join as Wt,relative as Vt}from"node:path";import{basename as Dt}from"node:path";var zt=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Bt=new Set([".pem",".key",".p12",".pfx"]);function Ae(o){let e=Dt(o).toLowerCase();if(zt.has(e))return!0;for(let t of Bt)if(e.endsWith(t))return!0;return!1}var Ut=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),qt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Le(o){let e=[];async function t(r){let s=await Ht(r,{withFileTypes:!0});for(let n of s){if(qt.has(n.name))continue;let i=Wt(r,n.name);if(n.isDirectory()){await t(i);continue}Ut.has(Kt(n.name))&&(Ae(i)||e.push(Vt(o,i)))}}return await t(o),e.sort()}import{readFile as Jt}from"node:fs/promises";import{join as Yt}from"node:path";import{createHash as Zt}from"node:crypto";import*as h from"typescript";function Qe(o,e){return Zt("sha256").update(`${o}:${e}`).digest("hex").slice(0,24)}function Ne(o,e){return o.getLineAndCharacterOfPosition(e.getStart(o)).line+1}async function Oe(o,e,t){let r=Yt(e,t),s=await Jt(r,"utf8"),n=h.createSourceFile(t,s,h.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?h.ScriptKind.TSX:h.ScriptKind.TS),i=[],a=[],c=[],l=[],p={id:Qe(o,`file:${t}`),projectId:o,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(p);let d=[],u=[];function f(m,x,v,b){let C=Qe(o,`${t}:${v}:${b??x}:${m.pos}`);return i.push({id:C,projectId:o,name:x,qualifiedName:b??x,type:v,filePath:t,startLine:Ne(n,m),endLine:n.getLineAndCharacterOfPosition(m.end).line+1}),C}function w(m){if(!h.isStringLiteral(m.moduleSpecifier))return;let x=[],v=m.importClause;if(v?.name&&x.push({localName:v.name.text,importedName:"default",kind:"default"}),v?.namedBindings&&h.isNamedImports(v.namedBindings))for(let b of v.namedBindings.elements)x.push({localName:b.name.text,importedName:b.propertyName?.text??b.name.text,kind:"named"});v?.namedBindings&&h.isNamespaceImport(v.namedBindings)&&x.push({localName:v.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:m.moduleSpecifier.text,bindings:x})}function S(m,x){for(let v of m.heritageClauses??[])for(let b of v.types){let C=b.expression.getText(n).split(".").at(-1)??"";C&&l.push({fromId:x,targetName:C,type:v.token===h.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function g(m){let x=!1,v=!1;if(h.isImportDeclaration(m)&&w(m),h.isInterfaceDeclaration(m)&&f(m,m.name.text,"interface",m.name.text),h.isClassDeclaration(m)&&m.name){let b=f(m,m.name.text,"class",m.name.text);S(m,b),u.push({id:b,name:m.name.text}),v=!0}if(h.isFunctionDeclaration(m)&&m.name){let b=f(m,m.name.text,"function",m.name.text);d.push(b),x=!0}if(h.isMethodDeclaration(m)&&m.name){let b=m.name.getText(n),C=u.at(-1)?.name,Pt=f(m,b,"method",C?`${C}.${b}`:b);d.push(Pt),x=!0}if(h.isCallExpression(m)&&(h.isIdentifier(m.expression)&&c.push({callerId:d.at(-1),calleeName:m.expression.text,line:Ne(n,m)}),h.isPropertyAccessExpression(m.expression))){let b=m.expression;c.push({callerId:d.at(-1),qualifier:b.expression.getText(n),calleeName:b.name.text,line:Ne(n,m)})}h.forEachChild(m,g),x&&d.pop(),v&&u.pop()}return g(n),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as Qt}from"node:crypto";import{dirname as Xt,extname as er,normalize as tr,posix as rr}from"node:path";var j=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(r=>r.projectId===e&&(r.name===t||r.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 r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function or(o,e,t,r){return Qt("sha256").update(`${o}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function P(o){return tr(o).replaceAll("\\","/")}function Fe(o,e,t){if(!e.startsWith("."))return;let r=P(rr.join(Xt(o),e)),s=er(r),n;if(s===".js"){let i=r.slice(0,-3);n=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(s===".mjs"){let i=r.slice(0,-4);n=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(s===".cjs"){let i=r.slice(0,-4);n=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else s?n=[r]:n=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return n.find(i=>t.has(P(i)))}var A=class{build(e,t){let r=new j,s=new Map;for(let i of t)for(let a of i.symbols)r.addSymbol(a),a.type==="file"&&s.set(P(i.filePath),a);let n=new Set(s.keys());for(let i of t){let a=P(i.filePath),c=s.get(a);if(c){for(let l of i.symbols)l.id!==c.id&&r.addEdge(this.edge(e,c.id,"DEFINES",l.id));for(let l of i.imports){let p=Fe(a,l.source,n);if(!p)continue;let d=s.get(p);d&&r.addEdge(this.edge(e,c.id,"IMPORTS",d.id,{source:l.source}))}for(let l of i.heritage){let p=r.findByName(e,l.targetName).filter(d=>d.type==="class"||d.type==="interface");for(let d of p)r.addEdge(this.edge(e,l.fromId,l.type,d.id))}for(let l of i.calls){if(!l.callerId)continue;let p=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let d of p)d.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",d.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,s,n,i,a){let c=P(t.filePath),l=i.findByName(e,r).filter(p=>P(p.filePath)===c);if(!s&&l.length)return l;if(s)for(let p of t.imports){if(!p.bindings.find(f=>f.kind==="namespace"&&f.localName===s))continue;let u=Fe(c,p.source,a);if(u)return i.findByName(e,r).filter(f=>P(f.filePath)===u)}for(let p of t.imports){let d=p.bindings.find(S=>S.localName===r);if(!d)continue;let u=Fe(c,p.source,a);if(!u)continue;let f=d.importedName==="default"?r:d.importedName,w=i.findByName(e,f).filter(S=>P(S.filePath)===u);if(w.length)return w}return i.findByName(e,r).filter(p=>p.type==="function"||p.type==="method")}edge(e,t,r,s,n){return{id:or(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:n}}};function Xe(o,e){let t=o.allSymbols(e),r=o.allEdges(e),s=i=>t.filter(a=>a.type===i).length,n=i=>r.filter(a=>a.type===i).length;return{files:s("file"),classes:s("class"),interfaces:s("interface"),functions:s("function"),methods:s("method"),properties:s("property"),routes:s("route"),symbols:t.length,edges:r.length,calls:n("CALLS"),callReferences:n("CALL_REFERENCE"),imports:n("IMPORTS"),inherits:n("INHERITS"),implements:n("IMPLEMENTS"),usesType:n("USES_TYPE"),tests:n("TESTS"),routeEdges:n("ROUTE"),writes:n("WRITES")}}var Z=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(s=>s.type==="CALLS"&&s.to===t).map(s=>s.from).map(s=>this.graph.getSymbol(s)).filter(s=>!!s)}};function sr(o,e){return e.ranges.length===0?!0:typeof o.startLine!="number"||typeof o.endLine!="number"?!1:e.ranges.some(t=>o.startLine<=t.endLine&&o.endLine>=t.startLine)}var Q=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),s=[];for(let n of t){let i=r.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>sr(l,n));if(c.length===0){let l=i.find(p=>p.type==="file");l&&s.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)s.push({symbol:l,fileStatus:n.status,direct:!0})}return s}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var nr={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function ir(o){return o>=30?"CRITICAL":o>=16?"HIGH":o>=6?"MEDIUM":"LOW"}function et(o){let e=o.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var X=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let s=this.graph.allEdges(e),n=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let d=new Set([p.symbol.id]),u=[{id:p.symbol.id,depth:0}];for(;u.length;){let f=u.shift();if(f.depth>=r)continue;let w=s.filter(S=>S.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(S.type));for(let S of w){if(d.has(S.from))continue;d.add(S.from);let g=this.graph.getSymbol(S.from);if(!g)continue;let m=f.depth+1,x=`${p.symbol.id}:${g.id}`;n.set(x,{symbol:g,relation:S.type,depth:m,sourceSymbolId:p.symbol.id});let v=nr[S.type]??1;i+=Math.max(1,v-(m-1)),u.push({id:g.id,depth:m})}}}let a=[...n.values()].sort((p,d)=>p.depth-d.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(et);return l.length===0&&l.push(...c.filter(p=>!et(p)).slice(0,10)),{risk:ir(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as ar}from"node:child_process";import{promisify as cr}from"node:util";var $e=cr(ar);function lr(o){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of o.matchAll(t)){let s=Number(r[1]),n=Number(r[2]??1);e.push({startLine:s,endLine:Math.max(s,s+n-1)})}return e}function dr(o){return o.startsWith("A")?"added":o.startsWith("D")?"deleted":o.startsWith("R")?"renamed":"modified"}async function tt(o){let e="";try{e=(await $e("git",["diff","HEAD","--name-status","--no-renames"],{cwd:o,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[s,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await $e("git",["diff","HEAD","--unified=0","--",i],{cwd:o,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:dr(s),ranges:lr(a)})}try{let r=await $e("git",["ls-files","--others","--exclude-standard"],{cwd:o});for(let s of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===s)||t.push({filePath:s,status:"added",ranges:[]})}catch{}return t}var ee=class{constructor(e){this.graph=e;this.mapper=new Q(e),this.blast=new X(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let s=await tt(t),n=this.mapper.map(e,s),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:s,...i}}analyzeFile(e,t,r={}){let s=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,s,r.maxDepth??4)}}};var pr=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,mr=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function rt(o){return o.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function ur(o){return o.length>0&&o.length<500&&!o.includes(`
4
- `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(o)}function fr(o){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let s of o.matchAll(r))s[1]&&e.push(rt(s[1]));return e}function _e(o,e,t){if(typeof o=="string"){let r=t?.toLowerCase();if(r&&mr.has(r)&&ur(o)&&e.add(rt(o)),o.includes("*** Update File:")||o.includes("*** Add File:")||o.includes("*** Delete File:")||o.includes("+++ b/"))for(let s of fr(o))e.add(s);return}if(Array.isArray(o)){for(let r of o)_e(r,e,t);return}if(o&&typeof o=="object")for(let[r,s]of Object.entries(o))_e(s,e,r)}function gr(o){return pr.test(o.toLowerCase())}function ot(o,e){if(!gr(o))return[];let t=new Set;return _e(e,t),[...t]}import{createHash as hr}from"node:crypto";import{readFile as yr}from"node:fs/promises";async function st(o){let e=await yr(o);return hr("sha256").update(e).digest("hex")}function nt(o,e){let t=o?.files??{},r=e.files,s=[],n=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let p=t[c];p?p.hash!==l.hash?n.push(c):a.push(c):s.push(c)}for(let c of Object.keys(t))r[c]||i.push(c);return{added:s.sort(),modified:n.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as Sr}from"node:path";async function it(o,e){let t=await Le(e),r={};for(let s of t)r[s]={path:s,hash:await st(Sr(e,s))};return{version:1,projectId:o,updatedAt:new Date().toISOString(),files:r}}var T=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 te=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 re=class{constructor(e){this.storage=e}storage;async index(e,t){let r=new te(this.storage),s=new T(this.storage),n=await r.load(e),i=await s.load(e),a=await it(e,t),c=nt(n,a),l=[...c.added,...c.modified];if(n&&i&&l.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let p=i?.symbols.filter(g=>c.unchanged.includes(g.filePath))??[],d=[];for(let g of l)d.push(await Oe(e,t,g));let u=new A().build(e,d),f=new j;for(let g of p)f.addSymbol(g);for(let g of u.allSymbols(e))f.addSymbol(g);let w=new Set(f.allSymbols(e).map(g=>g.id));for(let g of i?.edges??[])w.has(g.from)&&w.has(g.to)&&!l.includes(i.symbols.find(m=>m.id===g.from)?.filePath??"")&&!l.includes(i.symbols.find(m=>m.id===g.to)?.filePath??"")&&f.addEdge(g);for(let g of u.allEdges(e))f.addEdge(g);let S={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(a.files).length,symbols:f.allSymbols(e),edges:f.allEdges(e)};return await s.save(S),await r.save(a),{firstRun:n===null,scanned:Object.keys(a.files).length,parsed:l.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,unchanged:c.unchanged.length,symbols:S.symbols.length,edges:S.edges.length,saved:!0}}};var L=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[r,s]of this.records)s.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let s=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=br(t,n.vector);s.push({id:n.id,score:i,metadata:n.metadata})}return s.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function br(o,e){if(o.length===0||e.length===0||o.length!==e.length)return 0;let t=0,r=0,s=0;for(let n=0;n<o.length;n++){let i=o[n]??0,a=e[n]??0;t+=i*a,r+=i*i,s+=a*a}return r===0||s===0?0:t/(Math.sqrt(r)*Math.sqrt(s))}import*as E from"typescript";import*as y from"typescript";var Kn=new Set([y.SyntaxKind.EqualsToken,y.SyntaxKind.PlusEqualsToken,y.SyntaxKind.MinusEqualsToken,y.SyntaxKind.AsteriskEqualsToken,y.SyntaxKind.SlashEqualsToken,y.SyntaxKind.PercentEqualsToken,y.SyntaxKind.QuestionQuestionEqualsToken,y.SyntaxKind.AmpersandAmpersandEqualsToken,y.SyntaxKind.BarBarEqualsToken]);var oe=class{constructor(e,t){this.embeddings=e;this.store=t}embeddings;store;async index(e){let t=e.filter(n=>!this.store.has(n.id));if(t.length===0)return 0;let r=await this.embeddings.embedMany(t.map(n=>[n.type,n.content,...n.tags??[]].join(" "))),s=0;for(let n=0;n<t.length;n++){let i=t[n],a=r[n];!i||!a||(this.store.upsert({id:i.id,projectId:i.projectId,vector:a,metadata:{type:i.type,updatedAt:i.updatedAt}}),s++)}return s}};var N=class{constructor(e,t,r,s,n){this.projectId=e;this.model=t;this.embeddings=r;this.store=s;this.persistence=n}projectId;model;embeddings;store;persistence;async initialize(e){let t=0,r=await this.persistence.load(this.projectId);r&&r.model===this.model&&(t=this.store.importRecords(r.records));let s=new Set(e.map(d=>d.id)),n=0;for(let d of this.store.exportProject(this.projectId))s.has(d.id)||this.store.remove(d.id)&&n++;let a=await new oe(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),l=c[0]?.vector.length??this.embeddings.dimensions??0,p=!1;return(a>0||n>0||!r)&&(await this.persistence.save({version:1,projectId:this.projectId,model:this.model,dimensions:l,updatedAt:new Date().toISOString(),records:c}),p=!0),{loaded:t,indexed:a,removed:n,total:c.length,saved:p}}};var se=class{events=[];push(e){this.events.push(e)}drain(){let e=[...this.events];return this.events.length=0,e}list(){return[...this.events]}size(){return this.events.length}shouldFlush(e){return this.events.length>=e}};import{createHash as vr}from"node:crypto";var ne=class{seen=new Set;fingerprint(e){return vr("sha256").update(JSON.stringify({projectId:e.projectId,type:e.type,data:e.data})).digest("hex")}filter(e){let t=[];for(let r of e){let s=this.fingerprint(r);this.seen.has(s)||(this.seen.add(s),t.push(r))}return t}clear(){this.seen.clear()}};import{randomUUID as wr}from"node:crypto";var ie=class{constructor(e){this.queue=e}queue;sanitizer=new R;capture(e,t,r={}){let s={id:wr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(s),s}};import{randomUUID as Er}from"node:crypto";var ae=class{constructor(e){this.capture=e}capture;sessionId=Er();start(e){return this.capture.capture(e,"session_start",{sessionId:this.sessionId})}end(e){return this.capture.capture(e,"session_end",{sessionId:this.sessionId})}};var ce=class{extract(e){switch(e.type){case"decision":return{type:"decision",content:String(e.data.content??"Decision recorded"),tags:["decision"],source:"auto-extractor",metadata:e.data};case"todo":return{type:"todo",content:String(e.data.content??"TODO recorded"),tags:["todo"],source:"auto-extractor",metadata:e.data};case"error":return{type:"activity",content:`Error: ${String(e.data.message??"")}`,tags:["error"],source:"auto-extractor",metadata:e.data};case"file_write":return{type:"activity",content:`Modified file: ${String(e.data.filePath??"")}`,tags:["file","write"],source:"auto-extractor",metadata:e.data};case"command":return{type:"activity",content:`Command: ${String(e.data.command??"")}`,tags:["command"],source:"auto-extractor",metadata:e.data};case"session_start":case"session_end":case"file_read":case"tool_call":case"user_prompt":case"test":case"commit":case"deploy":return null;default:return null}}};function Ge(o){let e=o.toLowerCase();return["kh\xF4ng \u0111\u01B0\u1EE3c","b\u1EAFt bu\u1ED9c","ph\u1EA3i lu\xF4n","tuy\u1EC7t \u0111\u1ED1i","never ","must ","always ","do not "].some(t=>e.includes(t))}function De(o){let e=o.toLowerCase();return["quy\u1EBFt \u0111\u1ECBnh","ch\u1ECDn ","s\u1EED d\u1EE5ng ","d\xF9ng ","decided","decision","we will use","use "].some(t=>e.includes(t))}function ze(o){let e=o.toLowerCase();return["todo","c\u1EA7n l\xE0m","ch\u01B0a xong","c\xF2n ph\u1EA3i","next:","next step","pending"].some(t=>e.includes(t))}function le(o,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("tuy\u1EC7t \u0111\u1ED1i")||t.includes("must not")||t.includes("never ")?"critical":o==="rule"||o==="decision"?"high":o==="todo"||t.includes("error")||t.includes("failed")||t.includes("exception")?"normal":"temporary"}function O(o){return[...new Set(o.filter(Boolean))]}function de(o,e=120){return o.length>e?`${o.slice(0,e)}\u2026`:o}var pe=class{summarize(e){if(e.length===0)return null;let t=O(e.filter(c=>c.type==="file_write").map(c=>String(c.data.filePath??""))),r=O(e.filter(c=>c.type==="command").map(c=>de(String(c.data.command??"")))),s=O(e.filter(c=>c.type==="error").map(c=>de(String(c.data.message??"")))),n=O(e.filter(c=>c.type==="decision").map(c=>de(String(c.data.content??"")))),i=O(e.filter(c=>c.type==="todo").map(c=>de(String(c.data.content??""))));if(t.length===0&&r.length===0&&s.length===0&&n.length===0&&i.length===0)return null;let a=["Session summary:"];return t.length&&a.push(`- Files changed (${t.length}): ${t.slice(0,10).join(", ")}`),r.length&&a.push(`- Commands (${r.length}): ${r.slice(0,5).join("; ")}`),s.length&&a.push(`- Errors (${s.length}): ${s.slice(0,5).join("; ")}`),n.length&&a.push(`- Decisions: ${n.slice(0,5).join("; ")}`),i.length&&a.push(`- TODO: ${i.slice(0,5).join("; ")}`),a.join(`
5
- `)}};var me=class{constructor(e){this.memory=e}memory;extractor=new ce;summarizer=new pe;process(e){let t=0;for(let s of e){let n=this.extractor.extract(s);if(n){let i=this.refineType(n.type,n.content);this.memory.remember({projectId:s.projectId,type:i,content:n.content,importance:le(i,n.content),tags:n.tags,source:n.source,metadata:{eventId:s.id,timestamp:s.timestamp,...n.metadata}}),t++}if(s.type==="user_prompt"){let i=String(s.data.content??""),a=this.detectPromptMemoryType(i);a&&(this.memory.remember({projectId:s.projectId,type:a,content:i,importance:le(a,i),tags:["user",a],source:"auto-prompt-extractor",metadata:{eventId:s.id,timestamp:s.timestamp}}),t++)}}let r=this.summarizer.summarize(e);if(r){let s=e[0]?.projectId;s&&(this.memory.remember({projectId:s,type:"summary",content:r,importance:"temporary",tags:["summary"],source:"auto-summary",metadata:{eventCount:e.length}}),t++)}return t}refineType(e,t){return Ge(t)?"rule":ze(t)?"todo":De(t)?"decision":e}detectPromptMemoryType(e){return Ge(e)?"rule":ze(e)?"todo":De(e)?"decision":null}};import{createHash as Cr}from"node:crypto";function jr(o){return Cr("sha256").update([o.projectId,o.type,o.content.trim().toLowerCase()].join("|")).digest("hex")}function at(o){let e=new Set,t=[];for(let r of o){let s=jr(r);e.has(s)||(e.add(s),t.push(r))}return t}var ue=class{projectId;memory;memoryStore;queue=new se;capture=new ie(this.queue);session=new ae(this.capture);processor;dedup=new ne;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new me(this.memory)}async sessionStart(){this.session.start(this.projectId),await this.flushIfNeeded()}async sessionEnd(){this.session.end(this.projectId),await this.flush()}async userPrompt(e){this.capture.capture(this.projectId,"user_prompt",{content:e}),await this.flushIfNeeded()}async beforeTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"before",tool:e,input:t}),await this.flushIfNeeded()}async afterTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"after",tool:e,output:t}),await this.flushIfNeeded()}async fileRead(e){this.capture.capture(this.projectId,"file_read",{filePath:e}),await this.flushIfNeeded()}async fileWrite(e){this.capture.capture(this.projectId,"file_write",{filePath:e}),await this.flushIfNeeded()}async command(e,t){this.capture.capture(this.projectId,"command",{command:e,exitCode:t}),await this.flushIfNeeded()}async error(e){let t=e instanceof Error?e.message:String(e);this.capture.capture(this.projectId,"error",{message:t}),await this.flushIfNeeded()}async decision(e,t={}){this.capture.capture(this.projectId,"decision",{content:e,...t}),await this.flushIfNeeded()}async todo(e,t={}){this.capture.capture(this.projectId,"todo",{content:e,...t}),await this.flushIfNeeded()}async flushIfNeeded(){this.queue.shouldFlush(this.maxEventsBeforeFlush)&&await this.flush()}async flush(){let e=this.queue.drain();if(e.length===0)return 0;let t=this.dedup.filter(e);if(t.length===0)return 0;let r=this.processor.process(t),s=at(this.memory.exportProject(this.projectId));return this.memory.clearProject(this.projectId),this.memory.importRecords(s),await this.memoryStore.save(this.projectId,s),r}pendingEvents(){return this.queue.size()}};var fe=class{constructor(e,t,r){this.memory=e;this.retrieval=t;this.graph=r}memory;retrieval;graph;build(e,t,r={}){let s=r.maxRules??3,n=r.maxTodos??3,i=r.maxDecisions??3,a=r.maxRelevant??5,c=r.maxCharacters??7e3,l=this.memory.byType(e,"rule").slice(0,s),p=this.memory.byType(e,"todo").slice(0,n),d=this.memory.byType(e,"decision").slice(0,i),u=this.retrieval.search(e,t,{topK:a}),f=Xe(this.graph,e),w=[];w.push(["[PROJECT]",`files=${f.files}`,`classes=${f.classes}`,`functions=${f.functions}`,`methods=${f.methods}`,`calls=${f.calls}`].join(" "));for(let g of l)w.push(`[RULE] ${g.content}`);for(let g of d)w.push(`[DECISION] ${g.content}`);for(let g of p)w.push(`[TODO] ${g.content}`);for(let g of u){let x=`[${g.memory.type.toUpperCase()}] ${g.memory.content}`;w.includes(x)||w.push(x)}let S="";for(let g of w){let m=S.length===0?g:`${S}
6
- ${g}`;if(m.length>c)break;S=m}return S}};var ge=class{constructor(e,t,r){this.runtime=e;this.builder=t;this.projectId=r}runtime;builder;projectId;async prepare(e){await this.runtime.userPrompt(e);let t=this.builder.build(this.projectId,e);return{originalPrompt:e,context:t,augmentedPrompt:t?["<toolnet_memory>",t,"</toolnet_memory>","",e].join(`
7
- `):e}}};var ct={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},he=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=ot(e,t);if(r.length===0)return{triggered:!1,tool:e,highestRisk:"LOW",totalRiskScore:0,files:[],impactedFiles:[],suggestedTests:[],requiresVerification:!1,context:""};let s=[];for(let d of r){let u=this.guard.analyzeFile(this.projectId,d);s.push({filePath:d,risk:u.risk,riskScore:u.riskScore,impactedFiles:u.impactedFiles,suggestedTests:u.suggestedTests,impactedCount:u.impacted.length})}let n="LOW";for(let d of s)ct[d.risk]>ct[n]&&(n=d.risk);let i=[...new Set(s.flatMap(d=>d.impactedFiles))],a=[...new Set(s.flatMap(d=>d.suggestedTests))],c=s.reduce((d,u)=>d+u.riskScore,0),l=n==="HIGH"||n==="CRITICAL",p=["[TOOLNET IMPACT GUARD]",`Risk: ${n}`,`Risk score: ${c}`,`Files being changed: ${r.join(", ")}`,`Impacted files: ${i.length}`];return i.length&&p.push("Blast radius:",...i.slice(0,20).map(d=>`- ${d}`)),a.length&&p.push("Verify/tests:",...a.slice(0,15).map(d=>`- ${d}`)),l&&p.push("IMPORTANT: High blast radius. Inspect affected dependencies and run relevant tests after the edit."),{triggered:!0,tool:e,highestRisk:n,totalRiskScore:c,files:s,impactedFiles:i,suggestedTests:a,requiresVerification:l,context:p.join(`
8
- `)}}};import{homedir as zr}from"node:os";import{join as Br}from"node:path";import{DeleteObjectCommand as Pr,GetObjectCommand as Rr,HeadObjectCommand as kr,ListObjectsV2Command as Tr,PutObjectCommand as Mr,S3Client as Ir}from"@aws-sdk/client-s3";import{getSignedUrl as Ar}from"@aws-sdk/s3-request-presigner";var ye=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ir({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,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Mr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Ar(this.client,new Rr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.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 kr({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 Pr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new Tr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of s.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as lt,mkdir as Lr,readFile as Nr,readdir as Or,rm as Fr,stat as dt,writeFile as $r}from"node:fs/promises";import{dirname as _r,join as Gr,relative as pt,resolve as Dr}from"node:path";var F=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Dr(this.root,t)}async put(e,t){let r=this.path(e);await Lr(_r(r),{recursive:!0}),await $r(r,t)}async get(e){try{return await Nr(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 lt(this.path(e)),!0}catch{return!1}}async delete(e){await Fr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await lt(t)}catch{return r}let s=async i=>{let a=await Or(i,{withFileTypes:!0});for(let c of a){let l=Gr(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await dt(l);r.push({key:pt(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await dt(t);return n.isDirectory()?await s(t):r.push({key:pt(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};function mt(o){let e=o.localRoot??Br(zr(),".toolnet-memory","storage");if(o.provider==="huggingface"){let t=o.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new ye({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new F(e))}return new F(e)}var M=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 r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};var Se=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 r=JSON.parse(t);if(r.version!==1||r.projectId!==e||!Array.isArray(r.records))throw new Error("Invalid vector snapshot");return r}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function Hr(o){return new Promise(e=>setTimeout(e,o))}async function ut(o,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await o()}catch(a){if(n=a,i>=t)break;let c=Math.min(s,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Hr(c+l)}throw n}var Kr=new Set(["put","get","getText","delete","list"]);function ft(o,e={}){return new Proxy(o,{get(t,r){let s=Reflect.get(t,r,t);return typeof s!="function"?s:Kr.has(r)?(...n)=>ut(()=>Promise.resolve(s.apply(t,n)),e):s.bind(t)}})}function gt(o){let e=o.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}function ht(o){let e=o.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var be=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=gt(s??r),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(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}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"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
9
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=ht(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,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}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))}};function Vr(o){let e=o.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function Ur(o,e){let t=`projects/${o.id}/memory/learned/`,r=await e.list(t),s=[];for(let n of r.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(n.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;s.push(a)}catch{}}return s}async function yt(o,e){let t=await Ur(o,e),r=new M(e),s=await r.load(o.id),n=new k;n.importRecords(s);let i=new Set(s.map(p=>Vr(p)).filter(p=>!!p)),a=0,c=0,l=0;for(let p of t)for(let d of p.candidates){if(a+=1,i.has(d.fingerprint)){l+=1;continue}n.remember({projectId:o.id,type:d.type,content:d.content,importance:d.importance,tags:d.tags,source:"session-memory-learner",metadata:{learningFingerprint:d.fingerprint,learningKind:d.kind,confidence:d.confidence,provenance:d.provenance,sourceCreatedAt:d.createdAt,sessionKey:d.sessionKey,agent:d.agent,nativeSessionId:d.nativeSessionId}}),i.add(d.fingerprint),c+=1}return c>0&&await r.save(o.id,n.exportProject(o.id)),{batches:t.length,candidates:a,added:c,duplicates:l,memories:n.exportProject(o.id).length}}var qr=["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"],xe=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",r){let s=new Date().toISOString(),n=s.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of qr){let d=`${i}/${p}`,u=await this.storage.get(d);u&&(await this.storage.put(`${a}/${p}`,u,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:s,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),s=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of s){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.getText(`${r}/snapshot.json`);if(!s)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(s);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),s=await this.storage.list(r);for(let n of s)await this.storage.delete(n.key);return s.length}async prune(e,t=10){let s=(await this.list(e)).slice(t),n=0;for(let i of s)await this.remove(e,i.id),n++;return n}};import{closeSync as Jr,mkdirSync as Yr,openSync as Zr,readFileSync as Qr,unlinkSync as St,writeFileSync as Xr}from"node:fs";import{tmpdir as eo}from"node:os";import{join as bt}from"node:path";function to(o){try{return process.kill(o,0),!0}catch(e){return e?.code==="EPERM"}}var ve=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=bt(eo(),"toolnet-memory-locks");Yr(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=bt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=Zr(this.path,"wx");Xr(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),Jr(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let s=JSON.parse(Qr(this.path,"utf8"));Number.isInteger(s.pid)&&to(s.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{St(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{St(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var we=class{constructor(e){this.options=e;this.memoryStore=new M(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new Se(e.storage),this.processLock=new ve(e.project.id),this.retrieval=new q(this.memory),this.references=new Z(this.graph),this.hooks=new ue({projectId:e.project.id,memory:this.memory,memoryStore:this.memoryStore,maxEventsBeforeFlush:100});let t=new fe(this.memory,this.retrieval,this.graph);this.autoRetrieval=new ge(this.hooks,t,e.project.id),this.impactGuard=new ee(this.graph),this.autoImpactGuard=new he(this.impactGuard,e.project.id)}options;memory=new k;graph=new j;vectors=new L;retrieval;references;hooks;autoRetrieval;impactGuard;autoImpactGuard;memoryStore;graphStore;vectorStore;processLock;async start(){let{project:e}=this.options;await this.processLock.acquire(),await yt(e,this.options.storage);let t=await this.memoryStore.load(e.id);this.memory.importRecords(t);let s=new z(this.memory).run(e.id);(s.expiredRemoved>0||s.supersededRemoved>0)&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let n=await this.graphStore.load(e.id);n&&this.graph.import(n.symbols,n.edges);let i=Ie(),c=await new N(e.id,this.options.embeddingModel,i,this.vectors,this.vectorStore).initialize(this.memory.list(e.id));return await this.hooks.sessionStart(),{memories:t.length,graphSymbols:this.graph.allSymbols(e.id).length,graphEdges:this.graph.allEdges(e.id).length,vectors:c.total,vectorsIndexed:c.indexed}}async preparePrompt(e){return this.autoRetrieval.prepare(e)}async beforeTool(e,t){let r=await this.autoImpactGuard.beforeTool(e,t);return await this.hooks.beforeTool(e,t),r}async afterTool(e,t){return this.hooks.afterTool(e,t)}async stop(){let{project:e,storage:t,embeddingModel:r}=this.options,s=new xe(t),n=await s.create(e.id,"session-end-auto");await s.prune(e.id,10),await this.hooks.sessionEnd();let i=new B(this.memory).consolidate(e.id);i.summaryCreated&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let a=await new re(t).index(e.id,e.rootPath),c=await this.graphStore.load(e.id);c&&(this.graph.clearProject(e.id),this.graph.import(c.symbols,c.edges));let l=Ie(),d=await new N(e.id,r,l,this.vectors,this.vectorStore).initialize(this.memory.list(e.id)),u={code:a,vectors:d,consolidation:i,snapshot:n?.id,memories:this.memory.list(e.id).length};return await this.processLock.release(),u}};import"dotenv/config";import{existsSync as ro,readFileSync as oo}from"node:fs";import{homedir as so}from"node:os";import{join as no}from"node:path";function io(o){let e=o.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
10
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function ao(){let o=process.env.TOOLNET_GLOBAL_ENV??no(so(),".config","toolnet-memory",".env");if(!ro(o))return;let e=oo(o,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let n=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=io(r.slice(s+1)))}}ao();function Ee(o,e){return o===void 0?e:["1","true","yes","on"].includes(o.toLowerCase())}function $(o,e){if(!o)return e;let t=Number(o);return Number.isFinite(t)?t:e}function xt(){return{memory:{autoCapture:Ee(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:Ee(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:Ee(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:Ee(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:$(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:$(process.env.MEMORY_RERANK_TOP,10),finalContext:$(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:$(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",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:$(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as co}from"node:crypto";import{existsSync as Be,mkdirSync as lo,readFileSync as po,renameSync as mo,writeFileSync as uo}from"node:fs";import{basename as fo,dirname as Ce,join as Pe,parse as Et,resolve as _}from"node:path";var Ct=".toolnet",go="project.json";function ho(o){return co("sha256").update(o).digest("hex").slice(0,16)}function He(o){return Pe(o,Ct,go)}function yo(o){return Be(He(o))}function So(o,e){let t=_(o),r=Et(t).root;for(;;){if(yo(t))return t;if(t===r||e&&t===_(e))break;let s=Ce(t);if(s===t)break;t=s}return null}function bo(o){let e=_(o),t=Et(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>Be(Pe(e,n))))return e;if(e===t)break;let s=Ce(e);if(s===e)break;e=s}return _(o)}function xo(o){let e;try{e=JSON.parse(po(o,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${o}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${o}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${o}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${o}`);let r=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(o)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,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 vt(o,e){let t=Pe(o,Ct);lo(t,{recursive:!0});let r=He(o),s=`${r}.tmp-${process.pid}`;uo(s,JSON.stringify(e,null,2)+`
11
- `,{encoding:"utf8",mode:384}),mo(s,r)}function wt(o,e){return{id:o.id,name:o.name,remote:o.remote,rootPath:e,createdAt:o.createdAt,updatedAt:o.updatedAt,graphVersion:o.graphVersion,memoryVersion:o.memoryVersion,metadata:o.metadata}}var je=class{detect(e=process.cwd()){let t=_(e),r=bo(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Be(Pe(r,p))),i=So(t,n?r:void 0);if(i){let p=He(i),d=xo(p);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),vt(i,d)),wt(d,i)}let a=new Date().toISOString(),c=fo(r),l={version:1,id:ho(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return vt(r,l),wt(l,r)}};function jt(o=process.cwd()){let e=xt(),t=new je().detect(o),r=mt({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),s=ft(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),n=new be(s,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new we({project:t,storage:n,embeddingModel:i})}async function vo(){let o=jt(),e=await o.start(),t=await o.preparePrompt("Ti\u1EBFp t\u1EE5c c\xF4ng vi\u1EC7c hi\u1EC7n t\u1EA1i");console.log({started:!0,...e,contextCharacters:t.context.length});let r=await o.stop();console.log({stopped:!0,memories:r.memories,codeParsed:r.code.parsed,vectorsIndexed:r.vectors.indexed})}vo().catch(o=>{console.error(o),process.exit(1)});
1
+ import{randomUUID as $t}from"node:crypto";var Tt={critical:100,high:75,normal:50,temporary:20};function Ue(s){return Tt[s]}function Ve(s,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":s==="rule"||s==="decision"?"high":s==="todo"?"normal":s==="activity"||s==="summary"?"temporary":"normal"}var It=[{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}],z=class{scan(e){let t=[];for(let r of It){let o=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(o))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var j=class{scanner=new z;sanitize(e){let t=e,r=this.scanner.scan(e),o=new Set;for(let n of r)o.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.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[r,o]of Object.entries(e)){let n=r.toLowerCase();n.includes("password")||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(o)}return t}return e}};var Mt=new Set(["decision","rule","todo","summary","activity","user","error","file","write","command","learned","session","architecture","fix","context","opencode","agy","codex"]),At=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 qe(s){return new Set(s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_-]+/gu," ").split(/\s+/).filter(e=>e.length>2&&!At.has(e)))}function Lt(s,e){let t=qe(s),r=qe(e);if(t.size===0||r.size===0)return 0;let o=0;for(let i of t)r.has(i)&&o++;let n=new Set([...t,...r]).size;return o/n}function Je(s){return new Set(s.tags.filter(e=>!Mt.has(e.toLowerCase())))}var K=class{findSuperseded(e,t){if(e.type!=="rule"&&e.type!=="decision")return[];let r=typeof e.metadata?.topic=="string"?e.metadata.topic:void 0,o=Je(e);return t.filter(n=>{if(n.id===e.id||n.projectId!==e.projectId||n.type!==e.type||n.metadata?.supersededBy)return!1;let i=typeof n.metadata?.topic=="string"?n.metadata.topic:void 0;if(r&&i&&r===i)return!0;let a=Je(n);for(let c of o)if(a.has(c))return!0;return Lt(e.content,n.content)>=.6})}};var Nt={critical:100,high:75,normal:50,temporary:20},Ot={activity:14,summary:30,todo:90,decision:365,rule:730,code:180};function Ye(s,e,t=new Date){let r;if(e==="temporary"&&(r=30),s==="activity"&&(r=Math.min(r??14,14)),s==="summary"&&(r=Math.min(r??30,30)),!!r)return new Date(t.getTime()+r*864e5).toISOString()}function Re(s,e=Date.now()){return s.expiresAt?new Date(s.expiresAt).getTime()<=e:!1}function _t(s){return!!s.metadata?.supersededBy}function Te(s,e=Date.now()){return!Re(s,e)&&!_t(s)}function M(s,e=Date.now()){if(!Te(s,e))return 0;let t=Nt[s.importance];if(s.importance==="critical")return t;let r=Ot[s.type]??180,n=Math.max(0,e-new Date(s.updatedAt).getTime())/864e5,i=Math.pow(.5,n/r);return t*i}var R=class{memories=new Map;sanitizer=new j;conflicts=new K;remember(e){let t=new Date().toISOString(),r=this.sanitizer.sanitize(e.content.trim()).text,o=e.importance??Ve(e.type,r),n={id:$t(),projectId:e.projectId,type:e.type,content:r,importance:o,importanceScore:Ue(o),tags:e.tags??[],source:e.source??"agent",createdAt:t,updatedAt:t,expiresAt:e.expiresAt??Ye(e.type,o,new Date(t)),metadata:this.sanitizer.sanitizeValue(e.metadata)},i=this.conflicts.findSuperseded(n,this.list(e.projectId));if(i.length){n.metadata={...n.metadata??{},supersedes:i.map(a=>a.id)};for(let a of i)a.updatedAt=t,a.metadata={...a.metadata??{},supersededBy:n.id,supersededAt:t},this.memories.set(a.id,a)}return this.memories.set(n.id,n),n}importRecords(e){let t=0;for(let r of e)r?.id&&(this.memories.set(r.id,r),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,r)=>r.createdAt.localeCompare(t.createdAt))}list(e){return this.listAll(e).filter(t=>Te(t))}recent(e,t=10){return this.list(e).slice(0,t)}byType(e,t){return this.list(e).filter(r=>r.type===t)}search(e){let t=e.query.trim().toLowerCase(),r=e.limit??10,o=t.split(/\s+/).filter(Boolean);return this.list(e.projectId).filter(n=>{if(e.types&&!e.types.includes(n.type))return!1;let i=M(n);return!(e.minImportanceScore&&i<e.minImportanceScore||e.tags?.length&&!e.tags.some(c=>n.tags.includes(c)))}).map(n=>{let i=n.content.toLowerCase(),a=o.filter(p=>i.includes(p)).length,c=o.length===0?0:a/o.length,l=M(n)/500;return{memory:n,score:c+l,source:"memory"}}).filter(n=>t.length===0||n.score>0).sort((n,i)=>i.score-n.score).slice(0,r)}pruneExpired(e,t=Date.now()){let r=0;for(let[o,n]of this.memories)n.projectId===e&&Re(n,t)&&(this.memories.delete(o),r++);return r}pruneSuperseded(e,t=30,r=Date.now()){let o=0,n=t*864e5;for(let[i,a]of this.memories){if(a.projectId!==e)continue;let c=a.metadata?.supersededAt;if(typeof c!="string")continue;r-new Date(c).getTime()>=n&&(this.memories.delete(i),o++)}return o}clearProject(e){let t=0;for(let[r,o]of this.memories)o.projectId===e&&(this.memories.delete(r),t++);return t}};var B=class{constructor(e){this.memory=e}memory;run(e){let t=this.memory.pruneExpired(e),r=this.memory.pruneSuperseded(e,30);return{expiredRemoved:t,supersededRemoved:r,active:this.memory.list(e).length,total:this.memory.listAll(e).length}}};function Ie(s){return[...new Set(s.filter(Boolean))]}var H=class{constructor(e){this.memory=e}memory;consolidate(e,t={}){let r=t.minItems??4,o=t.maxItems??50,n=t.retentionDays??90,i=this.memory.byType(e,"activity").slice(0,o);if(i.length<r)return{scanned:i.length,consolidated:0,summaryCreated:!1};let a=this.buildSummary(i),c=new Date,l=new Date(c.getTime()+n*864e5).toISOString(),p=this.memory.remember({projectId:e,type:"summary",content:a,importance:"normal",tags:["consolidated","activity-summary"],source:"auto-consolidation",expiresAt:l,metadata:{consolidatedFrom:i.map(u=>u.id),itemCount:i.length}}),d=c.toISOString();for(let u of i){let f=this.memory.get(u.id);f&&(f.updatedAt=d,f.metadata={...f.metadata??{},consolidated:!0,supersededBy:p.id,supersededAt:d})}return{scanned:i.length,consolidated:i.length,summaryCreated:!0,summaryId:p.id}}buildSummary(e){let t=Ie(e.filter(i=>i.content.startsWith("Modified file:")).map(i=>i.content.replace("Modified file:","").trim())),r=Ie(e.filter(i=>i.content.startsWith("Command:")).map(i=>i.content.replace("Command:","").trim())),o=Ie(e.filter(i=>i.content.startsWith("Error:")).map(i=>i.content.replace("Error:","").trim())),n=["Activity consolidation:",`- Activities: ${e.length}`];return t.length&&n.push(`- Files changed: ${t.slice(0,15).join(", ")}`),r.length&&n.push(`- Commands: ${r.slice(0,10).join("; ")}`),o.length&&n.push(`- Errors: ${o.slice(0,10).join("; ")}`),n.join(`
2
+ `)}};function W(s){return s.toLowerCase().normalize("NFKC").replace(/[^\p{L}\p{N}_\-./]+/gu," ").split(/\s+/).map(e=>e.trim()).filter(e=>e.length>1)}var U=class{score(e,t){let r=W(e),o=W([t.content,...t.tags??[],t.type].join(" "));if(r.length===0||o.length===0)return 0;let n=new Map;for(let a of o)n.set(a,(n.get(a)??0)+1);let i=0;for(let a of r){let c=n.get(a)??0;c!==0&&(i+=1+Math.log(1+c))}return i/r.length}};function Qe(s,e=Date.now()){let t=s.updatedAt??s.createdAt,r=new Date(t).getTime();if(!Number.isFinite(r))return 0;let o=Math.max(0,e-r)/864e5;return Math.exp(-Math.LN2*o/30)}function Ze(s){return M(s)/100}var Ft={rule:1,decision:.9,todo:.8,summary:.6,activity:.3};function Xe(s){return Ft[s]??.4}var V=class{analyze(e){let t=e.toLowerCase(),r=[];return(t.includes("quy\u1EBFt \u0111\u1ECBnh")||t.includes("decision")||t.includes("\u0111\xE3 ch\u1ECDn"))&&r.push("decision"),(t.includes("todo")||t.includes("c\u1EA7n l\xE0m")||t.includes("ti\u1EBFp theo")||t.includes("ch\u01B0a xong"))&&r.push("todo"),(t.includes("quy t\u1EAFc")||t.includes("rule")||t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("b\u1EAFt bu\u1ED9c"))&&r.push("rule"),(t.includes("t\xF3m t\u1EAFt")||t.includes("summary")||t.includes("\u0111\xE3 l\xE0m"))&&r.push("summary"),{query:e,preferredTypes:r}}};var q=class{bm25=new U;analyzer=new V;search(e,t,r={}){let o=r.topK??8,n=r.minScore??.05,i=this.analyzer.analyze(e),a=[];for(let c of t){if(r.types?.length&&!r.types.includes(c.type))continue;let l=this.bm25.score(e,c),p=Qe(c),d=Ze(c),u=Xe(c.type);i.preferredTypes.includes(c.type)&&(u=Math.min(1,u+.25));let f=l*.55+d*.2+p*.15+u*.1;l<=0||f<n||a.push({memory:c,score:f,scores:{keyword:l,recency:p,importance:d,type:u}})}return a.sort((c,l)=>l.score-c.score).slice(0,o)}};var J=class{build(e,t=6e3){let r=[],o=0;for(let n of e){let i=n.memory,a=[`[${i.type.toUpperCase()}]`,i.content].join(" ");if(o+a.length>t)break;r.push(a),o+=a.length}return r.join(`
3
+ `)}};var Y=class{constructor(e){this.memory=e}memory;searcher=new q;contextBuilder=new J;search(e,t,r={}){return this.searcher.search(t,this.memory.list(e),r)}context(e,t,r={}){let o=this.search(e,t,r);return this.contextBuilder.build(o)}};var Q=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`,r=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(!r.ok)throw new Error(`HF embedding failed: ${r.status} ${await r.text()}`);let o=await r.json();if(!Array.isArray(o))throw new Error("HF embedding returned invalid response");return o.map(n=>Dt(n))}};function Dt(s){if(!Array.isArray(s))throw new Error("Invalid embedding");if(s.length>0&&typeof s[0]=="number")return s;if(s.length>0&&Array.isArray(s[0])){let e=s;if(e.length===0)return[];let t=e[0].length,r=new Array(t).fill(0);for(let o of e)for(let n=0;n<t;n++)r[n]+=o[n]??0;for(let o=0;o<t;o++)r[o]/=e.length;return r}throw new Error("Unsupported embedding shape")}import{createHash as Gt}from"node:crypto";var Z=class{name="hash-fallback";dimensions=128;async embed(e){let t=new Array(this.dimensions).fill(0),r=e.toLowerCase().split(/\s+/).filter(Boolean);for(let o of r){let i=Gt("sha256").update(o).digest().readUInt32BE(0)%this.dimensions;t[i]+=1}return zt(t)}async embedMany(e){return Promise.all(e.map(t=>this.embed(t)))}};function zt(s){let e=Math.sqrt(s.reduce((t,r)=>t+r*r,0));return e===0?s:s.map(t=>t/e)}var Me=class{constructor(e,t=new Z){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)}};function Ae(){let s=process.env.HF_TOKEN,e=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2",t=s?new Q({token:s,model:e}):null;return new Me(t)}import{readdir as Wt}from"node:fs/promises";import{extname as Ut,join as Vt,relative as qt}from"node:path";import{basename as Kt}from"node:path";var Bt=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Ht=new Set([".pem",".key",".p12",".pfx"]);function Le(s){let e=Kt(s).toLowerCase();if(Bt.has(e))return!0;for(let t of Ht)if(e.endsWith(t))return!0;return!1}var Jt=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Yt=new Set(["node_modules",".git","dist","build","coverage",".next",".cache",".toolnet-memory"]);async function Ne(s){let e=[];async function t(r){let o=await Wt(r,{withFileTypes:!0});for(let n of o){if(Yt.has(n.name))continue;let i=Vt(r,n.name);if(n.isDirectory()){await t(i);continue}Jt.has(Ut(n.name))&&(Le(i)||e.push(qt(s,i)))}}return await t(s),e.sort()}import{readFile as Qt}from"node:fs/promises";import{join as Zt}from"node:path";import{createHash as Xt}from"node:crypto";import*as h from"typescript";function et(s,e){return Xt("sha256").update(`${s}:${e}`).digest("hex").slice(0,24)}function Oe(s,e){return s.getLineAndCharacterOfPosition(e.getStart(s)).line+1}async function _e(s,e,t){let r=Zt(e,t),o=await Qt(r,"utf8"),n=h.createSourceFile(t,o,h.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?h.ScriptKind.TSX:h.ScriptKind.TS),i=[],a=[],c=[],l=[],p={id:et(s,`file:${t}`),projectId:s,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:n.getLineAndCharacterOfPosition(n.end).line+1};i.push(p);let d=[],u=[];function f(m,v,x,b){let C=et(s,`${t}:${x}:${b??v}:${m.pos}`);return i.push({id:C,projectId:s,name:v,qualifiedName:b??v,type:x,filePath:t,startLine:Oe(n,m),endLine:n.getLineAndCharacterOfPosition(m.end).line+1}),C}function w(m){if(!h.isStringLiteral(m.moduleSpecifier))return;let v=[],x=m.importClause;if(x?.name&&v.push({localName:x.name.text,importedName:"default",kind:"default"}),x?.namedBindings&&h.isNamedImports(x.namedBindings))for(let b of x.namedBindings.elements)v.push({localName:b.name.text,importedName:b.propertyName?.text??b.name.text,kind:"named"});x?.namedBindings&&h.isNamespaceImport(x.namedBindings)&&v.push({localName:x.namedBindings.name.text,importedName:"*",kind:"namespace"}),a.push({source:m.moduleSpecifier.text,bindings:v})}function S(m,v){for(let x of m.heritageClauses??[])for(let b of x.types){let C=b.expression.getText(n).split(".").at(-1)??"";C&&l.push({fromId:v,targetName:C,type:x.token===h.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function g(m){let v=!1,x=!1;if(h.isImportDeclaration(m)&&w(m),h.isInterfaceDeclaration(m)&&f(m,m.name.text,"interface",m.name.text),h.isClassDeclaration(m)&&m.name){let b=f(m,m.name.text,"class",m.name.text);S(m,b),u.push({id:b,name:m.name.text}),x=!0}if(h.isFunctionDeclaration(m)&&m.name){let b=f(m,m.name.text,"function",m.name.text);d.push(b),v=!0}if(h.isMethodDeclaration(m)&&m.name){let b=m.name.getText(n),C=u.at(-1)?.name,Rt=f(m,b,"method",C?`${C}.${b}`:b);d.push(Rt),v=!0}if(h.isCallExpression(m)&&(h.isIdentifier(m.expression)&&c.push({callerId:d.at(-1),calleeName:m.expression.text,line:Oe(n,m)}),h.isPropertyAccessExpression(m.expression))){let b=m.expression;c.push({callerId:d.at(-1),qualifier:b.expression.getText(n),calleeName:b.name.text,line:Oe(n,m)})}h.forEachChild(m,g),v&&d.pop(),x&&u.pop()}return g(n),{filePath:t,symbols:i,imports:a,calls:c,heritage:l}}import{createHash as er}from"node:crypto";import{dirname as tr,extname as rr,normalize as sr,posix as or}from"node:path";var P=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(r=>r.projectId===e&&(r.name===t||r.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 r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};function nr(s,e,t,r){return er("sha256").update(`${s}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function k(s){return sr(s).replaceAll("\\","/")}function $e(s,e,t){if(!e.startsWith("."))return;let r=k(or.join(tr(s),e)),o=rr(r),n;if(o===".js"){let i=r.slice(0,-3);n=[`${i}.ts`,`${i}.tsx`,`${i}.js`,`${i}.jsx`]}else if(o===".mjs"){let i=r.slice(0,-4);n=[`${i}.mts`,`${i}.ts`,`${i}.mjs`]}else if(o===".cjs"){let i=r.slice(0,-4);n=[`${i}.cts`,`${i}.ts`,`${i}.cjs`]}else o?n=[r]:n=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.js`,`${r}/index.jsx`];return n.find(i=>t.has(k(i)))}var A=class{build(e,t){let r=new P,o=new Map;for(let i of t)for(let a of i.symbols)r.addSymbol(a),a.type==="file"&&o.set(k(i.filePath),a);let n=new Set(o.keys());for(let i of t){let a=k(i.filePath),c=o.get(a);if(c){for(let l of i.symbols)l.id!==c.id&&r.addEdge(this.edge(e,c.id,"DEFINES",l.id));for(let l of i.imports){let p=$e(a,l.source,n);if(!p)continue;let d=o.get(p);d&&r.addEdge(this.edge(e,c.id,"IMPORTS",d.id,{source:l.source}))}for(let l of i.heritage){let p=r.findByName(e,l.targetName).filter(d=>d.type==="class"||d.type==="interface");for(let d of p)r.addEdge(this.edge(e,l.fromId,l.type,d.id))}for(let l of i.calls){if(!l.callerId)continue;let p=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,t,r,n);for(let d of p)d.id!==l.callerId&&r.addEdge(this.edge(e,l.callerId,"CALLS",d.id,{line:l.line,qualifier:l.qualifier}))}}}return r}resolveCallTargets(e,t,r,o,n,i,a){let c=k(t.filePath),l=i.findByName(e,r).filter(p=>k(p.filePath)===c);if(!o&&l.length)return l;if(o)for(let p of t.imports){if(!p.bindings.find(f=>f.kind==="namespace"&&f.localName===o))continue;let u=$e(c,p.source,a);if(u)return i.findByName(e,r).filter(f=>k(f.filePath)===u)}for(let p of t.imports){let d=p.bindings.find(S=>S.localName===r);if(!d)continue;let u=$e(c,p.source,a);if(!u)continue;let f=d.importedName==="default"?r:d.importedName,w=i.findByName(e,f).filter(S=>k(S.filePath)===u);if(w.length)return w}return i.findByName(e,r).filter(p=>p.type==="function"||p.type==="method")}edge(e,t,r,o,n){return{id:nr(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:n}}};function tt(s,e){let t=s.allSymbols(e),r=s.allEdges(e),o=i=>t.filter(a=>a.type===i).length,n=i=>r.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:r.length,calls:n("CALLS"),callReferences:n("CALL_REFERENCE"),imports:n("IMPORTS"),inherits:n("INHERITS"),implements:n("IMPLEMENTS"),usesType:n("USES_TYPE"),tests:n("TESTS"),routeEdges:n("ROUTE"),writes:n("WRITES")}}var X=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)}};function ir(s,e){return e.ranges.length===0?!0:typeof s.startLine!="number"||typeof s.endLine!="number"?!1:e.ranges.some(t=>s.startLine<=t.endLine&&s.endLine>=t.startLine)}var ee=class{constructor(e){this.graph=e}graph;map(e,t){let r=this.graph.allSymbols(e),o=[];for(let n of t){let i=r.filter(l=>l.filePath===n.filePath),c=i.filter(l=>l.type!=="file").filter(l=>ir(l,n));if(c.length===0){let l=i.find(p=>p.type==="file");l&&o.push({symbol:l,fileStatus:n.status,direct:!0});continue}for(let l of c)o.push({symbol:l,fileStatus:n.status,direct:!0})}return o}mapFile(e,t){return this.map(e,[{filePath:t,status:"modified",ranges:[]}])}};var ar={CALLS:4,CALL_REFERENCE:6,USES_TYPE:4,TESTS:2,ROUTE:4,WRITES:3,IMPORTS:3,INHERITS:5,IMPLEMENTS:5,DEFINES:1};function cr(s){return s>=30?"CRITICAL":s>=16?"HIGH":s>=6?"MEDIUM":"LOW"}function rt(s){let e=s.toLowerCase().replaceAll("\\","/");return e.startsWith("tests/")||e.includes("/tests/")||e.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(e)}var te=class{constructor(e){this.graph=e}graph;analyze(e,t,r=4){let o=this.graph.allEdges(e),n=new Map,i=0;for(let p of t){p.fileStatus==="deleted"?i+=8:p.fileStatus==="renamed"?i+=5:i+=2,p.symbol.type==="interface"&&(i+=5),p.symbol.type==="class"&&(i+=3);let d=new Set([p.symbol.id]),u=[{id:p.symbol.id,depth:0}];for(;u.length;){let f=u.shift();if(f.depth>=r)continue;let w=o.filter(S=>S.to===f.id&&["CALLS","CALL_REFERENCE","USES_TYPE","TESTS","ROUTE","WRITES","IMPORTS","INHERITS","IMPLEMENTS","DEFINES"].includes(S.type));for(let S of w){if(d.has(S.from))continue;d.add(S.from);let g=this.graph.getSymbol(S.from);if(!g)continue;let m=f.depth+1,v=`${p.symbol.id}:${g.id}`;n.set(v,{symbol:g,relation:S.type,depth:m,sourceSymbolId:p.symbol.id});let x=ar[S.type]??1;i+=Math.max(1,x-(m-1)),u.push({id:g.id,depth:m})}}}let a=[...n.values()].sort((p,d)=>p.depth-d.depth),c=[...new Set(a.map(p=>p.symbol.filePath))],l=c.filter(rt);return l.length===0&&l.push(...c.filter(p=>!rt(p)).slice(0,10)),{risk:cr(i),riskScore:i,changedSymbols:t,impacted:a,impactedFiles:c,suggestedTests:l}}};import{execFile as lr}from"node:child_process";import{promisify as dr}from"node:util";var Fe=dr(lr);function pr(s){let e=[],t=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm;for(let r of s.matchAll(t)){let o=Number(r[1]),n=Number(r[2]??1);e.push({startLine:o,endLine:Math.max(o,o+n-1)})}return e}function mr(s){return s.startsWith("A")?"added":s.startsWith("D")?"deleted":s.startsWith("R")?"renamed":"modified"}async function st(s){let e="";try{e=(await Fe("git",["diff","HEAD","--name-status","--no-renames"],{cwd:s,maxBuffer:10485760})).stdout}catch{return[]}let t=[];for(let r of e.split(/\r?\n/).filter(Boolean)){let[o,...n]=r.split(" "),i=n.at(-1);if(!i)continue;let a="";try{a=(await Fe("git",["diff","HEAD","--unified=0","--",i],{cwd:s,maxBuffer:20971520})).stdout}catch{a=""}t.push({filePath:i,status:mr(o),ranges:pr(a)})}try{let r=await Fe("git",["ls-files","--others","--exclude-standard"],{cwd:s});for(let o of r.stdout.split(/\r?\n/).filter(Boolean))t.some(n=>n.filePath===o)||t.push({filePath:o,status:"added",ranges:[]})}catch{}return t}var re=class{constructor(e){this.graph=e;this.mapper=new ee(e),this.blast=new te(e)}graph;mapper;blast;async analyzeGitDiff(e,t,r={}){let o=await st(t),n=this.mapper.map(e,o),i=this.blast.analyze(e,n,r.maxDepth??4);return{mode:"git_diff",changes:o,...i}}analyzeFile(e,t,r={}){let o=this.mapper.mapFile(e,t);return{mode:"planned_file",filePath:t,...this.blast.analyze(e,o,r.maxDepth??4)}}};var ur=/(^|[_-])(write|edit|patch|replace|multiedit|create|delete|remove|rename|move)([_-]|$)/i,fr=new Set(["path","filepath","file_path","filename","file","target","targetpath","target_path","sourcepath","source_path"]);function ot(s){return s.trim().replace(/^["']|["']$/g,"").replace(/^a\//,"").replace(/^b\//,"").replaceAll("\\","/")}function gr(s){return s.length>0&&s.length<500&&!s.includes(`
4
+ `)&&/(^|\/)[^/]+\.[A-Za-z0-9]+$/.test(s)}function hr(s){let e=[],t=[/^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/gm,/^\+\+\+\s+b\/(.+)$/gm,/^---\s+a\/(.+)$/gm];for(let r of t)for(let o of s.matchAll(r))o[1]&&e.push(ot(o[1]));return e}function De(s,e,t){if(typeof s=="string"){let r=t?.toLowerCase();if(r&&fr.has(r)&&gr(s)&&e.add(ot(s)),s.includes("*** Update File:")||s.includes("*** Add File:")||s.includes("*** Delete File:")||s.includes("+++ b/"))for(let o of hr(s))e.add(o);return}if(Array.isArray(s)){for(let r of s)De(r,e,t);return}if(s&&typeof s=="object")for(let[r,o]of Object.entries(s))De(o,e,r)}function yr(s){return ur.test(s.toLowerCase())}function nt(s,e){if(!yr(s))return[];let t=new Set;return De(e,t),[...t]}import{createHash as Sr}from"node:crypto";import{readFile as br}from"node:fs/promises";async function it(s){let e=await br(s);return Sr("sha256").update(e).digest("hex")}function at(s,e){let t=s?.files??{},r=e.files,o=[],n=[],i=[],a=[];for(let[c,l]of Object.entries(r)){let p=t[c];p?p.hash!==l.hash?n.push(c):a.push(c):o.push(c)}for(let c of Object.keys(t))r[c]||i.push(c);return{added:o.sort(),modified:n.sort(),deleted:i.sort(),unchanged:a.sort()}}import{join as vr}from"node:path";async function ct(s,e){let t=await Ne(e),r={};for(let o of t)r[o]={path:o,hash:await it(vr(e,o))};return{version:1,projectId:s,updatedAt:new Date().toISOString(),files:r}}var T=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 se=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 oe=class{constructor(e){this.storage=e}storage;async index(e,t){let r=new se(this.storage),o=new T(this.storage),n=await r.load(e),i=await o.load(e),a=await ct(e,t),c=at(n,a),l=[...c.added,...c.modified];if(n&&i&&l.length===0&&c.deleted.length===0)return{firstRun:!1,scanned:Object.keys(a.files).length,parsed:0,added:0,modified:0,deleted:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,saved:!1};let p=i?.symbols.filter(g=>c.unchanged.includes(g.filePath))??[],d=[];for(let g of l)d.push(await _e(e,t,g));let u=new A().build(e,d),f=new P;for(let g of p)f.addSymbol(g);for(let g of u.allSymbols(e))f.addSymbol(g);let w=new Set(f.allSymbols(e).map(g=>g.id));for(let g of i?.edges??[])w.has(g.from)&&w.has(g.to)&&!l.includes(i.symbols.find(m=>m.id===g.from)?.filePath??"")&&!l.includes(i.symbols.find(m=>m.id===g.to)?.filePath??"")&&f.addEdge(g);for(let g of u.allEdges(e))f.addEdge(g);let S={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(a.files).length,symbols:f.allSymbols(e),edges:f.allEdges(e)};return await o.save(S),await r.save(a),{firstRun:n===null,scanned:Object.keys(a.files).length,parsed:l.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,unchanged:c.unchanged.length,symbols:S.symbols.length,edges:S.edges.length,saved:!0}}};var L=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[r,o]of this.records)o.projectId===e&&(this.records.delete(r),t++);return t}exportProject(e){return[...this.records.values()].filter(t=>t.projectId===e)}importRecords(e){let t=0;for(let r of e)!r?.id||!r?.projectId||!Array.isArray(r.vector)||(this.records.set(r.id,r),t++);return t}search(e,t,r=10){let o=[];for(let n of this.records.values()){if(n.projectId!==e)continue;let i=xr(t,n.vector);o.push({id:n.id,score:i,metadata:n.metadata})}return o.sort((n,i)=>i.score-n.score).slice(0,r)}size(){return this.records.size}};function xr(s,e){if(s.length===0||e.length===0||s.length!==e.length)return 0;let t=0,r=0,o=0;for(let n=0;n<s.length;n++){let i=s[n]??0,a=e[n]??0;t+=i*a,r+=i*i,o+=a*a}return r===0||o===0?0:t/(Math.sqrt(r)*Math.sqrt(o))}import*as E from"typescript";import*as y from"typescript";var Xn=new Set([y.SyntaxKind.EqualsToken,y.SyntaxKind.PlusEqualsToken,y.SyntaxKind.MinusEqualsToken,y.SyntaxKind.AsteriskEqualsToken,y.SyntaxKind.SlashEqualsToken,y.SyntaxKind.PercentEqualsToken,y.SyntaxKind.QuestionQuestionEqualsToken,y.SyntaxKind.AmpersandAmpersandEqualsToken,y.SyntaxKind.BarBarEqualsToken]);var ne=class{constructor(e,t){this.embeddings=e;this.store=t}embeddings;store;async index(e){let t=e.filter(n=>!this.store.has(n.id));if(t.length===0)return 0;let r=await this.embeddings.embedMany(t.map(n=>[n.type,n.content,...n.tags??[]].join(" "))),o=0;for(let n=0;n<t.length;n++){let i=t[n],a=r[n];!i||!a||(this.store.upsert({id:i.id,projectId:i.projectId,vector:a,metadata:{type:i.type,updatedAt:i.updatedAt}}),o++)}return o}};var N=class{constructor(e,t,r,o,n){this.projectId=e;this.model=t;this.embeddings=r;this.store=o;this.persistence=n}projectId;model;embeddings;store;persistence;async initialize(e){let t=0,r=await this.persistence.load(this.projectId);r&&r.model===this.model&&(t=this.store.importRecords(r.records));let o=new Set(e.map(d=>d.id)),n=0;for(let d of this.store.exportProject(this.projectId))o.has(d.id)||this.store.remove(d.id)&&n++;let a=await new ne(this.embeddings,this.store).index(e),c=this.store.exportProject(this.projectId),l=c[0]?.vector.length??this.embeddings.dimensions??0,p=!1;return(a>0||n>0||!r)&&(await this.persistence.save({version:1,projectId:this.projectId,model:this.model,dimensions:l,updatedAt:new Date().toISOString(),records:c}),p=!0),{loaded:t,indexed:a,removed:n,total:c.length,saved:p}}};var ie=class{events=[];push(e){this.events.push(e)}drain(){let e=[...this.events];return this.events.length=0,e}list(){return[...this.events]}size(){return this.events.length}shouldFlush(e){return this.events.length>=e}};import{createHash as Er}from"node:crypto";var ae=class{seen=new Set;fingerprint(e){return Er("sha256").update(JSON.stringify({projectId:e.projectId,type:e.type,data:e.data})).digest("hex")}filter(e){let t=[];for(let r of e){let o=this.fingerprint(r);this.seen.has(o)||(this.seen.add(o),t.push(r))}return t}clear(){this.seen.clear()}};import{randomUUID as Cr}from"node:crypto";var ce=class{constructor(e){this.queue=e}queue;sanitizer=new j;capture(e,t,r={}){let o={id:Cr(),projectId:e,type:t,timestamp:new Date().toISOString(),data:this.sanitizer.sanitizeValue(r)};return this.queue.push(o),o}};import{randomUUID as Pr}from"node:crypto";var le=class{constructor(e){this.capture=e}capture;sessionId=Pr();start(e){return this.capture.capture(e,"session_start",{sessionId:this.sessionId})}end(e){return this.capture.capture(e,"session_end",{sessionId:this.sessionId})}};var de=class{extract(e){switch(e.type){case"decision":return{type:"decision",content:String(e.data.content??"Decision recorded"),tags:["decision"],source:"auto-extractor",metadata:e.data};case"todo":return{type:"todo",content:String(e.data.content??"TODO recorded"),tags:["todo"],source:"auto-extractor",metadata:e.data};case"error":return{type:"activity",content:`Error: ${String(e.data.message??"")}`,tags:["error"],source:"auto-extractor",metadata:e.data};case"file_write":return{type:"activity",content:`Modified file: ${String(e.data.filePath??"")}`,tags:["file","write"],source:"auto-extractor",metadata:e.data};case"command":return{type:"activity",content:`Command: ${String(e.data.command??"")}`,tags:["command"],source:"auto-extractor",metadata:e.data};case"session_start":case"session_end":case"file_read":case"tool_call":case"user_prompt":case"test":case"commit":case"deploy":return null;default:return null}}};function Ge(s){let e=s.toLowerCase();return["kh\xF4ng \u0111\u01B0\u1EE3c","b\u1EAFt bu\u1ED9c","ph\u1EA3i lu\xF4n","tuy\u1EC7t \u0111\u1ED1i","never ","must ","always ","do not "].some(t=>e.includes(t))}function ze(s){let e=s.toLowerCase();return["quy\u1EBFt \u0111\u1ECBnh","ch\u1ECDn ","s\u1EED d\u1EE5ng ","d\xF9ng ","decided","decision","we will use","use "].some(t=>e.includes(t))}function Ke(s){let e=s.toLowerCase();return["todo","c\u1EA7n l\xE0m","ch\u01B0a xong","c\xF2n ph\u1EA3i","next:","next step","pending"].some(t=>e.includes(t))}function pe(s,e){let t=e.toLowerCase();return t.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||t.includes("tuy\u1EC7t \u0111\u1ED1i")||t.includes("must not")||t.includes("never ")?"critical":s==="rule"||s==="decision"?"high":s==="todo"||t.includes("error")||t.includes("failed")||t.includes("exception")?"normal":"temporary"}function O(s){return[...new Set(s.filter(Boolean))]}function me(s,e=120){return s.length>e?`${s.slice(0,e)}\u2026`:s}var ue=class{summarize(e){if(e.length===0)return null;let t=O(e.filter(c=>c.type==="file_write").map(c=>String(c.data.filePath??""))),r=O(e.filter(c=>c.type==="command").map(c=>me(String(c.data.command??"")))),o=O(e.filter(c=>c.type==="error").map(c=>me(String(c.data.message??"")))),n=O(e.filter(c=>c.type==="decision").map(c=>me(String(c.data.content??"")))),i=O(e.filter(c=>c.type==="todo").map(c=>me(String(c.data.content??""))));if(t.length===0&&r.length===0&&o.length===0&&n.length===0&&i.length===0)return null;let a=["Session summary:"];return t.length&&a.push(`- Files changed (${t.length}): ${t.slice(0,10).join(", ")}`),r.length&&a.push(`- Commands (${r.length}): ${r.slice(0,5).join("; ")}`),o.length&&a.push(`- Errors (${o.length}): ${o.slice(0,5).join("; ")}`),n.length&&a.push(`- Decisions: ${n.slice(0,5).join("; ")}`),i.length&&a.push(`- TODO: ${i.slice(0,5).join("; ")}`),a.join(`
5
+ `)}};var fe=class{constructor(e){this.memory=e}memory;extractor=new de;summarizer=new ue;process(e){let t=0;for(let o of e){let n=this.extractor.extract(o);if(n){let i=this.refineType(n.type,n.content);this.memory.remember({projectId:o.projectId,type:i,content:n.content,importance:pe(i,n.content),tags:n.tags,source:n.source,metadata:{eventId:o.id,timestamp:o.timestamp,...n.metadata}}),t++}if(o.type==="user_prompt"){let i=String(o.data.content??""),a=this.detectPromptMemoryType(i);a&&(this.memory.remember({projectId:o.projectId,type:a,content:i,importance:pe(a,i),tags:["user",a],source:"auto-prompt-extractor",metadata:{eventId:o.id,timestamp:o.timestamp}}),t++)}}let r=this.summarizer.summarize(e);if(r){let o=e[0]?.projectId;o&&(this.memory.remember({projectId:o,type:"summary",content:r,importance:"temporary",tags:["summary"],source:"auto-summary",metadata:{eventCount:e.length}}),t++)}return t}refineType(e,t){return Ge(t)?"rule":Ke(t)?"todo":ze(t)?"decision":e}detectPromptMemoryType(e){return Ge(e)?"rule":Ke(e)?"todo":ze(e)?"decision":null}};import{createHash as kr}from"node:crypto";function jr(s){return kr("sha256").update([s.projectId,s.type,s.content.trim().toLowerCase()].join("|")).digest("hex")}function lt(s){let e=new Set,t=[];for(let r of s){let o=jr(r);e.has(o)||(e.add(o),t.push(r))}return t}var ge=class{projectId;memory;memoryStore;queue=new ie;capture=new ce(this.queue);session=new le(this.capture);processor;dedup=new ae;maxEventsBeforeFlush;constructor(e){this.projectId=e.projectId,this.memory=e.memory,this.memoryStore=e.memoryStore,this.maxEventsBeforeFlush=e.maxEventsBeforeFlush??100,this.processor=new fe(this.memory)}async sessionStart(){this.session.start(this.projectId),await this.flushIfNeeded()}async sessionEnd(){this.session.end(this.projectId),await this.flush()}async userPrompt(e){this.capture.capture(this.projectId,"user_prompt",{content:e}),await this.flushIfNeeded()}async beforeTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"before",tool:e,input:t}),await this.flushIfNeeded()}async afterTool(e,t){this.capture.capture(this.projectId,"tool_call",{phase:"after",tool:e,output:t}),await this.flushIfNeeded()}async fileRead(e){this.capture.capture(this.projectId,"file_read",{filePath:e}),await this.flushIfNeeded()}async fileWrite(e){this.capture.capture(this.projectId,"file_write",{filePath:e}),await this.flushIfNeeded()}async command(e,t){this.capture.capture(this.projectId,"command",{command:e,exitCode:t}),await this.flushIfNeeded()}async error(e){let t=e instanceof Error?e.message:String(e);this.capture.capture(this.projectId,"error",{message:t}),await this.flushIfNeeded()}async decision(e,t={}){this.capture.capture(this.projectId,"decision",{content:e,...t}),await this.flushIfNeeded()}async todo(e,t={}){this.capture.capture(this.projectId,"todo",{content:e,...t}),await this.flushIfNeeded()}async flushIfNeeded(){this.queue.shouldFlush(this.maxEventsBeforeFlush)&&await this.flush()}async flush(){let e=this.queue.drain();if(e.length===0)return 0;let t=this.dedup.filter(e);if(t.length===0)return 0;let r=this.processor.process(t),o=lt(this.memory.exportProject(this.projectId));return this.memory.clearProject(this.projectId),this.memory.importRecords(o),await this.memoryStore.save(this.projectId,o),r}pendingEvents(){return this.queue.size()}};var he=class{constructor(e,t,r){this.memory=e;this.retrieval=t;this.graph=r}memory;retrieval;graph;build(e,t,r={}){let o=r.maxRules??3,n=r.maxTodos??3,i=r.maxDecisions??3,a=r.maxRelevant??5,c=r.maxCharacters??7e3,l=this.memory.byType(e,"rule").slice(0,o),p=this.memory.byType(e,"todo").slice(0,n),d=this.memory.byType(e,"decision").slice(0,i),u=this.retrieval.search(e,t,{topK:a}),f=tt(this.graph,e),w=[];w.push(["[PROJECT]",`files=${f.files}`,`classes=${f.classes}`,`functions=${f.functions}`,`methods=${f.methods}`,`calls=${f.calls}`].join(" "));for(let g of l)w.push(`[RULE] ${g.content}`);for(let g of d)w.push(`[DECISION] ${g.content}`);for(let g of p)w.push(`[TODO] ${g.content}`);for(let g of u){let v=`[${g.memory.type.toUpperCase()}] ${g.memory.content}`;w.includes(v)||w.push(v)}let S="";for(let g of w){let m=S.length===0?g:`${S}
6
+ ${g}`;if(m.length>c)break;S=m}return S}};var ye=class{constructor(e,t,r){this.runtime=e;this.builder=t;this.projectId=r}runtime;builder;projectId;async prepare(e){await this.runtime.userPrompt(e);let t=this.builder.build(this.projectId,e);return{originalPrompt:e,context:t,augmentedPrompt:t?["<toolnet_memory>",t,"</toolnet_memory>","",e].join(`
7
+ `):e}}};var dt={LOW:0,MEDIUM:1,HIGH:2,CRITICAL:3},Se=class{constructor(e,t){this.guard=e;this.projectId=t}guard;projectId;async beforeTool(e,t){let r=nt(e,t);if(r.length===0)return{triggered:!1,tool:e,highestRisk:"LOW",totalRiskScore:0,files:[],impactedFiles:[],suggestedTests:[],requiresVerification:!1,context:""};let o=[];for(let d of r){let u=this.guard.analyzeFile(this.projectId,d);o.push({filePath:d,risk:u.risk,riskScore:u.riskScore,impactedFiles:u.impactedFiles,suggestedTests:u.suggestedTests,impactedCount:u.impacted.length})}let n="LOW";for(let d of o)dt[d.risk]>dt[n]&&(n=d.risk);let i=[...new Set(o.flatMap(d=>d.impactedFiles))],a=[...new Set(o.flatMap(d=>d.suggestedTests))],c=o.reduce((d,u)=>d+u.riskScore,0),l=n==="HIGH"||n==="CRITICAL",p=["[TOOLNET IMPACT GUARD]",`Risk: ${n}`,`Risk score: ${c}`,`Files being changed: ${r.join(", ")}`,`Impacted files: ${i.length}`];return i.length&&p.push("Blast radius:",...i.slice(0,20).map(d=>`- ${d}`)),a.length&&p.push("Verify/tests:",...a.slice(0,15).map(d=>`- ${d}`)),l&&p.push("IMPORTANT: High blast radius. Inspect affected dependencies and run relevant tests after the edit."),{triggered:!0,tool:e,highestRisk:n,totalRiskScore:c,files:o,impactedFiles:i,suggestedTests:a,requiresVerification:l,context:p.join(`
8
+ `)}}};import{homedir as Yr}from"node:os";import{join as Qr}from"node:path";import{DeleteObjectCommand as Rr,GetObjectCommand as Tr,HeadObjectCommand as Ir,ListObjectsV2Command as Mr,PutObjectCommand as Ar,S3Client as Lr}from"@aws-sdk/client-s3";import{getSignedUrl as Nr}from"@aws-sdk/s3-request-presigner";var be=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Lr({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ar({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Nr(this.client,new Tr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.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 Ir({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 Rr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Mr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as pt,mkdir as Or,readFile as _r,readdir as $r,rm as Fr,stat as mt,writeFile as Dr}from"node:fs/promises";import{dirname as Gr,join as zr,relative as ut,resolve as Kr}from"node:path";var _=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Kr(this.root,t)}async put(e,t){let r=this.path(e);await Or(Gr(r),{recursive:!0}),await Dr(r,t)}async get(e){try{return await _r(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 pt(this.path(e)),!0}catch{return!1}}async delete(e){await Fr(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await pt(t)}catch{return r}let o=async i=>{let a=await $r(i,{withFileTypes:!0});for(let c of a){let l=zr(i,c.name);if(c.isDirectory()){await o(l);continue}let p=await mt(l);r.push({key:ut(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await mt(t);return n.isDirectory()?await o(t):r.push({key:ut(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as Br,GetObjectCommand as Hr,HeadObjectCommand as Wr,ListObjectsV2Command as Ur,PutObjectCommand as Vr,S3Client as qr}from"@aws-sdk/client-s3";import{getSignedUrl as Jr}from"@aws-sdk/s3-request-presigner";var $=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new qr({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Vr({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Jr(this.client,new Hr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.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 Wr({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 Br({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Ur({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function Be(s,e){return console.warn(e),new _(s)}function ft(s){let e=s.localRoot??Qr(Yr(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(s.provider==="s3"){let t=s.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(e,"[storage] S3 credentials missing. Using local fallback.")}if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new be({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Be(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new _(e)}var I=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 r=JSON.parse(t);if(!Array.isArray(r))throw new Error("Invalid memory snapshot");return r}async save(e,t){let r=JSON.stringify(t,null,2);await this.storage.put(this.key(e),r,"application/json")}};var ve=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 r=JSON.parse(t);if(r.version!==1||r.projectId!==e||!Array.isArray(r.records))throw new Error("Invalid vector snapshot");return r}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function Zr(s){return new Promise(e=>setTimeout(e,s))}async function gt(s,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await s()}catch(a){if(n=a,i>=t)break;let c=Math.min(o,r*2**(i-1)),l=Math.floor(Math.random()*Math.max(1,c*.2));await Zr(c+l)}throw n}var Xr=new Set(["put","get","getText","delete","list"]);function ht(s,e={}){return new Proxy(s,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:Xr.has(r)?(...n)=>gt(()=>Promise.resolve(o.apply(t,n)),e):o.bind(t)}})}function yt(s){let e=s.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}function St(s){let e=s.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[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 xe=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=yt(o??r),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(),r=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"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
9
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=St(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,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}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))}};function ts(s){let e=s.metadata?.learningFingerprint;return typeof e=="string"?e:void 0}async function rs(s,e){let t=`projects/${s.id}/memory/learned/`,r=await e.list(t),o=[];for(let n of r.filter(i=>i.key.includes("/batches/")&&i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(n.key);if(i)try{let a=JSON.parse(i);if(a.version!==1||!Array.isArray(a.candidates))continue;o.push(a)}catch{}}return o}async function bt(s,e){let t=await rs(s,e),r=new I(e),o=await r.load(s.id),n=new R;n.importRecords(o);let i=new Set(o.map(p=>ts(p)).filter(p=>!!p)),a=0,c=0,l=0;for(let p of t)for(let d of p.candidates){if(a+=1,i.has(d.fingerprint)){l+=1;continue}n.remember({projectId:s.id,type:d.type,content:d.content,importance:d.importance,tags:d.tags,source:"session-memory-learner",metadata:{learningFingerprint:d.fingerprint,learningKind:d.kind,confidence:d.confidence,provenance:d.provenance,sourceCreatedAt:d.createdAt,sessionKey:d.sessionKey,agent:d.agent,nativeSessionId:d.nativeSessionId}}),i.add(d.fingerprint),c+=1}return c>0&&await r.save(s.id,n.exportProject(s.id)),{batches:t.length,candidates:a,added:c,duplicates:l,memories:n.exportProject(s.id).length}}var ss=["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"],we=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",r){let o=new Date().toISOString(),n=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,n),c=[];for(let p of ss){let d=`${i}/${p}`,u=await this.storage.get(d);u&&(await this.storage.put(`${a}/${p}`,u,"application/json"),c.push(p))}if(c.length===0)return null;let l={version:1,id:n,projectId:e,createdAt:o,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(l,null,2),"application/json"),l}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),n=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{n.push(JSON.parse(a))}catch{}}return n.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.getText(`${r}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let n=JSON.parse(o);if(n.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of n.objects){let l=await this.storage.get(`${r}/${c}`);l&&(await this.storage.put(`${i}/${c}`,l,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.list(r);for(let n of o)await this.storage.delete(n.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),n=0;for(let i of o)await this.remove(e,i.id),n++;return n}};import{closeSync as os,mkdirSync as ns,openSync as is,readFileSync as as,unlinkSync as vt,writeFileSync as cs}from"node:fs";import{tmpdir as ls}from"node:os";import{join as xt}from"node:path";function ds(s){try{return process.kill(s,0),!0}catch(e){return e?.code==="EPERM"}}var Ee=class{acquired=!1;path;exitHandler=()=>{this.releaseSync()};constructor(e){let t=xt(ls(),"toolnet-memory-locks");ns(t,{recursive:!0});let r=e.replace(/[^A-Za-z0-9_.-]/g,"_");this.path=xt(t,`${r}.lock`)}async acquire(){if(!this.acquired){for(let e=0;e<2;e++)try{let t=is(this.path,"wx");cs(t,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()})),os(t),this.acquired=!0,process.once("exit",this.exitHandler);return}catch(t){if(t?.code!=="EEXIST")throw t;let r=!0;try{let o=JSON.parse(as(this.path,"utf8"));Number.isInteger(o.pid)&&ds(o.pid)&&(r=!1)}catch{r=!0}if(!r)throw new Error("ToolNet Memory is already running for this project");try{vt(this.path)}catch{}}throw new Error("Unable to acquire ToolNet Memory project lock")}}async release(){this.releaseSync()}releaseSync(){if(this.acquired){try{vt(this.path)}catch{}this.acquired=!1,process.off("exit",this.exitHandler)}}};var Ce=class{constructor(e){this.options=e;this.memoryStore=new I(e.storage),this.graphStore=new T(e.storage),this.vectorStore=new ve(e.storage),this.processLock=new Ee(e.project.id),this.retrieval=new Y(this.memory),this.references=new X(this.graph),this.hooks=new ge({projectId:e.project.id,memory:this.memory,memoryStore:this.memoryStore,maxEventsBeforeFlush:100});let t=new he(this.memory,this.retrieval,this.graph);this.autoRetrieval=new ye(this.hooks,t,e.project.id),this.impactGuard=new re(this.graph),this.autoImpactGuard=new Se(this.impactGuard,e.project.id)}options;memory=new R;graph=new P;vectors=new L;retrieval;references;hooks;autoRetrieval;impactGuard;autoImpactGuard;memoryStore;graphStore;vectorStore;processLock;async start(){let{project:e}=this.options;await this.processLock.acquire(),await bt(e,this.options.storage);let t=await this.memoryStore.load(e.id);this.memory.importRecords(t);let o=new B(this.memory).run(e.id);(o.expiredRemoved>0||o.supersededRemoved>0)&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let n=await this.graphStore.load(e.id);n&&this.graph.import(n.symbols,n.edges);let i=Ae(),c=await new N(e.id,this.options.embeddingModel,i,this.vectors,this.vectorStore).initialize(this.memory.list(e.id));return await this.hooks.sessionStart(),{memories:t.length,graphSymbols:this.graph.allSymbols(e.id).length,graphEdges:this.graph.allEdges(e.id).length,vectors:c.total,vectorsIndexed:c.indexed}}async preparePrompt(e){return this.autoRetrieval.prepare(e)}async beforeTool(e,t){let r=await this.autoImpactGuard.beforeTool(e,t);return await this.hooks.beforeTool(e,t),r}async afterTool(e,t){return this.hooks.afterTool(e,t)}async stop(){let{project:e,storage:t,embeddingModel:r}=this.options,o=new we(t),n=await o.create(e.id,"session-end-auto");await o.prune(e.id,10),await this.hooks.sessionEnd();let i=new H(this.memory).consolidate(e.id);i.summaryCreated&&await this.memoryStore.save(e.id,this.memory.exportProject(e.id));let a=await new oe(t).index(e.id,e.rootPath),c=await this.graphStore.load(e.id);c&&(this.graph.clearProject(e.id),this.graph.import(c.symbols,c.edges));let l=Ae(),d=await new N(e.id,r,l,this.vectors,this.vectorStore).initialize(this.memory.list(e.id)),u={code:a,vectors:d,consolidation:i,snapshot:n?.id,memories:this.memory.list(e.id).length};return await this.processLock.release(),u}};import"dotenv/config";import{existsSync as ps,readFileSync as ms}from"node:fs";import{homedir as us}from"node:os";import{join as fs}from"node:path";function gs(s){let e=s.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
10
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function hs(){let s=process.env.TOOLNET_GLOBAL_ENV??fs(us(),".config","toolnet-memory",".env");if(!ps(s))return;let e=ms(s,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let n=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(n)&&process.env[n]===void 0&&(process.env[n]=gs(r.slice(o+1)))}}hs();function F(s,e){return s===void 0?e:["1","true","yes","on"].includes(s.toLowerCase())}function D(s,e){if(!s)return e;let t=Number(s);return Number.isFinite(t)?t:e}function wt(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:D(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:D(process.env.MEMORY_RERANK_TOP,10),finalContext:D(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:D(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:F(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:D(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ys}from"node:crypto";import{existsSync as He,mkdirSync as Ss,readFileSync as bs,renameSync as vs,writeFileSync as xs}from"node:fs";import{basename as ws,dirname as Pe,join as je,parse as Pt,resolve as G}from"node:path";var kt=".toolnet",Es="project.json";function Cs(s){return ys("sha256").update(s).digest("hex").slice(0,16)}function We(s){return je(s,kt,Es)}function Ps(s){return He(We(s))}function ks(s,e){let t=G(s),r=Pt(t).root;for(;;){if(Ps(t))return t;if(t===r||e&&t===G(e))break;let o=Pe(t);if(o===t)break;t=o}return null}function js(s){let e=G(s),t=Pt(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(n=>He(je(e,n))))return e;if(e===t)break;let o=Pe(e);if(o===e)break;e=o}return G(s)}function Rs(s){let e;try{e=JSON.parse(bs(s,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${s}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${s}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${s}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${s}`);let r=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:Pe(Pe(s)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,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 Et(s,e){let t=je(s,kt);Ss(t,{recursive:!0});let r=We(s),o=`${r}.tmp-${process.pid}`;xs(o,JSON.stringify(e,null,2)+`
11
+ `,{encoding:"utf8",mode:384}),vs(o,r)}function Ct(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var ke=class{detect(e=process.cwd()){let t=G(e),r=js(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>He(je(r,p))),i=ks(t,n?r:void 0);if(i){let p=We(i),d=Rs(p);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Et(i,d)),Ct(d,i)}let a=new Date().toISOString(),c=ws(r),l={version:1,id:Cs(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Et(r,l),Ct(l,r)}};function jt(s=process.cwd()){let e=wt(),t=new ke().detect(s),r=ft({provider:e.storage.provider,r2:e.storage.r2,s3:e.storage.s3,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),o=ht(r,{attempts:Number(process.env.TOOLNET_STORAGE_RETRIES??3)}),n=new xe(o,t.id,t.name,t.remote??t.name),i=process.env.HF_EMBEDDING_MODEL??"sentence-transformers/all-MiniLM-L6-v2";return new Ce({project:t,storage:n,embeddingModel:i})}async function Ts(){let s=jt(),e=await s.start(),t=await s.preparePrompt("Ti\u1EBFp t\u1EE5c c\xF4ng vi\u1EC7c hi\u1EC7n t\u1EA1i");console.log({started:!0,...e,contextCharacters:t.context.length});let r=await s.stop();console.log({stopped:!0,memories:r.memories,codeParsed:r.code.parsed,vectorsIndexed:r.vectors.indexed})}Ts().catch(s=>{console.error(s),process.exit(1)});