toolnet-memory 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/codex.js CHANGED
@@ -1,26 +1,26 @@
1
- import{existsSync as Ps,readFileSync as Os}from"node:fs";import{spawn as Es}from"node:child_process";import{homedir as Cs}from"node:os";import{join as Ms}from"node:path";import{existsSync as Ft,readFileSync as Wt}from"node:fs";import{homedir as zt}from"node:os";import{join as Bt}from"node:path";function Kt(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 Dt(){let t=process.env.TOOLNET_GLOBAL_ENV??Bt(zt(),".config","toolnet-memory",".env");if(!Ft(t))return;let e=Wt(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]=Kt(r.slice(s+1)))}}Dt();function q(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function W(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function Ae(){return{memory:{autoCapture:q(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:q(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:q(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:q(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:W(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:W(process.env.MEMORY_RERANK_TOP,10),finalContext:W(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:W(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:W(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Jt}from"node:crypto";import{existsSync as ge,mkdirSync as qt,readFileSync as Vt,renameSync as Ht,writeFileSync as Ut}from"node:fs";import{basename as Yt,dirname as V,join as H,parse as Te,resolve as z}from"node:path";var _e=".toolnet",Gt="project.json";function Xt(t){return Jt("sha256").update(t).digest("hex").slice(0,16)}function he(t){return H(t,_e,Gt)}function Qt(t){return ge(he(t))}function Zt(t,e){let n=z(t),r=Te(n).root;for(;;){if(Qt(n))return n;if(n===r||e&&n===z(e))break;let s=V(n);if(s===n)break;n=s}return null}function en(t){let e=z(t),n=Te(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>ge(H(e,o))))return e;if(e===n)break;let s=V(e);if(s===e)break;e=s}return z(t)}function tn(t){let e;try{e=JSON.parse(Vt(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:V(V(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 Re(t,e){let n=H(t,_e);qt(n,{recursive:!0});let r=he(t),s=`${r}.tmp-${process.pid}`;Ut(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Ht(s,r)}function Ne(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 T=class{detect(e=process.cwd()){let n=z(e),r=en(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>ge(H(r,p))),i=Zt(n,o?r:void 0);if(i){let p=he(i),l=tn(p);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Re(i,l)),Ne(l,i)}let u=new Date().toISOString(),a=Yt(r),c={version:1,id:Xt(r),name:a,remote:a,rootPath:r,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Re(r,c),Ne(c,r)}};var nn=[{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}],U=class{scan(e){let n=[];for(let r of nn){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 B=class{scanner=new U;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 vn}from"node:os";import{join as wn}from"node:path";import{DeleteObjectCommand as rn,GetObjectCommand as sn,HeadObjectCommand as on,ListObjectsV2Command as an,PutObjectCommand as cn,S3Client as un}from"@aws-sdk/client-s3";import{getSignedUrl as ln}from"@aws-sdk/s3-request-presigner";var Y=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new un({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 cn({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await ln(this.client,new sn({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 on({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 rn({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new an({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 $e,mkdir as dn,readFile as pn,readdir as fn,rm as mn,stat as Le,writeFile as gn}from"node:fs/promises";import{dirname as hn,join as yn,relative as Fe,resolve as Sn}from"node:path";var K=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Sn(this.root,n)}async put(e,n){let r=this.path(e);await dn(hn(r),{recursive:!0}),await gn(r,n)}async get(e){try{return await pn(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 $e(this.path(e)),!0}catch{return!1}}async delete(e){await mn(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await $e(n)}catch{return r}let s=async i=>{let u=await fn(i,{withFileTypes:!0});for(let a of u){let c=yn(i,a.name);if(a.isDirectory()){await s(c);continue}let p=await Le(c);r.push({key:Fe(this.root,c),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await Le(n);return o.isDirectory()?await s(n):r.push({key:Fe(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};function We(t){let e=t.localRoot??wn(vn(),".toolnet-memory","storage");if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Y({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new K(e))}return new K(e)}function jn(t){return new Promise(e=>setTimeout(e,t))}async function ze(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(u){if(o=u,i>=n)break;let a=Math.min(s,r*2**(i-1)),c=Math.floor(Math.random()*Math.max(1,a*.2));await jn(a+c)}throw o}var xn=new Set(["put","get","getText","delete","list"]);function Be(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:xn.has(r)?(...o)=>ze(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Ke(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 De(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var G=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Ke(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(u){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${u instanceof Error?u.message:String(u)}`)}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=De(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 Cn}from"node:path";import{createHash as bn}from"node:crypto";import{dirname as kn}from"node:path";import{mkdirSync as In,readFileSync as Pn,renameSync as On,writeFileSync as En}from"node:fs";function v(t){return bn("sha256").update(t).digest("hex")}function ye(t){if(Array.isArray(t))return t.map(ye);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=ye(e[r]);return n}return t}function Je(t){return JSON.stringify(ye(t))}function qe(t){try{return JSON.parse(Pn(t,"utf8"))}catch{return null}}function k(t,e){In(kn(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;En(n,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),On(n,t)}function Ve(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function He(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=Ve(r.toLowerCase(),"agent"),i=Ve(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:Cn(t.rootPath,".toolnet","sessions",o,i)}}function Ue(t){return String(t).padStart(12,"0")}var X=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
1
+ import{existsSync as Js,readFileSync as qs}from"node:fs";import{spawn as Vs}from"node:child_process";import{homedir as Us}from"node:os";import{join as Hs}from"node:path";import{existsSync as Dt,readFileSync as Jt}from"node:fs";import{homedir as qt}from"node:os";import{join as Vt}from"node:path";function Ut(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 Ht(){let t=process.env.TOOLNET_GLOBAL_ENV??Vt(qt(),".config","toolnet-memory",".env");if(!Dt(t))return;let e=Jt(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]=Ut(r.slice(s+1)))}}Ht();function F(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function W(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function _e(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:W(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:W(process.env.MEMORY_RERANK_TOP,10),finalContext:W(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:W(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:F(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:W(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Yt}from"node:crypto";import{existsSync as ye,mkdirSync as Gt,readFileSync as Qt,renameSync as Xt,writeFileSync as Zt}from"node:fs";import{basename as en,dirname as U,join as H,parse as Ke,resolve as z}from"node:path";var Fe=".toolnet",tn="project.json";function nn(t){return Yt("sha256").update(t).digest("hex").slice(0,16)}function Se(t){return H(t,Fe,tn)}function rn(t){return ye(Se(t))}function sn(t,e){let n=z(t),r=Ke(n).root;for(;;){if(rn(n))return n;if(n===r||e&&n===z(e))break;let s=U(n);if(s===n)break;n=s}return null}function on(t){let e=z(t),n=Ke(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>ye(H(e,o))))return e;if(e===n)break;let s=U(e);if(s===e)break;e=s}return z(t)}function an(t){let e;try{e=JSON.parse(Qt(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:U(U(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 $e(t,e){let n=H(t,Fe);Gt(n,{recursive:!0});let r=Se(t),s=`${r}.tmp-${process.pid}`;Zt(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),Xt(s,r)}function Le(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 N=class{detect(e=process.cwd()){let n=z(e),r=on(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>ye(H(r,f))),i=sn(n,o?r:void 0);if(i){let f=Se(i),l=an(f);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),$e(i,l)),Le(l,i)}let u=new Date().toISOString(),a=en(r),c={version:1,id:nn(r),name:a,remote:a,rootPath:r,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return $e(r,c),Le(c,r)}};var cn=[{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}],Y=class{scan(e){let n=[];for(let r of cn){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 B=class{scanner=new Y;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 Rn}from"node:os";import{join as Tn}from"node:path";import{DeleteObjectCommand as un,GetObjectCommand as ln,HeadObjectCommand as dn,ListObjectsV2Command as pn,PutObjectCommand as fn,S3Client as mn}from"@aws-sdk/client-s3";import{getSignedUrl as gn}from"@aws-sdk/s3-request-presigner";var G=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new mn({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 fn({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await gn(this.client,new ln({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 dn({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 un({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new pn({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 We,mkdir as hn,readFile as yn,readdir as Sn,rm as vn,stat as ze,writeFile as wn}from"node:fs/promises";import{dirname as bn,join as kn,relative as Be,resolve as jn}from"node:path";var D=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return jn(this.root,n)}async put(e,n){let r=this.path(e);await hn(bn(r),{recursive:!0}),await wn(r,n)}async get(e){try{return await yn(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 We(this.path(e)),!0}catch{return!1}}async delete(e){await vn(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await We(n)}catch{return r}let s=async i=>{let u=await Sn(i,{withFileTypes:!0});for(let a of u){let c=kn(i,a.name);if(a.isDirectory()){await s(c);continue}let f=await ze(c);r.push({key:Be(this.root,c),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await ze(n);return o.isDirectory()?await s(n):r.push({key:Be(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as xn,GetObjectCommand as In,HeadObjectCommand as Pn,ListObjectsV2Command as On,PutObjectCommand as En,S3Client as Cn}from"@aws-sdk/client-s3";import{getSignedUrl as An}from"@aws-sdk/s3-request-presigner";var J=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Cn({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 En({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await An(this.client,new In({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 Pn({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 xn({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new On({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 ve(t,e){return console.warn(e),new D(t)}function De(t){let e=t.localRoot??Tn(Rn(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new J({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ve(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 J({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ve(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 G({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):ve(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new D(e)}function Mn(t){return new Promise(e=>setTimeout(e,t))}async function Je(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(u){if(o=u,i>=n)break;let a=Math.min(s,r*2**(i-1)),c=Math.floor(Math.random()*Math.max(1,a*.2));await Mn(a+c)}throw o}var Nn=new Set(["put","get","getText","delete","list"]);function qe(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Nn.has(r)?(...o)=>Je(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Ve(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 Ue(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 Q=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Ve(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(u){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${u instanceof Error?u.message:String(u)}`)}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=Ue(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 zn}from"node:path";import{createHash as _n}from"node:crypto";import{dirname as $n}from"node:path";import{mkdirSync as Ln,readFileSync as Kn,renameSync as Fn,writeFileSync as Wn}from"node:fs";function v(t){return _n("sha256").update(t).digest("hex")}function we(t){if(Array.isArray(t))return t.map(we);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=we(e[r]);return n}return t}function He(t){return JSON.stringify(we(t))}function Ye(t){try{return JSON.parse(Kn(t,"utf8"))}catch{return null}}function x(t,e){Ln($n(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;Wn(n,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),Fn(n,t)}function Ge(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function Qe(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=Ge(r.toLowerCase(),"agent"),i=Ge(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:zn(t.rootPath,".toolnet","sessions",o,i)}}function Xe(t){return String(t).padStart(12,"0")}var X=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
6
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 u=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!u)continue;let a=Number(u[1]),c=Number(u[2]);!Number.isFinite(a)||!Number.isFinite(c)||(s.push({key:i.key,start:a,end:c}),o=Math.max(o,c))}return s.sort((i,u)=>i.start-u.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),u=n.filter(g=>g.sequence>i.maxSequence),a=0;for(let g of this.split(u)){let S=g[0],b=g[g.length-1],A=g.map(R=>JSON.stringify(R)).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),u=n.filter(g=>g.sequence>i.maxSequence),a=0;for(let g of this.split(u)){let S=g[0],j=g[g.length-1],R=g.map(T=>JSON.stringify(T)).join(`
8
8
  `)+`
9
- `,N=v(A).slice(0,16),E=[e.remotePrefix,"events",`${Ue(S.sequence)}-${Ue(b.sequence)}-${N}.jsonl`].join("/");await this.storage.exists(E)||await this.storage.put(E,A,"application/x-ndjson"),a+=g.length}let c=await this.scan(e),p=n[n.length-1],l=o?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?l="idle":p?.type==="error"?l="error":n.length>0&&(l="active");let f=new Date().toISOString(),d=n[0],y={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:o?.createdAt??d?.timestamp??f,updatedAt:p?.timestamp??f,firstEventAt:o?.firstEventAt??d?.timestamp,lastEventAt:p?.timestamp??o?.lastEventAt,eventCount:c.maxSequence,chunkCount:c.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(y.title=s.title??o?.title);let h={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:c.maxSequence,lastRemoteSequence:c.maxSequence,sourceCursors:r,updatedAt:f};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,y),{uploadedEvents:a,lastRemoteSequence:c.maxSequence,eventCount:y.eventCount,chunkCount:y.chunkCount,status:l}}};import{closeSync as Se,existsSync as Mn,fsyncSync as An,mkdirSync as Rn,openSync as ve,readSync as Nn,rmSync as Ye,statSync as Ge,writeSync as Tn}from"node:fs";import{join as we}from"node:path";var _n=12e4,$n=80,Ln=2e3;function Fn(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Q=class{constructor(e){this.identity=e;Rn(e.localDirectory,{recursive:!0}),this.eventsFile=we(e.localDirectory,"events.jsonl"),this.stateFile=we(e.localDirectory,"state.json"),this.lockFile=we(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 qe(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){k(this.stateFile,e)}acquireLock(){for(let e=0;e<$n;e+=1)try{return ve(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Ge(this.lockFile).mtimeMs>_n){Ye(this.lockFile,{force:!0});continue}}catch{}Fn(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{Se(n),Ye(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let f=l.timestamp??new Date().toISOString(),d=l.data??{},y=l.provenance?.rawDigest??v(Je(d)),h=l.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,l.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,l.type,f,y].join("|"),g=v(h).slice(0,32);if(r.has(g))continue;s+=1;let S={version:1,id:g,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:l.type,timestamp:f,data:d,provenance:{...l.provenance,rawDigest:y}};l.role!==void 0&&(S.role=l.role),l.sourceEventId!==void 0&&(S.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(S.sourceSequence=l.sourceSequence),o.push(S),r.add(g)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
9
+ `,M=v(R).slice(0,16),E=[e.remotePrefix,"events",`${Xe(S.sequence)}-${Xe(j.sequence)}-${M}.jsonl`].join("/");await this.storage.exists(E)||await this.storage.put(E,R,"application/x-ndjson"),a+=g.length}let c=await this.scan(e),f=n[n.length-1],l=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?l="idle":f?.type==="error"?l="error":n.length>0&&(l="active");let p=new Date().toISOString(),d=n[0],y={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:o?.createdAt??d?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:o?.firstEventAt??d?.timestamp,lastEventAt:f?.timestamp??o?.lastEventAt,eventCount:c.maxSequence,chunkCount:c.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(y.title=s.title??o?.title);let h={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:c.maxSequence,lastRemoteSequence:c.maxSequence,sourceCursors:r,updatedAt:p};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,y),{uploadedEvents:a,lastRemoteSequence:c.maxSequence,eventCount:y.eventCount,chunkCount:y.chunkCount,status:l}}};import{closeSync as be,existsSync as Bn,fsyncSync as Dn,mkdirSync as Jn,openSync as ke,readSync as qn,rmSync as Ze,statSync as et,writeSync as Vn}from"node:fs";import{join as je}from"node:path";var Un=12e4,Hn=80,Yn=2e3;function Gn(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Z=class{constructor(e){this.identity=e;Jn(e.localDirectory,{recursive:!0}),this.eventsFile=je(e.localDirectory,"events.jsonl"),this.stateFile=je(e.localDirectory,"state.json"),this.lockFile=je(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 Ye(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){x(this.stateFile,e)}acquireLock(){for(let e=0;e<Hn;e+=1)try{return ke(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-et(this.lockFile).mtimeMs>Un){Ze(this.lockFile,{force:!0});continue}}catch{}Gn(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{be(n),Ze(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let p=l.timestamp??new Date().toISOString(),d=l.data??{},y=l.provenance?.rawDigest??v(He(d)),h=l.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,l.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,l.type,p,y].join("|"),g=v(h).slice(0,32);if(r.has(g))continue;s+=1;let S={version:1,id:g,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:l.type,timestamp:p,data:d,provenance:{...l.provenance,rawDigest:y}};l.role!==void 0&&(S.role=l.role),l.sourceEventId!==void 0&&(S.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(S.sourceSequence=l.sourceSequence),o.push(S),r.add(g)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
10
10
  `)+`
11
- `,u=ve(this.eventsFile,"a",384);try{Tn(u,i,null,"utf8"),An(u)}finally{Se(u)}let a=o[o.length-1],c="active";a.type==="session_end"||a.type==="session_idle"?c="idle":a.type==="error"&&(c="error");let p=Array.from(r).slice(-Ln);return this.saveStateUnsafe({...n,status:c,updatedAt:a.timestamp,lastSequence:a.sequence,recentEventIds:p}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Mn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=Ge(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=ve(this.eventsFile,"r");try{Nn(i,o,0,s,r)}finally{Se(i)}return{events:o.toString("utf8").split(`
12
- `).filter(Boolean).map(c=>JSON.parse(c)),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 er,existsSync as tr,openSync as nr,readSync as rr,statSync as sr}from"node:fs";function Xe(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 tt=[/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],Wn=[/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],zn=[/\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],Bn=[/\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],Kn=[/đã 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],Qe=[/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],Dn=[/\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],Jn=[/đường dẫn/iu,/\bpath\b/iu,/\bport\b/iu,/\bendpoint\b/iu,/\bdomain\b/iu,/\bbucket\b/iu,/\brepository\b/iu,/\brepo\b/iu,/\bbranch\b/iu,/\/[A-Za-z0-9._/-]{4,}/u],qn=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],Ze=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Vn=new Set(["payload","data","content","message","messages","parts","summary"]);function I(t,e){return e.some(n=>n.test(t))}function nt(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Hn(t){return nt(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Un(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function je(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||Ze.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))je(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Ze.has(s)||Vn.has(s))&&je(o,s,n,r+1)}}function Yn(t){let e=[];je(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=nt(o);if(Un(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function et(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Gn(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&&I(t,tt)?{kind:"rule",confidence:.98}:r&&I(t,Wn)?{kind:"rule",confidence:.92}:I(t,zn)?{kind:I(t,Qe)?"architecture":"decision",confidence:r?.93:.86}:r&&I(t,Bn)?{kind:"todo",confidence:.87}:I(t,Qe)&&I(t,Dn)?{kind:"architecture",confidence:r?.88:.82}:s&&I(t,Kn)?{kind:"fix",confidence:.8}:r&&I(t,Jn)&&I(t,qn)?{kind:"context",confidence:.79}:null}function Xn(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Qn(t,e,n){return t==="rule"&&I(n,tt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Xe(e,n)}function rt(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,u=et(o);i&&u&&s.set(i,u)}for(let o of e){let i=et(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let a of Yn(o)){let c=Gn(a,i,o);if(!c||c.confidence<.75)continue;let p=Xn(c.kind),l=Hn(a),f=v([t.projectId,c.kind,l].join("|"));if(r.has(f))continue;r.add(f);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],y=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:f,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:c.kind,type:p,content:a,confidence:c.confidence,importance:Qn(c.kind,p,a),tags:[p],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:y,sourcePaths:d,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}function st(t){return String(t).padStart(12,"0")}function Zn(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Z=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(p=>p.sequence)),o=Math.max(...n.map(p=>p.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},u=JSON.stringify(i,null,2)+`
13
- `,a=v(r.map(p=>p.fingerprint).sort().join("|")).slice(0,16),c=[Zn(e),"batches",`${st(s)}-${st(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,u,"application/json"),c}};function or(t,e){if(!tr(t))return{events:[],nextOffset:e};let n=sr(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=nr(t,"r");try{rr(i,o,0,s,r)}finally{er(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
11
+ `,u=ke(this.eventsFile,"a",384);try{Vn(u,i,null,"utf8"),Dn(u)}finally{be(u)}let a=o[o.length-1],c="active";a.type==="session_end"||a.type==="session_idle"?c="idle":a.type==="error"&&(c="error");let f=Array.from(r).slice(-Yn);return this.saveStateUnsafe({...n,status:c,updatedAt:a.timestamp,lastSequence:a.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Bn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=et(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=ke(this.eventsFile,"r");try{qn(i,o,0,s,r)}finally{be(i)}return{events:o.toString("utf8").split(`
12
+ `).filter(Boolean).map(c=>JSON.parse(c)),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 pr,existsSync as fr,openSync as mr,readSync as gr,statSync as hr}from"node:fs";function tt(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 ot=[/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],Qn=[/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],Xn=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],Zn=[/\btodo\b/iu,/cần làm/iu,/cần thêm/iu,/cần sửa/iu,/cần kiểm tra/iu,/tiếp theo/iu,/bước tiếp theo/iu,/còn phải/iu,/còn cần/iu,/next step/iu,/\bneed to\b/iu,/\bremaining\b/iu,/follow[- ]?up/iu],er=[/đã 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],nt=[/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],tr=[/\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],nr=[/đườ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],rr=[/\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],rt=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),sr=new Set(["payload","data","content","message","messages","parts","summary"]);function I(t,e){return e.some(n=>n.test(t))}function it(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function or(t){return it(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function ir(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 xe(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||rt.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))xe(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(rt.has(s)||sr.has(s))&&xe(o,s,n,r+1)}}function ar(t){let e=[];xe(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=it(o);if(ir(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function st(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function cr(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&&I(t,ot)?{kind:"rule",confidence:.98}:r&&I(t,Qn)?{kind:"rule",confidence:.92}:I(t,Xn)?{kind:I(t,nt)?"architecture":"decision",confidence:r?.93:.86}:r&&I(t,Zn)?{kind:"todo",confidence:.87}:I(t,nt)&&I(t,tr)?{kind:"architecture",confidence:r?.88:.82}:s&&I(t,er)?{kind:"fix",confidence:.8}:r&&I(t,nr)&&I(t,rr)?{kind:"context",confidence:.79}:null}function ur(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function lr(t,e,n){return t==="rule"&&I(n,ot)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":tt(e,n)}function at(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,u=st(o);i&&u&&s.set(i,u)}for(let o of e){let i=st(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let a of ar(o)){let c=cr(a,i,o);if(!c||c.confidence<.75)continue;let f=ur(c.kind),l=or(a),p=v([t.projectId,c.kind,l].join("|"));if(r.has(p))continue;r.add(p);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],y=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:c.kind,type:f,content:a,confidence:c.confidence,importance:lr(c.kind,f,a),tags:[f],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:y,sourcePaths:d,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}function ct(t){return String(t).padStart(12,"0")}function dr(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var ee=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},u=JSON.stringify(i,null,2)+`
13
+ `,a=v(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),c=[dr(e),"batches",`${ct(s)}-${ct(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,u,"application/json"),c}};function yr(t,e){if(!fr(t))return{events:[],nextOffset:e};let n=hr(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=mr(t,"r");try{gr(i,o,0,s,r)}finally{pr(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
14
14
  `);if(a<0)return{events:[],nextOffset:r};let c=u.slice(0,a+1);return{events:c.split(`
15
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ee=class{constructor(e){this.options=e;this.journal=new Z(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=or(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=rt(this.options.identity,s.events),i=!1;return o.length>0&&(i=!!await this.journal.write(this.options.identity,s.events,o)),this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:o.length,journalWritten:i,nextOffset:s.nextOffset}}};import{closeSync as pr,existsSync as fr,openSync as mr,readSync as gr,statSync as hr}from"node:fs";var ir=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function $(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function it(t){return $(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(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))_(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(ir.has(r)||["data","payload","parts","messages"].includes(r))&&_(s,e,n+1)}}function te(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function ot(t){let e=$(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function j(t,e,n,r,s={}){let o=$(r),i=s.key??it(o);return{version:1,id:v([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function ar(t,e,n){let r=$(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(j(t,e,"goal",i[1],{confidence:.97}));let u=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(j(t,e,"plan",u[1],{confidence:.95}));let a=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,c;for(;!o&&(c=a.exec(r));){let f=Number(c[1]),d=$(c[2]??""),y=d&&!ot(d)?`Phase ${f} - ${d}`:`Phase ${f}`;s.push(j(t,e,"phase",y,{key:`phase:${f}`,order:f,status:te(r),confidence:.93}))}let p=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&s.push(j(t,e,"task",p[2],{status:p[1].trim()?"completed":te(p[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let f=l[1]?Number(l[1]):void 0,d=$(l[2]),y=ot(d);s.push(j(t,e,"task",y&&f!==void 0?`TODO ${f}`:d,{key:f!==void 0?`task:${f}`:it(d),order:f,status:te(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let f=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");f&&s.push(j(t,e,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(j(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(j(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(j(t,e,"decision",r,{confidence:.9})),s}function at(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 a=[];_(i.data,a);for(let c of a)s(j(t,i,"decision",c,{confidence:1}))}if(i.type==="todo"){let a=[];_(i.data,a);for(let c of a)s(j(t,i,"task",c,{status:te(c),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let a of["filePath","path","file"]){let c=i.data[a];typeof c=="string"&&c&&s(j(t,i,"file",c,{confidence:1}))}if(i.type==="test"){let a=[];_(i.data,a);for(let c of a)s(j(t,i,"test",c,{confidence:1}))}let u=[];_(i.data,u);for(let a of u)for(let c of a.split(/\n+/u))for(let p of ar(t,i,c))s(p)}let o=e[e.length-1];return s(j(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function ct(t){return String(t).padStart(12,"0")}var ne=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.sequence)),s=Math.max(...n.map(c=>c.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
16
- `,u=v(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${ct(r)}-${ct(s)}-${u}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,i,"application/json"),a}};import{join as ut}from"node:path";import{mkdirSync as cr}from"node:fs";function ur(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=ur(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function lr(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 lt(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&&lr(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function dr(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,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}async function re(t,e){let r=(await dr(t,e)).flatMap(m=>m.observations).sort((m,x)=>{let Ce=m.occurredAt.localeCompare(x.occurredAt);if(Ce!==0)return Ce;let Me=m.sequence-x.sequence;return Me!==0?Me:m.id.localeCompare(x.id)}),s=new Map,o=new Map,i,u,a,c=[],p=[],l=[],f=[],d=[],y=[];for(let m of r)switch(m.kind){case"goal":i=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,lt(s.get(m.key),m));break;case"task":o.set(m.key,lt(o.get(m.key),m));break;case"decision":c.push(m.text);break;case"blocker":p.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":f.push(m.text);break;case"file":d.push(m.text);break;case"test":y.push(m.text);break;case"session":a={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let h=Array.from(s.values()).sort((m,x)=>(m.order??Number.MAX_SAFE_INTEGER)-(x.order??Number.MAX_SAFE_INTEGER)),g=Array.from(o.values()).sort((m,x)=>(m.order??Number.MAX_SAFE_INTEGER)-(x.order??Number.MAX_SAFE_INTEGER)),S=h.find(m=>m.status==="in_progress")??h.find(m=>m.status==="blocked")??h.find(m=>m.status==="pending"),b=g.find(m=>m.status==="in_progress")??g.find(m=>m.status==="blocked")??g.find(m=>m.status==="pending"),A=L([...f,...b?[b.title]:[],...!b&&S?[S.title]:[],...g.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),N=L([...p,...h.filter(m=>m.status==="blocked").map(m=>m.title),...g.filter(m=>m.status==="blocked").map(m=>m.title)],20),E={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:g,decisions:L(c,20),blockers:N,warnings:L(l,20),nextActions:A,filesTouched:L(d,30),tests:L(y,20),currentPhase:S,currentTask:b,progress:{phasesTotal:h.length,phasesCompleted:h.filter(m=>m.status==="completed").length,tasksTotal:g.length,tasksCompleted:g.filter(m=>m.status==="completed").length,blocked:h.filter(m=>m.status==="blocked").length+g.filter(m=>m.status==="blocked").length},lastSession:a,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},R=ut(t.rootPath,".toolnet","work");return cr(R,{recursive:!0}),k(ut(R,"current.json"),E),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(E,null,2)+`
17
- `,"application/json"),E}async function se(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function yr(t,e){if(!fr(t))return{events:[],nextOffset:e};let n=hr(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=mr(t,"r");try{gr(i,o,0,s,r)}finally{pr(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
15
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var te=class{constructor(e){this.options=e;this.journal=new ee(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=yr(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=at(this.options.identity,s.events),i=!1;return o.length>0&&(i=!!await this.journal.write(this.options.identity,s.events,o)),this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:o.length,journalWritten:i,nextOffset:s.nextOffset}}};import{closeSync as xr,existsSync as Ir,openSync as Pr,readSync as Or,statSync as Er}from"node:fs";var Sr=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function $(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function lt(t){return $(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(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))_(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Sr.has(r)||["data","payload","parts","messages"].includes(r))&&_(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 ut(t){let e=$(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function b(t,e,n,r,s={}){let o=$(r),i=s.key??lt(o);return{version:1,id:v([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function vr(t,e,n){let r=$(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(b(t,e,"goal",i[1],{confidence:.97}));let u=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(b(t,e,"plan",u[1],{confidence:.95}));let a=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,c;for(;!o&&(c=a.exec(r));){let p=Number(c[1]),d=$(c[2]??""),y=d&&!ut(d)?`Phase ${p} - ${d}`:`Phase ${p}`;s.push(b(t,e,"phase",y,{key:`phase:${p}`,order:p,status:ne(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(b(t,e,"task",f[2],{status:f[1].trim()?"completed":ne(f[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let p=l[1]?Number(l[1]):void 0,d=$(l[2]),y=ut(d);s.push(b(t,e,"task",y&&p!==void 0?`TODO ${p}`:d,{key:p!==void 0?`task:${p}`:lt(d),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(b(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(b(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(b(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(b(t,e,"decision",r,{confidence:.9})),s}function dt(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 a=[];_(i.data,a);for(let c of a)s(b(t,i,"decision",c,{confidence:1}))}if(i.type==="todo"){let a=[];_(i.data,a);for(let c of a)s(b(t,i,"task",c,{status:ne(c),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let a of["filePath","path","file"]){let c=i.data[a];typeof c=="string"&&c&&s(b(t,i,"file",c,{confidence:1}))}if(i.type==="test"){let a=[];_(i.data,a);for(let c of a)s(b(t,i,"test",c,{confidence:1}))}let u=[];_(i.data,u);for(let a of u)for(let c of a.split(/\n+/u))for(let f of vr(t,i,c))s(f)}let o=e[e.length-1];return s(b(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function pt(t){return String(t).padStart(12,"0")}var re=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.sequence)),s=Math.max(...n.map(c=>c.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
16
+ `,u=v(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${pt(r)}-${pt(s)}-${u}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,i,"application/json"),a}};import{join as ft}from"node:path";import{mkdirSync as wr}from"node:fs";function br(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(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 kr(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 mt(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&&kr(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function jr(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,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}async function se(t,e){let r=(await jr(t,e)).flatMap(m=>m.observations).sort((m,k)=>{let Me=m.occurredAt.localeCompare(k.occurredAt);if(Me!==0)return Me;let Ne=m.sequence-k.sequence;return Ne!==0?Ne:m.id.localeCompare(k.id)}),s=new Map,o=new Map,i,u,a,c=[],f=[],l=[],p=[],d=[],y=[];for(let m of r)switch(m.kind){case"goal":i=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,mt(s.get(m.key),m));break;case"task":o.set(m.key,mt(o.get(m.key),m));break;case"decision":c.push(m.text);break;case"blocker":f.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":p.push(m.text);break;case"file":d.push(m.text);break;case"test":y.push(m.text);break;case"session":a={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let h=Array.from(s.values()).sort((m,k)=>(m.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),g=Array.from(o.values()).sort((m,k)=>(m.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),S=h.find(m=>m.status==="in_progress")??h.find(m=>m.status==="blocked")??h.find(m=>m.status==="pending"),j=g.find(m=>m.status==="in_progress")??g.find(m=>m.status==="blocked")??g.find(m=>m.status==="pending"),R=L([...p,...j?[j.title]:[],...!j&&S?[S.title]:[],...g.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),M=L([...f,...h.filter(m=>m.status==="blocked").map(m=>m.title),...g.filter(m=>m.status==="blocked").map(m=>m.title)],20),E={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:g,decisions:L(c,20),blockers:M,warnings:L(l,20),nextActions:R,filesTouched:L(d,30),tests:L(y,20),currentPhase:S,currentTask:j,progress:{phasesTotal:h.length,phasesCompleted:h.filter(m=>m.status==="completed").length,tasksTotal:g.length,tasksCompleted:g.filter(m=>m.status==="completed").length,blocked:h.filter(m=>m.status==="blocked").length+g.filter(m=>m.status==="blocked").length},lastSession:a,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},T=ft(t.rootPath,".toolnet","work");return wr(T,{recursive:!0}),x(ft(T,"current.json"),E),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(E,null,2)+`
17
+ `,"application/json"),E}async function oe(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 Cr(t,e){if(!Ir(t))return{events:[],nextOffset:e};let n=Er(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=Pr(t,"r");try{Or(i,o,0,s,r)}finally{xr(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
18
18
  `);if(a<0)return{events:[],nextOffset:r};let c=u.slice(0,a+1);return{events:c.split(`
19
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var oe=class{constructor(e){this.options=e;this.journal=new ne(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=yr(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=at(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await re(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Pr,existsSync as Or,openSync as Er,readSync as Cr,statSync as Mr}from"node:fs";var Sr=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function F(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function xe(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))xe(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Sr.has(r)||["data","payload","parts","messages"].includes(r))&&xe(s,e,n+1)}}function P(t,e,n,r,s,o=.95){let i=F(r);return{version:1,id:v([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function O(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 F(t.slice(r.length+1))}return null}function vr(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function wr(t){return F(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function dt(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=[];xe(o.data,i);for(let u of i){let a={type:"project"},c=null;for(let p of u.split(/\r?\n/u)){let l=F(p);if(!l){c=null;continue}let f=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let x=Number(f[1]);a={type:"phase",key:`phase:${x}`,order:x,title:F(f[2]??"")},c=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let x=Number(d[1]);a={type:"task",key:`task:${x}`,order:x,title:F(d[2]??"")},c=null;continue}let y=O(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(P(t,o,"mission",y,{type:"project"},.99)),c=null;continue}let h=O(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(P(t,o,a.type==="phase"?"phase_objective":"objective",h,a,.98)),c=null;continue}let g=O(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(P(t,o,a.type==="phase"?"phase_why":"why",g,a,.98)),c=null;continue}let S=O(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){s(P(t,o,"desired_outcome",S,{type:"project"},.98)),c=null;continue}let b=O(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(b){s(P(t,o,"plan_rationale",b,{type:"project"},.98)),c=null;continue}let A=O(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(A){s(P(t,o,"phase_deliverable",A,a,.97)),c=null;continue}let N=O(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(N){s(P(t,o,"acceptance_criterion",N,a,.98)),c="acceptance_criterion";continue}let E=O(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(E){s(P(t,o,"dependency",E,a,.97)),c="dependency";continue}let R=O(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){s(P(t,o,"open_question",R,a,.95)),c="open_question";continue}let m=O(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(m){s(P(t,o,"constraint",m,a,.97)),c="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){c="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){c="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){c="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){c="constraint";continue}if(c&&vr(p)){s(P(t,o,c,wr(p),a,.96));continue}c=null}}}return n}function pt(t){return String(t).padStart(12,"0")}var ie=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.evidence.sequence)),s=Math.max(...n.map(a=>a.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(a=>a.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${pt(r)}-${pt(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
20
- `,"application/json"),u}};import{mkdirSync as jr}from"node:fs";import{join as ft}from"node:path";function xr(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function br(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 C(t,e){return br(e,t)?e:t}function M(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 kr(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,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}function Ir(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function mt(t,e){let r=(await kr(t,e)).flatMap(h=>h.observations).sort((h,g)=>{let S=h.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===g.evidence.sessionKey?h.evidence.sequence-g.evidence.sequence:h.id.localeCompare(g.id)}),s,o,i,u,a,c=new Map,p=[],l=[],f=[];for(let h of r){let g=xr(h);if(h.scope==="phase"&&h.scopeKey){let S=c.get(h.scopeKey)??Ir(h);switch(h.kind){case"phase_objective":S.objective=C(S.objective,g);break;case"phase_why":S.why=C(S.why,g);break;case"phase_deliverable":S.deliverable=C(S.deliverable,g);break;case"acceptance_criterion":S.acceptanceCriteria.push(g);break;case"dependency":S.dependencies.push(g);break;case"open_question":S.openQuestions.push(g);break;case"constraint":S.constraints.push(g);break;case"note":S.notes.push(g);break}c.set(S.key,S);continue}switch(h.kind){case"mission":s=C(s,g);break;case"objective":o=C(o,g);break;case"why":i=C(i,g);break;case"desired_outcome":u=C(u,g);break;case"plan_rationale":a=C(a,g);break;case"open_question":p.push(g);break;case"constraint":l.push(g);break;case"note":f.push(g);break}}for(let h of c.values())h.acceptanceCriteria=M(h.acceptanceCriteria,20),h.dependencies=M(h.dependencies,15),h.openQuestions=M(h.openQuestions,15),h.constraints=M(h.constraints,15),h.notes=M(h.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:a,phases:Array.from(c.values()).sort((h,g)=>h.order-g.order),openQuestions:M(p,20),constraints:M(l,20),notes:M(f,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},y=ft(t.rootPath,".toolnet","work");return jr(y,{recursive:!0}),k(ft(y,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
21
- `,"application/json"),d}async function gt(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 Ar(t,e){if(!Or(t))return{events:[],nextOffset:e};let n=Mr(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=Er(t,"r");try{Cr(o,s,0,s.length,r)}finally{Pr(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
19
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ie=class{constructor(e){this.options=e;this.journal=new re(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=Cr(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=dt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await se(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 Kr,existsSync as Fr,openSync as Wr,readSync as zr,statSync as Br}from"node:fs";var Ar=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function K(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Ie(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))Ie(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Ar.has(r)||["data","payload","parts","messages"].includes(r))&&Ie(s,e,n+1)}}function P(t,e,n,r,s,o=.95){let i=K(r);return{version:1,id:v([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function O(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 K(t.slice(r.length+1))}return null}function Rr(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Tr(t){return K(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function gt(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=[];Ie(o.data,i);for(let u of i){let a={type:"project"},c=null;for(let f of u.split(/\r?\n/u)){let l=K(f);if(!l){c=null;continue}let p=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let k=Number(p[1]);a={type:"phase",key:`phase:${k}`,order:k,title:K(p[2]??"")},c=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let k=Number(d[1]);a={type:"task",key:`task:${k}`,order:k,title:K(d[2]??"")},c=null;continue}let y=O(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(P(t,o,"mission",y,{type:"project"},.99)),c=null;continue}let h=O(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(P(t,o,a.type==="phase"?"phase_objective":"objective",h,a,.98)),c=null;continue}let g=O(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(P(t,o,a.type==="phase"?"phase_why":"why",g,a,.98)),c=null;continue}let S=O(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){s(P(t,o,"desired_outcome",S,{type:"project"},.98)),c=null;continue}let j=O(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(j){s(P(t,o,"plan_rationale",j,{type:"project"},.98)),c=null;continue}let R=O(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(R){s(P(t,o,"phase_deliverable",R,a,.97)),c=null;continue}let M=O(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(M){s(P(t,o,"acceptance_criterion",M,a,.98)),c="acceptance_criterion";continue}let E=O(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(E){s(P(t,o,"dependency",E,a,.97)),c="dependency";continue}let T=O(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){s(P(t,o,"open_question",T,a,.95)),c="open_question";continue}let m=O(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(m){s(P(t,o,"constraint",m,a,.97)),c="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){c="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){c="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){c="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){c="constraint";continue}if(c&&Rr(f)){s(P(t,o,c,Tr(f),a,.96));continue}c=null}}}return n}function ht(t){return String(t).padStart(12,"0")}var ae=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.evidence.sequence)),s=Math.max(...n.map(a=>a.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(a=>a.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${ht(r)}-${ht(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
20
+ `,"application/json"),u}};import{mkdirSync as Mr}from"node:fs";import{join as yt}from"node:path";function Nr(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function _r(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 C(t,e){return _r(e,t)?e:t}function A(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function $r(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,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}function Lr(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function St(t,e){let r=(await $r(t,e)).flatMap(h=>h.observations).sort((h,g)=>{let S=h.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===g.evidence.sessionKey?h.evidence.sequence-g.evidence.sequence:h.id.localeCompare(g.id)}),s,o,i,u,a,c=new Map,f=[],l=[],p=[];for(let h of r){let g=Nr(h);if(h.scope==="phase"&&h.scopeKey){let S=c.get(h.scopeKey)??Lr(h);switch(h.kind){case"phase_objective":S.objective=C(S.objective,g);break;case"phase_why":S.why=C(S.why,g);break;case"phase_deliverable":S.deliverable=C(S.deliverable,g);break;case"acceptance_criterion":S.acceptanceCriteria.push(g);break;case"dependency":S.dependencies.push(g);break;case"open_question":S.openQuestions.push(g);break;case"constraint":S.constraints.push(g);break;case"note":S.notes.push(g);break}c.set(S.key,S);continue}switch(h.kind){case"mission":s=C(s,g);break;case"objective":o=C(o,g);break;case"why":i=C(i,g);break;case"desired_outcome":u=C(u,g);break;case"plan_rationale":a=C(a,g);break;case"open_question":f.push(g);break;case"constraint":l.push(g);break;case"note":p.push(g);break}}for(let h of c.values())h.acceptanceCriteria=A(h.acceptanceCriteria,20),h.dependencies=A(h.dependencies,15),h.openQuestions=A(h.openQuestions,15),h.constraints=A(h.constraints,15),h.notes=A(h.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:a,phases:Array.from(c.values()).sort((h,g)=>h.order-g.order),openQuestions:A(f,20),constraints:A(l,20),notes:A(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},y=yt(t.rootPath,".toolnet","work");return Mr(y,{recursive:!0}),x(yt(y,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
21
+ `,"application/json"),d}async function vt(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 Dr(t,e){if(!Fr(t))return{events:[],nextOffset:e};let n=Br(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=Wr(t,"r");try{zr(o,s,0,s.length,r)}finally{Kr(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
22
22
  `);if(u<0)return{events:[],nextOffset:r};let a=i.slice(0,u+1);return{events:a.split(`
23
- `).filter(Boolean).flatMap(c=>{try{return[JSON.parse(c)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var ae=class{constructor(e){this.options=e;this.journal=new ie(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Ar(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=dt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await mt(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 Br}from"node:fs";import{join as be}from"node:path";import{existsSync as St,mkdirSync as Rr,readFileSync as Nr,statSync as ht,writeFileSync as Tr}from"node:fs";import{dirname as _r,join as $r}from"node:path";var yt=64*1024,Lr=`# ToolNet Project Operating Manual
23
+ `).filter(Boolean).flatMap(c=>{try{return[JSON.parse(c)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var ce=class{constructor(e){this.options=e;this.journal=new ae(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Dr(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=gt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await St(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{mkdirSync as Zr}from"node:fs";import{join as Pe}from"node:path";import{existsSync as kt,mkdirSync as Jr,readFileSync as qr,statSync as wt,writeFileSync as Vr}from"node:fs";import{dirname as Ur,join as Hr}from"node:path";var bt=64*1024,Yr=`# ToolNet Project Operating Manual
24
24
 
25
25
  This file contains persistent instructions for AI agents working on this project.
26
26
 
@@ -63,30 +63,30 @@ Things an AI agent should always remember.
63
63
  <!--
64
64
  - [advisory] Prefer small focused files.
65
65
  -->
66
- `;function ce(t){return $r(t.rootPath,".toolnet","PROJECT.md")}function Fr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Wr(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=Fr(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;n.has(u)||(n.add(u),e.push({id:v(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function zr(t){let e=ce(t);return St(e)||(Rr(_r(e),{recursive:!0}),Tr(e,Lr,{encoding:"utf8",mode:384})),e}function ue(t,e=!1){let n=e?zr(t):ce(t);if(!St(n))return null;if(ht(n).size>yt)throw new Error(`PROJECT.md exceeds ${yt} bytes`);let s=Nr(n,"utf8");return{path:n,content:s,digest:v(s),rules:Wr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(ht(n).mtimeMs).toISOString()}}function Kr(t){return{goal:t.goal,plan:t.plan,phases:t.phases.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),tasks:t.tasks.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),decisions:t.decisions,blockers:t.blockers,warnings:t.warnings,nextActions:t.nextActions,filesTouched:t.filesTouched,tests:t.tests}}function Dr(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 le=class{constructor(e){this.options=e}options;async capture(e,n){let r=await se(this.options.project,this.options.storage);if(r||(r=await re(this.options.project,this.options.storage)),!Dr(r))return null;let s=ue(this.options.project,!1),o=s?s.rules.filter(f=>f.mode==="enforce").map(f=>f.text):[],i=v(JSON.stringify(Kr(r))),u=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),a=new Date().toISOString(),c={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:a,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(f=>f.status!=="completed"&&f.status!=="cancelled"),incompleteTasks:r.tasks.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:[...o,...r.warnings].slice(0,20),filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:i},p=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(p)||await this.options.storage.put(p,JSON.stringify(c,null,2)+`
66
+ `;function ue(t){return Hr(t.rootPath,".toolnet","PROJECT.md")}function Gr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Qr(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=Gr(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;n.has(u)||(n.add(u),e.push({id:v(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Xr(t){let e=ue(t);return kt(e)||(Jr(Ur(e),{recursive:!0}),Vr(e,Yr,{encoding:"utf8",mode:384})),e}function le(t,e=!1){let n=e?Xr(t):ue(t);if(!kt(n))return null;if(wt(n).size>bt)throw new Error(`PROJECT.md exceeds ${bt} bytes`);let s=qr(n,"utf8");return{path:n,content:s,digest:v(s),rules:Qr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(wt(n).mtimeMs).toISOString()}}function es(t){return{goal:t.goal,plan:t.plan,phases:t.phases.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),tasks:t.tasks.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),decisions:t.decisions,blockers:t.blockers,warnings:t.warnings,nextActions:t.nextActions,filesTouched:t.filesTouched,tests:t.tests}}function ts(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 de=class{constructor(e){this.options=e}options;async capture(e,n){let r=await oe(this.options.project,this.options.storage);if(r||(r=await se(this.options.project,this.options.storage)),!ts(r))return null;let s=le(this.options.project,!1),o=s?s.rules.filter(p=>p.mode==="enforce").map(p=>p.text):[],i=v(JSON.stringify(es(r))),u=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),a=new Date().toISOString(),c={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:a,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(p=>p.status!=="completed"&&p.status!=="cancelled"),incompleteTasks:r.tasks.filter(p=>p.status!=="completed"&&p.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:[...o,...r.warnings].slice(0,20),filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:i},f=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(f)||await this.options.storage.put(f,JSON.stringify(c,null,2)+`
67
67
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(c,null,2)+`
68
- `,"application/json");let l=be(this.options.project.rootPath,".toolnet","work","handoffs");return Br(l,{recursive:!0}),k(be(l,`${u}.json`),c),k(be(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),c),c}};async function vt(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 de=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=He(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Q(this.identity),this.remote=new X(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new ee({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new oe({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new ae({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new le({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 Jr,readFileSync as qr,readdirSync as Vr,statSync as wt}from"node:fs";import{homedir as Hr}from"node:os";import{join as pe,resolve as jt}from"node:path";function xt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Ur(){return process.env.CODEX_HOME??pe(Hr(),".codex")}function D(t){let e="";try{e=qr(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
69
- `))if(n)try{let r=xt(JSON.parse(n));if(r.type!=="session_meta")continue;let s=xt(r.payload),o=[s.id,s.thread_id,s.threadId,s.session_id,s.sessionId].find(u=>typeof u=="string"),i=typeof s.cwd=="string"?s.cwd:void 0;return{threadId:o,cwd:i,raw:s}}catch{}return{raw:{}}}function ke(t,e){if(!Jr(t))return;let n;try{n=Vr(t,{withFileTypes:!0})}catch{return}for(let r of n){let s=pe(t,r.name);if(r.isDirectory()){ke(s,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(s)}}function Ie(){let t=Ur(),e=[];return ke(pe(t,"sessions"),e),ke(pe(t,"archived_sessions"),e),e.sort((n,r)=>{try{return wt(r).mtimeMs-wt(n).mtimeMs}catch{return 0}})}function Pe(t){let e=Ie(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(D(r).threadId===t)return r;return null}function fe(t,e){let n=jt(t),r=jt(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as Yr,existsSync as Gr,openSync as Xr,readSync as Qr,statSync as Zr}from"node:fs";function bt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function es(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 ts(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=bt(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 kt(t,e=0){if(!Gr(t))return{events:[],nextOffset:e,reset:!1};let n=Zr(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),u=Xr(t,"r");try{Qr(u,i,0,o,s)}finally{Yr(u)}let a=i.toString("utf8"),c=a.lastIndexOf(`
70
- `);if(c<0)return{events:[],nextOffset:s,reset:r};let p=a.slice(0,c+1),l=0,f=[];for(let d of p.split(`
68
+ `,"application/json");let l=Pe(this.options.project.rootPath,".toolnet","work","handoffs");return Zr(l,{recursive:!0}),x(Pe(l,`${u}.json`),c),x(Pe(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),c),c}};async function jt(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 pe=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=Qe(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Z(this.identity),this.remote=new X(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new te({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new ie({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new ce({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new de({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 ns,readFileSync as rs,readdirSync as ss,statSync as xt}from"node:fs";import{homedir as os}from"node:os";import{join as fe,resolve as It}from"node:path";function Pt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function is(){return process.env.CODEX_HOME??fe(os(),".codex")}function q(t){let e="";try{e=rs(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
69
+ `))if(n)try{let r=Pt(JSON.parse(n));if(r.type!=="session_meta")continue;let s=Pt(r.payload),o=[s.id,s.thread_id,s.threadId,s.session_id,s.sessionId].find(u=>typeof u=="string"),i=typeof s.cwd=="string"?s.cwd:void 0;return{threadId:o,cwd:i,raw:s}}catch{}return{raw:{}}}function Oe(t,e){if(!ns(t))return;let n;try{n=ss(t,{withFileTypes:!0})}catch{return}for(let r of n){let s=fe(t,r.name);if(r.isDirectory()){Oe(s,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(s)}}function Ee(){let t=is(),e=[];return Oe(fe(t,"sessions"),e),Oe(fe(t,"archived_sessions"),e),e.sort((n,r)=>{try{return xt(r).mtimeMs-xt(n).mtimeMs}catch{return 0}})}function Ce(t){let e=Ee(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(q(r).threadId===t)return r;return null}function me(t,e){let n=It(t),r=It(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as as,existsSync as cs,openSync as us,readSync as ls,statSync as ds}from"node:fs";function Ot(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function ps(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 fs(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=Ot(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 Et(t,e=0){if(!cs(t))return{events:[],nextOffset:e,reset:!1};let n=ds(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),u=us(t,"r");try{ls(u,i,0,o,s)}finally{as(u)}let a=i.toString("utf8"),c=a.lastIndexOf(`
70
+ `);if(c<0)return{events:[],nextOffset:s,reset:r};let f=a.slice(0,c+1),l=0,p=[];for(let d of f.split(`
71
71
  `)){if(!d)continue;let y=Buffer.byteLength(d+`
72
- `,"utf8"),h=s+l;l+=y;let g;try{g=JSON.parse(d)}catch{continue}let S=bt(g),b=ts(S);f.push({type:b.type,timestamp:es(S),role:b.role,sourceEventId:`rollout:${h}`,sourceSequence:h,data:S,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:h}})}return{events:f,nextOffset:s+Buffer.byteLength(p,"utf8"),reset:r}}async function J(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=D(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!fe(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 de({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"],u=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(u=0),(!Number.isFinite(u)||u<0)&&(u=0);let a=kt(t.rolloutPath,u),c=[];o.lastSequence===0&&c.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&&c.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),a.reset&&c.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${a.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),c.push(...a.events),t.idle&&t.turnId&&c.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let p=s.recordMany(c);s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",a.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId);let l=await s.flush();return{threadId:e,imported:p.length,rolloutEvents:a.events.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,rolloutOffset:a.nextOffset,reset:a.reset}}import{existsSync as ns}from"node:fs";import{dirname as rs,join as ss,parse as os,resolve as is}from"node:path";function It(t){let e=is(t),n=os(e).root;for(;;){if(ns(ss(e,".toolnet","project.json")))return new T().detect(e);if(e===n)break;let r=rs(e);if(r===e)break;e=r}return null}async function Pt(t,e,n=100){let r=[];for(let s of Ie()){let o=D(s);if(!(!o.threadId||!o.cwd)&&fe(t.rootPath,o.cwd)&&(r.push(await J({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as as,mkdirSync as Ot,readFileSync as cs,writeFileSync as Et}from"node:fs";import{homedir as Ct}from"node:os";import{dirname as Mt,join as Oe}from"node:path";function us(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 At(t={}){let e=t.configFile??Oe(process.env.CODEX_HOME??Oe(Ct(),".codex"),"config.toml"),n=t.previousFile??Oe(Ct(),".config","toolnet-memory","codex-notify-previous.json");Ot(Mt(e),{recursive:!0}),Ot(Mt(n),{recursive:!0});let r=as(e)?cs(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
73
- `),u=i.findIndex(f=>/^\s*\[/.test(f));u<0&&(u=i.length);let a=-1,c=-1;for(let f=0;f<u;f+=1)if(/^\s*notify\s*=/.test(i[f])){if(a=f,c=f,i[f].includes("[")&&!i[f].includes("]"))for(;c+1<u&&(c+=1,!i[c].includes("]")););break}let p=[];if(a>=0){let f=i.slice(a,c+1).join(`
74
- `);p=us(f),i.splice(a,c-a+1,o)}else u=i.findIndex(f=>/^\s*\[/.test(f)),u<0&&(u=i.length),i.splice(u,0,o);let l=p.length>=2&&p[p.length-1]==="session:codex-notify";return p.length>0&&!l&&Et(n,JSON.stringify(p,null,2)+`
72
+ `,"utf8"),h=s+l;l+=y;let g;try{g=JSON.parse(d)}catch{continue}let S=Ot(g),j=fs(S);p.push({type:j.type,timestamp:ps(S),role:j.role,sourceEventId:`rollout:${h}`,sourceSequence:h,data:S,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:h}})}return{events:p,nextOffset:s+Buffer.byteLength(f,"utf8"),reset:r}}var ms=[/^<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*$/],gs=[/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],hs=["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 ys(t){let e=t.toLowerCase();return hs.some(n=>e.includes(n))}function Ss(t){if(!t.trim())return!0;for(let e of ms)if(e.test(t))return!0;return ys(t),!1}function vs(t){let e=t;for(let n of gs)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function Ae(t){let e=t.trim();return e?Ss(e)?{content:"",filtered:!0,reason:"noise"}:{content:vs(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=Ae(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=Ae(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 Ct(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&&Ae(r).filtered)return!0}return!1}async function V(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=q(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!me(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 pe({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"],u=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(u=0),(!Number.isFinite(u)||u<0)&&(u=0);let a=Et(t.rolloutPath,u),c=[];o.lastSequence===0&&c.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&&c.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),a.reset&&c.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${a.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=a.events.filter(d=>!Ct(d.data)).map(d=>({...d,data:ge(d.data)}));c.push(...f),t.idle&&t.turnId&&c.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let l=s.recordMany(c);s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",a.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId);let p=await s.flush();return{threadId:e,imported:l.length,rolloutEvents:a.events.length,eventCount:p.eventCount,chunkCount:p.chunkCount,status:p.status,rolloutOffset:a.nextOffset,reset:a.reset}}import{existsSync as ws}from"node:fs";import{dirname as bs,join as ks,parse as js,resolve as xs}from"node:path";function At(t){let e=xs(t),n=js(e).root;for(;;){if(ws(ks(e,".toolnet","project.json")))return new N().detect(e);if(e===n)break;let r=bs(e);if(r===e)break;e=r}return null}async function Rt(t,e,n=100){let r=[];for(let s of Ee()){let o=q(s);if(!(!o.threadId||!o.cwd)&&me(t.rootPath,o.cwd)&&(r.push(await V({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as Is,mkdirSync as Tt,readFileSync as Ps,writeFileSync as Mt}from"node:fs";import{homedir as Nt}from"node:os";import{dirname as _t,join as Re}from"node:path";function Os(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 $t(t={}){let e=t.configFile??Re(process.env.CODEX_HOME??Re(Nt(),".codex"),"config.toml"),n=t.previousFile??Re(Nt(),".config","toolnet-memory","codex-notify-previous.json");Tt(_t(e),{recursive:!0}),Tt(_t(n),{recursive:!0});let r=Is(e)?Ps(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
73
+ `),u=i.findIndex(p=>/^\s*\[/.test(p));u<0&&(u=i.length);let a=-1,c=-1;for(let p=0;p<u;p+=1)if(/^\s*notify\s*=/.test(i[p])){if(a=p,c=p,i[p].includes("[")&&!i[p].includes("]"))for(;c+1<u&&(c+=1,!i[c].includes("]")););break}let f=[];if(a>=0){let p=i.slice(a,c+1).join(`
74
+ `);f=Os(p),i.splice(a,c-a+1,o)}else u=i.findIndex(p=>/^\s*\[/.test(p)),u<0&&(u=i.length),i.splice(u,0,o);let l=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!l&&Mt(n,JSON.stringify(f,null,2)+`
75
75
  `,{encoding:"utf8",mode:384}),r=i.join(`
76
76
  `),r.endsWith(`
77
77
  `)||(r+=`
78
- `),Et(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:p.length>0&&!l}}import{existsSync as ls,mkdirSync as ds,readFileSync as ps,writeFileSync as fs}from"node:fs";import{homedir as ms}from"node:os";import{dirname as gs,join as Rt}from"node:path";function hs(t){return`'${t.replace(/'/g,"'\\''")}'`}function Nt(t={}){let e=t.hooksFile??Rt(process.env.CODEX_HOME??Rt(ms(),".codex"),"hooks.json");ds(gs(e),{recursive:!0});let n={};if(ls(e))try{n=JSON.parse(ps(e,"utf8"))}catch(u){throw new Error(`Invalid existing Codex hooks.json: ${u instanceof Error?u.message:String(u)}`)}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(u=>{try{return!JSON.stringify(u).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return o.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${hs(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=o,fs(e,JSON.stringify(n,null,2)+`
79
- `,{encoding:"utf8",mode:384}),e}import{existsSync as mc,mkdirSync as ws,readFileSync as gc,writeFileSync as js}from"node:fs";import{dirname as xs,join as _t}from"node:path";function Ee(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 w(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 ys(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(w(s,280)),e.length>=16))break}return e}function Ss(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(c=>o.startsWith(c));if(!u)continue;let a=s.slice(u.length).trim();a&&(u.includes("enforce")?e.push(a):n.push(a))}return{enforce:e,advisory:n}}function vs(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
80
- `);if(Ee(s)<=e){n.push(r);continue}let o=Ee(n.join(`
78
+ `),Mt(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:f.length>0&&!l}}import{existsSync as Es,mkdirSync as Cs,readFileSync as As,writeFileSync as Rs}from"node:fs";import{homedir as Ts}from"node:os";import{dirname as Ms,join as Lt}from"node:path";function Ns(t){return`'${t.replace(/'/g,"'\\''")}'`}function Kt(t={}){let e=t.hooksFile??Lt(process.env.CODEX_HOME??Lt(Ts(),".codex"),"hooks.json");Cs(Ms(e),{recursive:!0});let n={};if(Es(e))try{n=JSON.parse(As(e,"utf8"))}catch(u){throw new Error(`Invalid existing Codex hooks.json: ${u instanceof Error?u.message:String(u)}`)}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(u=>{try{return!JSON.stringify(u).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return o.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${Ns(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=o,Rs(e,JSON.stringify(n,null,2)+`
79
+ `,{encoding:"utf8",mode:384}),e}import{existsSync as zc,mkdirSync as Ks,readFileSync as Bc,writeFileSync as Fs}from"node:fs";import{dirname as Ws,join as Wt}from"node:path";function Te(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 w(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 _s(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(w(s,280)),e.length>=16))break}return e}function $s(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(c=>o.startsWith(c));if(!u)continue;let a=s.slice(u.length).trim();a&&(u.includes("enforce")?e.push(a):n.push(a))}return{enforce:e,advisory:n}}function Ls(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
80
+ `);if(Te(s)<=e){n.push(r);continue}let o=Te(n.join(`
81
81
  `)),i=Math.max(0,e-o);if(i>=16){let u=Math.floor(i*3.2),a=w(r,u);a&&n.push(a)}break}return n.join(`
82
- `).trim()}async function Tt(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=ue(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=Ss(r),o=n?n.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=n?n.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,u=r?ys(r):[],a=await se(t.project,t.storage),c=await gt(t.project,t.storage),p=await vt(t.project,t.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${t.project.name}`),l.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&l.push(`Full operating manual: ${ce(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${w(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${w(d,220)}`)}if(c&&(c.mission&&l.push("","MISSION",w(c.mission.value,420)),c.activeObjective&&l.push("","CURRENT OBJECTIVE",w(c.activeObjective.value,420)),c.why&&l.push("","WHY THIS WORK MATTERS",w(c.why.value,420)),c.desiredOutcome&&l.push("","DESIRED OUTCOME",w(c.desiredOutcome.value,420)),c.planRationale&&l.push("","WHY THIS APPROACH",w(c.planRationale.value,420))),a){if(l.push("","ACTIVE WORK"),a.goal&&l.push(`Goal: ${w(a.goal,320)}`),a.plan&&l.push(`Plan: ${w(a.plan,320)}`),l.push(`Progress: phases ${a.progress.phasesCompleted}/${a.progress.phasesTotal}; tasks ${a.progress.tasksCompleted}/${a.progress.tasksTotal}; blocked ${a.progress.blocked}`),a.currentPhase&&l.push(`Current phase: ${a.currentPhase.title} [${a.currentPhase.status}]`),a.currentPhase&&c){let d=c.phases.find(y=>y.order===a.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${w(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${w(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${w(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(y=>w(y.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(y=>{l.push(`- ${w(y.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(y=>{l.push(`- ${w(y.value,260)}`)})))}a.currentTask&&l.push(`Current task: ${a.currentTask.title} [${a.currentTask.status}]`),a.nextActions.length&&(l.push("","NEXT ACTIONS"),a.nextActions.slice(0,6).forEach((d,y)=>{l.push(`${y+1}. ${w(d,260)}`)})),a.blockers.length&&(l.push("","BLOCKERS"),a.blockers.slice(0,5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.warnings.length&&(l.push("","ATTENTION"),a.warnings.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.decisions.length&&(l.push("","RECENT DECISIONS"),a.decisions.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.lastSession&&l.push("",`Last work session: ${a.lastSession.agent} / ${a.lastSession.nativeSessionId}`)}if(c&&c.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),c.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${w(d.value,260)}`)})),p&&l.push(`Latest handoff: ${p.reason} / ${p.sourceSession.agent}`),u.length){l.push("","OPERATING NOTES");for(let d of u)l.push(`- ${d}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let f=vs(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:f,estimatedTokens:Ee(f),maxTokens:e,hasManual:!!r,hasWorkState:!!a,hasHandoff:!!p,generatedAt:new Date().toISOString()}}function bs(t){return _t(t.rootPath,".toolnet","context","startup.md")}function ks(t){return _t(t.rootPath,".toolnet","context","startup.json")}function Is(t,e){let n=bs(t);ws(xs(n),{recursive:!0}),js(n,e.text.endsWith(`
82
+ `).trim()}async function Ft(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=le(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=$s(r),o=n?n.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=n?n.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,u=r?_s(r):[],a=await oe(t.project,t.storage),c=await vt(t.project,t.storage),f=await jt(t.project,t.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${t.project.name}`),l.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&l.push(`Full operating manual: ${ue(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${w(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${w(d,220)}`)}if(c&&(c.mission&&l.push("","MISSION",w(c.mission.value,420)),c.activeObjective&&l.push("","CURRENT OBJECTIVE",w(c.activeObjective.value,420)),c.why&&l.push("","WHY THIS WORK MATTERS",w(c.why.value,420)),c.desiredOutcome&&l.push("","DESIRED OUTCOME",w(c.desiredOutcome.value,420)),c.planRationale&&l.push("","WHY THIS APPROACH",w(c.planRationale.value,420))),a){if(l.push("","ACTIVE WORK"),a.goal&&l.push(`Goal: ${w(a.goal,320)}`),a.plan&&l.push(`Plan: ${w(a.plan,320)}`),l.push(`Progress: phases ${a.progress.phasesCompleted}/${a.progress.phasesTotal}; tasks ${a.progress.tasksCompleted}/${a.progress.tasksTotal}; blocked ${a.progress.blocked}`),a.currentPhase&&l.push(`Current phase: ${a.currentPhase.title} [${a.currentPhase.status}]`),a.currentPhase&&c){let d=c.phases.find(y=>y.order===a.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${w(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${w(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${w(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(y=>w(y.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(y=>{l.push(`- ${w(y.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(y=>{l.push(`- ${w(y.value,260)}`)})))}a.currentTask&&l.push(`Current task: ${a.currentTask.title} [${a.currentTask.status}]`),a.nextActions.length&&(l.push("","NEXT ACTIONS"),a.nextActions.slice(0,6).forEach((d,y)=>{l.push(`${y+1}. ${w(d,260)}`)})),a.blockers.length&&(l.push("","BLOCKERS"),a.blockers.slice(0,5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.warnings.length&&(l.push("","ATTENTION"),a.warnings.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.decisions.length&&(l.push("","RECENT DECISIONS"),a.decisions.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),a.lastSession&&l.push("",`Last work session: ${a.lastSession.agent} / ${a.lastSession.nativeSessionId}`)}if(c&&c.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),c.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${w(d.value,260)}`)})),f&&l.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),u.length){l.push("","OPERATING NOTES");for(let d of u)l.push(`- ${d}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=Ls(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:p,estimatedTokens:Te(p),maxTokens:e,hasManual:!!r,hasWorkState:!!a,hasHandoff:!!f,generatedAt:new Date().toISOString()}}function zs(t){return Wt(t.rootPath,".toolnet","context","startup.md")}function Bs(t){return Wt(t.rootPath,".toolnet","context","startup.json")}function Ds(t,e){let n=zs(t);Ks(Ws(n),{recursive:!0}),Fs(n,e.text.endsWith(`
83
83
  `)?e.text:e.text+`
84
- `,{encoding:"utf8",mode:384}),k(ks(t),e)}async function $t(t,e,n=900){let r=await Tt({project:t,storage:e,maxTokens:n}),s={version:1,projectId:t.id,projectName:t.name,text:r.text,digest:v(r.text),estimatedTokens:r.estimatedTokens,generatedAt:new Date().toISOString()};return Is(t,s),await e.put(`projects/${t.id}/context/startup.md`,s.text+`
84
+ `,{encoding:"utf8",mode:384}),x(Bs(t),e)}async function zt(t,e,n=900){let r=await Ft({project:t,storage:e,maxTokens:n}),s={version:1,projectId:t.id,projectName:t.name,text:r.text,digest:v(r.text),estimatedTokens:r.estimatedTokens,generatedAt:new Date().toISOString()};return Ds(t,s),await e.put(`projects/${t.id}/context/startup.md`,s.text+`
85
85
  `,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(s,null,2)+`
86
- `,"application/json"),s}function me(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Lt(t){let e=Ae(),n=Be(We({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new G(n,t.id,t.name,t.remote??t.name)}async function As(t){for(let e=0;e<10;e+=1){let n=Pe(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function Rs(t){let e=Ms(Cs(),".config","toolnet-memory","codex-notify-previous.json");if(Ps(e))try{let n=JSON.parse(Os(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(s=>typeof s=="string"))return;Es(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Ns(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 u=It(o);if(!u)return;let a=await As(r);if(!a)return;let c=Lt(u);await J({project:u,storage:c,threadId:r,rolloutPath:a,cwd:o,turnId:s,client:i,idle:!0});try{await $t(u,c,900)}catch{}}async function Ts(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let o=me(e,"--bin"),i=At({binary:o}),u=Nt({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: ${u}`);return}if(t==="notify"){let o=e[e.length-1]??"";try{await Ns(o)}finally{Rs(o)}return}let n=me(e,"--project")??process.cwd(),r=new T().detect(n),s=Lt(r);if(t==="sync"){let o=e[0];if(!o)throw new Error("Usage: sync <thread-id>");let i=me(e,"--rollout")??Pe(o);if(!i)throw new Error(`Codex rollout not found for ${o}`);let u=await J({project:r,storage:s,threadId:o,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(u,null,2));return}if(t==="recover"){let o=Number(me(e,"--limit")??100),i=await Pt(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((u,a)=>u+a.imported,0)},null,2));return}console.log(`Codex Session Adapter
86
+ `,"application/json"),s}function he(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Bt(t){let e=_e(),n=qe(De({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new Q(n,t.id,t.name,t.remote??t.name)}async function Ys(t){for(let e=0;e<10;e+=1){let n=Ce(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function Gs(t){let e=Hs(Us(),".config","toolnet-memory","codex-notify-previous.json");if(Js(e))try{let n=JSON.parse(qs(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(s=>typeof s=="string"))return;Vs(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Qs(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 u=At(o);if(!u)return;let a=await Ys(r);if(!a)return;let c=Bt(u);await V({project:u,storage:c,threadId:r,rolloutPath:a,cwd:o,turnId:s,client:i,idle:!0});try{await zt(u,c,900)}catch{}}async function Xs(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let o=he(e,"--bin"),i=$t({binary:o}),u=Kt({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: ${u}`);return}if(t==="notify"){let o=e[e.length-1]??"";try{await Qs(o)}finally{Gs(o)}return}let n=he(e,"--project")??process.cwd(),r=new N().detect(n),s=Bt(r);if(t==="sync"){let o=e[0];if(!o)throw new Error("Usage: sync <thread-id>");let i=he(e,"--rollout")??Ce(o);if(!i)throw new Error(`Codex rollout not found for ${o}`);let u=await V({project:r,storage:s,threadId:o,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(u,null,2));return}if(t==="recover"){let o=Number(he(e,"--limit")??100),i=await Rt(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((u,a)=>u+a.imported,0)},null,2));return}console.log(`Codex Session Adapter
87
87
 
88
88
  Commands:
89
89
  install-notify
90
90
  sync <thread-id> [--project PATH]
91
91
  recover [--project PATH] [--limit N]
92
- `)}Ts().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});
92
+ `)}Xs().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});