toolnet-memory 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/agy.js CHANGED
@@ -1,26 +1,54 @@
1
- import{existsSync as Mt,readFileSync as Tt}from"node:fs";import{homedir as Rt}from"node:os";import{join as Ct}from"node:path";function Nt(t){let e=t.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 _t(){let t=process.env.TOOLNET_GLOBAL_ENV??Ct(Rt(),".config","toolnet-memory",".env");if(!Mt(t))return;let e=Tt(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=Nt(r.slice(s+1)))}}_t();function K(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function F(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function q(){return{memory:{autoCapture:K(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:K(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:K(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:K(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:F(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:F(process.env.MEMORY_RERANK_TOP,10),finalContext:F(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:F(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:K(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:F(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as $t}from"node:crypto";import{existsSync as de,mkdirSync as Lt,readFileSync as Kt,renameSync as Ft,writeFileSync as zt}from"node:fs";import{basename as Dt,dirname as J,join as U,parse as Ee,resolve as z}from"node:path";var Ae=".toolnet",Wt="project.json";function Bt(t){return $t("sha256").update(t).digest("hex").slice(0,16)}function fe(t){return U(t,Ae,Wt)}function qt(t){return de(fe(t))}function Jt(t,e){let n=z(t),r=Ee(n).root;for(;;){if(qt(n))return n;if(n===r||e&&n===z(e))break;let s=J(n);if(s===n)break;n=s}return null}function Vt(t){let e=z(t),n=Ee(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>de(U(e,o))))return e;if(e===n)break;let s=J(e);if(s===e)break;e=s}return z(t)}function Ut(t){let e;try{e=JSON.parse(Kt(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:J(J(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function Pe(t,e){let n=U(t,Ae);Lt(n,{recursive:!0});let r=fe(t),s=`${r}.tmp-${process.pid}`;zt(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Ft(s,r)}function Oe(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var V=class{detect(e=process.cwd()){let n=z(e),r=Vt(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>de(U(r,d))),i=Jt(n,o?r:void 0);if(i){let d=fe(i),l=Ut(d);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Pe(i,l)),Oe(l,i)}let c=new Date().toISOString(),u=Dt(r),a={version:1,id:Bt(r),name:u,remote:u,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return Pe(r,a),Oe(a,r)}};var Ht=[{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}],H=class{scan(e){let n=[];for(let r of Ht){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var D=class{scanner=new H;sanitize(e){let n=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as Sn}from"node:os";import{join as vn}from"node:path";import{DeleteObjectCommand as Yt,GetObjectCommand as Gt,HeadObjectCommand as Xt,ListObjectsV2Command as Zt,PutObjectCommand as Qt,S3Client as en}from"@aws-sdk/client-s3";import{getSignedUrl as tn}from"@aws-sdk/s3-request-presigner";var Y=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new en({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,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Qt({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await tn(this.client,new Gt({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{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 n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Xt({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Yt({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Zt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as Me,mkdir as nn,readFile as rn,readdir as sn,rm as on,stat as Te,writeFile as an}from"node:fs/promises";import{dirname as cn,join as un,relative as Re,resolve as ln}from"node:path";var W=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return ln(this.root,n)}async put(e,n){let r=this.path(e);await nn(cn(r),{recursive:!0}),await an(r,n)}async get(e){try{return await rn(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await Me(this.path(e)),!0}catch{return!1}}async delete(e){await on(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Me(n)}catch{return r}let s=async i=>{let c=await sn(i,{withFileTypes:!0});for(let u of c){let a=un(i,u.name);if(u.isDirectory()){await s(a);continue}let d=await Te(a);r.push({key:Re(this.root,a),size:d.size,updatedAt:d.mtime.toISOString()})}},o=await Te(n);return o.isDirectory()?await s(n):r.push({key:Re(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as pn,GetObjectCommand as dn,HeadObjectCommand as fn,ListObjectsV2Command as mn,PutObjectCommand as gn,S3Client as yn}from"@aws-sdk/client-s3";import{getSignedUrl as hn}from"@aws-sdk/s3-request-presigner";var B=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new yn({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,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new gn({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await hn(this.client,new dn({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{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 n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new fn({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new pn({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new mn({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function me(t,e){return console.warn(e),new W(t)}function Ce(t){let e=t.localRoot??vn(Sn(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new B({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):me(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new B({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):me(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Y({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):me(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new W(e)}function bn(t){return new Promise(e=>setTimeout(e,t))}async function Ne(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(c){if(o=c,i>=n)break;let u=Math.min(s,r*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,u*.2));await bn(u+a)}throw o}var kn=new Set(["put","get","getText","delete","list"]);function _e(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:kn.has(r)?(...o)=>Ne(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function $e(t){let e=t.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 Le(t){let e=t.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 n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[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 G=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=$e(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}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 o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Le(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,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,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))}};import{homedir as xe}from"node:os";import{join as xt,resolve as as}from"node:path";import{join as En}from"node:path";import{createHash as wn}from"node:crypto";import{dirname as xn}from"node:path";import{mkdirSync as jn,readFileSync as In,renameSync as Pn,writeFileSync as On}from"node:fs";function v(t){return wn("sha256").update(t).digest("hex")}function ge(t){if(Array.isArray(t))return t.map(ge);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=ge(e[r]);return n}return t}function Ke(t){return JSON.stringify(ge(t))}function Fe(t){try{return JSON.parse(In(t,"utf8"))}catch{return null}}function O(t,e){jn(xn(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;On(n,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),Pn(n,t)}function ze(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function De(t,e,n){let r=e.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=ze(r.toLowerCase(),"agent"),i=ze(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:En(t.rootPath,".toolnet","sessions",o,i)}}function We(t){return String(t).padStart(12,"0")}var X=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
6
- `,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let c=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!c)continue;let u=Number(c[1]),a=Number(c[2]);!Number.isFinite(u)||!Number.isFinite(a)||(s.push({key:i.key,start:u,end:a}),o=Math.max(o,a))}return s.sort((i,c)=>i.start-c.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
7
- `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),c=n.filter(g=>g.sequence>i.maxSequence),u=0;for(let g of this.split(c)){let h=g[0],b=g[g.length-1],M=g.map(T=>JSON.stringify(T)).join(`
1
+ import{existsSync as ms,readFileSync as fs}from"node:fs";import{homedir as gs}from"node:os";import{join as ys}from"node:path";function hs(t){let e=t.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 Ss(){let t=process.env.TOOLNET_GLOBAL_ENV??ys(gs(),".config","toolnet-memory",".env");if(!ms(t))return;let e=fs(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=hs(r.slice(s+1)))}}Ss();function ie(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function ae(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function be(){return{memory:{autoCapture:ie(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ie(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ie(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ie(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ae(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ae(process.env.MEMORY_RERANK_TOP,10),finalContext:ae(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ae(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:ie(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:ae(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ks}from"node:crypto";import{existsSync as ut,mkdirSync as vs,readFileSync as ws,renameSync as bs,writeFileSync as xs}from"node:fs";import{basename as As,dirname as xe,join as je,parse as Lt,resolve as ce}from"node:path";var Dt=".toolnet",js="project.json";function Is(t){return ks("sha256").update(t).digest("hex").slice(0,16)}function lt(t){return je(t,Dt,js)}function Cs(t){return ut(lt(t))}function Ps(t,e){let n=ce(t),r=Lt(n).root;for(;;){if(Cs(n))return n;if(n===r||e&&n===ce(e))break;let s=xe(n);if(s===n)break;n=s}return null}function Ms(t){let e=ce(t),n=Lt(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>ut(je(e,o))))return e;if(e===n)break;let s=xe(e);if(s===e)break;e=s}return ce(t)}function Es(t){let e;try{e=JSON.parse(ws(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:xe(xe(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function Wt(t,e){let n=je(t,Dt);vs(n,{recursive:!0});let r=lt(t),s=`${r}.tmp-${process.pid}`;xs(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),bs(s,r)}function Ft(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var Ae=class{detect(e=process.cwd()){let n=ce(e),r=Ms(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>ut(je(r,p))),i=Ps(n,o?r:void 0);if(i){let p=lt(i),m=Es(p);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),Wt(i,m)),Ft(m,i)}let a=new Date().toISOString(),c=As(r),u={version:1,id:Is(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Wt(r,u),Ft(u,r)}};var Os=[{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}],Ie=class{scan(e){let n=[];for(let r of Os){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var J=class{scanner=new Ie;sanitize(e){let n=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as eo}from"node:os";import{join as to}from"node:path";import{DeleteObjectCommand as Ts,GetObjectCommand as Rs,HeadObjectCommand as Ns,ListObjectsV2Command as _s,PutObjectCommand as Ks,S3Client as $s}from"@aws-sdk/client-s3";import{getSignedUrl as Ws}from"@aws-sdk/s3-request-presigner";var Ce=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new $s({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,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Ks({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Ws(this.client,new Rs({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{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 n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Ns({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Ts({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new _s({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as zt,mkdir as Fs,readFile as Ls,readdir as Ds,rm as zs,stat as qt,writeFile as qs}from"node:fs/promises";import{dirname as Bs,join as Vs,relative as Bt,resolve as Js}from"node:path";var ue=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Js(this.root,n)}async put(e,n){let r=this.path(e);await Fs(Bs(r),{recursive:!0}),await qs(r,n)}async get(e){try{return await Ls(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await zt(this.path(e)),!0}catch{return!1}}async delete(e){await zs(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await zt(n)}catch{return r}let s=async i=>{let a=await Ds(i,{withFileTypes:!0});for(let c of a){let u=Vs(i,c.name);if(c.isDirectory()){await s(u);continue}let p=await qt(u);r.push({key:Bt(this.root,u),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await qt(n);return o.isDirectory()?await s(n):r.push({key:Bt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Gs,GetObjectCommand as Hs,HeadObjectCommand as Us,ListObjectsV2Command as Ys,PutObjectCommand as Xs,S3Client as Qs}from"@aws-sdk/client-s3";import{getSignedUrl as Zs}from"@aws-sdk/s3-request-presigner";var le=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Qs({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,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Xs({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Zs(this.client,new Hs({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{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 n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Us({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Gs({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Ys({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function dt(t,e){return console.warn(e),new ue(t)}function Vt(t){let e=t.localRoot??to(eo(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new le({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):dt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new le({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):dt(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Ce({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):dt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ue(e)}function no(t){return new Promise(e=>setTimeout(e,t))}async function Jt(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await no(c+u)}throw o}var ro=new Set(["put","get","getText","delete","list"]);function Gt(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:ro.has(r)?(...o)=>Jt(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Ht(t){let e=t.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 Ut(t){let e=t.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 n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[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 Pe=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Ht(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,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 o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Ut(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,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,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))}};import{homedir as _t}from"node:os";import{join as Hr,resolve as iu}from"node:path";import{join as lo}from"node:path";import{createHash as so}from"node:crypto";import{dirname as oo}from"node:path";import{mkdirSync as io,readFileSync as ao,renameSync as co,writeFileSync as uo}from"node:fs";function v(t){return so("sha256").update(t).digest("hex")}function pt(t){if(Array.isArray(t))return t.map(pt);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=pt(e[r]);return n}return t}function Yt(t){return JSON.stringify(pt(t))}function Xt(t){try{return JSON.parse(ao(t,"utf8"))}catch{return null}}function O(t,e){io(oo(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;uo(n,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),co(n,t)}function Qt(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function Zt(t,e,n){let r=e.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=Qt(r.toLowerCase(),"agent"),i=Qt(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:lo(t.rootPath,".toolnet","sessions",o,i)}}function en(t){return String(t).padStart(12,"0")}var Me=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
6
+ `,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
7
+ `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],C=y.map(E=>JSON.stringify(E)).join(`
8
8
  `)+`
9
- `,C=v(M).slice(0,16),P=[e.remotePrefix,"events",`${We(h.sequence)}-${We(b.sequence)}-${C}.jsonl`].join("/");await this.storage.exists(P)||await this.storage.put(P,M,"application/x-ndjson"),u+=g.length}let a=await this.scan(e),d=n[n.length-1],l=o?.status??"active";d?.type==="session_end"||d?.type==="session_idle"?l="idle":d?.type==="error"?l="error":n.length>0&&(l="active");let m=new Date().toISOString(),p=n[0],S={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:o?.createdAt??p?.timestamp??m,updatedAt:d?.timestamp??m,firstEventAt:o?.firstEventAt??p?.timestamp,lastEventAt:d?.timestamp??o?.lastEventAt,eventCount:a.maxSequence,chunkCount:a.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(S.title=s.title??o?.title);let y={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:a.maxSequence,lastRemoteSequence:a.maxSequence,sourceCursors:r,updatedAt:m};return await this.putJson(`${e.remotePrefix}/cursor.json`,y),await this.putJson(`${e.remotePrefix}/session.json`,S),{uploadedEvents:u,lastRemoteSequence:a.maxSequence,eventCount:S.eventCount,chunkCount:S.chunkCount,status:l}}};import{closeSync as ye,existsSync as An,fsyncSync as Mn,mkdirSync as Tn,openSync as he,readSync as Rn,rmSync as Be,statSync as qe,writeSync as Cn}from"node:fs";import{join as Se}from"node:path";var Nn=12e4,_n=80,$n=2e3;function Ln(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Z=class{constructor(e){this.identity=e;Tn(e.localDirectory,{recursive:!0}),this.eventsFile=Se(e.localDirectory,"events.jsonl"),this.stateFile=Se(e.localDirectory,"state.json"),this.lockFile=Se(e.localDirectory,"journal.lock")}identity;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return Fe(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){O(this.stateFile,e)}acquireLock(){for(let e=0;e<_n;e+=1)try{return he(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-qe(this.lockFile).mtimeMs>Nn){Be(this.lockFile,{force:!0});continue}}catch{}Ln(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{ye(n),Be(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let m=l.timestamp??new Date().toISOString(),p=l.data??{},S=l.provenance?.rawDigest??v(Ke(p)),y=l.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,l.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,l.type,m,S].join("|"),g=v(y).slice(0,32);if(r.has(g))continue;s+=1;let h={version:1,id:g,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:l.type,timestamp:m,data:p,provenance:{...l.provenance,rawDigest:S}};l.role!==void 0&&(h.role=l.role),l.sourceEventId!==void 0&&(h.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(h.sourceSequence=l.sourceSequence),o.push(h),r.add(g)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
9
+ `,M=v(C).slice(0,16),I=[e.remotePrefix,"events",`${en(h.sequence)}-${en(k.sequence)}-${M}.jsonl`].join("/");await this.storage.exists(I)||await this.storage.put(I,C,"application/x-ndjson"),c+=y.length}let u=await this.scan(e),p=n[n.length-1],m=o?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?m="idle":p?.type==="error"?m="error":n.length>0&&(m="active");let d=new Date().toISOString(),l=n[0],g={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:m,createdAt:o?.createdAt??l?.timestamp??d,updatedAt:p?.timestamp??d,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:p?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(g.title=s.title??o?.title);let S={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:d};return await this.putJson(`${e.remotePrefix}/cursor.json`,S),await this.putJson(`${e.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:m}}};import{closeSync as ft,existsSync as ho,fsyncSync as So,mkdirSync as ko,openSync as gt,readSync as vo,rmSync as nn,statSync as rn,writeSync as wo}from"node:fs";import{join as yt}from"node:path";var po=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),mo=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function fo(t){return t.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function go(t){for(let e of["type","kind"]){let n=t[e];if(typeof n=="string"){let r=n.toLowerCase();if(mo.has(r))return n}}return null}function mt(t,e=0){if(e>12)return"[ToolNet nested value omitted]";if(Array.isArray(t))return t.map(o=>mt(o,e+1));if(!t||typeof t!="object")return t;let n=t,r=go(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))po.has(fo(o))||(s[o]=mt(i,e+1));return s}function yo(t){if(!t)return new Date().toISOString();let e=new Date(t);return Number.isNaN(e.getTime())?new Date().toISOString():e.toISOString()}function G(t){return t?.trim()||void 0}function tn(t,e={}){let n={...t.provenance??{}},r=G(t.source)??G(e.source)??G(n.source);return{...t,timestamp:yo(t.timestamp),source:r,turnId:G(t.turnId)??G(e.turnId),cwd:G(t.cwd)??G(e.cwd),data:mt(t.data??{}),provenance:n}}var bo=12e4,xo=80,Ao=2e3;function jo(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Ee=class{constructor(e,n={}){this.identity=e;this.eventContext=n;ko(e.localDirectory,{recursive:!0}),this.eventsFile=yt(e.localDirectory,"events.jsonl"),this.stateFile=yt(e.localDirectory,"state.json"),this.lockFile=yt(e.localDirectory,"journal.lock")}identity;eventContext;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return Xt(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){O(this.stateFile,e)}acquireLock(){for(let e=0;e<xo;e+=1)try{return gt(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-rn(this.lockFile).mtimeMs>bo){nn(this.lockFile,{force:!0});continue}}catch{}jo(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{ft(n),nn(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let m of e){let d=tn(m,this.eventContext),l=d.timestamp??new Date().toISOString(),g=d.data??{},S=d.provenance?.rawDigest??v(Yt(g)),y=d.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,d.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,d.type,l,S].join("|"),h=v(y).slice(0,32);if(r.has(h))continue;s+=1;let k={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:d.type,timestamp:l,source:d.source??d.provenance?.source??this.identity.agent,data:g,provenance:{...d.provenance,rawDigest:S}};d.role!==void 0&&(k.role=d.role),d.turnId!==void 0&&(k.turnId=d.turnId),d.cwd!==void 0&&(k.cwd=d.cwd),d.sourceEventId!==void 0&&(k.sourceEventId=d.sourceEventId),d.sourceSequence!==void 0&&(k.sourceSequence=d.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(m=>JSON.stringify(m)).join(`
10
10
  `)+`
11
- `,c=he(this.eventsFile,"a",384);try{Cn(c,i,null,"utf8"),Mn(c)}finally{ye(c)}let u=o[o.length-1],a="active";u.type==="session_end"||u.type==="session_idle"?a="idle":u.type==="error"&&(a="error");let d=Array.from(r).slice(-$n);return this.saveStateUnsafe({...n,status:a,updatedAt:u.timestamp,lastSequence:u.sequence,recentEventIds:d}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!An(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=qe(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=he(this.eventsFile,"r");try{Rn(i,o,0,s,r)}finally{ye(i)}return{events:o.toString("utf8").split(`
12
- `).filter(Boolean).map(a=>JSON.parse(a)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),updatedAt:new Date().toISOString()})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as Qn,existsSync as er,openSync as tr,readSync as nr,statSync as rr}from"node:fs";function Je(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var Ye=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],Kn=[/từ giờ/iu,/về sau/iu,/mỗi lần/iu,/luôn luôn/iu,/\bluôn\b/iu,/quy tắc/iu,/workflow/iu,/\balways\b/iu,/\brequired\b/iu,/\bmust\b/iu,/from now on/iu],Fn=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],zn=[/\btodo\b/iu,/cần làm/iu,/cần thêm/iu,/cần sửa/iu,/cần kiểm tra/iu,/tiếp theo/iu,/bước tiếp theo/iu,/còn phải/iu,/còn cần/iu,/next step/iu,/\bneed to\b/iu,/\bremaining\b/iu,/follow[- ]?up/iu],Dn=[/đã sửa/iu,/đã fix/iu,/đã khắc phục/iu,/đã xử lý/iu,/hoàn tất/iu,/hoàn thành/iu,/\bfixed\b/iu,/\bresolved\b/iu,/\bimplemented\b/iu,/\bcompleted\b/iu,/\bpasses?\b/iu],Ve=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],Wn=[/\bdùng\b/iu,/\btách\b/iu,/\bthay\b/iu,/\bchuyển\b/iu,/\blưu\b/iu,/\bmap\b/iu,/\buse\b/iu,/\bsplit\b/iu,/\bstore\b/iu,/\breplace\b/iu,/\bmove\b/iu],Bn=[/đường dẫn/iu,/\bpath\b/iu,/\bport\b/iu,/\bendpoint\b/iu,/\bdomain\b/iu,/\bbucket\b/iu,/\brepository\b/iu,/\brepo\b/iu,/\bbranch\b/iu,/\/[A-Za-z0-9._/-]{4,}/u],qn=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],Ue=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Jn=new Set(["payload","data","content","message","messages","parts","summary"]);function x(t,e){return e.some(n=>n.test(t))}function Ge(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Vn(t){return Ge(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Un(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function ve(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||Ue.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))ve(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Ue.has(s)||Jn.has(s))&&ve(o,s,n,r+1)}}function Hn(t){let e=[];ve(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=Ge(o);if(Un(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function He(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Yn(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&x(t,Ye)?{kind:"rule",confidence:.98}:r&&x(t,Kn)?{kind:"rule",confidence:.92}:x(t,Fn)?{kind:x(t,Ve)?"architecture":"decision",confidence:r?.93:.86}:r&&x(t,zn)?{kind:"todo",confidence:.87}:x(t,Ve)&&x(t,Wn)?{kind:"architecture",confidence:r?.88:.82}:s&&x(t,Dn)?{kind:"fix",confidence:.8}:r&&x(t,Bn)&&x(t,qn)?{kind:"context",confidence:.79}:null}function Gn(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Xn(t,e,n){return t==="rule"&&x(n,Ye)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Je(e,n)}function Xe(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,c=He(o);i&&c&&s.set(i,c)}for(let o of e){let i=He(o),c=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&c&&(i=s.get(c)??"");for(let u of Hn(o)){let a=Yn(u,i,o);if(!a||a.confidence<.75)continue;let d=Gn(a.kind),l=Vn(u),m=v([t.projectId,a.kind,l].join("|"));if(r.has(m))continue;r.add(m);let p=o.provenance.sourcePath?[o.provenance.sourcePath]:[],S=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:m,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:a.kind,type:d,content:u,confidence:a.confidence,importance:Xn(a.kind,d,u),tags:[d],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:S,sourcePaths:p,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}function Ze(t){return String(t).padStart(12,"0")}function Zn(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Q=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(d=>d.sequence)),o=Math.max(...n.map(d=>d.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},c=JSON.stringify(i,null,2)+`
13
- `,u=v(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),a=[Zn(e),"batches",`${Ze(s)}-${Ze(o)}-${u}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,c,"application/json"),a}};function sr(t,e){if(!er(t))return{events:[],nextOffset:e};let n=rr(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=tr(t,"r");try{nr(i,o,0,s,r)}finally{Qn(i)}let c=o.toString("utf8"),u=c.lastIndexOf(`
14
- `);if(u<0)return{events:[],nextOffset:r};let a=c.slice(0,u+1);return{events:a.split(`
15
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var ee=class{constructor(e){this.options=e;this.journal=new Q(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=sr(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Xe(this.options.identity,s.events),i=!1;return o.length>0&&(i=!!await this.journal.write(this.options.identity,s.events,o)),this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:o.length,journalWritten:i,nextOffset:s.nextOffset}}};import{closeSync as pr,existsSync as dr,openSync as fr,readSync as mr,statSync as gr}from"node:fs";var or=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function _(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function et(t){return _(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function N(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))N(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(or.has(r)||["data","payload","parts","messages"].includes(r))&&N(s,e,n+1)}}function te(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function Qe(t){let e=_(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function k(t,e,n,r,s={}){let o=_(r),i=s.key??et(o);return{version:1,id:v([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function ir(t,e,n){let r=_(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(k(t,e,"goal",i[1],{confidence:.97}));let c=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);c?.[1]&&s.push(k(t,e,"plan",c[1],{confidence:.95}));let u=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,a;for(;!o&&(a=u.exec(r));){let m=Number(a[1]),p=_(a[2]??""),S=p&&!Qe(p)?`Phase ${m} - ${p}`:`Phase ${m}`;s.push(k(t,e,"phase",S,{key:`phase:${m}`,order:m,status:te(r),confidence:.93}))}let d=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);d?.[2]&&s.push(k(t,e,"task",d[2],{status:d[1].trim()?"completed":te(d[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let m=l[1]?Number(l[1]):void 0,p=_(l[2]),S=Qe(p);s.push(k(t,e,"task",S&&m!==void 0?`TODO ${m}`:p,{key:m!==void 0?`task:${m}`:et(p),order:m,status:te(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let m=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");m&&s.push(k(t,e,"next_action",m,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(k(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(k(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(k(t,e,"decision",r,{confidence:.9})),s}function tt(t,e){if(e.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of e){if(i.type==="decision"){let u=[];N(i.data,u);for(let a of u)s(k(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let u=[];N(i.data,u);for(let a of u)s(k(t,i,"task",a,{status:te(a),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let u of["filePath","path","file"]){let a=i.data[u];typeof a=="string"&&a&&s(k(t,i,"file",a,{confidence:1}))}if(i.type==="test"){let u=[];N(i.data,u);for(let a of u)s(k(t,i,"test",a,{confidence:1}))}let c=[];N(i.data,c);for(let u of c)for(let a of u.split(/\n+/u))for(let d of ir(t,i,a))s(d)}let o=e[e.length-1];return s(k(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function nt(t){return String(t).padStart(12,"0")}var ne=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.sequence)),s=Math.max(...n.map(a=>a.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
16
- `,c=v(n.map(a=>a.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${nt(r)}-${nt(s)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,i,"application/json"),u}};import{join as rt}from"node:path";import{mkdirSync as ar}from"node:fs";function cr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=cr(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function ur(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function st(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&ur(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function lr(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await e.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}async function re(t,e){let r=(await lr(t,e)).flatMap(f=>f.observations).sort((f,w)=>{let je=f.occurredAt.localeCompare(w.occurredAt);if(je!==0)return je;let Ie=f.sequence-w.sequence;return Ie!==0?Ie:f.id.localeCompare(w.id)}),s=new Map,o=new Map,i,c,u,a=[],d=[],l=[],m=[],p=[],S=[];for(let f of r)switch(f.kind){case"goal":i=f.text;break;case"plan":c=f.text;break;case"phase":s.set(f.key,st(s.get(f.key),f));break;case"task":o.set(f.key,st(o.get(f.key),f));break;case"decision":a.push(f.text);break;case"blocker":d.push(f.text);break;case"warning":l.push(f.text);break;case"next_action":m.push(f.text);break;case"file":p.push(f.text);break;case"test":S.push(f.text);break;case"session":u={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let y=Array.from(s.values()).sort((f,w)=>(f.order??Number.MAX_SAFE_INTEGER)-(w.order??Number.MAX_SAFE_INTEGER)),g=Array.from(o.values()).sort((f,w)=>(f.order??Number.MAX_SAFE_INTEGER)-(w.order??Number.MAX_SAFE_INTEGER)),h=y.find(f=>f.status==="in_progress")??y.find(f=>f.status==="blocked")??y.find(f=>f.status==="pending"),b=g.find(f=>f.status==="in_progress")??g.find(f=>f.status==="blocked")??g.find(f=>f.status==="pending"),M=$([...m,...b?[b.title]:[],...!b&&h?[h.title]:[],...g.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),C=$([...d,...y.filter(f=>f.status==="blocked").map(f=>f.title),...g.filter(f=>f.status==="blocked").map(f=>f.title)],20),P={version:1,projectId:t.id,projectName:t.name,goal:i,plan:c,phases:y,tasks:g,decisions:$(a,20),blockers:C,warnings:$(l,20),nextActions:M,filesTouched:$(p,30),tests:$(S,20),currentPhase:h,currentTask:b,progress:{phasesTotal:y.length,phasesCompleted:y.filter(f=>f.status==="completed").length,tasksTotal:g.length,tasksCompleted:g.filter(f=>f.status==="completed").length,blocked:y.filter(f=>f.status==="blocked").length+g.filter(f=>f.status==="blocked").length},lastSession:u,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},T=rt(t.rootPath,".toolnet","work");return ar(T,{recursive:!0}),O(rt(T,"current.json"),P),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(P,null,2)+`
17
- `,"application/json"),P}async function ot(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function yr(t,e){if(!dr(t))return{events:[],nextOffset:e};let n=gr(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=fr(t,"r");try{mr(i,o,0,s,r)}finally{pr(i)}let c=o.toString("utf8"),u=c.lastIndexOf(`
18
- `);if(u<0)return{events:[],nextOffset:r};let a=c.slice(0,u+1);return{events:a.split(`
19
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var se=class{constructor(e){this.options=e;this.journal=new ne(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=yr(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=tt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await re(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Ir,existsSync as Pr,openSync as Or,readSync as Er,statSync as Ar}from"node:fs";var hr=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function L(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function be(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))be(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(hr.has(r)||["data","payload","parts","messages"].includes(r))&&be(s,e,n+1)}}function j(t,e,n,r,s,o=.95){let i=L(r);return{version:1,id:v([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function I(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return L(t.slice(r.length+1))}return null}function Sr(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function vr(t){return L(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function it(t,e){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of e){let i=[];be(o.data,i);for(let c of i){let u={type:"project"},a=null;for(let d of c.split(/\r?\n/u)){let l=L(d);if(!l){a=null;continue}let m=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(m){let w=Number(m[1]);u={type:"phase",key:`phase:${w}`,order:w,title:L(m[2]??"")},a=null;continue}let p=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let w=Number(p[1]);u={type:"task",key:`task:${w}`,order:w,title:L(p[2]??"")},a=null;continue}let S=I(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(S){s(j(t,o,"mission",S,{type:"project"},.99)),a=null;continue}let y=I(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(y){s(j(t,o,u.type==="phase"?"phase_objective":"objective",y,u,.98)),a=null;continue}let g=I(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(j(t,o,u.type==="phase"?"phase_why":"why",g,u,.98)),a=null;continue}let h=I(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(j(t,o,"desired_outcome",h,{type:"project"},.98)),a=null;continue}let b=I(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(b){s(j(t,o,"plan_rationale",b,{type:"project"},.98)),a=null;continue}let M=I(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(j(t,o,"phase_deliverable",M,u,.97)),a=null;continue}let C=I(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(C){s(j(t,o,"acceptance_criterion",C,u,.98)),a="acceptance_criterion";continue}let P=I(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(P){s(j(t,o,"dependency",P,u,.97)),a="dependency";continue}let T=I(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){s(j(t,o,"open_question",T,u,.95)),a="open_question";continue}let f=I(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(f){s(j(t,o,"constraint",f,u,.97)),a="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){a="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){a="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){a="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){a="constraint";continue}if(a&&Sr(d)){s(j(t,o,a,vr(d),u,.96));continue}a=null}}}return n}function at(t){return String(t).padStart(12,"0")}var oe=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),s=Math.max(...n.map(u=>u.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${at(r)}-${at(s)}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
20
- `,"application/json"),c}};import{mkdirSync as br}from"node:fs";import{join as ct}from"node:path";function kr(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function wr(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function E(t,e){return wr(e,t)?e:t}function A(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function xr(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await e.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}function jr(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function ut(t,e){let r=(await xr(t,e)).flatMap(y=>y.observations).sort((y,g)=>{let h=y.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return h!==0?h:y.evidence.sessionKey===g.evidence.sessionKey?y.evidence.sequence-g.evidence.sequence:y.id.localeCompare(g.id)}),s,o,i,c,u,a=new Map,d=[],l=[],m=[];for(let y of r){let g=kr(y);if(y.scope==="phase"&&y.scopeKey){let h=a.get(y.scopeKey)??jr(y);switch(y.kind){case"phase_objective":h.objective=E(h.objective,g);break;case"phase_why":h.why=E(h.why,g);break;case"phase_deliverable":h.deliverable=E(h.deliverable,g);break;case"acceptance_criterion":h.acceptanceCriteria.push(g);break;case"dependency":h.dependencies.push(g);break;case"open_question":h.openQuestions.push(g);break;case"constraint":h.constraints.push(g);break;case"note":h.notes.push(g);break}a.set(h.key,h);continue}switch(y.kind){case"mission":s=E(s,g);break;case"objective":o=E(o,g);break;case"why":i=E(i,g);break;case"desired_outcome":c=E(c,g);break;case"plan_rationale":u=E(u,g);break;case"open_question":d.push(g);break;case"constraint":l.push(g);break;case"note":m.push(g);break}}for(let y of a.values())y.acceptanceCriteria=A(y.acceptanceCriteria,20),y.dependencies=A(y.dependencies,15),y.openQuestions=A(y.openQuestions,15),y.constraints=A(y.constraints,15),y.notes=A(y.notes,20);let p={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:c,planRationale:u,phases:Array.from(a.values()).sort((y,g)=>y.order-g.order),openQuestions:A(d,20),constraints:A(l,20),notes:A(m,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},S=ct(t.rootPath,".toolnet","work");return br(S,{recursive:!0}),O(ct(S,"semantic-current.json"),p),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(p,null,2)+`
21
- `,"application/json"),p}function Mr(t,e){if(!Pr(t))return{events:[],nextOffset:e};let n=Ar(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=Or(t,"r");try{Er(o,s,0,s.length,r)}finally{Ir(o)}let i=s.toString("utf8"),c=i.lastIndexOf(`
22
- `);if(c<0)return{events:[],nextOffset:r};let u=i.slice(0,c+1);return{events:u.split(`
23
- `).filter(Boolean).flatMap(a=>{try{return[JSON.parse(a)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var ie=class{constructor(e){this.options=e;this.journal=new oe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Mr(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=it(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await ut(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{mkdirSync as zr}from"node:fs";import{join as ke}from"node:path";import{existsSync as dt,mkdirSync as Tr,readFileSync as Rr,statSync as lt,writeFileSync as Cr}from"node:fs";import{dirname as Nr,join as _r}from"node:path";var pt=64*1024,$r=`# ToolNet Project Operating Manual
11
+ `,a=gt(this.eventsFile,"a",384);try{wo(a,i,null,"utf8"),So(a)}finally{ft(a)}let c=o[o.length-1],u="active";c.type==="session_end"||c.type==="session_idle"?u="idle":c.type==="error"&&(u="error");let p=Array.from(r).slice(-Ao);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:p}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!ho(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=rn(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=gt(this.eventsFile,"r");try{vo(i,o,0,s,r)}finally{ft(i)}return{events:o.toString("utf8").split(`
12
+ `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ga,existsSync as ya,openSync as ha,readSync as Sa,statSync as ka}from"node:fs";function sn(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var un=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],Io=[/từ giờ/iu,/về sau/iu,/mỗi lần/iu,/luôn luôn/iu,/\bluôn\b/iu,/quy tắc/iu,/workflow/iu,/\balways\b/iu,/\brequired\b/iu,/\bmust\b/iu,/from now on/iu],Co=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],Po=[/\btodo\b/iu,/cần làm/iu,/cần thêm/iu,/cần sửa/iu,/cần kiểm tra/iu,/tiếp theo/iu,/bước tiếp theo/iu,/còn phải/iu,/còn cần/iu,/next step/iu,/\bneed to\b/iu,/\bremaining\b/iu,/follow[- ]?up/iu],Mo=[/đã sửa/iu,/đã fix/iu,/đã khắc phục/iu,/đã xử lý/iu,/hoàn tất/iu,/hoàn thành/iu,/\bfixed\b/iu,/\bresolved\b/iu,/\bimplemented\b/iu,/\bcompleted\b/iu,/\bpasses?\b/iu],on=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],Eo=[/\bdùng\b/iu,/\btách\b/iu,/\bthay\b/iu,/\bchuyển\b/iu,/\blưu\b/iu,/\bmap\b/iu,/\buse\b/iu,/\bsplit\b/iu,/\bstore\b/iu,/\breplace\b/iu,/\bmove\b/iu],Oo=[/đường dẫn/iu,/\bpath\b/iu,/\bport\b/iu,/\bendpoint\b/iu,/\bdomain\b/iu,/\bbucket\b/iu,/\brepository\b/iu,/\brepo\b/iu,/\bbranch\b/iu,/\/[A-Za-z0-9._/-]{4,}/u],To=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],an=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Ro=new Set(["payload","data","content","message","messages","parts","summary"]);function T(t,e){return e.some(n=>n.test(t))}function ln(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function No(t){return ln(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function _o(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function ht(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||an.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))ht(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(an.has(s)||Ro.has(s))&&ht(o,s,n,r+1)}}function Ko(t){let e=[];ht(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=ln(o);if(_o(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function cn(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function $o(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&T(t,un)?{kind:"rule",confidence:.98}:r&&T(t,Io)?{kind:"rule",confidence:.92}:T(t,Co)?{kind:T(t,on)?"architecture":"decision",confidence:r?.93:.86}:r&&T(t,Po)?{kind:"todo",confidence:.87}:T(t,on)&&T(t,Eo)?{kind:"architecture",confidence:r?.88:.82}:s&&T(t,Mo)?{kind:"fix",confidence:.8}:r&&T(t,Oo)&&T(t,To)?{kind:"context",confidence:.79}:null}function Wo(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Fo(t,e,n){return t==="rule"&&T(n,un)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":sn(e,n)}function dn(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=cn(o);i&&a&&s.set(i,a)}for(let o of e){let i=cn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Ko(o)){let u=$o(c,i,o);if(!u||u.confidence<.75)continue;let p=Wo(u.kind),m=No(c),d=v([t.projectId,u.kind,m].join("|"));if(r.has(d))continue;r.add(d);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:d,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:p,content:c,confidence:u.confidence,importance:Fo(u.kind,p,c),tags:[p],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as Lo}from"node:crypto";var Do=["project-knowledge","implementation","continuation","session-context"],zo={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function St(t){return Lo("sha256").update(t).digest("hex")}function Oe(t,e){return`${t}:${St(e).slice(0,24)}`}function qo(t){try{return St(JSON.stringify(t))}catch{return St(String(t))}}function H(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function mn(t,e=420){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:`${n.slice(0,Math.max(0,e-1)).trimEnd()}\u2026`}function Bo(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function pn(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function Vo(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,5).map(e=>mn(e.content)).join(" | ")}function Jo(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,6).map(e=>mn(e.content)).join(`
13
+ `)}function fn(t,e){let n=t.slice().sort((d,l)=>d.sequence-l.sequence||d.timestamp.localeCompare(l.timestamp)||d.id.localeCompare(l.id)),r=n.map(d=>({id:Oe("raw",[d.projectId,d.agent,d.nativeSessionId,d.id,String(d.sequence)].join("|")),level:"raw",eventId:d.id,sourceEventId:d.sourceEventId,sequence:d.sequence,type:d.type,role:d.role,timestamp:d.timestamp,sourcePath:d.provenance.sourcePath,payloadDigest:qo(d.data)})),s=new Map,o=new Map;n.forEach((d,l)=>{let g=r[l];g&&(s.set(d.id,g.id),d.sourceEventId&&o.set(d.sourceEventId,g.id))});let i=e.map(d=>{let l=H([...d.provenance.eventIds.map(g=>s.get(g)),...d.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:Oe("fact",d.fingerprint),level:"fact",fingerprint:d.fingerprint,kind:d.kind,type:d.type,content:d.content,knowledgeClass:d.knowledgeClass,importanceScore:d.importanceScore,confidence:d.confidence,tags:H([...d.tags,"level:fact",`class:${d.knowledgeClass}`,`kind:${d.kind}`]),rawIds:l,sourcePaths:H(d.provenance.sourcePaths)}}),a=new Map;for(let d of i){let l=Bo(d.kind),g=a.get(l)??[];g.push(d),a.set(l,g)}let c=[];for(let d of Do){let l=a.get(d);if(!l?.length)continue;let g=l.slice().sort((y,h)=>h.importanceScore-y.importanceScore||h.confidence-y.confidence||y.id.localeCompare(h.id)),S=g.map(y=>y.id);c.push({id:Oe("scene",`${d}|${S.join("|")}`),level:"scene",kind:d,title:zo[d],summary:Vo(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:pn(g.map(y=>y.confidence)),tags:H(["level:scene",`scene:${d}`,...g.flatMap(y=>y.tags)]),sourcePaths:H(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(d=>[d.id,d])),p=[];for(let d of c){let g=d.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(g.length===0)continue;let S=g.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",y=Jo(g);p.push({id:Oe("knowledge",`${d.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:d.title,content:y,sceneIds:[d.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:pn(g.map(h=>h.confidence)),tags:H(["level:knowledge",`class:${S}`,`scene:${d.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:H(g.flatMap(h=>h.sourcePaths))})}let m=[];for(let d of i)for(let l of d.rawIds)m.push({from:l,to:d.id,type:"supports"});for(let d of c)for(let l of d.factIds)m.push({from:l,to:d.id,type:"belongs_to"});for(let d of p)for(let l of d.sceneIds)m.push({from:l,to:d.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:p,links:m,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:p.length,links:m.length}}}function Go(t){return t?Math.ceil(t.length/3.5):0}function gn(t,e){if(!t)return"";if(Go(t)<=e)return t;let r=Math.floor(e*3.5),s=t.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
14
+ `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function U(){let t=be(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function yn(t){return(t||U()).rawTranscript}function hn(t){return(t||U()).durableMemoryMaxItemsPerSession}function Sn(t){return(t||U()).sessionSummaryMaxTokens}function kn(t){return(t||U()).archiveRemote}var vn=new J;function wn(t){let e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))try{let r=JSON.parse(e);return JSON.stringify(vn.sanitizeValue(r))}catch{}let n=vn.sanitize(t).text;return n=n.replace(/("(?:api[_-]?key|token|secret|password|cookie|authorization)"\s*:\s*)"[^"]*"/gi,'$1"[REDACTED]"').replace(/('(?:api[_-]?key|token|secret|password|cookie|authorization)'\s*:\s*)'[^']*'/gi,"$1'[REDACTED]'").replace(/\b(api[_-]?key|token|secret|password|cookie|authorization)\b\s*[:=]\s*[^\s,;]+/gi,"$1=[REDACTED]").replace(/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [REDACTED]"),n}function Ho(t,e){let n=t.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Uo(t,e){let n=[],r=new Set;for(let i of t){let a=i.split(`
15
+ `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let p=u.toLowerCase().replace(/\s+/g," ");if(r.has(p))continue;r.add(p);let m="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?m="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?m="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?m="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?m="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?m="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?m="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(m="file");let d=Ho(u,m);if(d<.3)continue;let l=wn(u);n.push({category:m,text:l,importance:d,sourceSessionId:e})}}let s=U(),o=hn(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function Yo(t){let e=U(),n=Sn(e),o=t.join(`
16
+
17
+ `).split(`
18
+ `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>wn(i)).join(`
19
+ `);return gn(o,n)}function Te(t,e){let r=(Array.isArray(t)?t:t.split(`
20
+
21
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Uo(r,e),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),a=s.filter(l=>l.category==="file").map(l=>l.text),c=s.filter(l=>l.category==="fix").map(l=>l.text),u=s.filter(l=>l.category==="blocker").map(l=>l.text),p=s.filter(l=>l.category==="next_action").map(l=>l.text),m=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Yo(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:m,blockers:u,nextActions:p,durableFacts:s}}function q(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function Xo(t){let e=new Map;for(let n of t){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=e.get(r);(!s||n.sequence>s.sequence)&&e.set(r,n)}return[...e.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Qo(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Zo(t){let e=Qo(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function ei(t){return t.importance==="temporary"||t.confidence<.78?"transient":t.kind==="rule"||t.kind==="architecture"?"permanent":t.kind==="decision"||t.kind==="todo"||t.kind==="fix"?"task":"session"}function ti(t){let e=t.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of e)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function ni(t){let e=ei(t),n=Zo(t),r=ti(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:q([...t.tags,"level:fact",`class:${e}`,`kind:${t.kind}`])}}function ri(t){return t.map(e=>{try{return JSON.stringify({type:e.type,role:e.role,data:e.data,provenance:{sourcePath:e.provenance.sourcePath,files:e.provenance.files}})}catch{return""}}).filter(Boolean)}function si(t,e,n){let r=Te(ri(e),t.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=q([...s,...r.nextActions]),c=q([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:q(r.decisions),files:q([...r.filesChanged,...o]),todos:a,completed:q(r.bugsFixed),blockers:q(r.blockers),nextActions:c,architecture:q(i)}}}function Re(t,e){let n=Xo(e),r=dn(t,n).map(ni),s=r.filter(p=>p.knowledgeClass!=="transient").sort((p,m)=>m.importanceScore-p.importanceScore),{summary:o,state:i}=si(t,n,s),a=s.map(p=>({fingerprint:p.fingerprint,kind:p.kind,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,content:p.content,terms:p.retrievalTerms})),c=fn(n,s),u=p=>r.filter(m=>m.knowledgeClass===p).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:e.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as oi}from"node:crypto";import{chmodSync as bn,existsSync as ii,mkdirSync as ai,readFileSync as ci,renameSync as ui,writeFileSync as xn}from"node:fs";import{dirname as An,join as Ne}from"node:path";var wt="toolnet.context-offload.v1",li="toolnet.context-offload-asset.v1",di=256,pi=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function jn(t){return Ne(t,".toolnet","offload")}function mi(t){return Ne(jn(t),"assets")}function In(t){return Ne(jn(t),"graph.json")}function Cn(t){ai(t,{recursive:!0,mode:448});try{bn(t,448)}catch{}}function fi(t,e){Cn(An(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;xn(n,e,{encoding:"utf8",mode:384}),ui(n,t);try{bn(t,384)}catch{}}function vt(t){return Array.isArray(t)?t.map(vt):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,vt(n)])):t}function gi(t){return oi("sha256").update(JSON.stringify(vt(t)),"utf8").digest("hex")}function kt(){return{schema:wt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function yi(t){let e=In(t);if(!ii(e))return kt();try{let n=JSON.parse(ci(e,"utf8"));return n.schema!==wt||n.version!==1||!Array.isArray(n.nodes)?kt():n}catch{return kt()}}function hi(t,e){fi(In(t),JSON.stringify(e,null,2)+`
22
+ `)}function Si(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function ki(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let s=Si(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function vi(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function wi(t,e){Cn(An(t));try{return xn(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function bi(t,e){let n=t.nodes.find(s=>s.id===e.id),r=n?{...n,kind:e.kind,bytes:e.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...e.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...e.files])).slice(0,6)}:e;return{schema:wt,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(s=>s.id!==e.id),r].slice(-di)}}function Pn(t,e){let n=yi(t),r=0,s=0,o=0,i=[];for(let a of e){if(!pi.has(a.type))continue;r+=1;let c=gi({type:a.type,data:a.data}),u={schema:li,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},p=JSON.stringify(u,null,2)+`
23
+ `;wi(Ne(mi(t),`${c}.json`),p)?s+=1:o+=1,i.push(c),n=bi(n,{id:c,kind:a.type,bytes:Buffer.byteLength(p,"utf8"),createdAt:a.timestamp,sourceRefs:[vi(a)],files:ki(a)})}return r>0&&hi(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Ei}from"node:crypto";import{existsSync as Oi,readdirSync as Ti,readFileSync as Ri}from"node:fs";import{basename as Ni,join as Vn}from"node:path";import{randomUUID as On}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function de(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function X(t){let e=t.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new A("Invalid Wiki slug",400);return e}function Mn(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(X(r))}return de(e)}function xi(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function En(t){return{id:`revision-${On()}`,pageId:t.id,slug:t.slug,revision:t.revision,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...t.tags],links:[...t.links],createdAt:t.updatedAt}}function Y(t){return structuredClone(t)}var _e=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let e=await this.ensureState(),n=new Set(e.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:de(e.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:e.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:e.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:e.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return Y([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=X(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new A(`Wiki page not found: ${e}`,404);return Y(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new A("Wiki title is required",400);let o=X(e.slug??r);if(n.pages.some(c=>c.slug===o))throw new A(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${On()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:de(e.tags??[]),links:Mn(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(En(a)),Y(a)})}async updatePage(e,n){return this.mutate(r=>{let s=X(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new A(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new A("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=Mn(o.content)),n.tags!==void 0&&(o.tags=de(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(En(o)),Y(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return Y(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(e){let n=await this.getPage(e),r=await this.ensureState();return Y(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(e,n=10){let r=await this.ensureState(),s=de(xi(e));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),p=a.summary?.toLowerCase()??"",m=a.content.toLowerCase(),d=a.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),c===g&&(l+=10),c.includes(g)&&(l+=6),u.includes(g)&&(l+=5),d.some(S=>S===g)?l+=5:d.some(S=>S.includes(g))&&(l+=3),p.includes(g)&&(l+=2),m.includes(g)&&(l+=1);l>0&&i.push({page:Y(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Tn="wiki/state.v1.json";function Ai(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function ji(t,e){let n=JSON.parse(t);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==e.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var Ke=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Tn);if(!e){let n=Ai(this.project);return await this.save(n),n}return ji(e,this.project)}async save(e){await this.storage.put(Tn,JSON.stringify(e,null,2),"application/json")}};import{createHash as Ii,randomUUID as Rn}from"node:crypto";var Nn="wiki/governance.v1.json",Wn="toolnet.knowledge-governance.v1",_n=500,pe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Ci(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function bt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Kn(t){return Ii("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Pi(t){let e=[t.title,t.summary??"",t.content.slice(0,2e3),...t.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function Mi(t){let e=t.sourceType==="skill"?.96:t.sourceType==="memory"?.94:.88,n=t.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(e+=.03),t.content.length>=200&&(e+=.02),t.content.length<80&&(e-=.05),t.title.length<4&&(e-=.05),Ci(e)}function $n(t){let e=new Date().toISOString();return{schema:Wn,version:1,projectId:t,policy:{...pe},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Fn(t){let e=t.autoApproveThreshold??pe.autoApproveThreshold,n=t.criticalApproveThreshold??pe.criticalApproveThreshold,r=t.staleAfterDays??pe.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new A("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new A("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new A("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var $e=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Nn);if(!e){let n=$n(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==Wn||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Fn(n.policy??pe)}}catch{let n=$n(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(Nn,JSON.stringify(e,null,2),"application/json")}},We=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,n,r,s={}){e.audit.push({id:Rn(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),e.audit.length>_n&&(e.audit=e.audit.slice(-_n))}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,n){return this.mutate(r=>(r.policy=Fn({...r.policy,...e}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let e=await this.ensureState(),n=r=>e.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!e||r.status===e).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(e=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(n.audit.slice(-r).reverse())}async assess(e,n){let r=await this.ensureState(),s=Mi(e),o=bt(e.title),i=n.filter(p=>p.slug!==e.slug&&bt(p.title)===o&&Kn(p.content)!==Kn(e.content)).map(p=>p.slug),a=Pi(e),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,n){let r=await this.assess(e,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:Rn(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(e,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===e&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:e}))})}async decide(e,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===e);if(!o)throw new A(`Governance review not found: ${e}`,404);if(o.status!=="pending")throw new A("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new A("targetReviewId is required for merge",400);let u=s.reviews.find(p=>p.id===n.targetReviewId);if(!u)throw new A("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new A(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(e){let n=await this.ensureState(),r=await e.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(p=>{let m=s-Date.parse(p.updatedAt);return{slug:p.slug,title:p.title,updatedAt:p.updatedAt,ageDays:Math.max(0,Math.floor(m/864e5)),stale:Number.isFinite(m)&&m>o}}).filter(p=>p.stale).map(({stale:p,...m})=>m),a=new Map;for(let p of r){let m=bt(p.title),d=a.get(m)??[];d.push(p),a.set(m,d)}let c=[...a.entries()].filter(([,p])=>p.length>1).map(([p,m])=>({title:p,pages:m.map(d=>d.slug)})),u=n.reviews.filter(p=>p.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(p=>p.tags.some(m=>m.startsWith("toolnet-auto-"))).length,manualPages:r.filter(p=>!p.tags.some(m=>m.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(p=>p.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(p=>p.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Jn="wiki/automation.v1.json",Gn="toolnet.wiki-automation.v1",jt=8e3,Ln=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function fe(t){return Ei("sha256").update(JSON.stringify(t)).digest("hex")}function me(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Dn(t){return Array.isArray(t)?t:[]}function Hn(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function xt(t){return Array.isArray(t)?t.map(Hn).filter(e=>!!e):[]}function _(t,e){for(let n of e){let r=Hn(t[n]);if(r)return r}}function ge(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function Fe(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Ln.has(r))return[];if(typeof t=="string"){let i=t.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(t))return t.flatMap(i=>Fe(i,e+1,n));let s=me(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Ln.has(c)||o.push(...Fe(a,e+1,i))}return o}function zn(t){let n=ge(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>Fe(t[s],0,s)));return(n.length>0?n:ge(Fe(t))).join(`
24
+
25
+ `).slice(0,jt)}function qn(t,e){return _(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function Bn(t,e){return _(t,["title","name","topic","label","task","kind","type"])??e}function _i(t){return(_(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Ki(t){return(_(t,["kind","sceneKind","type"])??"").toLowerCase()}function $i(t){let e=me(t);if(!e)return[];let n=[],r=Dn(e.knowledge);for(let[o,i]of r.entries()){let a=me(i);if(!a)continue;let c=_i(a);if(c==="session"||c==="transient")continue;let u=zn(a);if(u.length<20)continue;let p=qn(a,fe(a).slice(0,16)),m=Bn(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${p}`,sourceType:"memory",title:m,summary:_(a,["summary","description"]),content:u,tags:ge(["toolnet","auto","memory",...c?[c]:[]])})}let s=Dn(e.scenes);for(let[o,i]of s.entries()){let a=me(i);if(!a)continue;let c=Ki(a);if(c==="session-context")continue;let u=zn(a);if(u.length<20)continue;let p=qn(a,fe(a).slice(0,16)),m=Bn(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${p}`,sourceType:"scene",title:m,summary:_(a,["summary","description"]),content:u,tags:ge(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Wi(t){return Vn(t,".toolnet","memory","skills")}function Fi(t){let e=Wi(t);if(!Oi(e))return{candidates:[],failed:0};let n=[],r=0,s=Ti(e).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Ri(Vn(e,o),"utf8")),a=me(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=_(a,["id","fingerprint"])??Ni(o,".json"),u=_(a,["task"])??"",p=_(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,m=_(a,["summary"])??void 0,d=xt(a.steps),l=xt(a.verification),g=xt(a.files),S=[];u&&S.push(`## Task
26
+ ${u}`),m&&S.push(`## Summary
27
+ ${m}`),d.length>0&&S.push(`## Procedure
28
+ ${d.map((h,k)=>`${k+1}. ${h}`).join(`
29
+ `)}`),l.length>0&&S.push(`## Verification
30
+ ${l.map(h=>`- ${h}`).join(`
31
+ `)}`),g.length>0&&S.push(`## Relevant Files
32
+ ${g.map(h=>`- \`${h}\``).join(`
33
+ `)}`);let y=S.join(`
34
+
35
+ `).slice(0,jt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:p,summary:m,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function At(t){let e=new Date().toISOString();return{schema:Gn,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function Li(t,e){let n=await t.getText(Jn);if(!n)return At(e);try{let r=JSON.parse(n);return r.schema!==Gn||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?At(e):r}catch{return At(e)}}async function Di(t,e){await t.put(Jn,JSON.stringify(e,null,2),"application/json")}function zi(t){return`toolnet-auto-${fe(t).slice(0,12)}`}function qi(t){let e=X(t.title).slice(0,72),n=fe(t.sourceKey).slice(0,10);return X(`auto-${t.sourceType}-${e}-${n}`)}function Bi(t){return[`> Auto-generated by ToolNet Knowledge Automation from ${t.sourceType==="skill"?"reusable Skill Memory":t.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",t.content].join(`
36
+ `).slice(0,jt)}function Vi(t){return fe({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function Ji(t,e){return t.tags.includes(e)}async function Un(t){let e=$i(t.hierarchy),n=Fi(t.project.rootPath),r=new Map;for(let l of[...e,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:e.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new _e(new Ke(t.storage,t.project));await i.initialize();let a=new We(new $e(t.storage,t.project));await a.initialize();let c=await Li(t.storage,t.project.id),u=await i.listPages(),p=new Map(u.map(l=>[l.slug,l])),m=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=zi(l.sourceKey),S=Vi(l),y=m.get(l.sourceKey),h=y?.slug??qi(l),k=p.get(h);if(k&&!Ji(k,g)){o.skipped+=1;continue}let C=ge([...l.tags,g]),M=Bi(l),I=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,marker:g,digest:S,title:l.title,...l.summary?{summary:l.summary}:{},content:M,tags:C},[...p.values()]);if(!I.allowed){I.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}I.mode==="auto-approved"?o.autoApproved+=1:I.mode==="review-approved"&&(o.reviewApproved+=1),k?y?.digest!==S?(k=await i.updatePage(h,{title:l.title,summary:l.summary??"",content:M,tags:C}),p.set(k.slug,k),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,action:"unchanged"})):(k=await i.createPage({slug:h,title:l.title,summary:l.summary,content:M,tags:C}),p.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let E=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,digest:S,marker:g,updatedAt:E},w=c.entries.findIndex(F=>F.sourceKey===l.sourceKey);w>=0?c.entries[w]=x:c.entries.push(x),m.set(l.sourceKey,x),await a.markApplied(l.sourceKey,S)}catch(g){if(g instanceof A&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let d=new Date().toISOString();return c.updatedAt=d,c.lastRunAt=d,c.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Di(t.storage,c),o}import{createHash as Gi}from"node:crypto";import{chmodSync as Xn,existsSync as Hi,mkdirSync as Ui,readFileSync as Tp,readdirSync as Rp,renameSync as Yi,statSync as Np,writeFileSync as Xi}from"node:fs";import{join as Qn}from"node:path";var Qi="toolnet.skill-memory.v1",Yn=5,Zi=16,ea=24,ta=32;function na(t){return Gi("sha256").update(t).digest("hex")}function he(t,e=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function It(t,e=360){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function ra(t){return t.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function D(t,e=360){return t&&It(ra(t),e)||void 0}function Se(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function Zn(t,e){for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function er(t,e){for(let n of e){let r=t[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function tr(t){let e=t.data??{};if(er(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Zn(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=Se(e,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ye(t){let e=t.data??{};if(tr(t))return!1;if(er(e,["passed","pass","success","succeeded","ok"])===!0||Zn(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=Se(e,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:t.type==="commit"||t.type==="deploy"}function nr(t){let e=t.data??{},n=Se(e,["path","file","filePath","filename","target"]);if(n)return D(n,260);let r=t.provenance?.files;return D(r?.[0],260)}function Ct(t){return D(Se(t.data??{},["command","cmd","script"]),420)}function ee(t){return D(Se(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function sa(t){let e=[];for(let n of[...t].sort((r,s)=>r.sequence-s.sequence))if(ye(n)){if(n.type==="test"){let r=ee(n)??Ct(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=ee(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=ee(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return he(e,10)}function oa(t,e){let n=[];for(let r of[...t].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=nr(r);s&&n.push(`Update ${s}`);break}case"command":{if(tr(r))break;let s=Ct(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ye(r))break;let s=ee(r)??Ct(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!ye(r))break;let s=ee(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!ye(r))break;let s=ee(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of e.files.slice(0,8)){let s=D(r,260);s&&n.push(`Update ${s}`)}return he(n,Zi)}function ia(t,e){let n=[...e.files];for(let r of t){let s=nr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=D(o,260);i&&n.push(i)}}return he(n,ea)}function aa(t){return he(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),ta)}function ca(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function rr(t,e,n){if(e.length===0)return[];let r=sa(e),s=he(n.completed.map(g=>D(g,280)??""),Yn);if(!(s.length>0||e.some(g=>["test","commit","deploy"].includes(g.type)&&ye(g))))return[];let i=D(n.task,280)??D(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=oa(e,n);if(c.length===0)return[];let u=ia(e,n),p=aa(e),m=Math.min(...e.map(g=>g.sequence)),d=Math.max(...e.map(g=>g.sequence)),l=ca(e);return a.slice(0,Yn).map(g=>{let S=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),y=JSON.stringify({projectId:t.projectId,task:g,steps:c,verification:r,files:u}),h=na(y);return{schema:Qi,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:t.projectId,title:It(`SOP: ${g}`,180),task:g,summary:It(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:m,lastSequence:d,eventIds:p},createdAt:l}})}function ua(t){return Qn(t.rootPath,".toolnet","memory","skills")}function la(t){let e=ua(t);return Ui(e,{recursive:!0,mode:448}),Xn(e,448),e}function sr(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=la(t),r=0,s=0,o=[];for(let i of e){if(i.projectId!==t.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${t.id}`);let a=Qn(n,`${i.id}.json`);if(o.push(a),Hi(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Xi(c,JSON.stringify(i,null,2)+`
37
+ `,{encoding:"utf8",mode:384}),Yi(c,a),Xn(a,384),r+=1}return{written:r,deduped:s,files:o}}function or(t){return String(t).padStart(12,"0")}function da(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Le=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(p=>p.sequence)),o=Math.max(...n.map(p=>p.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
38
+ `,c=v(r.map(p=>p.fingerprint).sort().join("|")).slice(0,16),u=[da(e),"batches",`${or(s)}-${or(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as pa}from"node:crypto";function ir(t){return String(t).padStart(12,"0")}function ma(t){return pa("sha256").update(t).digest("hex")}function fa(t){return t.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var De=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=ma([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[fa(e),"batches",`${ir(s)}-${ir(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
39
+ `,"application/json"),c}};function va(t,e){if(!ya(t))return{events:[],nextOffset:e};let n=ka(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=ha(t,"r");try{Sa(i,o,0,s,r)}finally{ga(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
40
+ `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
41
+ `).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var ze=class{constructor(e){this.options=e;this.journal=new Le(e.storage),this.hierarchyJournal=new De(e.storage)}options;journal;hierarchyJournal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=va(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Re(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=rr(this.options.identity,s.events,o.state),p=sr(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",p.written),this.options.wal.setSourceCursor("memory.skill.deduped",p.deduped);try{let m=Pn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",m.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",m.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",m.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",m.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let m=await Un({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",m.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",m.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",m.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",m.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",m.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",m.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",m.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",m.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",m.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",m.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:a,nextOffset:s.nextOffset}}};import{closeSync as Wa,existsSync as Fa,openSync as La,readSync as Da,statSync as za}from"node:fs";function ar(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function ve(t){return t.toLowerCase().replace(/[^a-z0-9]/gu,"")}function ke(t,e,n=0){if(n>8)return;if(Array.isArray(t)){for(let s of t.slice(0,50))ke(s,e,n+1);return}let r=ar(t);if(r)for(let[s,o]of Object.entries(r))e(s,o,r),ke(o,e,n+1)}function te(t,e){let n=[];return ke(t,(r,s)=>{e.has(ve(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function wa(t){let e=t.trim();if(!e.startsWith("{"))return null;try{return ar(JSON.parse(e))}catch{return null}}function ba(t){let e=t.data;for(let r of["tool","toolName","tool_name"]){let s=e[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return ke(e,(r,s,o)=>{if(n)return;let i=ve(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function xa(t){let e=te(t.data,new Set(["command","cmd","script"])),n=te(t.data,new Set(["arguments","args"]));for(let r of n){let s=wa(r);if(s)for(let o of te(s,new Set(["command","cmd","script"])))e.push(o)}return Array.from(new Set(e.map(r=>r.trim()).filter(Boolean)))}function Aa(t){let e=te(t.data,new Set(["filepath","file_path","filename","file","path","target"].map(ve)));return Array.from(new Set(e.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
42
+ `))))}function ja(t,e){return t.type==="file_edit"||t.type==="file_write"?"modified":/\b(delete|remove|unlink)\b/iu.test(e)?"deleted":/\b(create|add[_-]?file|new[_-]?file)\b/iu.test(e)?"created":/\b(edit|write|patch|apply[_-]?patch|replace|update[_-]?file)\b/iu.test(e)?"modified":null}function Ia(t){let e=te(t.data,new Set(["patch","diff","arguments","input"].map(ve))),n=[];for(let r of e){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function Ca(t){let e=t.toLowerCase();return/\b(typecheck|type-check)\b/u.test(e)||/\btsc\b[\s\S]*--noemit\b/u.test(e)?"typecheck":/\b(eslint|lint)\b/u.test(e)?"lint":/\b(vitest|jest|pytest)\b/u.test(e)||/\bgo\s+test\b/u.test(e)||/\bcargo\s+test\b/u.test(e)||/\b(npm|pnpm|yarn)\s+(run\s+)?test\b/u.test(e)?"test":/\b(npm|pnpm|yarn)\s+(run\s+)?build\b/u.test(e)||/\bcargo\s+build\b/u.test(e)||/\bgo\s+build\b/u.test(e)||/\btsc\b/u.test(e)?"build":null}function Pa(t){let e=null;return ke(t,(n,r)=>{if(e===null&&["exitcode","code"].includes(ve(n))){if(typeof r=="number"&&Number.isFinite(r)){e=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(e=s)}}}),e}function Ma(t){return te(t,new Set(["status","state","result","output","outputsummary","message","text"]))}function Ea(t){let e=Pa(t.data);if(e!==null)return e===0?"passed":"failed";let n=Ma(t.data).join(`
43
+ `).toLowerCase();return/\b(error|failed|failure|failing)\b/u.test(n)&&!/\b0\s+failed\b/u.test(n)?"failed":/\b(success|successful|completed|passed|green)\b/u.test(n)||/\b\d+\s+passed\b/u.test(n)?"passed":/\b(running|started|in[_ -]?progress)\b/u.test(n)?"running":"unknown"}function Oa(t){let e=[],n=new Set;for(let r of t){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),e.push(r))}return e}function cr(t){let e=[],n=ba(t),r=ja(t,n);if(r)for(let s of Aa(t))e.push({kind:"file",text:s,fileAction:r,confidence:t.type==="file_edit"||t.type==="file_write"?1:.96});e.push(...Ia(t));for(let s of xa(t)){e.push({kind:"command",text:s,confidence:.98});let o=Ca(s);o&&e.push({kind:"test",text:s,checkKind:o,checkStatus:Ea(t),confidence:.98})}return Oa(e)}var Ta=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function Z(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function lr(t){return Z(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Q(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))Q(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Ta.has(r)||["data","payload","parts","messages"].includes(r))&&Q(s,e,n+1)}}function qe(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function ur(t){let e=Z(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function j(t,e,n,r,s={}){let o=Z(r),i=s.key??lr(o);return{version:1,id:v([t.projectId,n,i,e.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function Ra(t,e,n){let r=Z(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(j(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(j(t,e,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let d=Number(u[1]),l=Z(u[2]??""),g=l&&!ur(l)?`Phase ${d} - ${l}`:`Phase ${d}`;s.push(j(t,e,"phase",g,{key:`phase:${d}`,order:d,status:qe(r),confidence:.93}))}let p=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&s.push(j(t,e,"task",p[2],{status:p[1].trim()?"completed":qe(p[2]),confidence:.96}));let m=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(m?.[2]){let d=m[1]?Number(m[1]):void 0,l=Z(m[2]),g=ur(l);s.push(j(t,e,"task",g&&d!==void 0?`TODO ${d}`:l,{key:d!==void 0?`task:${d}`:lr(l),order:d,status:qe(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let d=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");d&&s.push(j(t,e,"next_action",d,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(j(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(j(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(j(t,e,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&s.push(j(t,e,"activity",r,{confidence:.86})),s}function Be(t,e){if(e.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of e){if(i.type==="user_prompt"||i.role==="user"){let c=[];Q(i.data,c);let u=c.map(p=>Z(p)).find(p=>p.length>=8&&p.length<=1200&&!/^\[?toolnet\b/iu.test(p));u&&s(j(t,i,"request",u,{confidence:.96}))}for(let c of cr(i))s(j(t,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];Q(i.data,c);for(let u of c)s(j(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];Q(i.data,c);for(let u of c)s(j(t,i,"task",u,{status:qe(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(j(t,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];Q(i.data,c);for(let u of c)s(j(t,i,"test",u,{confidence:1}))}let a=[];Q(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let p of Ra(t,i,u))s(p)}let o=e[e.length-1];return s(j(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function dr(t){return String(t).padStart(12,"0")}var Ve=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
44
+ `,a=v(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${dr(r)}-${dr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as pr}from"node:path";import{mkdirSync as Na}from"node:fs";function fr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function K(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=fr(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function _a(t,e=20){let n=new Map;for(let r of t){let s=`${r.kind}|${fr(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-e)}function Ka(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function mr(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&Ka(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function $a(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Je(t,e){let r=(await $a(t,e)).flatMap(f=>f.observations).sort((f,b)=>{let z=f.occurredAt.localeCompare(b.occurredAt);if(z!==0)return z;let $t=f.sequence-b.sequence;return $t!==0?$t:f.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,p,m=[],d=[],l=[],g=[],S=[],y=new Map,h=[],k=[],C=[],M=[],I=[],E=[];for(let f of r)switch(f.kind){case"request":i=f.text;break;case"activity":a=f.text;break;case"goal":c=f.text;break;case"plan":u=f.text;break;case"phase":s.set(f.key,mr(s.get(f.key),f));break;case"task":o.set(f.key,mr(o.get(f.key),f));break;case"decision":m.push(f.text);break;case"blocker":d.push(f.text);break;case"warning":l.push(f.text);break;case"next_action":g.push(f.text);break;case"file":{S.push(f.text);let b=f.fileAction??"active";y.delete(f.text),y.set(f.text,b),b==="modified"?h.push(f.text):b==="created"?k.push(f.text):b==="deleted"&&C.push(f.text);break}case"command":M.push(f.text);break;case"test":I.push(f.text),f.checkKind&&E.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":p={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=Array.from(s.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),w=Array.from(o.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),F=x.find(f=>f.status==="in_progress")??x.find(f=>f.status==="blocked")??x.find(f=>f.status==="pending"),L=w.find(f=>f.status==="in_progress")??w.find(f=>f.status==="blocked")??w.find(f=>f.status==="pending"),at=K([...g,...L?[L.title]:[],...!L&&F?[F.title]:[],...w.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),ct=K([...d,...x.filter(f=>f.status==="blocked").map(f=>f.title),...w.filter(f=>f.status==="blocked").map(f=>f.title)],20),se={version:1,projectId:t.id,projectName:t.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:w,decisions:K(m,20),blockers:ct,warnings:K(l,20),nextActions:at,filesTouched:K(S,30),activeFiles:Array.from(y.entries()).filter(([,f])=>f!=="deleted").map(([f])=>f).slice(-5),modifiedFiles:K(h,30),createdFiles:K(k,30),deletedFiles:K(C,30),commands:K(M,20),tests:K(I,20),checks:_a(E,20),currentPhase:F,currentTask:L,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+w.filter(f=>f.status==="blocked").length},lastSession:p,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},oe=pr(t.rootPath,".toolnet","work");return Na(oe,{recursive:!0}),O(pr(oe,"current.json"),se),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(se,null,2)+`
45
+ `,"application/json"),se}async function gr(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function qa(t,e){if(!Fa(t))return{events:[],nextOffset:e};let n=za(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=La(t,"r");try{Da(i,o,0,s,r)}finally{Wa(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
46
+ `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
47
+ `).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Ge=class{constructor(e){this.options=e;this.journal=new Ve(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=qa(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Be(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Je(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Qa,existsSync as Za,openSync as ec,readSync as tc,statSync as nc}from"node:fs";var Ba=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ne(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Pt(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))Pt(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Ba.has(r)||["data","payload","parts","messages"].includes(r))&&Pt(s,e,n+1)}}function R(t,e,n,r,s,o=.95){let i=ne(r);return{version:1,id:v([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function $(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return ne(t.slice(r.length+1))}return null}function Va(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Ja(t){return ne(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function yr(t,e){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of e){let i=[];Pt(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let p of a.split(/\r?\n/u)){let m=ne(p);if(!m){u=null;continue}let d=m.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let w=Number(d[1]);c={type:"phase",key:`phase:${w}`,order:w,title:ne(d[2]??"")},u=null;continue}let l=m.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let w=Number(l[1]);c={type:"task",key:`task:${w}`,order:w,title:ne(l[2]??"")},u=null;continue}let g=$(m,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(R(t,o,"mission",g,{type:"project"},.99)),u=null;continue}let S=$(m,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(R(t,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=$(m,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(R(t,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=$(m,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(R(t,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=$(m,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(R(t,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let C=$(m,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(C){s(R(t,o,"phase_deliverable",C,c,.97)),u=null;continue}let M=$(m,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(M){s(R(t,o,"acceptance_criterion",M,c,.98)),u="acceptance_criterion";continue}let I=$(m,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(I){s(R(t,o,"dependency",I,c,.97)),u="dependency";continue}let E=$(m,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(E){s(R(t,o,"open_question",E,c,.95)),u="open_question";continue}let x=$(m,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(R(t,o,"constraint",x,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(m)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(m)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(m)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(m)){u="constraint";continue}if(u&&Va(p)){s(R(t,o,u,Ja(p),c,.96));continue}u=null}}}return n}function hr(t){return String(t).padStart(12,"0")}var He=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${hr(r)}-${hr(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
48
+ `,"application/json"),a}};import{mkdirSync as Ga}from"node:fs";import{join as Sr}from"node:path";function Ha(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Ua(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function B(t,e){return Ua(e,t)?e:t}function V(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function Ya(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function Xa(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function kr(t,e){let r=(await Ya(t,e)).flatMap(S=>S.observations).sort((S,y)=>{let h=S.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===y.evidence.sessionKey?S.evidence.sequence-y.evidence.sequence:S.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,p=[],m=[],d=[];for(let S of r){let y=Ha(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??Xa(S);switch(S.kind){case"phase_objective":h.objective=B(h.objective,y);break;case"phase_why":h.why=B(h.why,y);break;case"phase_deliverable":h.deliverable=B(h.deliverable,y);break;case"acceptance_criterion":h.acceptanceCriteria.push(y);break;case"dependency":h.dependencies.push(y);break;case"open_question":h.openQuestions.push(y);break;case"constraint":h.constraints.push(y);break;case"note":h.notes.push(y);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=B(s,y);break;case"objective":o=B(o,y);break;case"why":i=B(i,y);break;case"desired_outcome":a=B(a,y);break;case"plan_rationale":c=B(c,y);break;case"open_question":p.push(y);break;case"constraint":m.push(y);break;case"note":d.push(y);break}}for(let S of u.values())S.acceptanceCriteria=V(S.acceptanceCriteria,20),S.dependencies=V(S.dependencies,15),S.openQuestions=V(S.openQuestions,15),S.constraints=V(S.constraints,15),S.notes=V(S.notes,20);let l={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,y)=>S.order-y.order),openQuestions:V(p,20),constraints:V(m,20),notes:V(d,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=Sr(t.rootPath,".toolnet","work");return Ga(g,{recursive:!0}),O(Sr(g,"semantic-current.json"),l),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
49
+ `,"application/json"),l}function rc(t,e){if(!Za(t))return{events:[],nextOffset:e};let n=nc(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=ec(t,"r");try{tc(o,s,0,s.length,r)}finally{Qa(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
50
+ `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
51
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Ue=class{constructor(e){this.options=e;this.journal=new He(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=rc(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=yr(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await kr(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as jc,mkdirSync as Ic}from"node:fs";import{join as Et}from"node:path";import{existsSync as br,mkdirSync as sc,readFileSync as oc,statSync as vr,writeFileSync as ic}from"node:fs";import{dirname as ac,join as cc}from"node:path";var wr=64*1024,uc=`# ToolNet Project Operating Manual
24
52
 
25
53
  This file contains persistent instructions for AI agents working on this project.
26
54
 
@@ -63,21 +91,68 @@ Things an AI agent should always remember.
63
91
  <!--
64
92
  - [advisory] Prefer small focused files.
65
93
  -->
66
- `;function ft(t){return _r(t.rootPath,".toolnet","PROJECT.md")}function Lr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Kr(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=Lr(s[2]);if(!i)continue;let c=`${o}:${i.toLowerCase()}`;n.has(c)||(n.add(c),e.push({id:v(c).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Fr(t){let e=ft(t);return dt(e)||(Tr(Nr(e),{recursive:!0}),Cr(e,$r,{encoding:"utf8",mode:384})),e}function mt(t,e=!1){let n=e?Fr(t):ft(t);if(!dt(n))return null;if(lt(n).size>pt)throw new Error(`PROJECT.md exceeds ${pt} bytes`);let s=Rr(n,"utf8");return{path:n,content:s,digest:v(s),rules:Kr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(lt(n).mtimeMs).toISOString()}}function Dr(t){return{goal:t.goal,plan:t.plan,phases:t.phases.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),tasks:t.tasks.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),decisions:t.decisions,blockers:t.blockers,warnings:t.warnings,nextActions:t.nextActions,filesTouched:t.filesTouched,tests:t.tests}}function Wr(t){return t.phases.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.tasks.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.nextActions.length>0||t.blockers.length>0}var ae=class{constructor(e){this.options=e}options;async capture(e,n){let r=await ot(this.options.project,this.options.storage);if(r||(r=await re(this.options.project,this.options.storage)),!Wr(r))return null;let s=mt(this.options.project,!1),o=s?s.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],i=v(JSON.stringify(Dr(r))),c=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),u=new Date().toISOString(),a={version:1,id:c,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:u,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:n},goal:r.goal,plan:r.plan,progress:r.progress,currentPhase:r.currentPhase,currentTask:r.currentTask,incompletePhases:r.phases.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:r.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:[...o,...r.warnings].slice(0,20),filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:i},d=`projects/${this.options.project.id}/work/handoffs/${c}.json`;await this.options.storage.exists(d)||await this.options.storage.put(d,JSON.stringify(a,null,2)+`
67
- `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(a,null,2)+`
68
- `,"application/json");let l=ke(this.options.project.rootPath,".toolnet","work","handoffs");return zr(l,{recursive:!0}),O(ke(l,`${c}.json`),a),O(ke(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),a),a}};var ce=class{identity;wal;remote;sanitizer=new D;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=De(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Z(this.identity),this.remote=new X(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new ee({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new se({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new ie({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new ae({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){return this.wal.append([this.sanitizeEvent(e)])[0]}recordMany(e){return this.wal.append(e.map(n=>this.sanitizeEvent(n)))}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as Br,openSync as qr,closeSync as Jr,readSync as Vr,statSync as Ur}from"node:fs";function Hr(t){let e=typeof t.role=="string"?t.role:"",n=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||n.includes("user")?"user_prompt":e==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":n.includes("error")?"error":"message"}function Yr(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let n of e){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function gt(t,e={offset:0}){if(!Br(t))return{events:[],nextOffset:e.offset,reset:!1};let n=Ur(t).size,r=e.offset>n,s=r?0:e.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),c=qr(t,"r");try{Vr(c,i,0,o,s)}finally{Jr(c)}let u=i.toString("utf8"),a=u.lastIndexOf(`
69
- `);if(a<0)return{events:[],nextOffset:s,reset:r};let d=u.slice(0,a+1),l=Buffer.byteLength(d,"utf8"),m=[],p=0;for(let S of d.split(`
70
- `)){if(!S)continue;let y=Buffer.byteLength(S+`
71
- `,"utf8"),g=s+p;p+=y;let h;try{h=JSON.parse(S)}catch{m.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:S},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}});continue}let b=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};m.push({type:Hr(b),timestamp:Yr(b),role:typeof b.role=="string"?b.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:b,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}})}return{events:m,nextOffset:s+l,reset:r}}var Gr=[/^<SYSTEM MESSAGE>/i,/^<EPHEMERAL MESSAGE>/i,/^<system>/i,/^<ephemeral>/i,/^ManageTask:/i,/^Task \d+ status:/i,/^Task \d+ killed/i,/^Task \d+ loading/i,/^Thought for \d+ tokens/i,/^Prioritizing Tool Usage/i,/^Tool call:/i,/^Tool response:/i,/^npm notice/i,/^npm WARN/i,/^added \d+ packages/i,/^removed \d+ packages/i,/^up to date/i,/^\d+ packages are looking for funding/i,/^run `npm fund` for details/i,/^[\d.]+%/,/^\[={10,}\]/,/^Loading\.\.\./i,/^Processing\.\.\./i,/^bash-\d+\.\d+\$/,/^\$ /,/^\s*$/],Xr=[/api[_-]?key[:\s=]+[^\s]+/gi,/token[:\s=]+[^\s]+/gi,/secret[:\s=]+[^\s]+/gi,/password[:\s=]+[^\s]+/gi,/bearer\s+[^\s]+/gi,/authorization:\s*[^\s]+/gi],Zr=["decision","decided","rule","convention","architecture","pattern","fixed","resolved","implemented","created","updated","deleted","deployed","blocker","blocked","issue","bug","error","next","todo","action","requirement","must","should","important"];function Qr(t){let e=t.toLowerCase();return Zr.some(n=>e.includes(n))}function es(t){if(!t.trim())return!0;for(let e of Gr)if(e.test(t))return!0;return Qr(t),!1}function ts(t){let e=t;for(let n of Xr)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function we(t){let e=t.trim();return e?es(e)?{content:"",filtered:!0,reason:"noise"}:{content:ts(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function ue(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=we(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=ue(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=we(s);return o.filtered?null:o.content}return s&&typeof s=="object"?ue(s):s}).filter(s=>s!==null):e[n]=r;return e}function yt(t){let e=typeof t.type=="string"?t.type.toLowerCase():"";if(e.includes("system")||e.includes("ephemeral")||e==="tool_call"&&!t.result)return!0;if(t.data&&typeof t.data=="object"){let n=t.data,r=typeof n.content=="string"?n.content:"";if(r&&we(r).filtered)return!0}return!1}function ns(t){return t?Math.ceil(t.length/3.5):0}function ht(t,e){if(!t)return"";if(ns(t)<=e)return t;let r=Math.floor(e*3.5),s=t.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
72
- `),c=Math.max(o,i);return c>r*.7?s.slice(0,c+1):s}function R(){let t=q(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),c=n,u=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:c,archiveRemote:u}}function St(t){return(t||R()).rawTranscript}function vt(t){return(t||R()).durableMemoryMaxItemsPerSession}function bt(t){return(t||R()).sessionSummaryMaxTokens}function kt(t){return(t||R()).archiveRemote}function rs(t){return t.replace(/\b[A-Za-z0-9_-]{20,}\b/g,"[REDACTED]").replace(/api[_-]?key[:\s=]+[^\s]+/gi,"api_key=[REDACTED]").replace(/token[:\s=]+[^\s]+/gi,"token=[REDACTED]").replace(/secret[:\s=]+[^\s]+/gi,"secret=[REDACTED]").replace(/password[:\s=]+[^\s]+/gi,"password=[REDACTED]")}function ss(t,e){let n=t.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function os(t,e){let n=[],r=new Set;for(let i of t){let c=i.split(`
73
- `).filter(u=>u.trim());for(let u of c){let a=u.trim();if(a.length<15)continue;let d=a.toLowerCase().replace(/\s+/g," ");if(r.has(d))continue;r.add(d);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(l="file");let m=ss(a,l);if(m<.3)continue;let p=rs(a);n.push({category:l,text:p,importance:m,sourceSessionId:e})}}let s=R(),o=vt(s);return n.sort((i,c)=>c.importance-i.importance).slice(0,o)}function is(t){let e=R(),n=bt(e),o=t.join(`
74
-
75
- `).split(`
76
- `).filter(i=>{let c=i.trim();return c.length>20&&!c.startsWith("npm")&&!c.startsWith("\u2713")&&!c.startsWith("Error:")}).slice(0,20).join(`
77
- `);return ht(o,n)}function wt(t,e){let r=(Array.isArray(t)?t:t.split(`
78
-
79
- `).filter(p=>p.trim())).map(p=>typeof p=="string"?p:JSON.stringify(p)).filter(p=>p.trim()),s=os(r,e),o=s.filter(p=>p.category==="decision").map(p=>p.text),i=s.filter(p=>p.category==="rule").map(p=>p.text),c=s.filter(p=>p.category==="file").map(p=>p.text),u=s.filter(p=>p.category==="fix").map(p=>p.text),a=s.filter(p=>p.category==="blocker").map(p=>p.text),d=s.filter(p=>p.category==="next_action").map(p=>p.text),l=s.filter(p=>p.category==="deploy").map(p=>p.text);return{summary:is(r),decisions:o,projectRules:i,filesChanged:c,bugsFixed:u,commands:l,blockers:a,nextActions:d,durableFacts:s}}function cs(t){return t==="~"?xe():t.startsWith("~/")?xt(xe(),t.slice(2)):t}async function le(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let n=as(cs(t.transcriptPath)),r=new ce({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,c=gt(n,{offset:Number.isFinite(i)?i:0}),u=[];s.lastSequence===0&&u.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:n,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),c.reset&&u.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${c.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let a=c.events.filter(m=>!yt(m.data)).map(m=>({...m,data:ue(m.data)}));u.push(...a),t.phase==="stop"&&(t.error&&u.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",c.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&u.push({type:"session_idle",sourceEventId:["agy",e,"idle",c.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let d=r.recordMany(u);if(r.setSourceCursor("agy.transcript.offset",c.nextOffset),t.phase&&r.setSourceCursor("agy.last.phase",t.phase),t.phase==="stop"&&a.length>0)try{let m=a.map(S=>JSON.stringify(S.data)),p=wt(m,e);r.setSourceCursor("agy.session.summary",p.summary),r.setSourceCursor("agy.session.facts_count",p.durableFacts.length),St()&&(kt()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await r.flush();return{conversationId:e,imported:d.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:c.nextOffset,reset:c.reset}}function jt(t){return xt(xe(),".gemini","antigravity-cli","brain",t,".system_generated","logs","transcript.jsonl")}import{existsSync as us,mkdirSync as ls,readFileSync as ps,writeFileSync as ds}from"node:fs";import{homedir as fs}from"node:os";import{dirname as ms,join as gs}from"node:path";function ys(t){return`'${t.replace(/'/g,"'\\''")}'`}function It(t={}){let e=t.hooksFile??gs(fs(),".gemini","config","hooks.json");ls(ms(e),{recursive:!0});let n={};if(us(e))try{n=JSON.parse(ps(e,"utf8"))}catch(o){throw new Error(`Invalid existing Agy hooks.json: ${o instanceof Error?o.message:String(o)}`)}let r=t.binary??"toolnet-memory",s=`${ys(r)} session:agy-hook`;return n["toolnet-memory"]={enabled:!0,PreInvocation:[{type:"command",command:`${s} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${s} post`,timeout:15}],Stop:[{type:"command",command:`${s} stop`,timeout:30}]},ds(e,JSON.stringify(n,null,2)+`
80
- `,{encoding:"utf8",mode:384}),e}import{existsSync as Pt}from"node:fs";import{homedir as hs}from"node:os";import{join as Ss,resolve as Ot}from"node:path";import{DatabaseSync as vs}from"node:sqlite";function Et(t){if(t.startsWith("file://"))try{return decodeURIComponent(new URL(t).pathname)}catch{return t}return t}function bs(t){if(typeof t!="string"||!t)return[];try{let e=JSON.parse(t);if(Array.isArray(e))return e.filter(n=>typeof n=="string").map(Et)}catch{}return[Et(t)]}function ks(t,e){let n=Ot(t.rootPath);return e.some(r=>{let s=Ot(r);return s===n||s.startsWith(n+"/")||n.startsWith(s+"/")})}async function At(t,e,n=10){console.log(`Recovering Agy sessions for project: ${t.name}`),console.log(`Limit: ${n} sessions`),console.log("");let r=process.env.AGY_SUMMARY_DB??Ss(hs(),".gemini","antigravity-cli","conversation_summaries.db");if(!Pt(r))throw new Error(`Agy summary database not found: ${r}`);let s=new vs(r,{readOnly:!0});s.exec("PRAGMA query_only = ON");let o=s.prepare(`
94
+ `;function xr(t){return cc(t.rootPath,".toolnet","PROJECT.md")}function lc(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function dc(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=lc(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:v(a).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function pc(t){let e=xr(t);return br(e)||(sc(ac(e),{recursive:!0}),ic(e,uc,{encoding:"utf8",mode:384})),e}function Ar(t,e=!1){let n=e?pc(t):xr(t);if(!br(n))return null;if(vr(n).size>wr)throw new Error(`PROJECT.md exceeds ${wr} bytes`);let s=oc(n,"utf8");return{path:n,content:s,digest:v(s),rules:dc(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(vr(n).mtimeMs).toISOString()}}import{existsSync as mc,mkdirSync as fc,readFileSync as gc,renameSync as yc,writeFileSync as hc}from"node:fs";import{dirname as Sc,join as kc}from"node:path";function vc(t,e){fc(Sc(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;hc(n,`${JSON.stringify(e,null,2)}
95
+ `,{encoding:"utf8",mode:384}),yc(n,t)}function Er(t){return kc(t.rootPath,".toolnet","work","current.json")}function Mt(t){let e=Er(t);if(!mc(e))return null;try{let n=JSON.parse(gc(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Ye(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function N(t,e,n){let r=[],s=new Set;for(let o of[...t,...e].reverse()){let i=Ye(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function wc(t,e,n=20){let r=new Map;for(let s of[...t,...e]){let o=`${s.kind}|${Ye(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function bc(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function jr(t,e){let n=e.status??t?.status??"pending",r=n;t?.status==="completed"&&n!=="completed"&&(r="completed"),t&&n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status);let s=t&&bc(e)?t.title:e.text;return{id:t?.id??e.id,title:s,status:r,order:e.order??t?.order,confidence:Math.max(t?.confidence??0,e.confidence),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}function Ir(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:Ye(n.title);e.set(r,n)}return e}function Cr(t){return t.order!==void 0?`order:${t.order}`:Ye(t.key||t.text)}function Pr(t){return Array.from(t).sort((e,n)=>{let r=e.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:e.updatedAt.localeCompare(n.updatedAt)})}function Mr(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function Or(t,e){let n=Mt(t),r=Ir(n?.phases??[]),s=Ir(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,p=[],m=[],d=[],l=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],C=[],M=[],I=[],E=[...e].sort((f,b)=>{let z=f.occurredAt.localeCompare(b.occurredAt);return z!==0?z:f.sequence-b.sequence});for(let f of E)switch(f.kind){case"request":o=f.text;break;case"activity":i=f.text;break;case"goal":a=f.text;break;case"plan":c=f.text;break;case"phase":{let b=Cr(f);r.set(b,jr(r.get(b),f));break}case"task":{let b=Cr(f);s.set(b,jr(s.get(b),f));break}case"decision":p.push(f.text);break;case"blocker":m.push(f.text);break;case"warning":d.push(f.text);break;case"next_action":l.push(f.text);break;case"file":{g.push(f.text);let b=f.fileAction??"active",z=S.indexOf(f.text);z>=0&&S.splice(z,1),b!=="deleted"&&S.push(f.text),b==="modified"?y.push(f.text):b==="created"?h.push(f.text):b==="deleted"&&k.push(f.text);break}case"command":C.push(f.text);break;case"test":M.push(f.text),f.checkKind&&I.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":u={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=Pr(r.values()),w=Pr(s.values()),F=Mr(x),L=Mr(w),at=N(n?.nextActions??[],[...l,...L?[L.title]:[],...!L&&F?[F.title]:[],...w.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),ct=N(n?.blockers??[],[...m,...x.filter(f=>f.status==="blocked").map(f=>f.title),...w.filter(f=>f.status==="blocked").map(f=>f.title)],20),se=E.length>0?E[E.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),oe={version:1,projectId:t.id,projectName:t.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:w,decisions:N(n?.decisions??[],p,20),blockers:ct,warnings:N(n?.warnings??[],d,20),nextActions:at,filesTouched:N(n?.filesTouched??[],g,30),activeFiles:N([],S,5),modifiedFiles:N(n?.modifiedFiles??[],y,30),createdFiles:N(n?.createdFiles??[],h,30),deletedFiles:N(n?.deletedFiles??[],k,30),commands:N(n?.commands??[],C,20),tests:N(n?.tests??[],M,20),checks:wc(n?.checks??[],I,20),currentPhase:F,currentTask:L,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+w.filter(f=>f.status==="blocked").length},lastSession:u,updatedAt:se};return vc(Er(t),oe),oe}function P(t,e){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function Tr(t){if(t)return{id:t.id,title:t.title,status:t.status}}function xc(t,e=[]){let n=e.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=t.slice(-10).join(`
96
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Ac(t){return v(JSON.stringify(t))}function Rr(t){let{project:e,identity:n,state:r}=t,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(k=>k.status==="completed").map(k=>k.title),i=r.tasks.filter(k=>k.status==="completed").map(k=>k.title),a=r.phases.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),c=r.tasks.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),u=new Set(r.tasks.filter(k=>k.status==="completed").map(k=>k.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),p=P(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),m=P([...c,...p],15),d=P(r.tests.slice().reverse(),10),l=P([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={schema:"toolnet.handoff.v2",version:2,project:{id:e.id,name:e.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:t.sequence,reason:t.reason},capturedAt:t.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:Tr(r.currentPhase),task:Tr(r.currentTask),file:s},completed:{phases:P(o,20),tasks:P(i,30)},remaining:{phases:P(a,20),tasks:P(c,30),todos:m},nextAction:p[0],blockers:P(r.blockers.slice().reverse(),10),decisions:P(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:P(r.activeFiles??[],10),modified:P(r.modifiedFiles??[],20),created:P(r.createdFiles??[],20),deleted:P(r.deletedFiles??[],20)},tests:{status:xc(r.tests,r.checks),recent:d,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},attention:P(t.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:Ac(h)}}function Cc(t){return!!(t.currentRequest||t.currentActivity||t.goal||t.plan||t.phases.length>0||t.tasks.length>0||t.nextActions.length>0||t.blockers.length>0||t.decisions.length>0||t.filesTouched.length>0)}function Nr(t,e,n,r,s){if(!Cc(n))return null;let o=Ar(t,!1),a=[...o?o.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...n.warnings].slice(0,20),c=Rr({project:t,identity:e,state:n,reason:r,sequence:s,attention:a}),u=c.stateDigest;return{version:1,id:v([t.id,e.sessionKey,u].join("|")).slice(0,24),projectId:t.id,projectName:t.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,sequence:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:n.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,filesTouched:n.filesTouched.slice(-20),activeFiles:n.activeFiles?.slice(-10),modifiedFiles:n.modifiedFiles?.slice(-20),createdFiles:n.createdFiles?.slice(-20),deletedFiles:n.deletedFiles?.slice(-20),tests:n.tests.slice(-15),checks:n.checks?.slice(-10),stateDigest:u,continuity:c}}function _r(t,e){let n=Et(t.rootPath,".toolnet","work","handoffs");Ic(n,{recursive:!0});let r=Et(n,`${e.id}.json`);jc(r)||O(r,e),O(Et(t.rootPath,".toolnet","work","handoff-latest.json"),e)}function Kr(t){let e=Nr(t.project,t.identity,t.state,t.reason,t.sequence);return e?(_r(t.project,e),e):null}var Xe=class{constructor(e){this.options=e}options;async capture(e,n){let r=Mt(this.options.project);r||(r=await gr(this.options.project,this.options.storage)),r||(r=await Je(this.options.project,this.options.storage));let s=Nr(this.options.project,this.options.identity,r,e,n);if(!s)return null;_r(this.options.project,s);let o=`projects/${this.options.project.id}/work/handoffs/${s.id}.json`;return await this.options.storage.exists(o)||await this.options.storage.put(o,JSON.stringify(s,null,2)+`
97
+ `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
98
+ `,"application/json"),s}};import{existsSync as Pc,readFileSync as Mc,writeFileSync as Ec}from"node:fs";import{join as Oc}from"node:path";var Wr="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Ot="<!-- TOOLNET:STABLE-WORK:END -->";function Tt(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function $r(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${Tt(n)} ${n.title}`)]:[]}function Tc(t){let e=[Wr,"# ToolNet Stable Work State","",`Updated: ${t.updatedAt}`];return t.lastSession&&e.push(`Last agent: ${t.lastSession.agent}`,`Last session: ${t.lastSession.nativeSessionId}`),t.currentRequest&&e.push("","Current request:",t.currentRequest),t.currentActivity&&e.push("","Current activity:",t.currentActivity),t.goal&&e.push("","Goal:",t.goal),t.plan&&e.push("","Plan:",t.plan),t.currentPhase&&e.push("","Current phase:",`${Tt(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${Tt(t.currentTask)} ${t.currentTask.title}`),e.push(...$r("Phases",t.phases)),e.push(...$r("TODO / Tasks",t.tasks)),e.push(...W("Next actions",t.nextActions)),e.push(...W("Blockers",t.blockers)),e.push(...W("Important decisions",t.decisions)),e.push(...W("Active files",t.activeFiles??[])),e.push(...W("Modified files",t.modifiedFiles??[])),e.push(...W("Created files",t.createdFiles??[])),e.push(...W("Deleted files",t.deletedFiles??[])),e.push(...W("Files touched",t.filesTouched)),e.push(...W("Recent commands",t.commands??[])),e.push(...W("Checks",(t.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),e.push("","Progress:",`- Phases: ${t.progress.phasesCompleted}/${t.progress.phasesTotal}`,`- Tasks: ${t.progress.tasksCompleted}/${t.progress.tasksTotal}`,`- Blocked: ${t.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",Ot),e.join(`
99
+ `)}function Fr(t,e){let n=Oc(t.rootPath,".toolnet","current.md"),r="";if(Pc(n))try{r=Mc(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=Tc(e),o=r.indexOf(Wr),i=r.indexOf(Ot),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+Ot.length).trimStart()].filter(Boolean).join(`
100
+
101
+ `):a=r.trim()?`${r.trim()}
102
+
103
+ ${s}`:s,Ec(n,`${a.trim()}
104
+ `,{encoding:"utf8",mode:384})}import{existsSync as Hm,mkdirSync as Rc,readFileSync as Um,renameSync as Nc,writeFileSync as _c}from"node:fs";import{dirname as Kc,join as $c}from"node:path";function Wc(t){return $c(t.rootPath,".toolnet","context","session-origin.json")}function Fc(t,e){Rc(Kc(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;_c(n,`${JSON.stringify(e,null,2)}
105
+ `,{encoding:"utf8",mode:384}),Nc(n,t)}function Qe(t,e){return[...t].filter(n=>n.kind===e).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function Lr(t,e){let n=Qe(e.observations,"file"),r=Qe(e.observations,"next_action"),s=Qe(e.observations,"blocker"),o=Qe(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentRequest:e.workState.currentRequest,currentActivity:e.workState.currentActivity,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??e.workState.activeFiles?.at(-1)??e.workState.filesTouched.at(-1),latestNextAction:r?.text??e.workState.nextActions.at(-1),latestBlocker:s?.text??e.workState.blockers.at(-1),latestDecision:o?.text??e.workState.decisions.at(-1)};return Fc(Wc(t),i),i}import{existsSync as Dr,mkdirSync as Lc,readFileSync as Dc}from"node:fs";import{join as Rt}from"node:path";function zr(t){return Rt(t.rootPath,".toolnet","memory","checkpoints")}function qr(t){return Rt(zr(t),"latest.json")}function zc(t){let e=qr(t);if(!Dr(e))return null;try{let n=JSON.parse(Dc(e,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==t.id?null:n}catch{return null}}function qc(t){return["rule","architecture","decision","fix"].includes(t)}function Bc(t,e){return e.length===0?[]:Re(t,e).candidates.filter(r=>qc(r.kind)&&r.knowledgeClass!=="transient"&&r.importanceScore>=.65).map(r=>({fingerprint:r.fingerprint,kind:r.kind,content:r.content,knowledgeClass:r.knowledgeClass,importanceScore:r.importanceScore,confidence:r.confidence,createdAt:r.createdAt,agent:t.agent,nativeSessionId:t.nativeSessionId}))}function Vc(t,e){let n=new Map;for(let r of[...t,...e]){let s=n.get(r.fingerprint);(!s||r.importanceScore>s.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,s)=>s.importanceScore-r.importanceScore||s.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Jc(t){return{request:t.currentRequest,activity:t.currentActivity,goal:t.goal,phase:t.currentPhase?{title:t.currentPhase.title,status:t.currentPhase.status}:void 0,task:t.currentTask?{title:t.currentTask.title,status:t.currentTask.status}:void 0,phases:t.phases.map(e=>({title:e.title,status:e.status})),tasks:t.tasks.map(e=>({title:e.title,status:e.status})),activeFiles:t.activeFiles??[],modifiedFiles:t.modifiedFiles??[],createdFiles:t.createdFiles??[],deletedFiles:t.deletedFiles??[],checks:t.checks??[],blockers:t.blockers,decisions:t.decisions,nextActions:t.nextActions}}function Br(t,e,n,r){let s=zc(t),o=Vc(s?.durableFacts??[],Bc(e,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),p=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),m={work:Jc(r),durableFacts:o.map(y=>y.fingerprint).sort()},d=v(JSON.stringify(m)).slice(0,32),l={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:t.id,name:t.name},source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:p},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:d},g=zr(t);Lc(g,{recursive:!0,mode:448});let S=Rt(g,`${d}.json`);return Dr(S)||O(S,l),O(qr(t),l),l}function Vr(t,e,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Be(e,n);if(r.length===0)return{updated:!1,observations:0};let s=Or(t,r);Fr(t,s),Lr(t,{agent:e.agent,nativeSessionId:e.nativeSessionId,observations:r,workState:s});try{Br(t,e,n,s)}catch{}try{Kr({project:t,identity:e,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var Ze=class{identity;wal;remote;sanitizer=new J;learner;continuity;semantic;handoff;project;title;metadata;constructor(e){this.project=e.project,this.identity=Zt(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Ee(this.identity,e.eventContext),this.remote=new Me(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new ze({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new Ge({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Ue({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new Xe({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}checkpointLocal(e){if(e.length!==0)try{Vr(this.project,this.identity,e)}catch{}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){let n=this.wal.append([this.sanitizeEvent(e)]);return this.checkpointLocal(n),n[0]}recordMany(e){let n=this.wal.append(e.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as Gc,openSync as Hc,closeSync as Uc,readSync as Yc,statSync as Xc}from"node:fs";function Qc(t){let e=typeof t.role=="string"?t.role:"",n=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||n.includes("user")?"user_prompt":e==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":n.includes("error")?"error":"message"}function Zc(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let n of e){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function Jr(t,e={offset:0}){if(!Gc(t))return{events:[],nextOffset:e.offset,reset:!1};let n=Xc(t).size,r=e.offset>n,s=r?0:e.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),a=Hc(t,"r");try{Yc(a,i,0,o,s)}finally{Uc(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
106
+ `);if(u<0)return{events:[],nextOffset:s,reset:r};let p=c.slice(0,u+1),m=Buffer.byteLength(p,"utf8"),d=[],l=0;for(let g of p.split(`
107
+ `)){if(!g)continue;let S=Buffer.byteLength(g+`
108
+ `,"utf8"),y=s+l;l+=S;let h;try{h=JSON.parse(g)}catch{d.push({type:"custom",sourceEventId:`transcript:${y}`,sourceSequence:y,data:{format:"raw-line",content:g},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:y}});continue}let k=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};d.push({type:Qc(k),timestamp:Zc(k),role:typeof k.role=="string"?k.role:void 0,sourceEventId:`transcript:${y}`,sourceSequence:y,data:k,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:y}})}return{events:d,nextOffset:s+m,reset:r}}var eu=[/^<SYSTEM MESSAGE>/i,/^<EPHEMERAL MESSAGE>/i,/^<system>/i,/^<ephemeral>/i,/^ManageTask:/i,/^Task \d+ status:/i,/^Task \d+ killed/i,/^Task \d+ loading/i,/^Thought for \d+ tokens/i,/^Prioritizing Tool Usage/i,/^Tool call:/i,/^Tool response:/i,/^npm notice/i,/^npm WARN/i,/^added \d+ packages/i,/^removed \d+ packages/i,/^up to date/i,/^\d+ packages are looking for funding/i,/^run `npm fund` for details/i,/^[\d.]+%/,/^\[={10,}\]/,/^Loading\.\.\./i,/^Processing\.\.\./i,/^bash-\d+\.\d+\$/,/^\$ /,/^\s*$/],tu=[/api[_-]?key[:\s=]+[^\s]+/gi,/token[:\s=]+[^\s]+/gi,/secret[:\s=]+[^\s]+/gi,/password[:\s=]+[^\s]+/gi,/bearer\s+[^\s]+/gi,/authorization:\s*[^\s]+/gi],nu=["decision","decided","rule","convention","architecture","pattern","fixed","resolved","implemented","created","updated","deleted","deployed","blocker","blocked","issue","bug","error","next","todo","action","requirement","must","should","important"];function ru(t){let e=t.toLowerCase();return nu.some(n=>e.includes(n))}function su(t){if(!t.trim())return!0;for(let e of eu)if(e.test(t))return!0;return ru(t),!1}function ou(t){let e=t;for(let n of tu)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function Nt(t){let e=t.trim();return e?su(e)?{content:"",filtered:!0,reason:"noise"}:{content:ou(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function et(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=Nt(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=et(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=Nt(s);return o.filtered?null:o.content}return s&&typeof s=="object"?et(s):s}).filter(s=>s!==null):e[n]=r;return e}function Gr(t){let e=typeof t.type=="string"?t.type.toLowerCase():"";if(e.includes("system")||e.includes("ephemeral")||e==="tool_call"&&!t.result)return!0;if(t.data&&typeof t.data=="object"){let n=t.data,r=typeof n.content=="string"?n.content:"";if(r&&Nt(r).filtered)return!0}return!1}function au(t){return t==="~"?_t():t.startsWith("~/")?Hr(_t(),t.slice(2)):t}async function tt(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let n=iu(au(t.transcriptPath)),r=new Ze({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName},eventContext:{source:"agy",cwd:t.workspacePaths?.[0]??t.project.rootPath}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,a=Jr(n,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:n,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(d=>!Gr(d.data)).map(d=>({...d,data:et(d.data)}));c.push(...u),t.phase==="stop"&&(t.error&&c.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",a.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",e,"idle",a.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let p=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),t.phase&&r.setSourceCursor("agy.last.phase",t.phase),u.length>0)try{let d=u.map(g=>JSON.stringify(g.data)),l=Te(d,e);r.setSourceCursor("agy.session.summary",l.summary),r.setSourceCursor("agy.session.facts_count",l.durableFacts.length),yn()&&(kn()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let m=await r.flush();return{conversationId:e,imported:p.length,eventCount:m.eventCount,chunkCount:m.chunkCount,status:m.status,transcriptOffset:a.nextOffset,reset:a.reset}}function Ur(t){return Hr(_t(),".gemini","antigravity-cli","brain",t,".system_generated","logs","transcript.jsonl")}import{existsSync as ot,mkdirSync as ss,readFileSync as os,renameSync as ju,writeFileSync as Iu}from"node:fs";import{dirname as Cu,join as st}from"node:path";import{existsSync as lu,mkdirSync as du,readFileSync as pu,renameSync as mu,rmSync as fu,writeFileSync as gu}from"node:fs";import{dirname as yu}from"node:path";import{homedir as cu}from"node:os";import{join as re}from"node:path";function Yr(t={}){return re(t.home??cu(),".gemini")}function Xr(t={}){return re(Yr(t),"config")}function nt(t={}){return re(Xr(t),"mcp_config.json")}function rt(t={}){return re(Xr(t),"hooks.json")}function uu(t={}){return re(Yr(t),"antigravity-cli")}function Qr(t="toolnet-memory",e={}){return re(uu(e),"plugins",t)}function hu(t){return`'${t.replace(/'/g,"'\\''")}'`}function Zr(t={}){let e=t.hooksFile??rt();du(yu(e),{recursive:!0,mode:448});let n={};if(lu(e)){let i;try{i=JSON.parse(pu(e,"utf8"))}catch(a){throw new Error(`Invalid existing Agy hooks.json: ${a instanceof Error?a.message:String(a)}`)}if(typeof i!="object"||i===null||Array.isArray(i))throw new Error("Invalid existing Agy hooks.json: root must be a JSON object.");n=i}let r=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",s=`${hu(r)} session:agy-hook`;n["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${s} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${s} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${s} post`,timeout:15}],Stop:[{type:"command",command:`${s} stop`,timeout:30}]};let o=`${e}.tmp-${process.pid}-${Date.now()}`;try{gu(o,JSON.stringify(n,null,2)+`
109
+ `,{encoding:"utf8",mode:384}),mu(o,e)}finally{fu(o,{force:!0})}return e}import{existsSync as Su,mkdirSync as ku,readFileSync as vu,renameSync as wu,writeFileSync as bu}from"node:fs";import{dirname as xu}from"node:path";function we(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Au(t,e){ku(xu(t),{recursive:!0,mode:448});let n=`${t}.tmp-${process.pid}-${Date.now()}`;bu(n,`${JSON.stringify(e,null,2)}
110
+ `,{encoding:"utf8",mode:384}),wu(n,t)}function es(t){if(!Su(t))return{};let e=vu(t,"utf8").trim();if(!e)return{};let n;try{n=JSON.parse(e)}catch(r){throw new Error(`Invalid existing Agy MCP config: ${r instanceof Error?r.message:String(r)}`)}if(!we(n))throw new Error("Invalid existing Agy MCP config: root must be a JSON object.");return n}function ts(t,e){return we(t)?t.command===e&&Array.isArray(t.args)&&t.args.length===1&&t.args[0]==="mcp":!1}function ns(t={}){let e=t.configFile??nt(),n=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=t.serverName??"toolnet-memory",s=es(e),o=s.mcpServers;if(o!==void 0&&!we(o))throw new Error("Invalid existing Agy MCP config: mcpServers must be an object.");let i=we(o)?{...o}:{},a=i[r];if(ts(a,n))return{installed:!0,changed:!1,configFile:e,serverName:r,command:n,args:["mcp"]};i[r]={command:n,args:["mcp"]};let c={...s,mcpServers:i};Au(e,c);let p=es(e).mcpServers;if(!we(p)||!ts(p[r],n))throw new Error("Agy MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:e,serverName:r,command:n,args:["mcp"]}}var Pu=`# ToolNet Memory Continuity
111
+
112
+ ToolNet Memory is the authoritative continuity layer for previous project work.
113
+
114
+ ## Resume / continue behavior
115
+
116
+ Whenever the user asks to continue, resume, finish, pick up, return to, or complete previous work:
117
+
118
+ 1. FIRST call the ToolNet Memory MCP tool \`memory_agent_ask\`.
119
+ 2. Use ToolNet's compact continuity result to determine:
120
+ - current task
121
+ - completed work
122
+ - current or last file
123
+ - TODOs
124
+ - blockers
125
+ - next action
126
+ 3. Only AFTER continuity is known may you inspect current source or git to verify repository truth.
127
+
128
+ ## Forbidden continuity recovery
129
+
130
+ Do NOT reconstruct previous work by reading, listing, searching, or shelling into:
131
+
132
+ - \`.toolnet/sessions/**\`
133
+ - \`state.json\`
134
+ - \`events.jsonl\`
135
+ - raw transcripts
136
+ - \`~/.gemini/antigravity-cli/brain/**\`
137
+ - Antigravity \`transcript.jsonl\`
138
+ - another coding agent's internal session history
139
+
140
+ Do NOT run Bash/cat/tail/grep against those locations to discover previous work.
141
+
142
+ Do NOT search the filesystem for the implementation or schema of \`memory_agent_ask\`.
143
+ Invoke the MCP tool directly.
144
+
145
+ For direct continuity facts, prefer \`mode="local"\`.
146
+ Use \`mode="ai"\` only when continuity is ambiguous or requires synthesis.
147
+
148
+ Current repository evidence overrides stale memory after ToolNet has restored the working context.
149
+
150
+ Do not ask the user to repeat context already available through ToolNet Memory.
151
+ `;function is(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Kt(t,e){ss(Cu(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Iu(n,e,{encoding:"utf8",mode:384}),ju(n,t)}function rs(t,e){ot(t)&&os(t,"utf8")===e||Kt(t,e)}function as(t){if(!ot(t))return{};let e=os(t,"utf8").trim();if(!e)return{};let n;try{n=JSON.parse(e)}catch(r){throw new Error(`Invalid legacy Antigravity config ${t}: ${r instanceof Error?r.message:String(r)}`)}if(!is(n))throw new Error(`Invalid legacy Antigravity config ${t}: root must be object`);return n}function Mu(t,e){if(!ot(t))return!1;let n=as(t);if(!is(n.mcpServers)||!Object.prototype.hasOwnProperty.call(n.mcpServers,e))return!1;let r={...n.mcpServers};return delete r[e],Kt(t,`${JSON.stringify({...n,mcpServers:r},null,2)}
152
+ `),!0}function Eu(t){if(!ot(t))return!1;let e=as(t);if(!Object.prototype.hasOwnProperty.call(e,"toolnet-memory"))return!1;let n={...e};return delete n["toolnet-memory"],Kt(t,`${JSON.stringify(n,null,2)}
153
+ `),!0}function cs(t={}){let e=t.pluginName??"toolnet-memory",n=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=t.pluginRoot??Qr(e),s=st(r,"plugin.json"),o=st(r,"mcp_config.json"),i=st(r,"hooks.json"),a=st(r,"rules","toolnet-memory-continuity.md");ss(r,{recursive:!0,mode:448}),rs(s,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:e,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
154
+ `),ns({configFile:o,binary:n,serverName:"toolnet-memory"}),Zr({hooksFile:i,binary:n}),rs(a,`${Pu.trim()}
155
+ `);let c=t.legacyMcpFile??nt(),u=t.legacyHooksFile??rt(),p=[];return c!==o&&Mu(c,"toolnet-memory")&&p.push(c),u!==i&&Eu(u)&&p.push(u),{installed:!0,pluginRoot:r,files:[s,o,i,a],migratedLegacy:p}}import{existsSync as us}from"node:fs";import{homedir as Ou}from"node:os";import{join as Tu,resolve as ls}from"node:path";import{DatabaseSync as Ru}from"node:sqlite";function ds(t){if(t.startsWith("file://"))try{return decodeURIComponent(new URL(t).pathname)}catch{return t}return t}function Nu(t){if(typeof t!="string"||!t)return[];try{let e=JSON.parse(t);if(Array.isArray(e))return e.filter(n=>typeof n=="string").map(ds)}catch{}return[ds(t)]}function _u(t,e){let n=ls(t.rootPath);return e.some(r=>{let s=ls(r);return s===n||s.startsWith(n+"/")||n.startsWith(s+"/")})}async function ps(t,e,n=10){console.log(`Recovering Agy sessions for project: ${t.name}`),console.log(`Limit: ${n} sessions`),console.log("");let r=process.env.AGY_SUMMARY_DB??Tu(Ou(),".gemini","antigravity-cli","conversation_summaries.db");if(!us(r))throw new Error(`Agy summary database not found: ${r}`);let s=new Ru(r,{readOnly:!0});s.exec("PRAGMA query_only = ON");let o=s.prepare(`
81
156
  SELECT
82
157
  conversation_id,
83
158
  title,
@@ -87,10 +162,11 @@ Things an AI agent should always remember.
87
162
  FROM conversation_summaries
88
163
  ORDER BY
89
164
  last_user_input_time DESC
90
- `).all();s.close();let i=[],c=0,u=Math.min(o.length,n);for(let a of o){let d=typeof a.conversation_id=="string"?a.conversation_id:"";if(!d)continue;let l=bs(a.workspace_uris);if(!ks(t,l))continue;let m=jt(d);if(!Pt(m))continue;c++,console.log(`[${c}/${u}] Processing conversation: ${d.slice(0,8)}...`);let p=await le({project:t,storage:e,conversationId:d,transcriptPath:m,workspacePaths:l,modelName:typeof a.agent_name=="string"?a.agent_name:void 0,phase:"recover"});if(console.log(` \u2713 Imported ${p.imported} events (${p.eventCount} total, ${p.chunkCount} chunks)`),i.push(p),i.length>=n)break}return console.log(""),console.log(`\u2713 Recovery complete: ${i.length} sessions processed`),console.log(`Total events: ${i.reduce((a,d)=>a+d.eventCount,0)}`),console.log(`Total chunks: ${i.reduce((a,d)=>a+d.chunkCount,0)}`),i}function pe(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function ws(t){let e=q(),n=_e(Ce({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new G(n,t.id,t.name,t.remote??t.name)}async function xs(){let[t="help",...e]=process.argv.slice(2);if(t==="install-hooks"){let o=It({binary:pe(e,"--bin")});console.log(`\u2705 Agy hooks installed: ${o}`);return}let n=pe(e,"--project")??process.cwd(),r=new V().detect(n),s=ws(r);if(t==="sync"){let o=e[0],i=pe(e,"--transcript");if(!o||!i)throw new Error("Usage: sync <conversation-id> --transcript <path>");let c=await le({project:r,storage:s,conversationId:o,transcriptPath:i,phase:"recover"});console.log(JSON.stringify(c,null,2));return}if(t==="recover"){let o=Number(pe(e,"--limit")??100),i=await At(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((c,u)=>c+u.imported,0)},null,2));return}console.log(`Agy Session Adapter
165
+ `).all();s.close();let i=[],a=0,c=Math.min(o.length,n);for(let u of o){let p=typeof u.conversation_id=="string"?u.conversation_id:"";if(!p)continue;let m=Nu(u.workspace_uris);if(!_u(t,m))continue;let d=Ur(p);if(!us(d))continue;a++,console.log(`[${a}/${c}] Processing conversation: ${p.slice(0,8)}...`);let l=await tt({project:t,storage:e,conversationId:p,transcriptPath:d,workspacePaths:m,modelName:typeof u.agent_name=="string"?u.agent_name:void 0,phase:"recover"});if(console.log(` \u2713 Imported ${l.imported} events (${l.eventCount} total, ${l.chunkCount} chunks)`),i.push(l),i.length>=n)break}return console.log(""),console.log(`\u2713 Recovery complete: ${i.length} sessions processed`),console.log(`Total events: ${i.reduce((u,p)=>u+p.eventCount,0)}`),console.log(`Total chunks: ${i.reduce((u,p)=>u+p.chunkCount,0)}`),i}function it(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Ku(t){let e=be(),n=Gt(Vt({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new Pe(n,t.id,t.name,t.remote??t.name)}async function $u(){let[t="help",...e]=process.argv.slice(2);if(t==="install-hooks"||t==="install-plugin"){let o=cs({binary:it(e,"--bin")});console.log(`\u2705 ToolNet Antigravity plugin installed: ${o.pluginRoot}`);for(let i of o.files)console.log(` \u2713 ${i}`);o.migratedLegacy.length&&console.log(" \u2713 Legacy ToolNet Agy config migrated"),console.log(""),console.log("Restart Antigravity CLI before testing.");return}let n=it(e,"--project")??process.cwd(),r=new Ae().detect(n),s=Ku(r);if(t==="sync"){let o=e[0],i=it(e,"--transcript");if(!o||!i)throw new Error("Usage: sync <conversation-id> --transcript <path>");let a=await tt({project:r,storage:s,conversationId:o,transcriptPath:i,phase:"recover"});console.log(JSON.stringify(a,null,2));return}if(t==="recover"){let o=Number(it(e,"--limit")??100),i=await ps(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((a,c)=>a+c.imported,0)},null,2));return}console.log(`Agy Session Adapter
91
166
 
92
167
  Commands:
93
168
  install-hooks
169
+ install-plugin
94
170
  sync <conversation-id> --transcript <path>
95
171
  recover [--project PATH] [--limit N]
96
- `)}xs().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1)});
172
+ `)}$u().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1)});