toolnet-memory 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/codex.js CHANGED
@@ -1,52 +1,54 @@
1
- import{existsSync as au,readFileSync as cu}from"node:fs";import{spawn as uu}from"node:child_process";import{homedir as lu}from"node:os";import{join as du}from"node:path";import{existsSync as Xr,readFileSync as Qr}from"node:fs";import{homedir as Zr}from"node:os";import{join as es}from"node:path";function ts(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 ns(){let t=process.env.TOOLNET_GLOBAL_ENV??es(Zr(),".config","toolnet-memory",".env");if(!Xr(t))return;let e=Qr(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]=ts(r.slice(s+1)))}}ns();function X(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function Q(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function fe(){return{memory:{autoCapture:X(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:X(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:X(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:X(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:Q(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Q(process.env.MEMORY_RERANK_TOP,10),finalContext:Q(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Q(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:X(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:Q(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as rs}from"node:crypto";import{existsSync as Qe,mkdirSync as ss,readFileSync as os,renameSync as is,writeFileSync as as}from"node:fs";import{basename as cs,dirname as me,join as ge,parse as Et,resolve as Z}from"node:path";var Tt=".toolnet",us="project.json";function ls(t){return rs("sha256").update(t).digest("hex").slice(0,16)}function Ze(t){return ge(t,Tt,us)}function ds(t){return Qe(Ze(t))}function ps(t,e){let n=Z(t),r=Et(n).root;for(;;){if(ds(n))return n;if(n===r||e&&n===Z(e))break;let s=me(n);if(s===n)break;n=s}return null}function fs(t){let e=Z(t),n=Et(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>Qe(ge(e,o))))return e;if(e===n)break;let s=me(e);if(s===e)break;e=s}return Z(t)}function ms(t){let e;try{e=JSON.parse(os(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:me(me(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 At(t,e){let n=ge(t,Tt);ss(n,{recursive:!0});let r=Ze(t),s=`${r}.tmp-${process.pid}`;as(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),is(s,r)}function Mt(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 q=class{detect(e=process.cwd()){let n=Z(e),r=fs(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>Qe(ge(r,f))),i=ps(n,o?r:void 0);if(i){let f=Ze(i),d=ms(f);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),At(i,d)),Mt(d,i)}let a=new Date().toISOString(),c=cs(r),u={version:1,id:ls(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return At(r,u),Mt(u,r)}};var gs=[{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}],ye=class{scan(e){let n=[];for(let r of gs){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 ee=class{scanner=new ye;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 Ws}from"node:os";import{join as Ls}from"node:path";import{DeleteObjectCommand as ys,GetObjectCommand as hs,HeadObjectCommand as Ss,ListObjectsV2Command as ks,PutObjectCommand as ws,S3Client as vs}from"@aws-sdk/client-s3";import{getSignedUrl as bs}from"@aws-sdk/s3-request-presigner";var he=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new vs({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 ws({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await bs(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(`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 Ss({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 ys({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new ks({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 Ot,mkdir as xs,readFile as js,readdir as Is,rm as Ps,stat as Rt,writeFile as Cs}from"node:fs/promises";import{dirname as As,join as Ms,relative as Nt,resolve as Es}from"node:path";var te=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Es(this.root,n)}async put(e,n){let r=this.path(e);await xs(As(r),{recursive:!0}),await Cs(r,n)}async get(e){try{return await js(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 Ot(this.path(e)),!0}catch{return!1}}async delete(e){await Ps(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Ot(n)}catch{return r}let s=async i=>{let a=await Is(i,{withFileTypes:!0});for(let c of a){let u=Ms(i,c.name);if(c.isDirectory()){await s(u);continue}let f=await Rt(u);r.push({key:Nt(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Rt(n);return o.isDirectory()?await s(n):r.push({key:Nt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Ts,GetObjectCommand as Os,HeadObjectCommand as Rs,ListObjectsV2Command as Ns,PutObjectCommand as _s,S3Client as $s}from"@aws-sdk/client-s3";import{getSignedUrl as Ks}from"@aws-sdk/s3-request-presigner";var ne=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new $s({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 _s({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Ks(this.client,new Os({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 Rs({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 Ns({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 et(t,e){return console.warn(e),new te(t)}function _t(t){let e=t.localRoot??Ls(Ws(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ne({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):et(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 ne({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):et(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 he({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):et(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new te(e)}function Fs(t){return new Promise(e=>setTimeout(e,t))}async function $t(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 Fs(c+u)}throw o}var Ds=new Set(["put","get","getText","delete","list"]);function Kt(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Ds.has(r)?(...o)=>$t(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Wt(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 Lt(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 Se=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Wt(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=Lt(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{join as Gs}from"node:path";import{createHash as zs}from"node:crypto";import{dirname as Bs}from"node:path";import{mkdirSync as qs,readFileSync as Vs,renameSync as Hs,writeFileSync as Js}from"node:fs";function w(t){return zs("sha256").update(t).digest("hex")}function tt(t){if(Array.isArray(t))return t.map(tt);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=tt(e[r]);return n}return t}function Ft(t){return JSON.stringify(tt(t))}function Dt(t){try{return JSON.parse(Vs(t,"utf8"))}catch{return null}}function M(t,e){qs(Bs(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;Js(n,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),Hs(n,t)}function zt(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(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 Bt(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=zt(r.toLowerCase(),"agent"),i=zt(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:Gs(t.rootPath,".toolnet","sessions",o,i)}}function qt(t){return String(t).padStart(12,"0")}var ke=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)+`
1
+ import{existsSync as ol,readFileSync as il}from"node:fs";import{spawn as al}from"node:child_process";import{homedir as cl}from"node:os";import{join as ul}from"node:path";import{existsSync as As,readFileSync as Is}from"node:fs";import{homedir as Ps}from"node:os";import{join as Ms}from"node:path";function Es(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 Ts(){let t=process.env.TOOLNET_GLOBAL_ENV??Ms(Ps(),".config","toolnet-memory",".env");if(!As(t))return;let e=Is(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]=Es(r.slice(s+1)))}}Ts();function ce(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function ue(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function Ce(){return{memory:{autoCapture:ce(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ce(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ce(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ce(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ue(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ue(process.env.MEMORY_RERANK_TOP,10),finalContext:ue(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ue(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:ce(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:ue(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Os}from"node:crypto";import{existsSync as gt,mkdirSync as Rs,readFileSync as Ns,renameSync as _s,writeFileSync as $s}from"node:fs";import{basename as Ks,dirname as Ae,join as Ie,parse as Ut,resolve as le}from"node:path";var Yt=".toolnet",Fs="project.json";function Ws(t){return Os("sha256").update(t).digest("hex").slice(0,16)}function yt(t){return Ie(t,Yt,Fs)}function Ls(t){return gt(yt(t))}function Ds(t,e){let n=le(t),r=Ut(n).root;for(;;){if(Ls(n))return n;if(n===r||e&&n===le(e))break;let s=Ae(n);if(s===n)break;n=s}return null}function zs(t){let e=le(t),n=Ut(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>gt(Ie(e,o))))return e;if(e===n)break;let s=Ae(e);if(s===e)break;e=s}return le(t)}function qs(t){let e;try{e=JSON.parse(Ns(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:Ae(Ae(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 Ht(t,e){let n=Ie(t,Yt);Rs(n,{recursive:!0});let r=yt(t),s=`${r}.tmp-${process.pid}`;$s(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),_s(s,r)}function Gt(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 te=class{detect(e=process.cwd()){let n=le(e),r=zs(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>gt(Ie(r,f))),i=Ds(n,o?r:void 0);if(i){let f=yt(i),d=qs(f);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Ht(i,d)),Gt(d,i)}let a=new Date().toISOString(),c=Ks(r),u={version:1,id:Ws(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Ht(r,u),Gt(u,r)}};var Bs=[{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}],Pe=class{scan(e){let n=[];for(let r of Bs){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 H=class{scanner=new Pe;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 mo}from"node:os";import{join as go}from"node:path";import{DeleteObjectCommand as Vs,GetObjectCommand as Js,HeadObjectCommand as Hs,ListObjectsV2Command as Gs,PutObjectCommand as Us,S3Client as Ys}from"@aws-sdk/client-s3";import{getSignedUrl as Xs}from"@aws-sdk/s3-request-presigner";var Me=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ys({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 Us({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Xs(this.client,new Js({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 Hs({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 Vs({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Gs({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 Xt,mkdir as Qs,readFile as Zs,readdir as eo,rm as to,stat as Qt,writeFile as no}from"node:fs/promises";import{dirname as ro,join as so,relative as Zt,resolve as oo}from"node:path";var de=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return oo(this.root,n)}async put(e,n){let r=this.path(e);await Qs(ro(r),{recursive:!0}),await no(r,n)}async get(e){try{return await Zs(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 Xt(this.path(e)),!0}catch{return!1}}async delete(e){await to(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Xt(n)}catch{return r}let s=async i=>{let a=await eo(i,{withFileTypes:!0});for(let c of a){let u=so(i,c.name);if(c.isDirectory()){await s(u);continue}let f=await Qt(u);r.push({key:Zt(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Qt(n);return o.isDirectory()?await s(n):r.push({key:Zt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as io,GetObjectCommand as ao,HeadObjectCommand as co,ListObjectsV2Command as uo,PutObjectCommand as lo,S3Client as po}from"@aws-sdk/client-s3";import{getSignedUrl as fo}from"@aws-sdk/s3-request-presigner";var pe=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new po({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 lo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await fo(this.client,new ao({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 co({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 io({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new uo({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 ht(t,e){return console.warn(e),new de(t)}function en(t){let e=t.localRoot??go(mo(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new pe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ht(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 pe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ht(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 Me({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ht(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(e)}function yo(t){return new Promise(e=>setTimeout(e,t))}async function tn(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 yo(c+u)}throw o}var ho=new Set(["put","get","getText","delete","list"]);function nn(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:ho.has(r)?(...o)=>tn(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function rn(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 sn(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 Ee=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=rn(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=sn(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{join as jo}from"node:path";import{createHash as So}from"node:crypto";import{dirname as ko}from"node:path";import{mkdirSync as wo,readFileSync as vo,renameSync as bo,writeFileSync as xo}from"node:fs";function w(t){return So("sha256").update(t).digest("hex")}function St(t){if(Array.isArray(t))return t.map(St);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=St(e[r]);return n}return t}function on(t){return JSON.stringify(St(t))}function an(t){try{return JSON.parse(vo(t,"utf8"))}catch{return null}}function O(t,e){wo(ko(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;xo(n,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),bo(n,t)}function cn(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(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 un(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=cn(r.toLowerCase(),"agent"),i=cn(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:jo(t.rootPath,".toolnet","sessions",o,i)}}function ln(t){return String(t).padStart(12,"0")}var Te=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
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(h=>h.sequence>i.maxSequence),c=0;for(let h of this.split(a)){let y=h[0],k=h[h.length-1],P=h.map(A=>JSON.stringify(A)).join(`
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],P=y.map(T=>JSON.stringify(T)).join(`
8
8
  `)+`
9
- `,C=w(P).slice(0,16),j=[e.remotePrefix,"events",`${qt(y.sequence)}-${qt(k.sequence)}-${C}.jsonl`].join("/");await this.storage.exists(j)||await this.storage.put(j,P,"application/x-ndjson"),c+=h.length}let u=await this.scan(e),f=n[n.length-1],d=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?d="idle":f?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),l=n[0],m={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:d,createdAt:o?.createdAt??l?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:f?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(m.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:p};return await this.putJson(`${e.remotePrefix}/cursor.json`,S),await this.putJson(`${e.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:d}}};import{closeSync as nt,existsSync as Us,fsyncSync as Ys,mkdirSync as Xs,openSync as rt,readSync as Qs,rmSync as Vt,statSync as Ht,writeSync as Zs}from"node:fs";import{join as st}from"node:path";var eo=12e4,to=80,no=2e3;function ro(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var we=class{constructor(e){this.identity=e;Xs(e.localDirectory,{recursive:!0}),this.eventsFile=st(e.localDirectory,"events.jsonl"),this.stateFile=st(e.localDirectory,"state.json"),this.lockFile=st(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 Dt(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){M(this.stateFile,e)}acquireLock(){for(let e=0;e<to;e+=1)try{return rt(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Ht(this.lockFile).mtimeMs>eo){Vt(this.lockFile,{force:!0});continue}}catch{}ro(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{nt(n),Vt(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 d of e){let p=d.timestamp??new Date().toISOString(),l=d.data??{},m=d.provenance?.rawDigest??w(Ft(l)),S=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,p,m].join("|"),h=w(S).slice(0,32);if(r.has(h))continue;s+=1;let y={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:d.type,timestamp:p,data:l,provenance:{...d.provenance,rawDigest:m}};d.role!==void 0&&(y.role=d.role),d.sourceEventId!==void 0&&(y.sourceEventId=d.sourceEventId),d.sourceSequence!==void 0&&(y.sourceSequence=d.sourceSequence),o.push(y),r.add(h)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
9
+ `,E=w(P).slice(0,16),I=[e.remotePrefix,"events",`${ln(h.sequence)}-${ln(k.sequence)}-${E}.jsonl`].join("/");await this.storage.exists(I)||await this.storage.put(I,P,"application/x-ndjson"),c+=y.length}let u=await this.scan(e),f=n[n.length-1],d=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?d="idle":f?.type==="error"?d="error":n.length>0&&(d="active");let p=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:d,createdAt:o?.createdAt??l?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:f?.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:p};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:d}}};import{closeSync as wt,existsSync as Eo,fsyncSync as To,mkdirSync as Oo,openSync as vt,readSync as Ro,rmSync as pn,statSync as fn,writeSync as No}from"node:fs";import{join as bt}from"node:path";var Co=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),Ao=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Io(t){return t.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Po(t){for(let e of["type","kind"]){let n=t[e];if(typeof n=="string"){let r=n.toLowerCase();if(Ao.has(r))return n}}return null}function kt(t,e=0){if(e>12)return"[ToolNet nested value omitted]";if(Array.isArray(t))return t.map(o=>kt(o,e+1));if(!t||typeof t!="object")return t;let n=t,r=Po(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))Co.has(Io(o))||(s[o]=kt(i,e+1));return s}function Mo(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 dn(t,e={}){let n={...t.provenance??{}},r=G(t.source)??G(e.source)??G(n.source);return{...t,timestamp:Mo(t.timestamp),source:r,turnId:G(t.turnId)??G(e.turnId),cwd:G(t.cwd)??G(e.cwd),data:kt(t.data??{}),provenance:n}}var _o=12e4,$o=80,Ko=2e3;function Fo(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Oe=class{constructor(e,n={}){this.identity=e;this.eventContext=n;Oo(e.localDirectory,{recursive:!0}),this.eventsFile=bt(e.localDirectory,"events.jsonl"),this.stateFile=bt(e.localDirectory,"state.json"),this.lockFile=bt(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 an(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){O(this.stateFile,e)}acquireLock(){for(let e=0;e<$o;e+=1)try{return vt(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-fn(this.lockFile).mtimeMs>_o){pn(this.lockFile,{force:!0});continue}}catch{}Fo(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{wt(n),pn(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 d of e){let p=dn(d,this.eventContext),l=p.timestamp??new Date().toISOString(),g=p.data??{},S=p.provenance?.rawDigest??w(on(g)),y=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,p.type,l,S].join("|"),h=w(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:p.type,timestamp:l,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:S}};p.role!==void 0&&(k.role=p.role),p.turnId!==void 0&&(k.turnId=p.turnId),p.cwd!==void 0&&(k.cwd=p.cwd),p.sourceEventId!==void 0&&(k.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(k.sourceSequence=p.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
10
10
  `)+`
11
- `,a=rt(this.eventsFile,"a",384);try{Zs(a,i,null,"utf8"),Ys(a)}finally{nt(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 f=Array.from(r).slice(-no);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Us(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=Ht(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=rt(this.eventsFile,"r");try{Qs(i,o,0,s,r)}finally{nt(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();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 Gi,existsSync as Ui,openSync as Yi,readSync as Xi,statSync as Qi}from"node:fs";function Jt(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 Xt=[/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],so=[/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],oo=[/\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],io=[/\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],ao=[/đã 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],Gt=[/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],co=[/\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],uo=[/đườ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],lo=[/\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],Ut=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),po=new Set(["payload","data","content","message","messages","parts","summary"]);function E(t,e){return e.some(n=>n.test(t))}function Qt(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function fo(t){return Qt(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function mo(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 ot(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||Ut.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))ot(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Ut.has(s)||po.has(s))&&ot(o,s,n,r+1)}}function go(t){let e=[];ot(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=Qt(o);if(mo(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Yt(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function yo(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&&E(t,Xt)?{kind:"rule",confidence:.98}:r&&E(t,so)?{kind:"rule",confidence:.92}:E(t,oo)?{kind:E(t,Gt)?"architecture":"decision",confidence:r?.93:.86}:r&&E(t,io)?{kind:"todo",confidence:.87}:E(t,Gt)&&E(t,co)?{kind:"architecture",confidence:r?.88:.82}:s&&E(t,ao)?{kind:"fix",confidence:.8}:r&&E(t,uo)&&E(t,lo)?{kind:"context",confidence:.79}:null}function ho(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function So(t,e,n){return t==="rule"&&E(n,Xt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Jt(e,n)}function Zt(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=Yt(o);i&&a&&s.set(i,a)}for(let o of e){let i=Yt(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of go(o)){let u=yo(c,i,o);if(!u||u.confidence<.75)continue;let f=ho(u.kind),d=fo(c),p=w([t.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],m=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:f,content:c,confidence:u.confidence,importance:So(u.kind,f,c),tags:[f],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:m,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as ko}from"node:crypto";var wo=["project-knowledge","implementation","continuation","session-context"],vo={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function it(t){return ko("sha256").update(t).digest("hex")}function ve(t,e){return`${t}:${it(e).slice(0,24)}`}function bo(t){try{return it(JSON.stringify(t))}catch{return it(String(t))}}function F(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 tn(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 xo(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function en(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function jo(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=>tn(e.content)).join(" | ")}function Io(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=>tn(e.content)).join(`
13
- `)}function nn(t,e){let n=t.slice().sort((p,l)=>p.sequence-l.sequence||p.timestamp.localeCompare(l.timestamp)||p.id.localeCompare(l.id)),r=n.map(p=>({id:ve("raw",[p.projectId,p.agent,p.nativeSessionId,p.id,String(p.sequence)].join("|")),level:"raw",eventId:p.id,sourceEventId:p.sourceEventId,sequence:p.sequence,type:p.type,role:p.role,timestamp:p.timestamp,sourcePath:p.provenance.sourcePath,payloadDigest:bo(p.data)})),s=new Map,o=new Map;n.forEach((p,l)=>{let m=r[l];m&&(s.set(p.id,m.id),p.sourceEventId&&o.set(p.sourceEventId,m.id))});let i=e.map(p=>{let l=F([...p.provenance.eventIds.map(m=>s.get(m)),...p.provenance.sourceEventIds.map(m=>o.get(m))]);return{id:ve("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:F([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:l,sourcePaths:F(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let l=xo(p.kind),m=a.get(l)??[];m.push(p),a.set(l,m)}let c=[];for(let p of wo){let l=a.get(p);if(!l?.length)continue;let m=l.slice().sort((h,y)=>y.importanceScore-h.importanceScore||y.confidence-h.confidence||h.id.localeCompare(y.id)),S=m.map(h=>h.id);c.push({id:ve("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:vo[p],summary:jo(m),factIds:S,importanceScore:Math.max(...m.map(h=>h.importanceScore)),confidence:en(m.map(h=>h.confidence)),tags:F(["level:scene",`scene:${p}`,...m.flatMap(h=>h.tags)]),sourcePaths:F(m.flatMap(h=>h.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),f=[];for(let p of c){let m=p.factIds.map(y=>u.get(y)).filter(y=>!!y).filter(y=>(y.knowledgeClass==="permanent"||y.knowledgeClass==="task")&&y.importanceScore>=.55);if(m.length===0)continue;let S=m.some(y=>y.knowledgeClass==="permanent")?"permanent":"task",h=Io(m);f.push({id:ve("knowledge",`${p.id}|${S}|${m.map(y=>y.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:h,sceneIds:[p.id],factIds:m.map(y=>y.id),importanceScore:Math.max(...m.map(y=>y.importanceScore)),confidence:en(m.map(y=>y.confidence)),tags:F(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...m.flatMap(y=>y.tags)]),sourcePaths:F(m.flatMap(y=>y.sourcePaths))})}let d=[];for(let p of i)for(let l of p.rawIds)d.push({from:l,to:p.id,type:"supports"});for(let p of c)for(let l of p.factIds)d.push({from:l,to:p.id,type:"belongs_to"});for(let p of f)for(let l of p.sceneIds)d.push({from:l,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:f,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:f.length,links:d.length}}}function be(t){return t?Math.ceil(t.length/3.5):0}function xe(t,e){if(!t)return"";if(be(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 D(){let t=fe(),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 rn(t){return(t||D()).rawTranscript}function sn(t){return(t||D()).durableMemoryMaxItemsPerSession}function on(t){return(t||D()).sessionSummaryMaxTokens}function an(t){return(t||D()).archiveRemote}function Po(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 Co(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 Ao(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 f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let d="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)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=Co(u,d);if(p<.3)continue;let l=Po(u);n.push({category:d,text:l,importance:p,sourceSessionId:e})}}let s=D(),o=sn(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function Mo(t){let e=D(),n=on(e),o=t.join(`
11
+ `,a=vt(this.eventsFile,"a",384);try{No(a,i,null,"utf8"),To(a)}finally{wt(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 f=Array.from(r).slice(-Ko);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Eo(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=fn(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=vt(this.eventsFile,"r");try{Ro(i,o,0,s,r)}finally{wt(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 Ia,existsSync as Pa,openSync as Ma,readSync as Ea,statSync as Ta}from"node:fs";function mn(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 Sn=[/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],Wo=[/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],Lo=[/\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],Do=[/\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],zo=[/đã 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],gn=[/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],qo=[/\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],Bo=[/đườ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],Vo=[/\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],yn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Jo=new Set(["payload","data","content","message","messages","parts","summary"]);function R(t,e){return e.some(n=>n.test(t))}function kn(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ho(t){return kn(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Go(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 xt(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||yn.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))xt(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(yn.has(s)||Jo.has(s))&&xt(o,s,n,r+1)}}function Uo(t){let e=[];xt(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=kn(o);if(Go(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function hn(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Yo(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&&R(t,Sn)?{kind:"rule",confidence:.98}:r&&R(t,Wo)?{kind:"rule",confidence:.92}:R(t,Lo)?{kind:R(t,gn)?"architecture":"decision",confidence:r?.93:.86}:r&&R(t,Do)?{kind:"todo",confidence:.87}:R(t,gn)&&R(t,qo)?{kind:"architecture",confidence:r?.88:.82}:s&&R(t,zo)?{kind:"fix",confidence:.8}:r&&R(t,Bo)&&R(t,Vo)?{kind:"context",confidence:.79}:null}function Xo(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Qo(t,e,n){return t==="rule"&&R(n,Sn)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":mn(e,n)}function wn(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=hn(o);i&&a&&s.set(i,a)}for(let o of e){let i=hn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Uo(o)){let u=Yo(c,i,o);if(!u||u.confidence<.75)continue;let f=Xo(u.kind),d=Ho(c),p=w([t.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:f,content:c,confidence:u.confidence,importance:Qo(u.kind,f,c),tags:[f],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 Zo}from"node:crypto";var ei=["project-knowledge","implementation","continuation","session-context"],ti={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function jt(t){return Zo("sha256").update(t).digest("hex")}function Re(t,e){return`${t}:${jt(e).slice(0,24)}`}function ni(t){try{return jt(JSON.stringify(t))}catch{return jt(String(t))}}function U(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 bn(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 ri(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function vn(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function si(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=>bn(e.content)).join(" | ")}function oi(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=>bn(e.content)).join(`
13
+ `)}function xn(t,e){let n=t.slice().sort((p,l)=>p.sequence-l.sequence||p.timestamp.localeCompare(l.timestamp)||p.id.localeCompare(l.id)),r=n.map(p=>({id:Re("raw",[p.projectId,p.agent,p.nativeSessionId,p.id,String(p.sequence)].join("|")),level:"raw",eventId:p.id,sourceEventId:p.sourceEventId,sequence:p.sequence,type:p.type,role:p.role,timestamp:p.timestamp,sourcePath:p.provenance.sourcePath,payloadDigest:ni(p.data)})),s=new Map,o=new Map;n.forEach((p,l)=>{let g=r[l];g&&(s.set(p.id,g.id),p.sourceEventId&&o.set(p.sourceEventId,g.id))});let i=e.map(p=>{let l=U([...p.provenance.eventIds.map(g=>s.get(g)),...p.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:Re("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:U([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:l,sourcePaths:U(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let l=ri(p.kind),g=a.get(l)??[];g.push(p),a.set(l,g)}let c=[];for(let p of ei){let l=a.get(p);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:Re("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:ti[p],summary:si(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:vn(g.map(y=>y.confidence)),tags:U(["level:scene",`scene:${p}`,...g.flatMap(y=>y.tags)]),sourcePaths:U(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),f=[];for(let p of c){let g=p.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=oi(g);f.push({id:Re("knowledge",`${p.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:y,sceneIds:[p.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:vn(g.map(h=>h.confidence)),tags:U(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:U(g.flatMap(h=>h.sourcePaths))})}let d=[];for(let p of i)for(let l of p.rawIds)d.push({from:l,to:p.id,type:"supports"});for(let p of c)for(let l of p.factIds)d.push({from:l,to:p.id,type:"belongs_to"});for(let p of f)for(let l of p.sceneIds)d.push({from:l,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:f,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:f.length,links:d.length}}}function Ne(t){return t?Math.ceil(t.length/3.5):0}function _e(t,e){if(!t)return"";if(Ne(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 Y(){let t=Ce(),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 jn(t){return(t||Y()).rawTranscript}function Cn(t){return(t||Y()).durableMemoryMaxItemsPerSession}function An(t){return(t||Y()).sessionSummaryMaxTokens}function In(t){return(t||Y()).archiveRemote}var Pn=new H;function Mn(t){let e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))try{let r=JSON.parse(e);return JSON.stringify(Pn.sanitizeValue(r))}catch{}let n=Pn.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 ii(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 ai(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 f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let d="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)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=ii(u,d);if(p<.3)continue;let l=Mn(u);n.push({category:d,text:l,importance:p,sourceSessionId:e})}}let s=Y(),o=Cn(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function ci(t){let e=Y(),n=An(e),o=t.join(`
16
16
 
17
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).join(`
19
- `);return xe(o,n)}function je(t,e){let r=(Array.isArray(t)?t:t.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=>Mn(i)).join(`
19
+ `);return _e(o,n)}function $e(t,e){let r=(Array.isArray(t)?t:t.split(`
20
20
 
21
- `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Ao(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),f=s.filter(l=>l.category==="next_action").map(l=>l.text),d=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Mo(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:f,durableFacts:s}}function $(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 Eo(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 To(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Oo(t){let e=To(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function Ro(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 No(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 _o(t){let e=Ro(t),n=Oo(t),r=No(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:$([...t.tags,"level:fact",`class:${e}`,`kind:${t.kind}`])}}function $o(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 Ko(t,e,n){let r=je($o(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=$([...s,...r.nextActions]),c=$([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:$(r.decisions),files:$([...r.filesChanged,...o]),todos:a,completed:$(r.bugsFixed),blockers:$(r.blockers),nextActions:c,architecture:$(i)}}}function cn(t,e){let n=Eo(e),r=Zt(t,n).map(_o),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,d)=>d.importanceScore-f.importanceScore),{summary:o,state:i}=Ko(t,n,s),a=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),c=nn(n,s),u=f=>r.filter(d=>d.knowledgeClass===f).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 Wo}from"node:crypto";import{chmodSync as un,existsSync as Lo,mkdirSync as Fo,readFileSync as Do,renameSync as zo,writeFileSync as ln}from"node:fs";import{dirname as dn,join as Ie}from"node:path";var ut="toolnet.context-offload.v1",Bo="toolnet.context-offload-asset.v1",qo=256,Vo=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function pn(t){return Ie(t,".toolnet","offload")}function Ho(t){return Ie(pn(t),"assets")}function fn(t){return Ie(pn(t),"graph.json")}function mn(t){Fo(t,{recursive:!0,mode:448});try{un(t,448)}catch{}}function Jo(t,e){mn(dn(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;ln(n,e,{encoding:"utf8",mode:384}),zo(n,t);try{un(t,384)}catch{}}function ct(t){return Array.isArray(t)?t.map(ct):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,ct(n)])):t}function Go(t){return Wo("sha256").update(JSON.stringify(ct(t)),"utf8").digest("hex")}function at(){return{schema:ut,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Uo(t){let e=fn(t);if(!Lo(e))return at();try{let n=JSON.parse(Do(e,"utf8"));return n.schema!==ut||n.version!==1||!Array.isArray(n.nodes)?at():n}catch{return at()}}function Yo(t,e){Jo(fn(t),JSON.stringify(e,null,2)+`
22
- `)}function Xo(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function Qo(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let s=Xo(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Zo(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function ei(t,e){mn(dn(t));try{return ln(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function ti(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:ut,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(s=>s.id!==e.id),r].slice(-qo)}}function gn(t,e){let n=Uo(t),r=0,s=0,o=0,i=[];for(let a of e){if(!Vo.has(a.type))continue;r+=1;let c=Go({type:a.type,data:a.data}),u={schema:Bo,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}},f=JSON.stringify(u,null,2)+`
23
- `;ei(Ie(Ho(t),`${c}.json`),f)?s+=1:o+=1,i.push(c),n=ti(n,{id:c,kind:a.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:a.timestamp,sourceRefs:[Zo(a)],files:Qo(a)})}return r>0&&Yo(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as ui}from"node:crypto";import{existsSync as li,readdirSync as di,readFileSync as pi}from"node:fs";import{basename as fi,join as On}from"node:path";import{randomUUID as Sn}from"node:crypto";var x=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function re(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 B(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 x("Invalid Wiki slug",400);return e}function yn(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(B(r))}return re(e)}function ni(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function hn(t){return{id:`revision-${Sn()}`,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 z(t){return structuredClone(t)}var Pe=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:re(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 z([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=B(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new x(`Wiki page not found: ${e}`,404);return z(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new x("Wiki title is required",400);let o=B(e.slug??r);if(n.pages.some(c=>c.slug===o))throw new x(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Sn()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:re(e.tags??[]),links:yn(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(hn(a)),z(a)})}async updatePage(e,n){return this.mutate(r=>{let s=B(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new x(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new x("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=yn(o.content)),n.tags!==void 0&&(o.tags=re(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(hn(o)),z(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return z(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 z(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=re(ni(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(),f=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),l=0;for(let m of s)u===m&&(l+=12),c===m&&(l+=10),c.includes(m)&&(l+=6),u.includes(m)&&(l+=5),p.some(S=>S===m)?l+=5:p.some(S=>S.includes(m))&&(l+=3),f.includes(m)&&(l+=2),d.includes(m)&&(l+=1);l>0&&i.push({page:z(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var kn="wiki/state.v1.json";function ri(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function si(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 Ce=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(kn);if(!e){let n=ri(this.project);return await this.save(n),n}return si(e,this.project)}async save(e){await this.storage.put(kn,JSON.stringify(e,null,2),"application/json")}};import{createHash as oi,randomUUID as wn}from"node:crypto";var vn="wiki/governance.v1.json",In="toolnet.knowledge-governance.v1",bn=500,se={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function ii(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function lt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function xn(t){return oi("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ai(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 ci(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),ii(e)}function jn(t){let e=new Date().toISOString();return{schema:In,version:1,projectId:t,policy:{...se},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Pn(t){let e=t.autoApproveThreshold??se.autoApproveThreshold,n=t.criticalApproveThreshold??se.criticalApproveThreshold,r=t.staleAfterDays??se.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new x("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new x("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new x("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var Ae=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(vn);if(!e){let n=jn(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==In||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Pn(n.policy??se)}}catch{let n=jn(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(vn,JSON.stringify(e,null,2),"application/json")}},Me=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:wn(),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>bn&&(e.audit=e.audit.slice(-bn))}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=Pn({...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=ci(e),o=lt(e.title),i=n.filter(f=>f.slug!==e.slug&&lt(f.title)===o&&xn(f.content)!==xn(e.content)).map(f=>f.slug),a=ai(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:wn(),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 x(`Governance review not found: ${e}`,404);if(o.status!=="pending")throw new x("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 x("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new x("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 x(`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(f=>{let d=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(f=>f.stale).map(({stale:f,...d})=>d),a=new Map;for(let f of r){let d=lt(f.title),p=a.get(d)??[];p.push(f),a.set(d,p)}let c=[...a.entries()].filter(([,f])=>f.length>1).map(([f,d])=>({title:f,pages:d.map(p=>p.slug)})),u=n.reviews.filter(f=>f.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(f=>f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(f=>f.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(f=>f.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Rn="wiki/automation.v1.json",Nn="toolnet.wiki-automation.v1",ft=8e3,Cn=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function ie(t){return ui("sha256").update(JSON.stringify(t)).digest("hex")}function oe(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function An(t){return Array.isArray(t)?t:[]}function _n(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function dt(t){return Array.isArray(t)?t.map(_n).filter(e=>!!e):[]}function R(t,e){for(let n of e){let r=_n(t[n]);if(r)return r}}function ae(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 Ee(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Cn.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=>Ee(i,e+1,n));let s=oe(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Cn.has(c)||o.push(...Ee(a,e+1,i))}return o}function Mn(t){let n=ae(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>Ee(t[s],0,s)));return(n.length>0?n:ae(Ee(t))).join(`
21
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=ai(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),f=s.filter(l=>l.category==="next_action").map(l=>l.text),d=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:ci(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:f,durableFacts:s}}function B(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 ui(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 li(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function di(t){let e=li(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function pi(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 fi(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 mi(t){let e=pi(t),n=di(t),r=fi(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:B([...t.tags,"level:fact",`class:${e}`,`kind:${t.kind}`])}}function gi(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 yi(t,e,n){let r=$e(gi(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=B([...s,...r.nextActions]),c=B([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:B(r.decisions),files:B([...r.filesChanged,...o]),todos:a,completed:B(r.bugsFixed),blockers:B(r.blockers),nextActions:c,architecture:B(i)}}}function Ke(t,e){let n=ui(e),r=wn(t,n).map(mi),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,d)=>d.importanceScore-f.importanceScore),{summary:o,state:i}=yi(t,n,s),a=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),c=xn(n,s),u=f=>r.filter(d=>d.knowledgeClass===f).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 hi}from"node:crypto";import{chmodSync as En,existsSync as Si,mkdirSync as ki,readFileSync as wi,renameSync as vi,writeFileSync as Tn}from"node:fs";import{dirname as On,join as Fe}from"node:path";var It="toolnet.context-offload.v1",bi="toolnet.context-offload-asset.v1",xi=256,ji=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Rn(t){return Fe(t,".toolnet","offload")}function Ci(t){return Fe(Rn(t),"assets")}function Nn(t){return Fe(Rn(t),"graph.json")}function _n(t){ki(t,{recursive:!0,mode:448});try{En(t,448)}catch{}}function Ai(t,e){_n(On(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;Tn(n,e,{encoding:"utf8",mode:384}),vi(n,t);try{En(t,384)}catch{}}function At(t){return Array.isArray(t)?t.map(At):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,At(n)])):t}function Ii(t){return hi("sha256").update(JSON.stringify(At(t)),"utf8").digest("hex")}function Ct(){return{schema:It,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Pi(t){let e=Nn(t);if(!Si(e))return Ct();try{let n=JSON.parse(wi(e,"utf8"));return n.schema!==It||n.version!==1||!Array.isArray(n.nodes)?Ct():n}catch{return Ct()}}function Mi(t,e){Ai(Nn(t),JSON.stringify(e,null,2)+`
22
+ `)}function Ei(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function Ti(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let s=Ei(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Oi(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Ri(t,e){_n(On(t));try{return Tn(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Ni(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:It,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(s=>s.id!==e.id),r].slice(-xi)}}function $n(t,e){let n=Pi(t),r=0,s=0,o=0,i=[];for(let a of e){if(!ji.has(a.type))continue;r+=1;let c=Ii({type:a.type,data:a.data}),u={schema:bi,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}},f=JSON.stringify(u,null,2)+`
23
+ `;Ri(Fe(Ci(t),`${c}.json`),f)?s+=1:o+=1,i.push(c),n=Ni(n,{id:c,kind:a.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:a.timestamp,sourceRefs:[Oi(a)],files:Ti(a)})}return r>0&&Mi(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as zi}from"node:crypto";import{existsSync as qi,readdirSync as Bi,readFileSync as Vi}from"node:fs";import{basename as Ji,join as Zn}from"node:path";import{randomUUID as Wn}from"node:crypto";var C=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function fe(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 Q(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 C("Invalid Wiki slug",400);return e}function Kn(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(Q(r))}return fe(e)}function _i(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function Fn(t){return{id:`revision-${Wn()}`,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 X(t){return structuredClone(t)}var 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}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:fe(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 X([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=Q(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new C(`Wiki page not found: ${e}`,404);return X(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new C("Wiki title is required",400);let o=Q(e.slug??r);if(n.pages.some(c=>c.slug===o))throw new C(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Wn()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:fe(e.tags??[]),links:Kn(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Fn(a)),X(a)})}async updatePage(e,n){return this.mutate(r=>{let s=Q(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new C(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new C("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=Kn(o.content)),n.tags!==void 0&&(o.tags=fe(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Fn(o)),X(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return X(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 X(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=fe(_i(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(),f=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=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),p.some(S=>S===g)?l+=5:p.some(S=>S.includes(g))&&(l+=3),f.includes(g)&&(l+=2),d.includes(g)&&(l+=1);l>0&&i.push({page:X(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Ln="wiki/state.v1.json";function $i(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function Ki(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 Le=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Ln);if(!e){let n=$i(this.project);return await this.save(n),n}return Ki(e,this.project)}async save(e){await this.storage.put(Ln,JSON.stringify(e,null,2),"application/json")}};import{createHash as Fi,randomUUID as Dn}from"node:crypto";var zn="wiki/governance.v1.json",Jn="toolnet.knowledge-governance.v1",qn=500,me={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Wi(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function Pt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Bn(t){return Fi("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Li(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 Di(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),Wi(e)}function Vn(t){let e=new Date().toISOString();return{schema:Jn,version:1,projectId:t,policy:{...me},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Hn(t){let e=t.autoApproveThreshold??me.autoApproveThreshold,n=t.criticalApproveThreshold??me.criticalApproveThreshold,r=t.staleAfterDays??me.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new C("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new C("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new C("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var De=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(zn);if(!e){let n=Vn(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==Jn||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Hn(n.policy??me)}}catch{let n=Vn(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(zn,JSON.stringify(e,null,2),"application/json")}},ze=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:Dn(),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>qn&&(e.audit=e.audit.slice(-qn))}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=Hn({...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=Di(e),o=Pt(e.title),i=n.filter(f=>f.slug!==e.slug&&Pt(f.title)===o&&Bn(f.content)!==Bn(e.content)).map(f=>f.slug),a=Li(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:Dn(),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 C(`Governance review not found: ${e}`,404);if(o.status!=="pending")throw new C("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 C("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new C("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 C(`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(f=>{let d=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(f=>f.stale).map(({stale:f,...d})=>d),a=new Map;for(let f of r){let d=Pt(f.title),p=a.get(d)??[];p.push(f),a.set(d,p)}let c=[...a.entries()].filter(([,f])=>f.length>1).map(([f,d])=>({title:f,pages:d.map(p=>p.slug)})),u=n.reviews.filter(f=>f.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(f=>f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(f=>f.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(f=>f.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var er="wiki/automation.v1.json",tr="toolnet.wiki-automation.v1",Tt=8e3,Gn=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function ye(t){return zi("sha256").update(JSON.stringify(t)).digest("hex")}function ge(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Un(t){return Array.isArray(t)?t:[]}function nr(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function Mt(t){return Array.isArray(t)?t.map(nr).filter(e=>!!e):[]}function $(t,e){for(let n of e){let r=nr(t[n]);if(r)return r}}function he(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 qe(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Gn.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=>qe(i,e+1,n));let s=ge(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Gn.has(c)||o.push(...qe(a,e+1,i))}return o}function Yn(t){let n=he(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>qe(t[s],0,s)));return(n.length>0?n:he(qe(t))).join(`
24
24
 
25
- `).slice(0,ft)}function En(t,e){return R(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function Tn(t,e){return R(t,["title","name","topic","label","task","kind","type"])??e}function mi(t){return(R(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function gi(t){return(R(t,["kind","sceneKind","type"])??"").toLowerCase()}function yi(t){let e=oe(t);if(!e)return[];let n=[],r=An(e.knowledge);for(let[o,i]of r.entries()){let a=oe(i);if(!a)continue;let c=mi(a);if(c==="session"||c==="transient")continue;let u=Mn(a);if(u.length<20)continue;let f=En(a,ie(a).slice(0,16)),d=Tn(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:d,summary:R(a,["summary","description"]),content:u,tags:ae(["toolnet","auto","memory",...c?[c]:[]])})}let s=An(e.scenes);for(let[o,i]of s.entries()){let a=oe(i);if(!a)continue;let c=gi(a);if(c==="session-context")continue;let u=Mn(a);if(u.length<20)continue;let f=En(a,ie(a).slice(0,16)),d=Tn(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:d,summary:R(a,["summary","description"]),content:u,tags:ae(["toolnet","auto","scene",...c?[c]:[]])})}return n}function hi(t){return On(t,".toolnet","memory","skills")}function Si(t){let e=hi(t);if(!li(e))return{candidates:[],failed:0};let n=[],r=0,s=di(e).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(pi(On(e,o),"utf8")),a=oe(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=R(a,["id","fingerprint"])??fi(o,".json"),u=R(a,["task"])??"",f=R(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=R(a,["summary"])??void 0,p=dt(a.steps),l=dt(a.verification),m=dt(a.files),S=[];u&&S.push(`## Task
25
+ `).slice(0,Tt)}function Xn(t,e){return $(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function Qn(t,e){return $(t,["title","name","topic","label","task","kind","type"])??e}function Hi(t){return($(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Gi(t){return($(t,["kind","sceneKind","type"])??"").toLowerCase()}function Ui(t){let e=ge(t);if(!e)return[];let n=[],r=Un(e.knowledge);for(let[o,i]of r.entries()){let a=ge(i);if(!a)continue;let c=Hi(a);if(c==="session"||c==="transient")continue;let u=Yn(a);if(u.length<20)continue;let f=Xn(a,ye(a).slice(0,16)),d=Qn(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:d,summary:$(a,["summary","description"]),content:u,tags:he(["toolnet","auto","memory",...c?[c]:[]])})}let s=Un(e.scenes);for(let[o,i]of s.entries()){let a=ge(i);if(!a)continue;let c=Gi(a);if(c==="session-context")continue;let u=Yn(a);if(u.length<20)continue;let f=Xn(a,ye(a).slice(0,16)),d=Qn(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:d,summary:$(a,["summary","description"]),content:u,tags:he(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Yi(t){return Zn(t,".toolnet","memory","skills")}function Xi(t){let e=Yi(t);if(!qi(e))return{candidates:[],failed:0};let n=[],r=0,s=Bi(e).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Vi(Zn(e,o),"utf8")),a=ge(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??Ji(o,".json"),u=$(a,["task"])??"",f=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=$(a,["summary"])??void 0,p=Mt(a.steps),l=Mt(a.verification),g=Mt(a.files),S=[];u&&S.push(`## Task
26
26
  ${u}`),d&&S.push(`## Summary
27
27
  ${d}`),p.length>0&&S.push(`## Procedure
28
- ${p.map((y,k)=>`${k+1}. ${y}`).join(`
28
+ ${p.map((h,k)=>`${k+1}. ${h}`).join(`
29
29
  `)}`),l.length>0&&S.push(`## Verification
30
- ${l.map(y=>`- ${y}`).join(`
31
- `)}`),m.length>0&&S.push(`## Relevant Files
32
- ${m.map(y=>`- \`${y}\``).join(`
33
- `)}`);let h=S.join(`
34
-
35
- `).slice(0,ft);if(h.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:f,summary:d,content:h,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function pt(t){let e=new Date().toISOString();return{schema:Nn,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function ki(t,e){let n=await t.getText(Rn);if(!n)return pt(e);try{let r=JSON.parse(n);return r.schema!==Nn||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?pt(e):r}catch{return pt(e)}}async function wi(t,e){await t.put(Rn,JSON.stringify(e,null,2),"application/json")}function vi(t){return`toolnet-auto-${ie(t).slice(0,12)}`}function bi(t){let e=B(t.title).slice(0,72),n=ie(t.sourceKey).slice(0,10);return B(`auto-${t.sourceType}-${e}-${n}`)}function xi(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,ft)}function ji(t){return ie({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function Ii(t,e){return t.tags.includes(e)}async function $n(t){let e=yi(t.hierarchy),n=Si(t.project.rootPath),r=new Map;for(let l of[...e,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,m)=>l.sourceKey.localeCompare(m.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 Pe(new Ce(t.storage,t.project));await i.initialize();let a=new Me(new Ae(t.storage,t.project));await a.initialize();let c=await ki(t.storage,t.project.id),u=await i.listPages(),f=new Map(u.map(l=>[l.slug,l])),d=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let m=vi(l.sourceKey),S=ji(l),h=d.get(l.sourceKey),y=h?.slug??bi(l),k=f.get(y);if(k&&!Ii(k,m)){o.skipped+=1;continue}let P=ae([...l.tags,m]),C=xi(l),j=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,marker:m,digest:S,title:l.title,...l.summary?{summary:l.summary}:{},content:C,tags:P},[...f.values()]);if(!j.allowed){j.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}j.mode==="auto-approved"?o.autoApproved+=1:j.mode==="review-approved"&&(o.reviewApproved+=1),k?h?.digest!==S?(k=await i.updatePage(y,{title:l.title,summary:l.summary??"",content:C,tags:P}),f.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:y,action:"unchanged"})):(k=await i.createPage({slug:y,title:l.title,summary:l.summary,content:C,tags:P}),f.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let A=new Date().toISOString(),g={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,digest:S,marker:m,updatedAt:A},v=c.entries.findIndex(L=>L.sourceKey===l.sourceKey);v>=0?c.entries[v]=g:c.entries.push(g),d.set(l.sourceKey,g),await a.markApplied(l.sourceKey,S)}catch(m){if(m instanceof x&&m.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((l,m)=>l.sourceKey.localeCompare(m.sourceKey)),await wi(t.storage,c),o}import{createHash as Pi}from"node:crypto";import{chmodSync as Wn,existsSync as Ci,mkdirSync as Ai,readFileSync as ap,readdirSync as cp,renameSync as Mi,statSync as up,writeFileSync as Ei}from"node:fs";import{join as Ln}from"node:path";var Ti="toolnet.skill-memory.v1",Kn=5,Oi=16,Ri=24,Ni=32;function _i(t){return Pi("sha256").update(t).digest("hex")}function ue(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 mt(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 $i(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 _(t,e=360){return t&&mt($i(t),e)||void 0}function le(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function Fn(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 Dn(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 zn(t){let e=t.data??{};if(Dn(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Fn(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=le(e,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ce(t){let e=t.data??{};if(zn(t))return!1;if(Dn(e,["passed","pass","success","succeeded","ok"])===!0||Fn(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=le(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 Bn(t){let e=t.data??{},n=le(e,["path","file","filePath","filename","target"]);if(n)return _(n,260);let r=t.provenance?.files;return _(r?.[0],260)}function gt(t){return _(le(t.data??{},["command","cmd","script"]),420)}function V(t){return _(le(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Ki(t){let e=[];for(let n of[...t].sort((r,s)=>r.sequence-s.sequence))if(ce(n)){if(n.type==="test"){let r=V(n)??gt(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=V(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=V(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return ue(e,10)}function Wi(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=Bn(r);s&&n.push(`Update ${s}`);break}case"command":{if(zn(r))break;let s=gt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ce(r))break;let s=V(r)??gt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!ce(r))break;let s=V(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!ce(r))break;let s=V(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=_(r,260);s&&n.push(`Update ${s}`)}return ue(n,Oi)}function Li(t,e){let n=[...e.files];for(let r of t){let s=Bn(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=_(o,260);i&&n.push(i)}}return ue(n,Ri)}function Fi(t){return ue(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),Ni)}function Di(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function qn(t,e,n){if(e.length===0)return[];let r=Ki(e),s=ue(n.completed.map(m=>_(m,280)??""),Kn);if(!(s.length>0||e.some(m=>["test","commit","deploy"].includes(m.type)&&ce(m))))return[];let i=_(n.task,280)??_(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=Wi(e,n);if(c.length===0)return[];let u=Li(e,n),f=Fi(e),d=Math.min(...e.map(m=>m.sequence)),p=Math.max(...e.map(m=>m.sequence)),l=Di(e);return a.slice(0,Kn).map(m=>{let S=[`Reusable procedure learned from successful task: ${m}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),h=JSON.stringify({projectId:t.projectId,task:m,steps:c,verification:r,files:u}),y=_i(h);return{schema:Ti,version:1,id:`skill-${y.slice(0,24)}`,fingerprint:y,projectId:t.projectId,title:mt(`SOP: ${m}`,180),task:m,summary:mt(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:d,lastSequence:p,eventIds:f},createdAt:l}})}function zi(t){return Ln(t.rootPath,".toolnet","memory","skills")}function Bi(t){let e=zi(t);return Ai(e,{recursive:!0,mode:448}),Wn(e,448),e}function Vn(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=Bi(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=Ln(n,`${i.id}.json`);if(o.push(a),Ci(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Ei(c,JSON.stringify(i,null,2)+`
37
- `,{encoding:"utf8",mode:384}),Mi(c,a),Wn(a,384),r+=1}return{written:r,deduped:s,files:o}}function Hn(t){return String(t).padStart(12,"0")}function qi(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Te=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(f=>f.sequence)),o=Math.max(...n.map(f=>f.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=w(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[qi(e),"batches",`${Hn(s)}-${Hn(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as Vi}from"node:crypto";function Jn(t){return String(t).padStart(12,"0")}function Hi(t){return Vi("sha256").update(t).digest("hex")}function Ji(t){return t.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Oe=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=Hi([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[Ji(e),"batches",`${Jn(s)}-${Jn(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 Zi(t,e){if(!Ui(t))return{events:[],nextOffset:e};let n=Qi(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=Yi(t,"r");try{Xi(i,o,0,s,r)}finally{Gi(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
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,Tt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:f,summary:d,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Et(t){let e=new Date().toISOString();return{schema:tr,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function Qi(t,e){let n=await t.getText(er);if(!n)return Et(e);try{let r=JSON.parse(n);return r.schema!==tr||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?Et(e):r}catch{return Et(e)}}async function Zi(t,e){await t.put(er,JSON.stringify(e,null,2),"application/json")}function ea(t){return`toolnet-auto-${ye(t).slice(0,12)}`}function ta(t){let e=Q(t.title).slice(0,72),n=ye(t.sourceKey).slice(0,10);return Q(`auto-${t.sourceType}-${e}-${n}`)}function na(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,Tt)}function ra(t){return ye({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function sa(t,e){return t.tags.includes(e)}async function rr(t){let e=Ui(t.hierarchy),n=Xi(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 We(new Le(t.storage,t.project));await i.initialize();let a=new ze(new De(t.storage,t.project));await a.initialize();let c=await Qi(t.storage,t.project.id),u=await i.listPages(),f=new Map(u.map(l=>[l.slug,l])),d=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=ea(l.sourceKey),S=ra(l),y=d.get(l.sourceKey),h=y?.slug??ta(l),k=f.get(h);if(k&&!sa(k,g)){o.skipped+=1;continue}let P=he([...l.tags,g]),E=na(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:E,tags:P},[...f.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:E,tags:P}),f.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:E,tags:P}),f.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let T=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,digest:S,marker:g,updatedAt:T},v=c.entries.findIndex(L=>L.sourceKey===l.sourceKey);v>=0?c.entries[v]=x:c.entries.push(x),d.set(l.sourceKey,x),await a.markApplied(l.sourceKey,S)}catch(g){if(g instanceof C&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Zi(t.storage,c),o}import{createHash as oa}from"node:crypto";import{chmodSync as or,existsSync as ia,mkdirSync as aa,readFileSync as uf,readdirSync as lf,renameSync as ca,statSync as df,writeFileSync as ua}from"node:fs";import{join as ir}from"node:path";var la="toolnet.skill-memory.v1",sr=5,da=16,pa=24,fa=32;function ma(t){return oa("sha256").update(t).digest("hex")}function ke(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 Ot(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 ga(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 z(t,e=360){return t&&Ot(ga(t),e)||void 0}function we(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function ar(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 cr(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 ur(t){let e=t.data??{};if(cr(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=ar(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=we(e,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function Se(t){let e=t.data??{};if(ur(t))return!1;if(cr(e,["passed","pass","success","succeeded","ok"])===!0||ar(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=we(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 lr(t){let e=t.data??{},n=we(e,["path","file","filePath","filename","target"]);if(n)return z(n,260);let r=t.provenance?.files;return z(r?.[0],260)}function Rt(t){return z(we(t.data??{},["command","cmd","script"]),420)}function ne(t){return z(we(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function ya(t){let e=[];for(let n of[...t].sort((r,s)=>r.sequence-s.sequence))if(Se(n)){if(n.type==="test"){let r=ne(n)??Rt(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=ne(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=ne(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return ke(e,10)}function ha(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=lr(r);s&&n.push(`Update ${s}`);break}case"command":{if(ur(r))break;let s=Rt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!Se(r))break;let s=ne(r)??Rt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!Se(r))break;let s=ne(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!Se(r))break;let s=ne(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=z(r,260);s&&n.push(`Update ${s}`)}return ke(n,da)}function Sa(t,e){let n=[...e.files];for(let r of t){let s=lr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=z(o,260);i&&n.push(i)}}return ke(n,pa)}function ka(t){return ke(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),fa)}function wa(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function dr(t,e,n){if(e.length===0)return[];let r=ya(e),s=ke(n.completed.map(g=>z(g,280)??""),sr);if(!(s.length>0||e.some(g=>["test","commit","deploy"].includes(g.type)&&Se(g))))return[];let i=z(n.task,280)??z(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=ha(e,n);if(c.length===0)return[];let u=Sa(e,n),f=ka(e),d=Math.min(...e.map(g=>g.sequence)),p=Math.max(...e.map(g=>g.sequence)),l=wa(e);return a.slice(0,sr).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=ma(y);return{schema:la,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:t.projectId,title:Ot(`SOP: ${g}`,180),task:g,summary:Ot(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:d,lastSequence:p,eventIds:f},createdAt:l}})}function va(t){return ir(t.rootPath,".toolnet","memory","skills")}function ba(t){let e=va(t);return aa(e,{recursive:!0,mode:448}),or(e,448),e}function pr(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=ba(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=ir(n,`${i.id}.json`);if(o.push(a),ia(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;ua(c,JSON.stringify(i,null,2)+`
37
+ `,{encoding:"utf8",mode:384}),ca(c,a),or(a,384),r+=1}return{written:r,deduped:s,files:o}}function fr(t){return String(t).padStart(12,"0")}function xa(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Be=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(f=>f.sequence)),o=Math.max(...n.map(f=>f.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=w(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[xa(e),"batches",`${fr(s)}-${fr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as ja}from"node:crypto";function mr(t){return String(t).padStart(12,"0")}function Ca(t){return ja("sha256").update(t).digest("hex")}function Aa(t){return t.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Ve=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=Ca([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[Aa(e),"batches",`${mr(s)}-${mr(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 Oa(t,e){if(!Pa(t))return{events:[],nextOffset:e};let n=Ta(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=Ma(t,"r");try{Ea(i,o,0,s,r)}finally{Ia(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
40
40
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
41
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Re=class{constructor(e){this.options=e;this.journal=new Te(e.storage),this.hierarchyJournal=new Oe(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=Zi(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=cn(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=qn(this.options.identity,s.events,o.state),f=Vn(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",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let d=gn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",d.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",d.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",d.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",d.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let d=await $n({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",d.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",d.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",d.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",d.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",d.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",d.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",d.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",d.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",d.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",d.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 ia,existsSync as aa,openSync as ca,readSync as ua,statSync as la}from"node:fs";var ea=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function J(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Un(t){return J(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function H(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))H(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(ea.has(r)||["data","payload","parts","messages"].includes(r))&&H(s,e,n+1)}}function Ne(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 Gn(t){let e=J(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 I(t,e,n,r,s={}){let o=J(r),i=s.key??Un(o);return{version:1,id:w([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 ta(t,e,n){let r=J(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(I(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(I(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 p=Number(u[1]),l=J(u[2]??""),m=l&&!Gn(l)?`Phase ${p} - ${l}`:`Phase ${p}`;s.push(I(t,e,"phase",m,{key:`phase:${p}`,order:p,status:Ne(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(I(t,e,"task",f[2],{status:f[1].trim()?"completed":Ne(f[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,l=J(d[2]),m=Gn(l);s.push(I(t,e,"task",m&&p!==void 0?`TODO ${p}`:l,{key:p!==void 0?`task:${p}`:Un(l),order:p,status:Ne(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 p=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");p&&s.push(I(t,e,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(I(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(I(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(I(t,e,"decision",r,{confidence:.9})),s}function _e(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 c=[];H(i.data,c);for(let u of c)s(I(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];H(i.data,c);for(let u of c)s(I(t,i,"task",u,{status:Ne(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(I(t,i,"file",u,{confidence:1}))}if(i.type==="test"){let c=[];H(i.data,c);for(let u of c)s(I(t,i,"test",u,{confidence:1}))}let a=[];H(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let f of ta(t,i,u))s(f)}let o=e[e.length-1];return s(I(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Yn(t){return String(t).padStart(12,"0")}var $e=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)+`
42
- `,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Yn(r)}-${Yn(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Xn}from"node:path";import{mkdirSync as na}from"node:fs";function ra(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function G(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=ra(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function sa(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 Qn(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&&sa(e)?t.title:e.text;return{id:t?.id??w(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 oa(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 Ke(t,e){let r=(await oa(t,e)).flatMap(g=>g.observations).sort((g,v)=>{let L=g.occurredAt.localeCompare(v.occurredAt);if(L!==0)return L;let Ct=g.sequence-v.sequence;return Ct!==0?Ct:g.id.localeCompare(v.id)}),s=new Map,o=new Map,i,a,c,u=[],f=[],d=[],p=[],l=[],m=[];for(let g of r)switch(g.kind){case"goal":i=g.text;break;case"plan":a=g.text;break;case"phase":s.set(g.key,Qn(s.get(g.key),g));break;case"task":o.set(g.key,Qn(o.get(g.key),g));break;case"decision":u.push(g.text);break;case"blocker":f.push(g.text);break;case"warning":d.push(g.text);break;case"next_action":p.push(g.text);break;case"file":l.push(g.text);break;case"test":m.push(g.text);break;case"session":c={agent:g.agent,nativeSessionId:g.nativeSessionId,sessionKey:g.sessionKey,updatedAt:g.occurredAt};break}let S=Array.from(s.values()).sort((g,v)=>(g.order??Number.MAX_SAFE_INTEGER)-(v.order??Number.MAX_SAFE_INTEGER)),h=Array.from(o.values()).sort((g,v)=>(g.order??Number.MAX_SAFE_INTEGER)-(v.order??Number.MAX_SAFE_INTEGER)),y=S.find(g=>g.status==="in_progress")??S.find(g=>g.status==="blocked")??S.find(g=>g.status==="pending"),k=h.find(g=>g.status==="in_progress")??h.find(g=>g.status==="blocked")??h.find(g=>g.status==="pending"),P=G([...p,...k?[k.title]:[],...!k&&y?[y.title]:[],...h.filter(g=>g.status==="pending").slice(0,5).map(g=>g.title)],8),C=G([...f,...S.filter(g=>g.status==="blocked").map(g=>g.title),...h.filter(g=>g.status==="blocked").map(g=>g.title)],20),j={version:1,projectId:t.id,projectName:t.name,goal:i,plan:a,phases:S,tasks:h,decisions:G(u,20),blockers:C,warnings:G(d,20),nextActions:P,filesTouched:G(l,30),tests:G(m,20),currentPhase:y,currentTask:k,progress:{phasesTotal:S.length,phasesCompleted:S.filter(g=>g.status==="completed").length,tasksTotal:h.length,tasksCompleted:h.filter(g=>g.status==="completed").length,blocked:S.filter(g=>g.status==="blocked").length+h.filter(g=>g.status==="blocked").length},lastSession:c,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},A=Xn(t.rootPath,".toolnet","work");return na(A,{recursive:!0}),M(Xn(A,"current.json"),j),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(j,null,2)+`
43
- `,"application/json"),j}async function We(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 da(t,e){if(!aa(t))return{events:[],nextOffset:e};let n=la(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=ca(t,"r");try{ua(i,o,0,s,r)}finally{ia(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
41
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Je=class{constructor(e){this.options=e;this.journal=new Be(e.storage),this.hierarchyJournal=new Ve(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=Oa(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Ke(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=dr(this.options.identity,s.events,o.state),f=pr(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",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let d=$n(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",d.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",d.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",d.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",d.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let d=await rr({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",d.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",d.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",d.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",d.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",d.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",d.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",d.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",d.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",d.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",d.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 Ya,existsSync as Xa,openSync as Qa,readSync as Za,statSync as ec}from"node:fs";function gr(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function be(t){return t.toLowerCase().replace(/[^a-z0-9]/gu,"")}function ve(t,e,n=0){if(n>8)return;if(Array.isArray(t)){for(let s of t.slice(0,50))ve(s,e,n+1);return}let r=gr(t);if(r)for(let[s,o]of Object.entries(r))e(s,o,r),ve(o,e,n+1)}function re(t,e){let n=[];return ve(t,(r,s)=>{e.has(be(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function Ra(t){let e=t.trim();if(!e.startsWith("{"))return null;try{return gr(JSON.parse(e))}catch{return null}}function Na(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 ve(e,(r,s,o)=>{if(n)return;let i=be(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 _a(t){let e=re(t.data,new Set(["command","cmd","script"])),n=re(t.data,new Set(["arguments","args"]));for(let r of n){let s=Ra(r);if(s)for(let o of re(s,new Set(["command","cmd","script"])))e.push(o)}return Array.from(new Set(e.map(r=>r.trim()).filter(Boolean)))}function $a(t){let e=re(t.data,new Set(["filepath","file_path","filename","file","path","target"].map(be)));return Array.from(new Set(e.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
42
+ `))))}function Ka(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 Fa(t){let e=re(t.data,new Set(["patch","diff","arguments","input"].map(be))),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 Wa(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 La(t){let e=null;return ve(t,(n,r)=>{if(e===null&&["exitcode","code"].includes(be(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 Da(t){return re(t,new Set(["status","state","result","output","outputsummary","message","text"]))}function za(t){let e=La(t.data);if(e!==null)return e===0?"passed":"failed";let n=Da(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 qa(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 yr(t){let e=[],n=Na(t),r=Ka(t,n);if(r)for(let s of $a(t))e.push({kind:"file",text:s,fileAction:r,confidence:t.type==="file_edit"||t.type==="file_write"?1:.96});e.push(...Fa(t));for(let s of _a(t)){e.push({kind:"command",text:s,confidence:.98});let o=Wa(s);o&&e.push({kind:"test",text:s,checkKind:o,checkStatus:za(t),confidence:.98})}return qa(e)}var Ba=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ee(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Sr(t){return ee(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Z(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))Z(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))&&Z(s,e,n+1)}}function He(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 hr(t){let e=ee(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 A(t,e,n,r,s={}){let o=ee(r),i=s.key??Sr(o);return{version:1,id:w([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 Va(t,e,n){let r=ee(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(A(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(A(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 p=Number(u[1]),l=ee(u[2]??""),g=l&&!hr(l)?`Phase ${p} - ${l}`:`Phase ${p}`;s.push(A(t,e,"phase",g,{key:`phase:${p}`,order:p,status:He(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(A(t,e,"task",f[2],{status:f[1].trim()?"completed":He(f[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,l=ee(d[2]),g=hr(l);s.push(A(t,e,"task",g&&p!==void 0?`TODO ${p}`:l,{key:p!==void 0?`task:${p}`:Sr(l),order:p,status:He(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 p=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");p&&s.push(A(t,e,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(A(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(A(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(A(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(A(t,e,"activity",r,{confidence:.86})),s}function se(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=[];Z(i.data,c);let u=c.map(f=>ee(f)).find(f=>f.length>=8&&f.length<=1200&&!/^\[?toolnet\b/iu.test(f));u&&s(A(t,i,"request",u,{confidence:.96}))}for(let c of yr(i))s(A(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=[];Z(i.data,c);for(let u of c)s(A(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];Z(i.data,c);for(let u of c)s(A(t,i,"task",u,{status:He(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(A(t,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];Z(i.data,c);for(let u of c)s(A(t,i,"test",u,{confidence:1}))}let a=[];Z(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let f of Va(t,i,u))s(f)}let o=e[e.length-1];return s(A(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function kr(t){return String(t).padStart(12,"0")}var Ge=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=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${kr(r)}-${kr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as wr}from"node:path";import{mkdirSync as Ja}from"node:fs";function br(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=br(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function Ha(t,e=20){let n=new Map;for(let r of t){let s=`${r.kind}|${br(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-e)}function Ga(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 vr(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&&Ga(e)?t.title:e.text;return{id:t?.id??w(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 Ua(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 Ue(t,e){let r=(await Ua(t,e)).flatMap(m=>m.observations).sort((m,b)=>{let q=m.occurredAt.localeCompare(b.occurredAt);if(q!==0)return q;let Jt=m.sequence-b.sequence;return Jt!==0?Jt:m.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,f,d=[],p=[],l=[],g=[],S=[],y=new Map,h=[],k=[],P=[],E=[],I=[],T=[];for(let m of r)switch(m.kind){case"request":i=m.text;break;case"activity":a=m.text;break;case"goal":c=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,vr(s.get(m.key),m));break;case"task":o.set(m.key,vr(o.get(m.key),m));break;case"decision":d.push(m.text);break;case"blocker":p.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":g.push(m.text);break;case"file":{S.push(m.text);let b=m.fileAction??"active";y.delete(m.text),y.set(m.text,b),b==="modified"?h.push(m.text):b==="created"?k.push(m.text):b==="deleted"&&P.push(m.text);break}case"command":E.push(m.text);break;case"test":I.push(m.text),m.checkKind&&T.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":f={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=Array.from(s.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),v=Array.from(o.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),L=x.find(m=>m.status==="in_progress")??x.find(m=>m.status==="blocked")??x.find(m=>m.status==="pending"),D=v.find(m=>m.status==="in_progress")??v.find(m=>m.status==="blocked")??v.find(m=>m.status==="pending"),ft=K([...g,...D?[D.title]:[],...!D&&L?[L.title]:[],...v.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),mt=K([...p,...x.filter(m=>m.status==="blocked").map(m=>m.title),...v.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie={version:1,projectId:t.id,projectName:t.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:v,decisions:K(d,20),blockers:mt,warnings:K(l,20),nextActions:ft,filesTouched:K(S,30),activeFiles:Array.from(y.entries()).filter(([,m])=>m!=="deleted").map(([m])=>m).slice(-5),modifiedFiles:K(h,30),createdFiles:K(k,30),deletedFiles:K(P,30),commands:K(E,20),tests:K(I,20),checks:Ha(T,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+v.filter(m=>m.status==="blocked").length},lastSession:f,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ae=wr(t.rootPath,".toolnet","work");return Ja(ae,{recursive:!0}),O(wr(ae,"current.json"),ie),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(ie,null,2)+`
45
+ `,"application/json"),ie}async function Ye(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 tc(t,e){if(!Xa(t))return{events:[],nextOffset:e};let n=ec(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=Qa(t,"r");try{Za(i,o,0,s,r)}finally{Ya(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
44
46
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
45
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Le=class{constructor(e){this.options=e;this.journal=new $e(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=da(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=_e(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ke(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 wa,existsSync as va,openSync as ba,readSync as xa,statSync as ja}from"node:fs";var pa=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function U(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function yt(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))yt(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(pa.has(r)||["data","payload","parts","messages"].includes(r))&&yt(s,e,n+1)}}function T(t,e,n,r,s,o=.95){let i=U(r);return{version:1,id:w([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 N(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 U(t.slice(r.length+1))}return null}function fa(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function ma(t){return U(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Zn(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=[];yt(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let f of a.split(/\r?\n/u)){let d=U(f);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let v=Number(p[1]);c={type:"phase",key:`phase:${v}`,order:v,title:U(p[2]??"")},u=null;continue}let l=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let v=Number(l[1]);c={type:"task",key:`task:${v}`,order:v,title:U(l[2]??"")},u=null;continue}let m=N(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){s(T(t,o,"mission",m,{type:"project"},.99)),u=null;continue}let S=N(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(T(t,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let h=N(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(h){s(T(t,o,c.type==="phase"?"phase_why":"why",h,c,.98)),u=null;continue}let y=N(d,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(y){s(T(t,o,"desired_outcome",y,{type:"project"},.98)),u=null;continue}let k=N(d,["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(T(t,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let P=N(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(P){s(T(t,o,"phase_deliverable",P,c,.97)),u=null;continue}let C=N(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(C){s(T(t,o,"acceptance_criterion",C,c,.98)),u="acceptance_criterion";continue}let j=N(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(j){s(T(t,o,"dependency",j,c,.97)),u="dependency";continue}let A=N(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(A){s(T(t,o,"open_question",A,c,.95)),u="open_question";continue}let g=N(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(g){s(T(t,o,"constraint",g,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&fa(f)){s(T(t,o,u,ma(f),c,.96));continue}u=null}}}return n}function er(t){return String(t).padStart(12,"0")}var Fe=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=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${er(r)}-${er(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
46
- `,"application/json"),a}};import{mkdirSync as ga}from"node:fs";import{join as tr}from"node:path";function ya(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function ha(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 K(t,e){return ha(e,t)?e:t}function W(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 Sa(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 ka(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function nr(t,e){let r=(await Sa(t,e)).flatMap(S=>S.observations).sort((S,h)=>{let y=S.evidence.occurredAt.localeCompare(h.evidence.occurredAt);return y!==0?y:S.evidence.sessionKey===h.evidence.sessionKey?S.evidence.sequence-h.evidence.sequence:S.id.localeCompare(h.id)}),s,o,i,a,c,u=new Map,f=[],d=[],p=[];for(let S of r){let h=ya(S);if(S.scope==="phase"&&S.scopeKey){let y=u.get(S.scopeKey)??ka(S);switch(S.kind){case"phase_objective":y.objective=K(y.objective,h);break;case"phase_why":y.why=K(y.why,h);break;case"phase_deliverable":y.deliverable=K(y.deliverable,h);break;case"acceptance_criterion":y.acceptanceCriteria.push(h);break;case"dependency":y.dependencies.push(h);break;case"open_question":y.openQuestions.push(h);break;case"constraint":y.constraints.push(h);break;case"note":y.notes.push(h);break}u.set(y.key,y);continue}switch(S.kind){case"mission":s=K(s,h);break;case"objective":o=K(o,h);break;case"why":i=K(i,h);break;case"desired_outcome":a=K(a,h);break;case"plan_rationale":c=K(c,h);break;case"open_question":f.push(h);break;case"constraint":d.push(h);break;case"note":p.push(h);break}}for(let S of u.values())S.acceptanceCriteria=W(S.acceptanceCriteria,20),S.dependencies=W(S.dependencies,15),S.openQuestions=W(S.openQuestions,15),S.constraints=W(S.constraints,15),S.notes=W(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,h)=>S.order-h.order),openQuestions:W(f,20),constraints:W(d,20),notes:W(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=tr(t.rootPath,".toolnet","work");return ga(m,{recursive:!0}),M(tr(m,"semantic-current.json"),l),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
47
- `,"application/json"),l}async function rr(t,e){let n=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Ia(t,e){if(!va(t))return{events:[],nextOffset:e};let n=ja(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=ba(t,"r");try{xa(o,s,0,s.length,r)}finally{wa(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
47
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Xe=class{constructor(e){this.options=e;this.journal=new Ge(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=tc(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=se(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ue(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 lc,existsSync as dc,openSync as pc,readSync as fc,statSync as mc}from"node:fs";var nc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function oe(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Nt(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))Nt(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(nc.has(r)||["data","payload","parts","messages"].includes(r))&&Nt(s,e,n+1)}}function N(t,e,n,r,s,o=.95){let i=oe(r);return{version:1,id:w([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 F(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 oe(t.slice(r.length+1))}return null}function rc(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function sc(t){return oe(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function xr(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=[];Nt(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let f of a.split(/\r?\n/u)){let d=oe(f);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let v=Number(p[1]);c={type:"phase",key:`phase:${v}`,order:v,title:oe(p[2]??"")},u=null;continue}let l=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let v=Number(l[1]);c={type:"task",key:`task:${v}`,order:v,title:oe(l[2]??"")},u=null;continue}let g=F(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(N(t,o,"mission",g,{type:"project"},.99)),u=null;continue}let S=F(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(N(t,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=F(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(N(t,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=F(d,["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(N(t,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=F(d,["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(N(t,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let P=F(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(P){s(N(t,o,"phase_deliverable",P,c,.97)),u=null;continue}let E=F(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(E){s(N(t,o,"acceptance_criterion",E,c,.98)),u="acceptance_criterion";continue}let I=F(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(I){s(N(t,o,"dependency",I,c,.97)),u="dependency";continue}let T=F(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){s(N(t,o,"open_question",T,c,.95)),u="open_question";continue}let x=F(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(N(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(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&rc(f)){s(N(t,o,u,sc(f),c,.96));continue}u=null}}}return n}function jr(t){return String(t).padStart(12,"0")}var Qe=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=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${jr(r)}-${jr(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 oc}from"node:fs";import{join as Cr}from"node:path";function ic(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function ac(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 V(t,e){return ac(e,t)?e:t}function J(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 cc(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 uc(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Ar(t,e){let r=(await cc(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,f=[],d=[],p=[];for(let S of r){let y=ic(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??uc(S);switch(S.kind){case"phase_objective":h.objective=V(h.objective,y);break;case"phase_why":h.why=V(h.why,y);break;case"phase_deliverable":h.deliverable=V(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=V(s,y);break;case"objective":o=V(o,y);break;case"why":i=V(i,y);break;case"desired_outcome":a=V(a,y);break;case"plan_rationale":c=V(c,y);break;case"open_question":f.push(y);break;case"constraint":d.push(y);break;case"note":p.push(y);break}}for(let S of u.values())S.acceptanceCriteria=J(S.acceptanceCriteria,20),S.dependencies=J(S.dependencies,15),S.openQuestions=J(S.openQuestions,15),S.constraints=J(S.constraints,15),S.notes=J(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:J(f,20),constraints:J(d,20),notes:J(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=Cr(t.rootPath,".toolnet","work");return oc(g,{recursive:!0}),O(Cr(g,"semantic-current.json"),l),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
49
+ `,"application/json"),l}async function Ir(t,e){let n=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function gc(t,e){if(!dc(t))return{events:[],nextOffset:e};let n=mc(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=pc(t,"r");try{fc(o,s,0,s.length,r)}finally{lc(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
48
50
  `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
49
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var De=class{constructor(e){this.options=e;this.journal=new Fe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Ia(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=Zn(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await nr(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 Ka}from"node:fs";import{join as ht}from"node:path";import{existsSync as ir,mkdirSync as Pa,readFileSync as Ca,statSync as sr,writeFileSync as Aa}from"node:fs";import{dirname as Ma,join as Ea}from"node:path";var or=64*1024,Ta=`# ToolNet Project Operating Manual
51
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Ze=class{constructor(e){this.options=e;this.journal=new Qe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=gc(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=xr(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ar(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 Kc,mkdirSync as Fc}from"node:fs";import{join as $t}from"node:path";import{existsSync as Er,mkdirSync as yc,readFileSync as hc,statSync as Pr,writeFileSync as Sc}from"node:fs";import{dirname as kc,join as wc}from"node:path";var Mr=64*1024,vc=`# ToolNet Project Operating Manual
50
52
 
51
53
  This file contains persistent instructions for AI agents working on this project.
52
54
 
@@ -89,51 +91,51 @@ Things an AI agent should always remember.
89
91
  <!--
90
92
  - [advisory] Prefer small focused files.
91
93
  -->
92
- `;function ze(t){return Ea(t.rootPath,".toolnet","PROJECT.md")}function Oa(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Ra(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=Oa(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Na(t){let e=ze(t);return ir(e)||(Pa(Ma(e),{recursive:!0}),Aa(e,Ta,{encoding:"utf8",mode:384})),e}function Be(t,e=!1){let n=e?Na(t):ze(t);if(!ir(n))return null;if(sr(n).size>or)throw new Error(`PROJECT.md exceeds ${or} bytes`);let s=Ca(n,"utf8");return{path:n,content:s,digest:w(s),rules:Ra(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(sr(n).mtimeMs).toISOString()}}function O(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 ar(t){if(t)return{id:t.id,title:t.title,status:t.status}}function _a(t){let e=t.slice(-10).join(`
93
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(e)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(e)?"passing":"unknown"}function $a(t){return w(JSON.stringify(t))}function cr(t){let{project:e,identity:n,state:r}=t,s=r.filesTouched.at(-1),o=r.phases.filter(y=>y.status==="completed").map(y=>y.title),i=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),a=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),c=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),u=O(r.nextActions,10),f=O([...c,...u],15),d=O(r.tests.slice().reverse(),10),p=O(r.filesTouched.slice().reverse(),20),l={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,current:{phase:ar(r.currentPhase),task:ar(r.currentTask),file:s},completed:{phases:O(o,20),tasks:O(i,30)},remaining:{phases:O(a,20),tasks:O(c,30),todos:f},nextAction:u[0],blockers:O(r.blockers.slice().reverse(),10),decisions:O(r.decisions.slice().reverse(),10),files:{current:s,recent:p},tests:{status:_a(r.tests),recent:d},attention:O(t.attention??[],20),progress:r.progress},{capturedAt:m,source:S,...h}=l;return{...l,stateDigest:$a(h)}}function Wa(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 qe=class{constructor(e){this.options=e}options;async capture(e,n){let r=await We(this.options.project,this.options.storage);if(r||(r=await Ke(this.options.project,this.options.storage)),!Wa(r))return null;let s=Be(this.options.project,!1),i=[...s?s.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...r.warnings].slice(0,20),a=cr({project:this.options.project,identity:this.options.identity,state:r,reason:e,sequence:n,attention:i}),c=a.stateDigest,u=w([this.options.project.id,this.options.identity.sessionKey,c].join("|")).slice(0,24),f=new Date().toISOString(),d={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:f,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:i,filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:c,continuity:a},p=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(p)||await this.options.storage.put(p,JSON.stringify(d,null,2)+`
94
- `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(d,null,2)+`
95
- `,"application/json");let l=ht(this.options.project.rootPath,".toolnet","work","handoffs");return Ka(l,{recursive:!0}),M(ht(l,`${u}.json`),d),M(ht(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),d),d}};async function ur(t,e){let n=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}var Ve=class{identity;wal;remote;sanitizer=new ee;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=Bt(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new we(this.identity),this.remote=new ke(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new Re({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new Le({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new De({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new qe({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 La,readFileSync as Fa,readdirSync as Da,statSync as lr}from"node:fs";import{homedir as za}from"node:os";import{join as He,resolve as dr}from"node:path";function pr(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Ba(){return process.env.CODEX_HOME??He(za(),".codex")}function de(t){let e="";try{e=Fa(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
96
- `))if(n)try{let r=pr(JSON.parse(n));if(r.type!=="session_meta")continue;let s=pr(r.payload),o=[s.id,s.thread_id,s.threadId,s.session_id,s.sessionId].find(a=>typeof a=="string"),i=typeof s.cwd=="string"?s.cwd:void 0;return{threadId:o,cwd:i,raw:s}}catch{}return{raw:{}}}function St(t,e){if(!La(t))return;let n;try{n=Da(t,{withFileTypes:!0})}catch{return}for(let r of n){let s=He(t,r.name);if(r.isDirectory()){St(s,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(s)}}function kt(){let t=Ba(),e=[];return St(He(t,"sessions"),e),St(He(t,"archived_sessions"),e),e.sort((n,r)=>{try{return lr(r).mtimeMs-lr(n).mtimeMs}catch{return 0}})}function wt(t){let e=kt(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(de(r).threadId===t)return r;return null}function Je(t,e){let n=dr(t),r=dr(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as qa,existsSync as Va,openSync as Ha,readSync as Ja,statSync as Ga}from"node:fs";function fr(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Ua(t){let e=t.timestamp;if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Ya(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=fr(t.payload),r=typeof n.type=="string"?n.type.toLowerCase():"",s=typeof n.role=="string"?n.role.toLowerCase():void 0;return e==="session_meta"?{type:"custom"}:s==="user"||r==="user_message"?{type:"user_prompt",role:"user"}:s==="assistant"||r==="agent_message"||r==="assistant_message"?{type:"assistant_message",role:"assistant"}:r.includes("function_call")||r.includes("tool_call")||r.includes("exec_command_begin")||r.includes("exec_command_start")?{type:"tool_call"}:r.includes("function_call_output")||r.includes("tool_result")||r.includes("exec_command_end")||r.includes("exec_command_complete")?{type:"tool_result"}:r.includes("error")?{type:"error"}:e.includes("compacted")||r.includes("compacted")?{type:"session_compact"}:{type:"custom",role:s}}function mr(t,e=0){if(!Va(t))return{events:[],nextOffset:e,reset:!1};let n=Ga(t).size,r=e>n,s=r?0:e;if(s>=n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),a=Ha(t,"r");try{Ja(a,i,0,o,s)}finally{qa(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
97
- `);if(u<0)return{events:[],nextOffset:s,reset:r};let f=c.slice(0,u+1),d=0,p=[];for(let l of f.split(`
98
- `)){if(!l)continue;let m=Buffer.byteLength(l+`
99
- `,"utf8"),S=s+d;d+=m;let h;try{h=JSON.parse(l)}catch{continue}let y=fr(h),k=Ya(y);p.push({type:k.type,timestamp:Ua(y),role:k.role,sourceEventId:`rollout:${S}`,sourceSequence:S,data:y,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:S}})}return{events:p,nextOffset:s+Buffer.byteLength(f,"utf8"),reset:r}}var Xa=[/^<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*$/],Qa=[/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],Za=["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 ec(t){let e=t.toLowerCase();return Za.some(n=>e.includes(n))}function tc(t){if(!t.trim())return!0;for(let e of Xa)if(e.test(t))return!0;return ec(t),!1}function nc(t){let e=t;for(let n of Qa)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function vt(t){let e=t.trim();return e?tc(e)?{content:"",filtered:!0,reason:"noise"}:{content:nc(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function Ge(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=vt(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=Ge(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=vt(s);return o.filtered?null:o.content}return s&&typeof s=="object"?Ge(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&&vt(r).filtered)return!0}return!1}import{existsSync as rc,mkdirSync as sc,readFileSync as oc,renameSync as ic,writeFileSync as ac}from"node:fs";import{dirname as cc,join as uc}from"node:path";function lc(t,e){sc(cc(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;ac(n,`${JSON.stringify(e,null,2)}
100
- `,{encoding:"utf8",mode:384}),ic(n,t)}function vr(t){return uc(t.rootPath,".toolnet","work","current.json")}function dc(t){let e=vr(t);if(!rc(e))return null;try{let n=JSON.parse(oc(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function bt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Y(t,e,n){let r=[],s=new Set;for(let o of[...t,...e].reverse()){let i=bt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function pc(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 yr(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&&pc(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 hr(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:bt(n.title);e.set(r,n)}return e}function Sr(t){return t.order!==void 0?`order:${t.order}`:bt(t.key||t.text)}function kr(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 wr(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function br(t,e){let n=dc(t),r=hr(n?.phases??[]),s=hr(n?.tasks??[]),o=n?.goal,i=n?.plan,a=n?.lastSession,c=[],u=[],f=[],d=[],p=[],l=[],m=[...e].sort((g,v)=>{let L=g.occurredAt.localeCompare(v.occurredAt);return L!==0?L:g.sequence-v.sequence});for(let g of m)switch(g.kind){case"goal":o=g.text;break;case"plan":i=g.text;break;case"phase":{let v=Sr(g);r.set(v,yr(r.get(v),g));break}case"task":{let v=Sr(g);s.set(v,yr(s.get(v),g));break}case"decision":c.push(g.text);break;case"blocker":u.push(g.text);break;case"warning":f.push(g.text);break;case"next_action":d.push(g.text);break;case"file":p.push(g.text);break;case"test":l.push(g.text);break;case"session":a={agent:g.agent,nativeSessionId:g.nativeSessionId,sessionKey:g.sessionKey,updatedAt:g.occurredAt};break}let S=kr(r.values()),h=kr(s.values()),y=wr(S),k=wr(h),P=Y(n?.nextActions??[],[...d,...k?[k.title]:[],...!k&&y?[y.title]:[],...h.filter(g=>g.status==="pending").slice(0,5).map(g=>g.title)],8),C=Y(n?.blockers??[],[...u,...S.filter(g=>g.status==="blocked").map(g=>g.title),...h.filter(g=>g.status==="blocked").map(g=>g.title)],20),j=m.length>0?m[m.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),A={version:1,projectId:t.id,projectName:t.name,goal:o,plan:i,phases:S,tasks:h,decisions:Y(n?.decisions??[],c,20),blockers:C,warnings:Y(n?.warnings??[],f,20),nextActions:P,filesTouched:Y(n?.filesTouched??[],p,30),tests:Y(n?.tests??[],l,20),currentPhase:y,currentTask:k,progress:{phasesTotal:S.length,phasesCompleted:S.filter(g=>g.status==="completed").length,tasksTotal:h.length,tasksCompleted:h.filter(g=>g.status==="completed").length,blocked:S.filter(g=>g.status==="blocked").length+h.filter(g=>g.status==="blocked").length},lastSession:a,updatedAt:j};return lc(vr(t),A),A}import{existsSync as fc,readFileSync as mc,writeFileSync as gc}from"node:fs";import{join as yc}from"node:path";var jr="<!-- TOOLNET:STABLE-WORK:BEGIN -->",xt="<!-- TOOLNET:STABLE-WORK:END -->";function jt(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function Ue(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function xr(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${jt(n)} ${n.title}`)]:[]}function hc(t){let e=[jr,"# ToolNet Stable Work State","",`Updated: ${t.updatedAt}`];return t.lastSession&&e.push(`Last agent: ${t.lastSession.agent}`,`Last session: ${t.lastSession.nativeSessionId}`),t.goal&&e.push("","Goal:",t.goal),t.plan&&e.push("","Plan:",t.plan),t.currentPhase&&e.push("","Current phase:",`${jt(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${jt(t.currentTask)} ${t.currentTask.title}`),e.push(...xr("Phases",t.phases)),e.push(...xr("TODO / Tasks",t.tasks)),e.push(...Ue("Next actions",t.nextActions)),e.push(...Ue("Blockers",t.blockers)),e.push(...Ue("Important decisions",t.decisions)),e.push(...Ue("Files touched",t.filesTouched)),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.",xt),e.join(`
101
- `)}function Ir(t,e){let n=yc(t.rootPath,".toolnet","current.md"),r="";if(fc(n))try{r=mc(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=hc(e),o=r.indexOf(jr),i=r.indexOf(xt),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+xt.length).trimStart()].filter(Boolean).join(`
94
+ `;function et(t){return wc(t.rootPath,".toolnet","PROJECT.md")}function bc(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function xc(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=bc(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function jc(t){let e=et(t);return Er(e)||(yc(kc(e),{recursive:!0}),Sc(e,vc,{encoding:"utf8",mode:384})),e}function tt(t,e=!1){let n=e?jc(t):et(t);if(!Er(n))return null;if(Pr(n).size>Mr)throw new Error(`PROJECT.md exceeds ${Mr} bytes`);let s=hc(n,"utf8");return{path:n,content:s,digest:w(s),rules:xc(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(Pr(n).mtimeMs).toISOString()}}import{existsSync as Cc,mkdirSync as Ac,readFileSync as Ic,renameSync as Pc,writeFileSync as Mc}from"node:fs";import{dirname as Ec,join as Tc}from"node:path";function Oc(t,e){Ac(Ec(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Mc(n,`${JSON.stringify(e,null,2)}
95
+ `,{encoding:"utf8",mode:384}),Pc(n,t)}function $r(t){return Tc(t.rootPath,".toolnet","work","current.json")}function _t(t){let e=$r(t);if(!Cc(e))return null;try{let n=JSON.parse(Ic(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function nt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(t,e,n){let r=[],s=new Set;for(let o of[...t,...e].reverse()){let i=nt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Rc(t,e,n=20){let r=new Map;for(let s of[...t,...e]){let o=`${s.kind}|${nt(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function Nc(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 Tr(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&&Nc(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 Or(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:nt(n.title);e.set(r,n)}return e}function Rr(t){return t.order!==void 0?`order:${t.order}`:nt(t.key||t.text)}function Nr(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 _r(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function rt(t,e){let n=_t(t),r=Or(n?.phases??[]),s=Or(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,f=[],d=[],p=[],l=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],P=[],E=[],I=[],T=[...e].sort((m,b)=>{let q=m.occurredAt.localeCompare(b.occurredAt);return q!==0?q:m.sequence-b.sequence});for(let m of T)switch(m.kind){case"request":o=m.text;break;case"activity":i=m.text;break;case"goal":a=m.text;break;case"plan":c=m.text;break;case"phase":{let b=Rr(m);r.set(b,Tr(r.get(b),m));break}case"task":{let b=Rr(m);s.set(b,Tr(s.get(b),m));break}case"decision":f.push(m.text);break;case"blocker":d.push(m.text);break;case"warning":p.push(m.text);break;case"next_action":l.push(m.text);break;case"file":{g.push(m.text);let b=m.fileAction??"active",q=S.indexOf(m.text);q>=0&&S.splice(q,1),b!=="deleted"&&S.push(m.text),b==="modified"?y.push(m.text):b==="created"?h.push(m.text):b==="deleted"&&k.push(m.text);break}case"command":P.push(m.text);break;case"test":E.push(m.text),m.checkKind&&I.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":u={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=Nr(r.values()),v=Nr(s.values()),L=_r(x),D=_r(v),ft=_(n?.nextActions??[],[...l,...D?[D.title]:[],...!D&&L?[L.title]:[],...v.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),mt=_(n?.blockers??[],[...d,...x.filter(m=>m.status==="blocked").map(m=>m.title),...v.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie=T.length>0?T[T.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ae={version:1,projectId:t.id,projectName:t.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:v,decisions:_(n?.decisions??[],f,20),blockers:mt,warnings:_(n?.warnings??[],p,20),nextActions:ft,filesTouched:_(n?.filesTouched??[],g,30),activeFiles:_([],S,5),modifiedFiles:_(n?.modifiedFiles??[],y,30),createdFiles:_(n?.createdFiles??[],h,30),deletedFiles:_(n?.deletedFiles??[],k,30),commands:_(n?.commands??[],P,20),tests:_(n?.tests??[],E,20),checks:Rc(n?.checks??[],I,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+v.filter(m=>m.status==="blocked").length},lastSession:u,updatedAt:ie};return Oc($r(t),ae),ae}function M(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 Kr(t){if(t)return{id:t.id,title:t.title,status:t.status}}function _c(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 $c(t){return w(JSON.stringify(t))}function Fr(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())),f=M(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=M([...c,...f],15),p=M(r.tests.slice().reverse(),10),l=M([...(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:Kr(r.currentPhase),task:Kr(r.currentTask),file:s},completed:{phases:M(o,20),tasks:M(i,30)},remaining:{phases:M(a,20),tasks:M(c,30),todos:d},nextAction:f[0],blockers:M(r.blockers.slice().reverse(),10),decisions:M(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:M(r.activeFiles??[],10),modified:M(r.modifiedFiles??[],20),created:M(r.createdFiles??[],20),deleted:M(r.deletedFiles??[],20)},tests:{status:_c(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},attention:M(t.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:$c(h)}}function Wc(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 Wr(t,e,n,r,s){if(!Wc(n))return null;let o=tt(t,!1),a=[...o?o.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=Fr({project:t,identity:e,state:n,reason:r,sequence:s,attention:a}),u=c.stateDigest;return{version:1,id:w([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(d=>d.status!=="completed"&&d.status!=="cancelled"),incompleteTasks:n.tasks.filter(d=>d.status!=="completed"&&d.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 Lr(t,e){let n=$t(t.rootPath,".toolnet","work","handoffs");Fc(n,{recursive:!0});let r=$t(n,`${e.id}.json`);Kc(r)||O(r,e),O($t(t.rootPath,".toolnet","work","handoff-latest.json"),e)}function Dr(t){let e=Wr(t.project,t.identity,t.state,t.reason,t.sequence);return e?(Lr(t.project,e),e):null}var st=class{constructor(e){this.options=e}options;async capture(e,n){let r=_t(this.options.project);r||(r=await Ye(this.options.project,this.options.storage)),r||(r=await Ue(this.options.project,this.options.storage));let s=Wr(this.options.project,this.options.identity,r,e,n);if(!s)return null;Lr(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}};async function zr(t,e){let n=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{existsSync as Lc,readFileSync as Dc,writeFileSync as zc}from"node:fs";import{join as qc}from"node:path";var Br="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Kt="<!-- TOOLNET:STABLE-WORK:END -->";function Ft(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 qr(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${Ft(n)} ${n.title}`)]:[]}function Bc(t){let e=[Br,"# 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:",`${Ft(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${Ft(t.currentTask)} ${t.currentTask.title}`),e.push(...qr("Phases",t.phases)),e.push(...qr("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.",Kt),e.join(`
99
+ `)}function ot(t,e){let n=qc(t.rootPath,".toolnet","current.md"),r="";if(Lc(n))try{r=Dc(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=Bc(e),o=r.indexOf(Br),i=r.indexOf(Kt),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+Kt.length).trimStart()].filter(Boolean).join(`
102
100
 
103
101
  `):a=r.trim()?`${r.trim()}
104
102
 
105
- ${s}`:s,gc(n,`${a.trim()}
106
- `,{encoding:"utf8",mode:384})}import{existsSync as Sc,mkdirSync as kc,readFileSync as wc,renameSync as vc,writeFileSync as bc}from"node:fs";import{dirname as xc,join as jc}from"node:path";function Pr(t){return jc(t.rootPath,".toolnet","context","session-origin.json")}function Ic(t,e){kc(xc(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;bc(n,`${JSON.stringify(e,null,2)}
107
- `,{encoding:"utf8",mode:384}),vc(n,t)}function Ye(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 Cr(t,e){let n=Ye(e.observations,"file"),r=Ye(e.observations,"next_action"),s=Ye(e.observations,"blocker"),o=Ye(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??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 Ic(Pr(t),i),i}function Pc(t){let e=Pr(t);if(!Sc(e))return null;try{let n=JSON.parse(wc(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Ar(t){let e=Pc(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
108
- `)}async function pe(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=de(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!Je(t.project.rootPath,r))throw new Error(`Codex thread does not belong to project: ${r}`);if(n.threadId&&n.threadId!==e)throw new Error(`Codex rollout thread mismatch: expected ${e}, got ${n.threadId}`);let s=new Ve({project:t.project,storage:t.storage,agent:"codex",nativeSessionId:e,metadata:{source:"codex-rollout",rolloutPath:t.rolloutPath,cwd:r,client:t.client}}),o=s.status(),i=o.sourceCursors["codex.rollout.path"],a=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(a=0),(!Number.isFinite(a)||a<0)&&(a=0);let c=mr(t.rolloutPath,a),u=[];o.lastSequence===0&&u.push({type:"session_start",sourceEventId:`codex:${e}:start`,data:{threadId:e,cwd:r,rolloutPath:t.rolloutPath,sessionMeta:n.raw},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),i&&i!==t.rolloutPath&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),c.reset&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${c.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=c.events.filter(l=>!gr(l.data)).map(l=>({...l,data:Ge(l.data)}));if(u.push(...f),t.idle&&f.length>0)try{let l={projectId:t.project.id,projectName:t.project.name,projectRoot:t.project.rootPath,agent:"codex",nativeSessionId:e,sessionKey:`codex:${e}`,remotePrefix:`projects/${t.project.id}/sessions/codex/${e}`,localDirectory:""},m=f.map((y,k)=>({version:1,id:`codex-work-${e}-${y.sourceSequence??k}`,sequence:k+1,projectId:t.project.id,agent:"codex",nativeSessionId:e,type:y.type,timestamp:y.timestamp??new Date().toISOString(),role:y.role,sourceEventId:y.sourceEventId,sourceSequence:y.sourceSequence,data:y.data??{},provenance:y.provenance??{}})),S=_e(l,m),h=br(t.project,S);Ir(t.project,h),Cr(t.project,{agent:"codex",nativeSessionId:e,observations:S,workState:h})}catch{}t.idle&&t.turnId&&u.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let d=s.recordMany(u);if(s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",c.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId),t.idle&&f.length>0)try{let l=f.map(S=>JSON.stringify(S.data)),m=je(l,e);s.setSourceCursor("codex.session.summary",m.summary),s.setSourceCursor("codex.session.facts_count",m.durableFacts.length),rn()&&!an()&&s.setSourceCursor("codex.raw_transcript.archived","local")}catch{}let p=await s.flush();return{threadId:e,imported:d.length,rolloutEvents:c.events.length,eventCount:p.eventCount,chunkCount:p.chunkCount,status:p.status,rolloutOffset:c.nextOffset,reset:c.reset}}import{existsSync as Cc}from"node:fs";import{dirname as Ac,join as Mc,parse as Ec,resolve as Tc}from"node:path";function Mr(t){let e=Tc(t),n=Ec(e).root;for(;;){if(Cc(Mc(e,".toolnet","project.json")))return new q().detect(e);if(e===n)break;let r=Ac(e);if(r===e)break;e=r}return null}async function Er(t,e,n=100){let r=[];for(let s of kt()){let o=de(s);if(!(!o.threadId||!o.cwd)&&Je(t.rootPath,o.cwd)&&(r.push(await pe({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as Oc,mkdirSync as Tr,readFileSync as Rc,writeFileSync as Or}from"node:fs";import{homedir as Rr}from"node:os";import{dirname as Nr,join as It}from"node:path";function Nc(t){let e=[],n=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=n.exec(t);){let s=r[1]??r[2]??"";try{e.push(r[1]!==void 0?JSON.parse(`"${s}"`):s)}catch{e.push(s)}}return e}function _r(t={}){let e=t.configFile??It(process.env.CODEX_HOME??It(Rr(),".codex"),"config.toml"),n=t.previousFile??It(Rr(),".config","toolnet-memory","codex-notify-previous.json");Tr(Nr(e),{recursive:!0}),Tr(Nr(n),{recursive:!0});let r=Oc(e)?Rc(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
103
+ ${s}`:s,zc(n,`${a.trim()}
104
+ `,{encoding:"utf8",mode:384})}import{existsSync as Vc,mkdirSync as Jc,readFileSync as Hc,renameSync as Gc,writeFileSync as Uc}from"node:fs";import{dirname as Yc,join as Xc}from"node:path";function Vr(t){return Xc(t.rootPath,".toolnet","context","session-origin.json")}function Qc(t,e){Jc(Yc(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Uc(n,`${JSON.stringify(e,null,2)}
105
+ `,{encoding:"utf8",mode:384}),Gc(n,t)}function it(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 at(t,e){let n=it(e.observations,"file"),r=it(e.observations,"next_action"),s=it(e.observations,"blocker"),o=it(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 Qc(Vr(t),i),i}function Zc(t){let e=Vr(t);if(!Vc(e))return null;try{let n=JSON.parse(Hc(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Jr(t){let e=Zc(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentRequest&&n.push(`- Current request: ${e.currentRequest}`),e.currentActivity&&n.push(`- Current activity: ${e.currentActivity}`),e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
106
+ `)}import{existsSync as Hr,mkdirSync as eu,readFileSync as tu}from"node:fs";import{join as Wt}from"node:path";function Gr(t){return Wt(t.rootPath,".toolnet","memory","checkpoints")}function Ur(t){return Wt(Gr(t),"latest.json")}function nu(t){let e=Ur(t);if(!Hr(e))return null;try{let n=JSON.parse(tu(e,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==t.id?null:n}catch{return null}}function ru(t){return["rule","architecture","decision","fix"].includes(t)}function su(t,e){return e.length===0?[]:Ke(t,e).candidates.filter(r=>ru(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 ou(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 iu(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 Yr(t,e,n,r){let s=nu(t),o=ou(s?.durableFacts??[],su(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),f=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),d={work:iu(r),durableFacts:o.map(y=>y.fingerprint).sort()},p=w(JSON.stringify(d)).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:f},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:p},g=Gr(t);eu(g,{recursive:!0,mode:448});let S=Wt(g,`${p}.json`);return Hr(S)||O(S,l),O(Ur(t),l),l}function Xr(t,e,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=se(e,n);if(r.length===0)return{updated:!1,observations:0};let s=rt(t,r);ot(t,s),at(t,{agent:e.agent,nativeSessionId:e.nativeSessionId,observations:r,workState:s});try{Yr(t,e,n,s)}catch{}try{Dr({project:t,identity:e,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var ct=class{identity;wal;remote;sanitizer=new H;learner;continuity;semantic;handoff;project;title;metadata;constructor(e){this.project=e.project,this.identity=un(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Oe(this.identity,e.eventContext),this.remote=new Te(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new Je({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new Xe({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Ze({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new st({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{Xr(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 au,readFileSync as cu,readdirSync as uu,statSync as Qr}from"node:fs";import{homedir as lu}from"node:os";import{join as ut,resolve as Zr}from"node:path";function es(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function du(){return process.env.CODEX_HOME??ut(lu(),".codex")}function xe(t){let e="";try{e=cu(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
107
+ `))if(n)try{let r=es(JSON.parse(n));if(r.type!=="session_meta")continue;let s=es(r.payload),o=[s.id,s.thread_id,s.threadId,s.session_id,s.sessionId].find(a=>typeof a=="string"),i=typeof s.cwd=="string"?s.cwd:void 0;return{threadId:o,cwd:i,raw:s}}catch{}return{raw:{}}}function Lt(t,e){if(!au(t))return;let n;try{n=uu(t,{withFileTypes:!0})}catch{return}for(let r of n){let s=ut(t,r.name);if(r.isDirectory()){Lt(s,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(s)}}function Dt(){let t=du(),e=[];return Lt(ut(t,"sessions"),e),Lt(ut(t,"archived_sessions"),e),e.sort((n,r)=>{try{return Qr(r).mtimeMs-Qr(n).mtimeMs}catch{return 0}})}function zt(t){let e=Dt(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(xe(r).threadId===t)return r;return null}function lt(t,e){let n=Zr(t),r=Zr(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as pu,existsSync as fu,openSync as mu,readSync as gu,statSync as yu}from"node:fs";function ts(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function hu(t){let e=t.timestamp;if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Su(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=ts(t.payload),r=typeof n.type=="string"?n.type.toLowerCase():"",s=typeof n.role=="string"?n.role.toLowerCase():void 0;return e==="session_meta"?{type:"custom"}:s==="user"||r==="user_message"?{type:"user_prompt",role:"user"}:s==="assistant"||r==="agent_message"||r==="assistant_message"?{type:"assistant_message",role:"assistant"}:r.includes("function_call")||r.includes("tool_call")||r.includes("exec_command_begin")||r.includes("exec_command_start")?{type:"tool_call"}:r.includes("function_call_output")||r.includes("tool_result")||r.includes("exec_command_end")||r.includes("exec_command_complete")?{type:"tool_result"}:r.includes("error")?{type:"error"}:e.includes("compacted")||r.includes("compacted")?{type:"session_compact"}:{type:"custom",role:s}}function ns(t,e=0){if(!fu(t))return{events:[],nextOffset:e,reset:!1};let n=yu(t).size,r=e>n,s=r?0:e;if(s>=n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),a=mu(t,"r");try{gu(a,i,0,o,s)}finally{pu(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
108
+ `);if(u<0)return{events:[],nextOffset:s,reset:r};let f=c.slice(0,u+1),d=0,p=[];for(let l of f.split(`
109
+ `)){if(!l)continue;let g=Buffer.byteLength(l+`
110
+ `,"utf8"),S=s+d;d+=g;let y;try{y=JSON.parse(l)}catch{continue}let h=ts(y),k=Su(h);p.push({type:k.type,timestamp:hu(h),role:k.role,sourceEventId:`rollout:${S}`,sourceSequence:S,data:h,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:S}})}return{events:p,nextOffset:s+Buffer.byteLength(f,"utf8"),reset:r}}var ku=[/^<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*$/],wu=[/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],vu=["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 bu(t){let e=t.toLowerCase();return vu.some(n=>e.includes(n))}function xu(t){if(!t.trim())return!0;for(let e of ku)if(e.test(t))return!0;return bu(t),!1}function ju(t){let e=t;for(let n of wu)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function qt(t){let e=t.trim();return e?xu(e)?{content:"",filtered:!0,reason:"noise"}:{content:ju(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function dt(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=qt(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=dt(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=qt(s);return o.filtered?null:o.content}return s&&typeof s=="object"?dt(s):s}).filter(s=>s!==null):e[n]=r;return e}function rs(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&&qt(r).filtered)return!0}return!1}async function je(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=xe(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!lt(t.project.rootPath,r))throw new Error(`Codex thread does not belong to project: ${r}`);if(n.threadId&&n.threadId!==e)throw new Error(`Codex rollout thread mismatch: expected ${e}, got ${n.threadId}`);let s=new ct({project:t.project,storage:t.storage,agent:"codex",nativeSessionId:e,metadata:{source:"codex-rollout",rolloutPath:t.rolloutPath,cwd:r,client:t.client},eventContext:{source:"codex",cwd:r??t.project.rootPath,turnId:t.turnId}}),o=s.status(),i=o.sourceCursors["codex.rollout.path"],a=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(a=0),(!Number.isFinite(a)||a<0)&&(a=0);let c=ns(t.rolloutPath,a),u=[];o.lastSequence===0&&u.push({type:"session_start",sourceEventId:`codex:${e}:start`,data:{threadId:e,cwd:r,rolloutPath:t.rolloutPath,sessionMeta:n.raw},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),i&&i!==t.rolloutPath&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),c.reset&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${c.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=c.events.filter(l=>!rs(l.data)).map(l=>({...l,data:dt(l.data)}));if(u.push(...f),f.length>0)try{let l={projectId:t.project.id,projectName:t.project.name,projectRoot:t.project.rootPath,agent:"codex",nativeSessionId:e,sessionKey:`codex:${e}`,remotePrefix:`projects/${t.project.id}/sessions/codex/${e}`,localDirectory:""},g=f.map((h,k)=>({version:1,id:`codex-work-${e}-${h.sourceSequence??k}`,sequence:k+1,projectId:t.project.id,agent:"codex",nativeSessionId:e,type:h.type,timestamp:h.timestamp??new Date().toISOString(),role:h.role,sourceEventId:h.sourceEventId,sourceSequence:h.sourceSequence,data:h.data??{},provenance:h.provenance??{}})),S=se(l,g),y=rt(t.project,S);ot(t.project,y),at(t.project,{agent:"codex",nativeSessionId:e,observations:S,workState:y})}catch{}t.idle&&t.turnId&&u.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let d=s.recordMany(u);if(s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",c.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId),t.idle&&f.length>0)try{let l=f.map(S=>JSON.stringify(S.data)),g=$e(l,e);s.setSourceCursor("codex.session.summary",g.summary),s.setSourceCursor("codex.session.facts_count",g.durableFacts.length),jn()&&!In()&&s.setSourceCursor("codex.raw_transcript.archived","local")}catch{}let p=await s.flush();return{threadId:e,imported:d.length,rolloutEvents:c.events.length,eventCount:p.eventCount,chunkCount:p.chunkCount,status:p.status,rolloutOffset:c.nextOffset,reset:c.reset}}import{existsSync as Cu}from"node:fs";import{dirname as Au,join as Iu,parse as Pu,resolve as Mu}from"node:path";function ss(t){let e=Mu(t),n=Pu(e).root;for(;;){if(Cu(Iu(e,".toolnet","project.json")))return new te().detect(e);if(e===n)break;let r=Au(e);if(r===e)break;e=r}return null}async function os(t,e,n=100){let r=[];for(let s of Dt()){let o=xe(s);if(!(!o.threadId||!o.cwd)&&lt(t.rootPath,o.cwd)&&(r.push(await je({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as Eu,mkdirSync as is,readFileSync as Tu,writeFileSync as as}from"node:fs";import{homedir as cs}from"node:os";import{dirname as us,join as Bt}from"node:path";function Ou(t){let e=[],n=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=n.exec(t);){let s=r[1]??r[2]??"";try{e.push(r[1]!==void 0?JSON.parse(`"${s}"`):s)}catch{e.push(s)}}return e}function ls(t={}){let e=t.configFile??Bt(process.env.CODEX_HOME??Bt(cs(),".codex"),"config.toml"),n=t.previousFile??Bt(cs(),".config","toolnet-memory","codex-notify-previous.json");is(us(e),{recursive:!0}),is(us(n),{recursive:!0});let r=Eu(e)?Tu(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
109
111
  `),a=i.findIndex(p=>/^\s*\[/.test(p));a<0&&(a=i.length);let c=-1,u=-1;for(let p=0;p<a;p+=1)if(/^\s*notify\s*=/.test(i[p])){if(c=p,u=p,i[p].includes("[")&&!i[p].includes("]"))for(;u+1<a&&(u+=1,!i[u].includes("]")););break}let f=[];if(c>=0){let p=i.slice(c,u+1).join(`
110
- `);f=Nc(p),i.splice(c,u-c+1,o)}else a=i.findIndex(p=>/^\s*\[/.test(p)),a<0&&(a=i.length),i.splice(a,0,o);let d=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!d&&Or(n,JSON.stringify(f,null,2)+`
112
+ `);f=Ou(p),i.splice(c,u-c+1,o)}else a=i.findIndex(p=>/^\s*\[/.test(p)),a<0&&(a=i.length),i.splice(a,0,o);let d=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!d&&as(n,JSON.stringify(f,null,2)+`
111
113
  `,{encoding:"utf8",mode:384}),r=i.join(`
112
114
  `),r.endsWith(`
113
115
  `)||(r+=`
114
- `),Or(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:f.length>0&&!d}}import{existsSync as _c,mkdirSync as $c,readFileSync as Kc,writeFileSync as Wc}from"node:fs";import{homedir as Lc}from"node:os";import{dirname as Fc,join as $r}from"node:path";function Dc(t){return`'${t.replace(/'/g,"'\\''")}'`}function Kr(t={}){let e=t.hooksFile??$r(process.env.CODEX_HOME??$r(Lc(),".codex"),"hooks.json");$c(Fc(e),{recursive:!0});let n={};if(_c(e))try{n=JSON.parse(Kc(e,"utf8"))}catch(a){throw new Error(`Invalid existing Codex hooks.json: ${a instanceof Error?a.message:String(a)}`)}let r=n.hooks&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)?n.hooks:{};n.hooks=r;let o=(Array.isArray(r.SessionStart)?r.SessionStart:[]).filter(a=>{try{return!JSON.stringify(a).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return o.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${Dc(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=o,Wc(e,JSON.stringify(n,null,2)+`
115
- `,{encoding:"utf8",mode:384}),e}import{existsSync as Sm,mkdirSync as Vc,readFileSync as km,writeFileSync as Hc}from"node:fs";import{dirname as Jc,join as Lr}from"node:path";function Pt(t){if(!t)return 0;let e=Array.from(t).length,n=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,n*1.3))}function b(t,e){let n=t.replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function zc(t){let e=[],n=!1;for(let r of t.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&e.push(b(s,280)),e.length>=16))break}return e}function Bc(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),a=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>o.startsWith(u));if(!a)continue;let c=s.slice(a.length).trim();c&&(a.includes("enforce")?e.push(c):n.push(c))}return{enforce:e,advisory:n}}function qc(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
116
- `);if(Pt(s)<=e){n.push(r);continue}let o=Pt(n.join(`
117
- `)),i=Math.max(0,e-o);if(i>=16){let a=Math.floor(i*3.2),c=b(r,a);c&&n.push(c)}break}return n.join(`
118
- `).trim()}async function Wr(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=Be(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=Bc(r),o=n?n.rules.filter(l=>l.mode==="enforce").map(l=>l.text):s.enforce,i=n?n.rules.filter(l=>l.mode==="advisory").map(l=>l.text):s.advisory,a=r?zc(r):[],c=await We(t.project,t.storage),u=await rr(t.project,t.storage),f=await ur(t.project,t.storage),d=[];if(d.push("[TOOLNET PROJECT CONTEXT]"),d.push(`Project: ${t.project.name}`),d.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&d.push(`Full operating manual: ${ze(t.project)}`),o.length){d.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let l of o.slice(0,24))d.push(`- [ENFORCE] ${b(l,240)}`)}if(i.length){d.push("","PROJECT PREFERENCES");for(let l of i.slice(0,10))d.push(`- ${b(l,220)}`)}if(u&&(u.mission&&d.push("","MISSION",b(u.mission.value,420)),u.activeObjective&&d.push("","CURRENT OBJECTIVE",b(u.activeObjective.value,420)),u.why&&d.push("","WHY THIS WORK MATTERS",b(u.why.value,420)),u.desiredOutcome&&d.push("","DESIRED OUTCOME",b(u.desiredOutcome.value,420)),u.planRationale&&d.push("","WHY THIS APPROACH",b(u.planRationale.value,420))),c){if(d.push("","ACTIVE WORK"),c.goal&&d.push(`Goal: ${b(c.goal,320)}`),c.plan&&d.push(`Plan: ${b(c.plan,320)}`),d.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&d.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&u){let l=u.phases.find(m=>m.order===c.currentPhase?.order);l&&(l.objective&&d.push(`Phase objective: ${b(l.objective.value,340)}`),l.why?d.push(`Why this phase: ${b(l.why.value,340)}`):d.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),l.deliverable&&d.push(`Deliverable: ${b(l.deliverable.value,340)}`),l.dependencies.length&&d.push(`Depends on: ${l.dependencies.slice(0,4).map(m=>b(m.value,180)).join("; ")}`),l.acceptanceCriteria.length&&(d.push("","DEFINITION OF DONE"),l.acceptanceCriteria.slice(0,6).forEach(m=>{d.push(`- ${b(m.value,260)}`)})),l.openQuestions.length&&(d.push("","OPEN QUESTIONS FOR CURRENT PHASE"),l.openQuestions.slice(0,4).forEach(m=>{d.push(`- ${b(m.value,260)}`)})))}c.currentTask&&d.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(d.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((l,m)=>{d.push(`${m+1}. ${b(l,260)}`)})),c.blockers.length&&(d.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(l=>{d.push(`- ${b(l,260)}`)})),c.warnings.length&&(d.push("","ATTENTION"),c.warnings.slice(-5).forEach(l=>{d.push(`- ${b(l,260)}`)})),c.decisions.length&&(d.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(l=>{d.push(`- ${b(l,260)}`)})),c.lastSession&&d.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(d.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(l=>{d.push(`- ${b(l.value,260)}`)})),f&&d.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),a.length){d.push("","OPERATING NOTES");for(let l of a)d.push(`- ${l}`)}d.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=qc(d,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:p,estimatedTokens:Pt(p),maxTokens:e,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!f,generatedAt:new Date().toISOString()}}function Gc(t){return Lr(t.rootPath,".toolnet","context","startup.md")}function Uc(t){return Lr(t.rootPath,".toolnet","context","startup.json")}function Yc(t,e){let n=Gc(t);Vc(Jc(n),{recursive:!0}),Hc(n,e.text.endsWith(`
116
+ `),as(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:f.length>0&&!d}}import{existsSync as Ru,mkdirSync as Nu,readFileSync as _u,writeFileSync as $u}from"node:fs";import{homedir as Ku}from"node:os";import{dirname as Fu,join as ds}from"node:path";function Wu(t){return`'${t.replace(/'/g,"'\\''")}'`}function ps(t={}){let e=t.hooksFile??ds(process.env.CODEX_HOME??ds(Ku(),".codex"),"hooks.json");Nu(Fu(e),{recursive:!0});let n={};if(Ru(e))try{n=JSON.parse(_u(e,"utf8"))}catch(a){throw new Error(`Invalid existing Codex hooks.json: ${a instanceof Error?a.message:String(a)}`)}let r=n.hooks&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)?n.hooks:{};n.hooks=r;let o=(Array.isArray(r.SessionStart)?r.SessionStart:[]).filter(a=>{try{return!JSON.stringify(a).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return o.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${Wu(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=o,$u(e,JSON.stringify(n,null,2)+`
117
+ `,{encoding:"utf8",mode:384}),e}import{existsSync as Ng,mkdirSync as qu,readFileSync as _g,writeFileSync as Bu}from"node:fs";import{dirname as Vu,join as ms}from"node:path";function Vt(t){if(!t)return 0;let e=Array.from(t).length,n=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,n*1.3))}function j(t,e){let n=t.replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function Lu(t){let e=[],n=!1;for(let r of t.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&e.push(j(s,280)),e.length>=16))break}return e}function Du(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),a=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>o.startsWith(u));if(!a)continue;let c=s.slice(a.length).trim();c&&(a.includes("enforce")?e.push(c):n.push(c))}return{enforce:e,advisory:n}}function zu(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
118
+ `);if(Vt(s)<=e){n.push(r);continue}let o=Vt(n.join(`
119
+ `)),i=Math.max(0,e-o);if(i>=16){let a=Math.floor(i*3.2),c=j(r,a);c&&n.push(c)}break}return n.join(`
120
+ `).trim()}async function fs(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=tt(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=Du(r),o=n?n.rules.filter(l=>l.mode==="enforce").map(l=>l.text):s.enforce,i=n?n.rules.filter(l=>l.mode==="advisory").map(l=>l.text):s.advisory,a=r?Lu(r):[],c=await Ye(t.project,t.storage),u=await Ir(t.project,t.storage),f=await zr(t.project,t.storage),d=[];if(d.push("[TOOLNET PROJECT CONTEXT]"),d.push(`Project: ${t.project.name}`),d.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&d.push(`Full operating manual: ${et(t.project)}`),o.length){d.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let l of o.slice(0,24))d.push(`- [ENFORCE] ${j(l,240)}`)}if(i.length){d.push("","PROJECT PREFERENCES");for(let l of i.slice(0,10))d.push(`- ${j(l,220)}`)}if(u&&(u.mission&&d.push("","MISSION",j(u.mission.value,420)),u.activeObjective&&d.push("","CURRENT OBJECTIVE",j(u.activeObjective.value,420)),u.why&&d.push("","WHY THIS WORK MATTERS",j(u.why.value,420)),u.desiredOutcome&&d.push("","DESIRED OUTCOME",j(u.desiredOutcome.value,420)),u.planRationale&&d.push("","WHY THIS APPROACH",j(u.planRationale.value,420))),c){if(d.push("","ACTIVE WORK"),c.goal&&d.push(`Goal: ${j(c.goal,320)}`),c.plan&&d.push(`Plan: ${j(c.plan,320)}`),d.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&d.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&u){let l=u.phases.find(g=>g.order===c.currentPhase?.order);l&&(l.objective&&d.push(`Phase objective: ${j(l.objective.value,340)}`),l.why?d.push(`Why this phase: ${j(l.why.value,340)}`):d.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),l.deliverable&&d.push(`Deliverable: ${j(l.deliverable.value,340)}`),l.dependencies.length&&d.push(`Depends on: ${l.dependencies.slice(0,4).map(g=>j(g.value,180)).join("; ")}`),l.acceptanceCriteria.length&&(d.push("","DEFINITION OF DONE"),l.acceptanceCriteria.slice(0,6).forEach(g=>{d.push(`- ${j(g.value,260)}`)})),l.openQuestions.length&&(d.push("","OPEN QUESTIONS FOR CURRENT PHASE"),l.openQuestions.slice(0,4).forEach(g=>{d.push(`- ${j(g.value,260)}`)})))}c.currentTask&&d.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(d.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((l,g)=>{d.push(`${g+1}. ${j(l,260)}`)})),c.blockers.length&&(d.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(l=>{d.push(`- ${j(l,260)}`)})),c.warnings.length&&(d.push("","ATTENTION"),c.warnings.slice(-5).forEach(l=>{d.push(`- ${j(l,260)}`)})),c.decisions.length&&(d.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(l=>{d.push(`- ${j(l,260)}`)})),c.lastSession&&d.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(d.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(l=>{d.push(`- ${j(l.value,260)}`)})),f&&d.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),a.length){d.push("","OPERATING NOTES");for(let l of a)d.push(`- ${l}`)}d.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=zu(d,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:p,estimatedTokens:Vt(p),maxTokens:e,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!f,generatedAt:new Date().toISOString()}}function Ju(t){return ms(t.rootPath,".toolnet","context","startup.md")}function Hu(t){return ms(t.rootPath,".toolnet","context","startup.json")}function Gu(t,e){let n=Ju(t);qu(Vu(n),{recursive:!0}),Bu(n,e.text.endsWith(`
119
121
  `)?e.text:e.text+`
120
- `,{encoding:"utf8",mode:384}),M(Uc(t),e)}async function Fr(t,e,n=800){let s=(await Wr({project:t,storage:e,maxTokens:n})).text;be(s)>n&&(s=xe(s,n),s+=`
122
+ `,{encoding:"utf8",mode:384}),O(Hu(t),e)}async function gs(t,e,n=800){let s=(await fs({project:t,storage:e,maxTokens:n})).text;Ne(s)>n&&(s=_e(s,n),s+=`
121
123
 
122
124
  [Context trimmed by ToolNet Memory token budget]
123
- `);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:w(s),estimatedTokens:be(s),generatedAt:new Date().toISOString()};return Yc(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
125
+ `);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:w(s),estimatedTokens:Ne(s),generatedAt:new Date().toISOString()};return Gu(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
124
126
  `,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(i,null,2)+`
125
- `,"application/json"),i}import{existsSync as nu,readFileSync as ru}from"node:fs";import{join as su}from"node:path";import{existsSync as Dr,mkdirSync as Xc,readFileSync as zr,renameSync as Qc,writeFileSync as Zc}from"node:fs";import{dirname as eu,join as Br}from"node:path";function qr(t){return Br(t.rootPath,".toolnet","context","handoff.md")}function Vr(t){return Br(t.rootPath,".toolnet","context","handoff.json")}function Hr(t,e){Xc(eu(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Zc(n,e.endsWith(`
127
+ `,"application/json"),i}import{existsSync as el,readFileSync as tl}from"node:fs";import{join as nl}from"node:path";import{existsSync as ys,mkdirSync as Uu,readFileSync as hs,renameSync as Yu,writeFileSync as Xu}from"node:fs";import{dirname as Qu,join as Ss}from"node:path";function ks(t){return Ss(t.rootPath,".toolnet","context","handoff.md")}function ws(t){return Ss(t.rootPath,".toolnet","context","handoff.json")}function vs(t,e){Uu(Qu(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Xu(n,e.endsWith(`
126
128
  `)?e:`${e}
127
- `,{encoding:"utf8",mode:384}),Qc(n,t)}function tu(t,e){Hr(t,`${JSON.stringify(e,null,2)}
128
- `)}function Jr(t,e){let n=e.replace(/\r\n/g,`
129
- `).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return Hr(qr(t),n),tu(Vr(t),r),r}function Gr(t){let e=qr(t);if(!Dr(e))return null;try{let n=zr(e,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=Vr(t);if(Dr(s))try{let o=JSON.parse(zr(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function ou(t){let e=su(t.rootPath,".toolnet","current.md");if(!nu(e))return null;try{return ru(e,"utf8").trim()}catch{return null}}function iu(t,e){let n=e.replace(/\r\n/g,`
129
+ `,{encoding:"utf8",mode:384}),Yu(n,t)}function Zu(t,e){vs(t,`${JSON.stringify(e,null,2)}
130
+ `)}function bs(t,e){let n=e.replace(/\r\n/g,`
131
+ `).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return vs(ks(t),n),Zu(ws(t),r),r}function xs(t){let e=ks(t);if(!ys(e))return null;try{let n=hs(e,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=ws(t);if(ys(s))try{let o=JSON.parse(hs(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function rl(t){let e=nl(t.rootPath,".toolnet","current.md");if(!el(e))return null;try{return tl(e,"utf8").trim()}catch{return null}}function sl(t,e){let n=e.replace(/\r\n/g,`
130
132
  `).trim(),r=2400,s=n.length>r?`${n.slice(0,r)}
131
133
 
132
- [Current work truncated for fast handoff]`:n,o=Ar(t);return["# ToolNet Fast Handoff","",`Project: ${t.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
133
- `)}function Ur(t){let e=ou(t);if(e===null)return{updated:!1,reason:"missing-current",chars:0};if(!e.trim())return{updated:!1,reason:"empty-current",chars:0};let n=iu(t,e);return Gr(t)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(Jr(t,n),{updated:!0,reason:"updated",chars:n.length})}function Xe(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Yr(t){let e=fe(),n=Kt(_t({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new Se(n,t.id,t.name,t.remote??t.name)}async function pu(t){for(let e=0;e<10;e+=1){let n=wt(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function fu(t){let e=du(lu(),".config","toolnet-memory","codex-notify-previous.json");if(au(e))try{let n=JSON.parse(cu(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(s=>typeof s=="string"))return;uu(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function mu(t){let e;try{e=JSON.parse(t)}catch{return}if(e.type!=="agent-turn-complete")return;let r=typeof e["thread-id"]=="string"?e["thread-id"]:"",s=typeof e["turn-id"]=="string"?e["turn-id"]:"",o=typeof e.cwd=="string"?e.cwd:"",i=typeof e.client=="string"?e.client:void 0;if(!r||!o)return;let a=Mr(o);if(!a)return;let c=await pu(r);if(!c)return;let u=Yr(a);await pe({project:a,storage:u,threadId:r,rolloutPath:c,cwd:o,turnId:s,client:i,idle:!0});try{await Fr(a,u,800)}catch{}try{Ur(a)}catch{}}async function gu(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let o=Xe(e,"--bin"),i=_r({binary:o}),a=Kr({binary:o});console.log(`\u2705 Codex notify installed: ${i.configFile}`),i.preservedPrevious&&console.log(`\u2705 Previous notify preserved: ${i.previousFile}`),console.log(`\u2705 Codex SessionStart context hook: ${a}`);return}if(t==="notify"){let o=e[e.length-1]??"";try{await mu(o)}finally{fu(o)}return}let n=Xe(e,"--project")??process.cwd(),r=new q().detect(n),s=Yr(r);if(t==="sync"){let o=e[0];if(!o)throw new Error("Usage: sync <thread-id>");let i=Xe(e,"--rollout")??wt(o);if(!i)throw new Error(`Codex rollout not found for ${o}`);let a=await pe({project:r,storage:s,threadId:o,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(a,null,2));return}if(t==="recover"){let o=Number(Xe(e,"--limit")??100),i=await Er(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(`Codex Session Adapter
134
+ [Current work truncated for fast handoff]`:n,o=Jr(t);return["# ToolNet Fast Handoff","",`Project: ${t.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
135
+ `)}function js(t){let e=rl(t);if(e===null)return{updated:!1,reason:"missing-current",chars:0};if(!e.trim())return{updated:!1,reason:"empty-current",chars:0};let n=sl(t,e);return xs(t)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(bs(t,n),{updated:!0,reason:"updated",chars:n.length})}function pt(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Cs(t){let e=Ce(),n=nn(en({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new Ee(n,t.id,t.name,t.remote??t.name)}async function ll(t){for(let e=0;e<10;e+=1){let n=zt(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function dl(t){let e=ul(cl(),".config","toolnet-memory","codex-notify-previous.json");if(ol(e))try{let n=JSON.parse(il(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(s=>typeof s=="string"))return;al(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function pl(t){let e;try{e=JSON.parse(t)}catch{return}if(e.type!=="agent-turn-complete")return;let r=typeof e["thread-id"]=="string"?e["thread-id"]:"",s=typeof e["turn-id"]=="string"?e["turn-id"]:"",o=typeof e.cwd=="string"?e.cwd:"",i=typeof e.client=="string"?e.client:void 0;if(!r||!o)return;let a=ss(o);if(!a)return;let c=await ll(r);if(!c)return;let u=Cs(a);await je({project:a,storage:u,threadId:r,rolloutPath:c,cwd:o,turnId:s,client:i,idle:!0});try{await gs(a,u,800)}catch{}try{js(a)}catch{}}async function fl(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let o=pt(e,"--bin"),i=ls({binary:o}),a=ps({binary:o});console.log(`\u2705 Codex notify installed: ${i.configFile}`),i.preservedPrevious&&console.log(`\u2705 Previous notify preserved: ${i.previousFile}`),console.log(`\u2705 Codex SessionStart context hook: ${a}`);return}if(t==="notify"){let o=e[e.length-1]??"";try{await pl(o)}finally{dl(o)}return}let n=pt(e,"--project")??process.cwd(),r=new te().detect(n),s=Cs(r);if(t==="sync"){let o=e[0];if(!o)throw new Error("Usage: sync <thread-id>");let i=pt(e,"--rollout")??zt(o);if(!i)throw new Error(`Codex rollout not found for ${o}`);let a=await je({project:r,storage:s,threadId:o,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(a,null,2));return}if(t==="recover"){let o=Number(pt(e,"--limit")??100),i=await os(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(`Codex Session Adapter
134
136
 
135
137
  Commands:
136
138
  install-notify
137
139
  sync <thread-id> [--project PATH]
138
140
  recover [--project PATH] [--limit N]
139
- `)}gu().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});
141
+ `)}fl().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});