toolnet-memory 0.2.18 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
- import{existsSync as Kt,readFileSync as Bt}from"node:fs";import{homedir as Ut}from"node:os";import{join as Wt}from"node:path";function zt(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 qt(){let t=process.env.TOOLNET_GLOBAL_ENV??Wt(Ut(),".config","toolnet-memory",".env");if(!Kt(t))return;let e=Bt(t,"utf8");for(let r of e.split(/\r?\n/)){let n=r.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let s=n.indexOf("=");if(s<=0)continue;let o=n.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=zt(n.slice(s+1)))}}qt();function F(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function K(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function J(){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:K(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:K(process.env.MEMORY_RERANK_TOP,10),finalContext:K(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:K(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:K(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Jt}from"node:crypto";import{existsSync as ye,mkdirSync as Ht,readFileSync as Vt,renameSync as Gt,writeFileSync as Yt}from"node:fs";import{basename as Qt,dirname as H,join as G,parse as Re,resolve as B}from"node:path";var Ce=".toolnet",Xt="project.json";function Zt(t){return Jt("sha256").update(t).digest("hex").slice(0,16)}function Se(t){return G(t,Ce,Xt)}function er(t){return ye(Se(t))}function tr(t,e){let r=B(t),n=Re(r).root;for(;;){if(er(r))return r;if(r===n||e&&r===B(e))break;let s=H(r);if(s===r)break;r=s}return null}function rr(t){let e=B(t),r=Re(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(o=>ye(G(e,o))))return e;if(e===r)break;let s=H(e);if(s===e)break;e=s}return B(t)}function nr(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 r=e;if(typeof r.id!="string"||!r.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof r.name!="string"||!r.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let n=new Date().toISOString();return{version:1,id:r.id,name:r.name,remote:typeof r.remote=="string"&&r.remote.trim()?r.remote:r.name,rootPath:typeof r.rootPath=="string"?r.rootPath:H(H(t)),createdAt:typeof r.createdAt=="string"?r.createdAt:n,updatedAt:typeof r.updatedAt=="string"?r.updatedAt:n,graphVersion:typeof r.graphVersion=="number"?r.graphVersion:0,memoryVersion:typeof r.memoryVersion=="number"?r.memoryVersion:0,metadata:r.metadata&&typeof r.metadata=="object"?r.metadata:void 0}}function Me(t,e){let r=G(t,Ce);Ht(r,{recursive:!0});let n=Se(t),s=`${n}.tmp-${process.pid}`;Yt(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Gt(s,n)}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 V=class{detect(e=process.cwd()){let r=B(e),n=rr(r),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>ye(G(n,p))),i=tr(r,o?n:void 0);if(i){let p=Se(i),l=nr(p);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Me(i,l)),Ne(l,i)}let u=new Date().toISOString(),c=Qt(n),a={version:1,id:Zt(n),name:c,remote:c,rootPath:n,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Me(n,a),Ne(a,n)}};var sr=[{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 r=[];for(let n of sr){let s=new RegExp(n.regex.source,n.regex.flags);for(let o of e.matchAll(s))r.push({type:n.type,value:o[0]})}return r}hasSecrets(e){return this.scan(e).length>0}};var U=class{scanner=new Y;sanitize(e){let r=e,n=this.scanner.scan(e),s=new Set;for(let o of n)s.add(o.type),r=r.split(o.value).join(`[REDACTED:${o.type}]`);return{text:r,redacted:n.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(r=>this.sanitizeValue(r));if(e&&typeof e=="object"){let r={};for(let[n,s]of Object.entries(e)){let o=n.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?r[n]="[REDACTED]":r[n]=this.sanitizeValue(s)}return r}return e}};import{homedir as jr}from"node:os";import{join as Or}from"node:path";import{DeleteObjectCommand as or,GetObjectCommand as ir,HeadObjectCommand as ar,ListObjectsV2Command as cr,PutObjectCommand as ur,S3Client as lr}from"@aws-sdk/client-s3";import{getSignedUrl as dr}from"@aws-sdk/s3-request-presigner";var Q=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new lr({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new ur({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await dr(this.client,new ir({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new ar({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new or({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new cr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let o of s.Contents??[])o.Key&&r.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};import{access as Le,mkdir as pr,readFile as fr,readdir as mr,rm as gr,stat as $e,writeFile as hr}from"node:fs/promises";import{dirname as yr,join as Sr,relative as De,resolve as vr}from"node:path";var W=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return vr(this.root,r)}async put(e,r){let n=this.path(e);await pr(yr(n),{recursive:!0}),await hr(n,r)}async get(e){try{return await fr(this.path(e))}catch(r){if(typeof r=="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return null;throw r}}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await Le(this.path(e)),!0}catch{return!1}}async delete(e){await gr(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),n=[];try{await Le(r)}catch{return n}let s=async i=>{let u=await mr(i,{withFileTypes:!0});for(let c of u){let a=Sr(i,c.name);if(c.isDirectory()){await s(a);continue}let p=await $e(a);n.push({key:De(this.root,a),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await $e(r);return o.isDirectory()?await s(r):n.push({key:De(this.root,r),size:o.size,updatedAt:o.mtime.toISOString()}),n}};import{DeleteObjectCommand as kr,GetObjectCommand as br,HeadObjectCommand as wr,ListObjectsV2Command as xr,PutObjectCommand as Ar,S3Client as Er}from"@aws-sdk/client-s3";import{getSignedUrl as Ir}from"@aws-sdk/s3-request-presigner";var z=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Er({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,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new Ar({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await Ir(this.client,new br({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new wr({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new kr({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new xr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let o of s.Contents??[])o.Key&&r.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};function ve(t,e){return console.warn(e),new W(t)}function Fe(t){let e=t.localRoot??Or(jr(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new z({name:"r2",endpoint:`https://${r.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:r.bucket,forcePathStyle:!0,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let r=t.s3;return r?.bucket&&r.accessKeyId&&r.secretAccessKey?new z({name:"s3",endpoint:r.endpoint,region:r.region??"us-east-1",bucket:r.bucket,forcePathStyle:r.forcePathStyle??!1,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let r=t.huggingface;return r?.namespace&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new Q({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new W(e)}function Pr(t){return new Promise(e=>setTimeout(e,t))}async function Ke(t,e={}){let r=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=r;i++)try{return await t()}catch(u){if(o=u,i>=r)break;let c=Math.min(s,n*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,c*.2));await Pr(c+a)}throw o}var Tr=new Set(["put","get","getText","delete","list"]);function Be(t,e={}){return new Proxy(t,{get(r,n){let s=Reflect.get(r,n,r);return typeof s!="function"?s:Tr.has(n)?(...o)=>Ke(()=>Promise.resolve(s.apply(r,o)),e):s.bind(r)}})}function Ue(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 We(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 r=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let 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 X=class{constructor(e,r,n,s){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=n,this.folder=Ue(s??n),this.sourcePrefix=`projects/${r}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,r=new Date().toISOString(),n=r,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"&&(n=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:r};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=We(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,r,n){return await this.ensureRegistered(),this.provider.put(this.key(e),r,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{createHash as _r}from"node:crypto";import{dirname as Mr}from"node:path";import{mkdirSync as Nr,readFileSync as Rr,renameSync as Cr,writeFileSync as Lr}from"node:fs";function v(t){return _r("sha256").update(t).digest("hex")}function ke(t){if(Array.isArray(t))return t.map(ke);if(t&&typeof t=="object"){let e=t,r={};for(let n of Object.keys(e).sort())r[n]=ke(e[n]);return r}return t}function ze(t){return JSON.stringify(ke(t))}function qe(t){try{return JSON.parse(Rr(t,"utf8"))}catch{return null}}function A(t,e){Nr(Mr(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;Lr(r,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),Cr(r,t)}var $r=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function L(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function He(t){return L(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function C(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))C(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))($r.has(n)||["data","payload","parts","messages"].includes(n))&&C(s,e,r+1)}}function Z(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 Je(t){let e=L(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 w(t,e,r,n,s={}){let o=L(n),i=s.key??He(o);return{version:1,id:v([t.projectId,r,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:r,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 Dr(t,e,r){let n=L(r);if(n.length<5||n.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(n),i=n.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(w(t,e,"goal",i[1],{confidence:.97}));let u=n.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(w(t,e,"plan",u[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,a;for(;!o&&(a=c.exec(n));){let f=Number(a[1]),d=L(a[2]??""),y=d&&!Je(d)?`Phase ${f} - ${d}`:`Phase ${f}`;s.push(w(t,e,"phase",y,{key:`phase:${f}`,order:f,status:Z(n),confidence:.93}))}let p=r.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&s.push(w(t,e,"task",p[2],{status:p[1].trim()?"completed":Z(p[2]),confidence:.96}));let l=n.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(l[2]),y=Je(d);s.push(w(t,e,"task",y&&f!==void 0?`TODO ${f}`:d,{key:f!==void 0?`task:${f}`:He(d),order:f,status:Z(n),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(n)){let f=n.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(w(t,e,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(n)&&s.push(w(t,e,"blocker",n,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(n)&&s.push(w(t,e,"warning",n,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(n)&&s.push(w(t,e,"decision",n,{confidence:.9})),s}function Ve(t,e){if(e.length===0)return[];let r=[],n=new Set;function s(i){n.has(i.id)||(n.add(i.id),r.push(i))}for(let i of e){if(i.type==="decision"){let c=[];C(i.data,c);for(let a of c)s(w(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let c=[];C(i.data,c);for(let a of c)s(w(t,i,"task",a,{status:Z(a),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let a=i.data[c];typeof a=="string"&&a&&s(w(t,i,"file",a,{confidence:1}))}if(i.type==="test"){let c=[];C(i.data,c);for(let a of c)s(w(t,i,"test",a,{confidence:1}))}let u=[];C(i.data,u);for(let c of u)for(let a of c.split(/\n+/u))for(let p of Dr(t,i,a))s(p)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),r}function Ge(t){return String(t).padStart(12,"0")}var ee=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(a=>a.sequence)),s=Math.max(...r.map(a=>a.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:n,lastSequence:s,observations:r},i=JSON.stringify(o,null,2)+`
6
- `,u=v(r.map(a=>a.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Ge(n)}-${Ge(s)}-${u}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Ye}from"node:path";import{mkdirSync as Fr}from"node:fs";function Kr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(t,e=20){let r=[],n=new Set;for(let s of t.slice().reverse()){let o=Kr(s);if(!(!o||n.has(o))&&(n.add(o),r.push(s),r.length>=e))break}return r.reverse()}function Br(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 Qe(t,e){let r=e.status??t?.status??"pending",n=r;t&&(t.status==="completed"&&r!=="completed"?n="completed":r==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(n=t.status));let s=t&&Br(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:n,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 Ur(t,e){let r=`projects/${t.id}/work/observations/`,n=await e.list(r),s=[];for(let o of n.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 te(t,e){let n=(await Ur(t,e)).flatMap(m=>m.observations).sort((m,x)=>{let Te=m.occurredAt.localeCompare(x.occurredAt);if(Te!==0)return Te;let _e=m.sequence-x.sequence;return _e!==0?_e:m.id.localeCompare(x.id)}),s=new Map,o=new Map,i,u,c,a=[],p=[],l=[],f=[],d=[],y=[];for(let m of n)switch(m.kind){case"goal":i=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,Qe(s.get(m.key),m));break;case"task":o.set(m.key,Qe(o.get(m.key),m));break;case"decision":a.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":c={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"),_=$([...f,...b?[b.title]:[],...!b&&S?[S.title]:[],...g.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),R=$([...p,...h.filter(m=>m.status==="blocked").map(m=>m.title),...g.filter(m=>m.status==="blocked").map(m=>m.title)],20),O={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:g,decisions:$(a,20),blockers:R,warnings:$(l,20),nextActions:_,filesTouched:$(d,30),tests:$(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:c,updatedAt:n.length?n[n.length-1].occurredAt:new Date().toISOString()},M=Ye(t.rootPath,".toolnet","work");return Fr(M,{recursive:!0}),A(Ye(M,"current.json"),O),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(O,null,2)+`
7
- `,"application/json"),O}async function re(t,e){let r=await e.getText(`projects/${t.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{closeSync as Wr,existsSync as zr,openSync as qr,readSync as Jr,statSync as Hr}from"node:fs";function Vr(t,e){if(!zr(t))return{events:[],nextOffset:e};let r=Hr(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=qr(t,"r");try{Jr(i,o,0,s,n)}finally{Wr(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
1
+ import{existsSync as Wt,readFileSync as zt}from"node:fs";import{homedir as qt}from"node:os";import{join as Jt}from"node:path";function Vt(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??Jt(qt(),".config","toolnet-memory",".env");if(!Wt(t))return;let e=zt(t,"utf8");for(let r of e.split(/\r?\n/)){let n=r.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let s=n.indexOf("=");if(s<=0)continue;let o=n.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=Vt(n.slice(s+1)))}}Ht();function B(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function U(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function H(){return{memory:{autoCapture:B(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:B(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:B(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:B(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:U(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:U(process.env.MEMORY_RERANK_TOP,10),finalContext:U(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:U(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:B(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:U(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Gt}from"node:crypto";import{existsSync as Se,mkdirSync as Yt,readFileSync as Qt,renameSync as Xt,writeFileSync as Zt}from"node:fs";import{basename as er,dirname as G,join as Q,parse as $e,resolve as W}from"node:path";var De=".toolnet",tr="project.json";function rr(t){return Gt("sha256").update(t).digest("hex").slice(0,16)}function ke(t){return Q(t,De,tr)}function nr(t){return Se(ke(t))}function sr(t,e){let r=W(t),n=$e(r).root;for(;;){if(nr(r))return r;if(r===n||e&&r===W(e))break;let s=G(r);if(s===r)break;r=s}return null}function or(t){let e=W(t),r=$e(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(o=>Se(Q(e,o))))return e;if(e===r)break;let s=G(e);if(s===e)break;e=s}return W(t)}function ir(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 r=e;if(typeof r.id!="string"||!r.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof r.name!="string"||!r.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let n=new Date().toISOString();return{version:1,id:r.id,name:r.name,remote:typeof r.remote=="string"&&r.remote.trim()?r.remote:r.name,rootPath:typeof r.rootPath=="string"?r.rootPath:G(G(t)),createdAt:typeof r.createdAt=="string"?r.createdAt:n,updatedAt:typeof r.updatedAt=="string"?r.updatedAt:n,graphVersion:typeof r.graphVersion=="number"?r.graphVersion:0,memoryVersion:typeof r.memoryVersion=="number"?r.memoryVersion:0,metadata:r.metadata&&typeof r.metadata=="object"?r.metadata:void 0}}function Ce(t,e){let r=Q(t,De);Yt(r,{recursive:!0});let n=ke(t),s=`${n}.tmp-${process.pid}`;Zt(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),Xt(s,n)}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 Y=class{detect(e=process.cwd()){let r=W(e),n=or(r),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Se(Q(n,p))),i=sr(r,o?n:void 0);if(i){let p=ke(i),l=ir(p);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Ce(i,l)),Le(l,i)}let u=new Date().toISOString(),c=er(n),a={version:1,id:rr(n),name:c,remote:c,rootPath:n,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Ce(n,a),Le(a,n)}};var ar=[{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}],X=class{scan(e){let r=[];for(let n of ar){let s=new RegExp(n.regex.source,n.regex.flags);for(let o of e.matchAll(s))r.push({type:n.type,value:o[0]})}return r}hasSecrets(e){return this.scan(e).length>0}};var z=class{scanner=new X;sanitize(e){let r=e,n=this.scanner.scan(e),s=new Set;for(let o of n)s.add(o.type),r=r.split(o.value).join(`[REDACTED:${o.type}]`);return{text:r,redacted:n.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(r=>this.sanitizeValue(r));if(e&&typeof e=="object"){let r={};for(let[n,s]of Object.entries(e)){let o=n.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?r[n]="[REDACTED]":r[n]=this.sanitizeValue(s)}return r}return e}};import{homedir as Tr}from"node:os";import{join as _r}from"node:path";import{DeleteObjectCommand as cr,GetObjectCommand as ur,HeadObjectCommand as lr,ListObjectsV2Command as dr,PutObjectCommand as pr,S3Client as fr}from"@aws-sdk/client-s3";import{getSignedUrl as mr}from"@aws-sdk/s3-request-presigner";var Z=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new fr({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,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new pr({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await mr(this.client,new ur({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new lr({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new cr({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new dr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let o of s.Contents??[])o.Key&&r.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};import{access as Fe,mkdir as gr,readFile as hr,readdir as yr,rm as Sr,stat as Ke,writeFile as kr}from"node:fs/promises";import{dirname as vr,join as br,relative as Be,resolve as wr}from"node:path";var q=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return wr(this.root,r)}async put(e,r){let n=this.path(e);await gr(vr(n),{recursive:!0}),await kr(n,r)}async get(e){try{return await hr(this.path(e))}catch(r){if(typeof r=="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return null;throw r}}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await Fe(this.path(e)),!0}catch{return!1}}async delete(e){await Sr(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),n=[];try{await Fe(r)}catch{return n}let s=async i=>{let u=await yr(i,{withFileTypes:!0});for(let c of u){let a=br(i,c.name);if(c.isDirectory()){await s(a);continue}let p=await Ke(a);n.push({key:Be(this.root,a),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await Ke(r);return o.isDirectory()?await s(r):n.push({key:Be(this.root,r),size:o.size,updatedAt:o.mtime.toISOString()}),n}};import{DeleteObjectCommand as xr,GetObjectCommand as Ar,HeadObjectCommand as jr,ListObjectsV2Command as Er,PutObjectCommand as Ir,S3Client as Or}from"@aws-sdk/client-s3";import{getSignedUrl as Pr}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 Or({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,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new Ir({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await Pr(this.client,new Ar({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new jr({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new xr({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new Er({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let o of s.Contents??[])o.Key&&r.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};function ve(t,e){return console.warn(e),new q(t)}function Ue(t){let e=t.localRoot??_r(Tr(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new J({name:"r2",endpoint:`https://${r.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:r.bucket,forcePathStyle:!0,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let r=t.s3;return r?.bucket&&r.accessKeyId&&r.secretAccessKey?new J({name:"s3",endpoint:r.endpoint,region:r.region??"us-east-1",bucket:r.bucket,forcePathStyle:r.forcePathStyle??!1,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let r=t.huggingface;return r?.namespace&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new Z({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):ve(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new q(e)}function Mr(t){return new Promise(e=>setTimeout(e,t))}async function We(t,e={}){let r=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=r;i++)try{return await t()}catch(u){if(o=u,i>=r)break;let c=Math.min(s,n*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,c*.2));await Mr(c+a)}throw o}var Nr=new Set(["put","get","getText","delete","list"]);function ze(t,e={}){return new Proxy(t,{get(r,n){let s=Reflect.get(r,n,r);return typeof s!="function"?s:Nr.has(n)?(...o)=>We(()=>Promise.resolve(s.apply(r,o)),e):s.bind(r)}})}function qe(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 Je(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 r=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var ee=class{constructor(e,r,n,s){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=n,this.folder=qe(s??n),this.sourcePrefix=`projects/${r}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,r=new Date().toISOString(),n=r,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"&&(n=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:r};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=Je(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,r,n){return await this.ensureRegistered(),this.provider.put(this.key(e),r,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{createHash as Rr}from"node:crypto";import{dirname as Cr}from"node:path";import{mkdirSync as Lr,readFileSync as $r,renameSync as Dr,writeFileSync as Fr}from"node:fs";function k(t){return Rr("sha256").update(t).digest("hex")}function be(t){if(Array.isArray(t))return t.map(be);if(t&&typeof t=="object"){let e=t,r={};for(let n of Object.keys(e).sort())r[n]=be(e[n]);return r}return t}function Ve(t){return JSON.stringify(be(t))}function He(t){try{return JSON.parse($r(t,"utf8"))}catch{return null}}function A(t,e){Lr(Cr(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;Fr(r,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),Dr(r,t)}var Kr=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 Ye(t){return $(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))L(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(Kr.has(n)||["data","payload","parts","messages"].includes(n))&&L(s,e,r+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 Ge(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 w(t,e,r,n,s={}){let o=$(n),i=s.key??Ye(o);return{version:1,id:k([t.projectId,r,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:r,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 Br(t,e,r){let n=$(r);if(n.length<5||n.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(n),i=n.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(w(t,e,"goal",i[1],{confidence:.97}));let u=n.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(w(t,e,"plan",u[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,a;for(;!o&&(a=c.exec(n));){let f=Number(a[1]),d=$(a[2]??""),y=d&&!Ge(d)?`Phase ${f} - ${d}`:`Phase ${f}`;s.push(w(t,e,"phase",y,{key:`phase:${f}`,order:f,status:te(n),confidence:.93}))}let p=r.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&s.push(w(t,e,"task",p[2],{status:p[1].trim()?"completed":te(p[2]),confidence:.96}));let l=n.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=Ge(d);s.push(w(t,e,"task",y&&f!==void 0?`TODO ${f}`:d,{key:f!==void 0?`task:${f}`:Ye(d),order:f,status:te(n),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(n)){let f=n.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(w(t,e,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(n)&&s.push(w(t,e,"blocker",n,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(n)&&s.push(w(t,e,"warning",n,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(n)&&s.push(w(t,e,"decision",n,{confidence:.9})),s}function Qe(t,e){if(e.length===0)return[];let r=[],n=new Set;function s(i){n.has(i.id)||(n.add(i.id),r.push(i))}for(let i of e){if(i.type==="decision"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"task",a,{status:te(a),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let a=i.data[c];typeof a=="string"&&a&&s(w(t,i,"file",a,{confidence:1}))}if(i.type==="test"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"test",a,{confidence:1}))}let u=[];L(i.data,u);for(let c of u)for(let a of c.split(/\n+/u))for(let p of Br(t,i,a))s(p)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),r}function Xe(t){return String(t).padStart(12,"0")}var re=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(a=>a.sequence)),s=Math.max(...r.map(a=>a.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:n,lastSequence:s,observations:r},i=JSON.stringify(o,null,2)+`
6
+ `,u=k(r.map(a=>a.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Xe(n)}-${Xe(s)}-${u}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Ze}from"node:path";import{mkdirSync as Ur}from"node:fs";function Wr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function D(t,e=20){let r=[],n=new Set;for(let s of t.slice().reverse()){let o=Wr(s);if(!(!o||n.has(o))&&(n.add(o),r.push(s),r.length>=e))break}return r.reverse()}function zr(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 et(t,e){let r=e.status??t?.status??"pending",n=r;t&&(t.status==="completed"&&r!=="completed"?n="completed":r==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(n=t.status));let s=t&&zr(e)?t.title:e.text;return{id:t?.id??k(e.key).slice(0,24),title:s,status:n,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 qr(t,e){let r=`projects/${t.id}/work/observations/`,n=await e.list(r),s=[];for(let o of n.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 ne(t,e){let n=(await qr(t,e)).flatMap(m=>m.observations).sort((m,x)=>{let Ne=m.occurredAt.localeCompare(x.occurredAt);if(Ne!==0)return Ne;let Re=m.sequence-x.sequence;return Re!==0?Re:m.id.localeCompare(x.id)}),s=new Map,o=new Map,i,u,c,a=[],p=[],l=[],f=[],d=[],y=[];for(let m of n)switch(m.kind){case"goal":i=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,et(s.get(m.key),m));break;case"task":o.set(m.key,et(o.get(m.key),m));break;case"decision":a.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":c={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"),M=D([...f,...b?[b.title]:[],...!b&&S?[S.title]:[],...g.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),C=D([...p,...h.filter(m=>m.status==="blocked").map(m=>m.title),...g.filter(m=>m.status==="blocked").map(m=>m.title)],20),O={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:g,decisions:D(a,20),blockers:C,warnings:D(l,20),nextActions:M,filesTouched:D(d,30),tests:D(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:c,updatedAt:n.length?n[n.length-1].occurredAt:new Date().toISOString()},N=Ze(t.rootPath,".toolnet","work");return Ur(N,{recursive:!0}),A(Ze(N,"current.json"),O),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(O,null,2)+`
7
+ `,"application/json"),O}async function F(t,e){let r=await e.getText(`projects/${t.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{closeSync as Jr,existsSync as Vr,openSync as Hr,readSync as Gr,statSync as Yr}from"node:fs";function Qr(t,e){if(!Vr(t))return{events:[],nextOffset:e};let r=Yr(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=Hr(t,"r");try{Gr(i,o,0,s,n)}finally{Jr(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
8
8
  `);if(c<0)return{events:[],nextOffset:n};let a=u.slice(0,c+1);return{events:a.split(`
9
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var ne=class{constructor(e){this.options=e;this.journal=new ee(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["work.continuity.offset"]??0),n=Vr(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=Ve(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await te(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{mkdirSync as sn}from"node:fs";import{join as be}from"node:path";import{existsSync as et,mkdirSync as Gr,readFileSync as Yr,statSync as Xe,writeFileSync as Qr}from"node:fs";import{dirname as Xr,join as Zr}from"node:path";var Ze=64*1024,en=`# ToolNet Project Operating Manual
9
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var se=class{constructor(e){this.options=e;this.journal=new re(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["work.continuity.offset"]??0),n=Qr(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=Qe(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await ne(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{mkdirSync as cn}from"node:fs";import{join as we}from"node:path";import{existsSync as nt,mkdirSync as Xr,readFileSync as Zr,statSync as tt,writeFileSync as en}from"node:fs";import{dirname as tn,join as rn}from"node:path";var rt=64*1024,nn=`# ToolNet Project Operating Manual
10
10
 
11
11
  This file contains persistent instructions for AI agents working on this project.
12
12
 
@@ -49,57 +49,69 @@ Things an AI agent should always remember.
49
49
  <!--
50
50
  - [advisory] Prefer small focused files.
51
51
  -->
52
- `;function se(t){return Zr(t.rootPath,".toolnet","PROJECT.md")}function tn(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function rn(t){let e=[],r=new Set,n=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=n.exec(t);){let o=s[1].toLowerCase(),i=tn(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;r.has(u)||(r.add(u),e.push({id:v(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function nn(t){let e=se(t);return et(e)||(Gr(Xr(e),{recursive:!0}),Qr(e,en,{encoding:"utf8",mode:384})),e}function oe(t,e=!1){let r=e?nn(t):se(t);if(!et(r))return null;if(Xe(r).size>Ze)throw new Error(`PROJECT.md exceeds ${Ze} bytes`);let s=Yr(r,"utf8");return{path:r,content:s,digest:v(s),rules:rn(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(Xe(r).mtimeMs).toISOString()}}function on(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 an(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 ie=class{constructor(e){this.options=e}options;async capture(e,r){let n=await re(this.options.project,this.options.storage);if(n||(n=await te(this.options.project,this.options.storage)),!an(n))return null;let s=oe(this.options.project,!1),o=s?s.rules.filter(f=>f.mode==="enforce").map(f=>f.text):[],i=v(JSON.stringify(on(n))),u=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),c=new Date().toISOString(),a={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:c,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:r},goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),incompleteTasks:n.tasks.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),nextActions:n.nextActions.slice(0,10),blockers:n.blockers.slice(0,10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:[...o,...n.warnings].slice(0,20),filesTouched:n.filesTouched.slice(-20),tests:n.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(a,null,2)+`
52
+ `;function oe(t){return rn(t.rootPath,".toolnet","PROJECT.md")}function sn(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function on(t){let e=[],r=new Set,n=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=n.exec(t);){let o=s[1].toLowerCase(),i=sn(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;r.has(u)||(r.add(u),e.push({id:k(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function an(t){let e=oe(t);return nt(e)||(Xr(tn(e),{recursive:!0}),en(e,nn,{encoding:"utf8",mode:384})),e}function ie(t,e=!1){let r=e?an(t):oe(t);if(!nt(r))return null;if(tt(r).size>rt)throw new Error(`PROJECT.md exceeds ${rt} bytes`);let s=Zr(r,"utf8");return{path:r,content:s,digest:k(s),rules:on(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(tt(r).mtimeMs).toISOString()}}function un(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 ln(t){return t.phases.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.tasks.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.nextActions.length>0||t.blockers.length>0}var ae=class{constructor(e){this.options=e}options;async capture(e,r){let n=await F(this.options.project,this.options.storage);if(n||(n=await ne(this.options.project,this.options.storage)),!ln(n))return null;let s=ie(this.options.project,!1),o=s?s.rules.filter(f=>f.mode==="enforce").map(f=>f.text):[],i=k(JSON.stringify(un(n))),u=k([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),c=new Date().toISOString(),a={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:c,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:r},goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),incompleteTasks:n.tasks.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),nextActions:n.nextActions.slice(0,10),blockers:n.blockers.slice(0,10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:[...o,...n.warnings].slice(0,20),filesTouched:n.filesTouched.slice(-20),tests:n.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(a,null,2)+`
53
53
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(a,null,2)+`
54
- `,"application/json");let l=be(this.options.project.rootPath,".toolnet","work","handoffs");return sn(l,{recursive:!0}),A(be(l,`${u}.json`),a),A(be(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),a),a}};async function tt(t,e){let r=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{mkdirSync as cn}from"node:fs";import{join as rt}from"node:path";function un(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function ln(t,e){if(!e)return!0;let r=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return r!==0?r>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function P(t,e){return ln(e,t)?e:t}function T(t,e=30){let r=new Set,n=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||r.has(o)||(r.add(o),n.push(s))}return n.slice(-e)}async function dn(t,e){let r=`projects/${t.id}/work/semantic/observations/`,n=await e.list(r),s=[];for(let o of n.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 pn(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function nt(t,e){let n=(await dn(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,c,a=new Map,p=[],l=[],f=[];for(let h of n){let g=un(h);if(h.scope==="phase"&&h.scopeKey){let S=a.get(h.scopeKey)??pn(h);switch(h.kind){case"phase_objective":S.objective=P(S.objective,g);break;case"phase_why":S.why=P(S.why,g);break;case"phase_deliverable":S.deliverable=P(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}a.set(S.key,S);continue}switch(h.kind){case"mission":s=P(s,g);break;case"objective":o=P(o,g);break;case"why":i=P(i,g);break;case"desired_outcome":u=P(u,g);break;case"plan_rationale":c=P(c,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 a.values())h.acceptanceCriteria=T(h.acceptanceCriteria,20),h.dependencies=T(h.dependencies,15),h.openQuestions=T(h.openQuestions,15),h.constraints=T(h.constraints,15),h.notes=T(h.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:c,phases:Array.from(a.values()).sort((h,g)=>h.order-g.order),openQuestions:T(p,20),constraints:T(l,20),notes:T(f,20),updatedAt:n.length?n[n.length-1].evidence.occurredAt:new Date().toISOString()},y=rt(t.rootPath,".toolnet","work");return cn(y,{recursive:!0}),A(rt(y,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
55
- `,"application/json"),d}async function st(t,e){let r=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function we(t){if(!t)return 0;let e=Array.from(t).length,r=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,r*1.3))}function k(t,e){let r=t.replace(/\s+/g," ").trim();return r.length<=e?r:r.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function fn(t){let e=[],r=!1;for(let n of t.split(/\r?\n/u)){let s=n.trim();if(s.includes("<!--")&&(r=!0),r){s.includes("-->")&&(r=!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(k(s,280)),e.length>=16))break}return e}function mn(t){let e=[],r=[];for(let n of t.split(/\\r?\\n/u)){let s=n.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(a=>o.startsWith(a));if(!u)continue;let c=s.slice(u.length).trim();c&&(u.includes("enforce")?e.push(c):r.push(c))}return{enforce:e,advisory:r}}function gn(t,e){let r=[];for(let n of t){let s=[...r,n].join(`
56
- `);if(we(s)<=e){r.push(n);continue}let o=we(r.join(`
57
- `)),i=Math.max(0,e-o);if(i>=16){let u=Math.floor(i*3.2),c=k(n,u);c&&r.push(c)}break}return r.join(`
58
- `).trim()}async function ot(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),r=oe(t.project,!1),n=r?.content??"";n||(n=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=mn(n),o=r?r.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=r?r.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,u=n?fn(n):[],c=await re(t.project,t.storage),a=await st(t.project,t.storage),p=await tt(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."),n&&l.push(`Full operating manual: ${se(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${k(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${k(d,220)}`)}if(a&&(a.mission&&l.push("","MISSION",k(a.mission.value,420)),a.activeObjective&&l.push("","CURRENT OBJECTIVE",k(a.activeObjective.value,420)),a.why&&l.push("","WHY THIS WORK MATTERS",k(a.why.value,420)),a.desiredOutcome&&l.push("","DESIRED OUTCOME",k(a.desiredOutcome.value,420)),a.planRationale&&l.push("","WHY THIS APPROACH",k(a.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${k(c.goal,320)}`),c.plan&&l.push(`Plan: ${k(c.plan,320)}`),l.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&l.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&a){let d=a.phases.find(y=>y.order===c.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${k(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${k(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${k(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(y=>k(y.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(y=>{l.push(`- ${k(y.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(y=>{l.push(`- ${k(y.value,260)}`)})))}c.currentTask&&l.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(l.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((d,y)=>{l.push(`${y+1}. ${k(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${k(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${k(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${k(d,260)}`)})),c.lastSession&&l.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(a&&a.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),a.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${k(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=gn(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:f,estimatedTokens:we(f),maxTokens:e,hasManual:!!n,hasWorkState:!!c,hasHandoff:!!p,generatedAt:new Date().toISOString()}}var hn=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function D(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function xe(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))xe(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(hn.has(n)||["data","payload","parts","messages"].includes(n))&&xe(s,e,r+1)}}function E(t,e,r,n,s,o=.95){let i=D(n);return{version:1,id:v([t.projectId,r,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:r,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 j(t,e){let r=t.toLowerCase();for(let n of e){let s=n.toLowerCase();if(r.startsWith(`${s}:`)||r.startsWith(`${s} -`)||r.startsWith(`${s} \u2014`))return D(t.slice(n.length+1))}return null}function yn(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Sn(t){return D(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function it(t,e){let r=[],n=new Set;function s(o){!o.value||o.value.length<3||n.has(o.id)||(n.add(o.id),r.push(o))}for(let o of e){let i=[];xe(o.data,i);for(let u of i){let c={type:"project"},a=null;for(let p of u.split(/\r?\n/u)){let l=D(p);if(!l){a=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]);c={type:"phase",key:`phase:${x}`,order:x,title:D(f[2]??"")},a=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let x=Number(d[1]);c={type:"task",key:`task:${x}`,order:x,title:D(d[2]??"")},a=null;continue}let y=j(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(E(t,o,"mission",y,{type:"project"},.99)),a=null;continue}let h=j(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(E(t,o,c.type==="phase"?"phase_objective":"objective",h,c,.98)),a=null;continue}let g=j(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(E(t,o,c.type==="phase"?"phase_why":"why",g,c,.98)),a=null;continue}let S=j(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(E(t,o,"desired_outcome",S,{type:"project"},.98)),a=null;continue}let b=j(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(E(t,o,"plan_rationale",b,{type:"project"},.98)),a=null;continue}let _=j(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(_){s(E(t,o,"phase_deliverable",_,c,.97)),a=null;continue}let R=j(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(R){s(E(t,o,"acceptance_criterion",R,c,.98)),a="acceptance_criterion";continue}let O=j(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(O){s(E(t,o,"dependency",O,c,.97)),a="dependency";continue}let M=j(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(M){s(E(t,o,"open_question",M,c,.95)),a="open_question";continue}let m=j(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(m){s(E(t,o,"constraint",m,c,.97)),a="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){a="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){a="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){a="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){a="constraint";continue}if(a&&yn(p)){s(E(t,o,a,Sn(p),c,.96));continue}a=null}}}return r}function at(t){return String(t).padStart(12,"0")}var ae=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(c=>c.evidence.sequence)),s=Math.max(...r.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:n,lastSequence:s,createdAt:new Date().toISOString(),observations:r},i=v(r.map(c=>c.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${at(n)}-${at(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
59
- `,"application/json"),u}};import{closeSync as vn,existsSync as kn,openSync as bn,readSync as wn,statSync as xn}from"node:fs";function An(t,e){if(!kn(t))return{events:[],nextOffset:e};let r=xn(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=Buffer.alloc(r-n),o=bn(t,"r");try{wn(o,s,0,s.length,n)}finally{vn(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
54
+ `,"application/json");let l=we(this.options.project.rootPath,".toolnet","work","handoffs");return cn(l,{recursive:!0}),A(we(l,`${u}.json`),a),A(we(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),a),a}};async function st(t,e){let r=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{mkdirSync as dn}from"node:fs";import{join as ot}from"node:path";function pn(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function fn(t,e){if(!e)return!0;let r=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return r!==0?r>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function P(t,e){return fn(e,t)?e:t}function T(t,e=30){let r=new Set,n=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||r.has(o)||(r.add(o),n.push(s))}return n.slice(-e)}async function mn(t,e){let r=`projects/${t.id}/work/semantic/observations/`,n=await e.list(r),s=[];for(let o of n.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 gn(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function it(t,e){let n=(await mn(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,c,a=new Map,p=[],l=[],f=[];for(let h of n){let g=pn(h);if(h.scope==="phase"&&h.scopeKey){let S=a.get(h.scopeKey)??gn(h);switch(h.kind){case"phase_objective":S.objective=P(S.objective,g);break;case"phase_why":S.why=P(S.why,g);break;case"phase_deliverable":S.deliverable=P(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}a.set(S.key,S);continue}switch(h.kind){case"mission":s=P(s,g);break;case"objective":o=P(o,g);break;case"why":i=P(i,g);break;case"desired_outcome":u=P(u,g);break;case"plan_rationale":c=P(c,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 a.values())h.acceptanceCriteria=T(h.acceptanceCriteria,20),h.dependencies=T(h.dependencies,15),h.openQuestions=T(h.openQuestions,15),h.constraints=T(h.constraints,15),h.notes=T(h.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:c,phases:Array.from(a.values()).sort((h,g)=>h.order-g.order),openQuestions:T(p,20),constraints:T(l,20),notes:T(f,20),updatedAt:n.length?n[n.length-1].evidence.occurredAt:new Date().toISOString()},y=ot(t.rootPath,".toolnet","work");return dn(y,{recursive:!0}),A(ot(y,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
55
+ `,"application/json"),d}async function at(t,e){let r=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function xe(t){if(!t)return 0;let e=Array.from(t).length,r=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,r*1.3))}function v(t,e){let r=t.replace(/\s+/g," ").trim();return r.length<=e?r:r.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function hn(t){let e=[],r=!1;for(let n of t.split(/\r?\n/u)){let s=n.trim();if(s.includes("<!--")&&(r=!0),r){s.includes("-->")&&(r=!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(v(s,280)),e.length>=16))break}return e}function yn(t){let e=[],r=[];for(let n of t.split(/\\r?\\n/u)){let s=n.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(a=>o.startsWith(a));if(!u)continue;let c=s.slice(u.length).trim();c&&(u.includes("enforce")?e.push(c):r.push(c))}return{enforce:e,advisory:r}}function Sn(t,e){let r=[];for(let n of t){let s=[...r,n].join(`
56
+ `);if(xe(s)<=e){r.push(n);continue}let o=xe(r.join(`
57
+ `)),i=Math.max(0,e-o);if(i>=16){let u=Math.floor(i*3.2),c=v(n,u);c&&r.push(c)}break}return r.join(`
58
+ `).trim()}async function ct(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),r=ie(t.project,!1),n=r?.content??"";n||(n=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=yn(n),o=r?r.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=r?r.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,u=n?hn(n):[],c=await F(t.project,t.storage),a=await at(t.project,t.storage),p=await st(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."),n&&l.push(`Full operating manual: ${oe(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${v(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${v(d,220)}`)}if(a&&(a.mission&&l.push("","MISSION",v(a.mission.value,420)),a.activeObjective&&l.push("","CURRENT OBJECTIVE",v(a.activeObjective.value,420)),a.why&&l.push("","WHY THIS WORK MATTERS",v(a.why.value,420)),a.desiredOutcome&&l.push("","DESIRED OUTCOME",v(a.desiredOutcome.value,420)),a.planRationale&&l.push("","WHY THIS APPROACH",v(a.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${v(c.goal,320)}`),c.plan&&l.push(`Plan: ${v(c.plan,320)}`),l.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&l.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&a){let d=a.phases.find(y=>y.order===c.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${v(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${v(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${v(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(y=>v(y.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(y=>{l.push(`- ${v(y.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(y=>{l.push(`- ${v(y.value,260)}`)})))}c.currentTask&&l.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(l.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((d,y)=>{l.push(`${y+1}. ${v(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${v(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${v(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${v(d,260)}`)})),c.lastSession&&l.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(a&&a.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),a.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${v(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=Sn(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:f,estimatedTokens:xe(f),maxTokens:e,hasManual:!!n,hasWorkState:!!c,hasHandoff:!!p,generatedAt:new Date().toISOString()}}var kn=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 Ae(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))Ae(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(kn.has(n)||["data","payload","parts","messages"].includes(n))&&Ae(s,e,r+1)}}function j(t,e,r,n,s,o=.95){let i=K(n);return{version:1,id:k([t.projectId,r,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:r,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function I(t,e){let r=t.toLowerCase();for(let n of e){let s=n.toLowerCase();if(r.startsWith(`${s}:`)||r.startsWith(`${s} -`)||r.startsWith(`${s} \u2014`))return K(t.slice(n.length+1))}return null}function vn(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function bn(t){return K(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function ut(t,e){let r=[],n=new Set;function s(o){!o.value||o.value.length<3||n.has(o.id)||(n.add(o.id),r.push(o))}for(let o of e){let i=[];Ae(o.data,i);for(let u of i){let c={type:"project"},a=null;for(let p of u.split(/\r?\n/u)){let l=K(p);if(!l){a=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]);c={type:"phase",key:`phase:${x}`,order:x,title:K(f[2]??"")},a=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let x=Number(d[1]);c={type:"task",key:`task:${x}`,order:x,title:K(d[2]??"")},a=null;continue}let y=I(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(j(t,o,"mission",y,{type:"project"},.99)),a=null;continue}let h=I(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(j(t,o,c.type==="phase"?"phase_objective":"objective",h,c,.98)),a=null;continue}let g=I(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(j(t,o,c.type==="phase"?"phase_why":"why",g,c,.98)),a=null;continue}let S=I(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){s(j(t,o,"desired_outcome",S,{type:"project"},.98)),a=null;continue}let b=I(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(b){s(j(t,o,"plan_rationale",b,{type:"project"},.98)),a=null;continue}let M=I(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(j(t,o,"phase_deliverable",M,c,.97)),a=null;continue}let C=I(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(C){s(j(t,o,"acceptance_criterion",C,c,.98)),a="acceptance_criterion";continue}let O=I(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(O){s(j(t,o,"dependency",O,c,.97)),a="dependency";continue}let N=I(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(N){s(j(t,o,"open_question",N,c,.95)),a="open_question";continue}let m=I(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(m){s(j(t,o,"constraint",m,c,.97)),a="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){a="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){a="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){a="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){a="constraint";continue}if(a&&vn(p)){s(j(t,o,a,bn(p),c,.96));continue}a=null}}}return r}function lt(t){return String(t).padStart(12,"0")}var ce=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(c=>c.evidence.sequence)),s=Math.max(...r.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:n,lastSequence:s,createdAt:new Date().toISOString(),observations:r},i=k(r.map(c=>c.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${lt(n)}-${lt(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
59
+ `,"application/json"),u}};import{closeSync as wn,existsSync as xn,openSync as An,readSync as jn,statSync as En}from"node:fs";function In(t,e){if(!xn(t))return{events:[],nextOffset:e};let r=En(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=Buffer.alloc(r-n),o=An(t,"r");try{jn(o,s,0,s.length,n)}finally{wn(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
60
60
  `);if(u<0)return{events:[],nextOffset:n};let c=i.slice(0,u+1);return{events:c.split(`
61
- `).filter(Boolean).flatMap(a=>{try{return[JSON.parse(a)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"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(),r=Number(e.sourceCursors["work.semantic.offset"]??0),n=An(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=it(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await nt(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{existsSync as En,mkdirSync as In,readFileSync as jn,writeFileSync as On}from"node:fs";import{dirname as Pn,join as ct}from"node:path";function ue(t){return t?Math.ceil(t.length/3.5):0}function le(t,e){if(!t)return"";if(ue(t)<=e)return t;let n=Math.floor(e*3.5),s=t.slice(0,n),o=s.lastIndexOf("."),i=s.lastIndexOf(`
62
- `),u=Math.max(o,i);return u>n*.7?s.slice(0,u+1):s}function ut(t){return ct(t.rootPath,".toolnet","context","startup.md")}function Tn(t){return ct(t.rootPath,".toolnet","context","startup.json")}function lt(t,e){let r=ut(t);In(Pn(r),{recursive:!0}),On(r,e.text.endsWith(`
61
+ `).filter(Boolean).flatMap(a=>{try{return[JSON.parse(a)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"utf8")}}var ue=class{constructor(e){this.options=e;this.journal=new ce(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["work.semantic.offset"]??0),n=In(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=ut(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await it(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{existsSync as On,mkdirSync as Pn,readFileSync as Tn,writeFileSync as _n}from"node:fs";import{dirname as Mn,join as dt}from"node:path";function le(t){return t?Math.ceil(t.length/3.5):0}function de(t,e){if(!t)return"";if(le(t)<=e)return t;let n=Math.floor(e*3.5),s=t.slice(0,n),o=s.lastIndexOf("."),i=s.lastIndexOf(`
62
+ `),u=Math.max(o,i);return u>n*.7?s.slice(0,u+1):s}function pt(t){return dt(t.rootPath,".toolnet","context","startup.md")}function Nn(t){return dt(t.rootPath,".toolnet","context","startup.json")}function ft(t,e){let r=pt(t);Pn(Mn(r),{recursive:!0}),_n(r,e.text.endsWith(`
63
63
  `)?e.text:e.text+`
64
- `,{encoding:"utf8",mode:384}),A(Tn(t),e)}async function Ae(t,e,r=800){let s=(await ot({project:t,storage:e,maxTokens:r})).text;ue(s)>r&&(s=le(s,r),s+=`
64
+ `,{encoding:"utf8",mode:384}),A(Nn(t),e)}async function je(t,e,r=800){let s=(await ct({project:t,storage:e,maxTokens:r})).text;le(s)>r&&(s=de(s,r),s+=`
65
65
 
66
66
  [Context trimmed by ToolNet Memory token budget]
67
- `);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:v(s),estimatedTokens:ue(s),generatedAt:new Date().toISOString()};return lt(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
67
+ `);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:k(s),estimatedTokens:le(s),generatedAt:new Date().toISOString()};return ft(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
68
68
  `,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(i,null,2)+`
69
- `,"application/json"),i}async function dt(t,e,r=900){try{let s=await e.getText(`projects/${t.id}/context/startup.md`);if(s&&s.trim()){let o=s.trim(),i={version:1,projectId:t.id,projectName:t.name,text:o,digest:v(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return lt(t,i),i}}catch{}let n=ut(t);if(En(n))try{let s=jn(n,"utf8").trim();if(s)return{version:1,projectId:t.id,projectName:t.name,text:s,digest:v(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await Ae(t,e,r)}catch{return null}}import{existsSync as _n,mkdirSync as Mn,readFileSync as Nn}from"node:fs";import{homedir as Rn}from"node:os";import{dirname as Cn,join as mt}from"node:path";var pt="memory_agent_ask";function ft(){return`
69
+ `,"application/json"),i}async function mt(t,e,r=900){try{let s=await e.getText(`projects/${t.id}/context/startup.md`);if(s&&s.trim()){let o=s.trim(),i={version:1,projectId:t.id,projectName:t.name,text:o,digest:k(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return ft(t,i),i}}catch{}let n=pt(t);if(On(n))try{let s=Tn(n,"utf8").trim();if(s)return{version:1,projectId:t.id,projectName:t.name,text:s,digest:k(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await je(t,e,r)}catch{return null}}import{existsSync as ht,mkdirSync as Rn,readFileSync as yt}from"node:fs";import{homedir as Cn}from"node:os";import{dirname as Ln,join as Ie}from"node:path";var Ee="memory_agent_ask";function gt(){return`
70
70
  [TOOLNET MEMORY AGENT]
71
71
 
72
72
  Tool:
73
- - ${pt}
74
-
75
- If the user asks to resume previous work and the fast context
76
- is insufficient, call ${pt} before guessing.
73
+ - ${Ee}
74
+
75
+ For resume/continue requests:
76
+
77
+ 1. Use the injected ToolNet continuity handoff FIRST.
78
+ 2. If the handoff is missing or ambiguous, invoke
79
+ ${Ee} directly BEFORE repository/history exploration.
80
+ 3. NEVER reconstruct prior work from:
81
+ - .toolnet/sessions/**
82
+ - state.json
83
+ - events.jsonl
84
+ - raw transcripts
85
+ 4. NEVER search for the implementation/schema of
86
+ ${Ee}; invoke the MCP tool directly.
87
+ 5. Inspect git/source only AFTER continuity context is known.
77
88
 
78
89
  Use:
79
90
  - mode="local" for current task, last file, blocker or next action.
80
91
  - mode="ai" for ambiguous or combined continuity questions.
81
92
 
82
93
  Current repository evidence overrides stale memory.
83
- `.trim()}function Ln(t,e,r){let n=r??mt(Rn(),".config","toolnet-memory","injections","agy");return mt(n,`${t.id}-${e}.json`)}function $n(t){if(!_n(t))return null;try{return JSON.parse(Nn(t,"utf8"))}catch{return null}}async function gt(t){let e=t.now??Date.now(),r=t.resumeAfterMs??360*60*1e3,n=Ln(t.project,t.conversationId,t.markerDirectory),s=$n(n),o=s?Date.parse(s.injectedAt):0,i=o?e-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let u=t.invocationNum===0,c=i>=r;if(s&&!u&&!c)return{};let a=await dt(t.project,t.storage,900);return a?.text?(Mn(Cn(n),{recursive:!0}),A(n,{digest:a.digest,injectedAt:new Date(e).toISOString()}),{injectSteps:[{userMessage:`${a.text}
94
+ `.trim()}function $n(t,e,r){let n=r??Ie(Cn(),".config","toolnet-memory","injections","agy");return Ie(n,`${t.id}-${e}.json`)}function Dn(t){if(!ht(t))return null;try{return JSON.parse(yt(t,"utf8"))}catch{return null}}function _(t,e=280){let r=(t??"").replace(/\s+/g," ").trim();return r.length<=e?r:r.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function Fn(t){let e=Ie(t.rootPath,".toolnet","work","current.json");if(!ht(e))return null;try{let r=JSON.parse(yt(e,"utf8"));if(r.version===1&&r.projectId===t.id)return r}catch{}return null}function Kn(t,e){let r=e.tasks.filter(i=>i.status==="completed").slice(-3).map(i=>_(i.title,220)),n=Array.from(new Set([...e.currentTask?[e.currentTask.title]:[],...e.tasks.filter(i=>i.status==="in_progress"||i.status==="blocked"||i.status==="pending").slice(0,4).map(i=>i.title)].map(i=>_(i,220)).filter(Boolean))),s=e.filesTouched.at(-1),o=["[TOOLNET CONTINUITY HANDOFF]",`Project: ${t.name}`];return e.currentTask?.title?o.push(`Task: ${_(e.currentTask.title)}`):e.currentPhase?.title?o.push(`Task: ${_(e.currentPhase.title)}`):e.goal&&o.push(`Task: ${_(e.goal)}`),r.length&&o.push(`Completed: ${r.join("; ")}`),s&&o.push(`Current file: ${_(s,260)}`),n.length&&o.push(`TODO: ${n.join("; ")}`),e.nextActions.length&&o.push(`Next action: ${_(e.nextActions[0])}`),e.blockers.length&&o.push(`Blocker: ${_(e.blockers[0])}`),o.push("","CONTINUATION CONTRACT:","- Continue from this compact handoff; do not reconstruct the prior session.","- NEVER inspect .toolnet/sessions/**, state.json, events.jsonl, or raw transcripts.","- If this handoff is insufficient, invoke memory_agent_ask directly.","- Do not search for memory_agent_ask implementation/schema.","- Inspect git/source only to validate current code after continuity is resolved."),o.join(`
95
+ `)}async function Bn(t){let e=Fn(t.project);if(!e)try{e=await F(t.project,t.storage)}catch{e=null}let r=e?Kn(t.project,e):"";if(!r)try{r=(await mt(t.project,t.storage,700))?.text??""}catch{r=""}return[r,gt()].filter(Boolean).join(`
84
96
 
85
- ${ft()}`}]}):{}}import{existsSync as Un}from"node:fs";import{dirname as Wn,join as zn,parse as qn,resolve as Jn}from"node:path";function yt(t){for(let e of t){let r=Jn(e),n=qn(r).root;for(;;){if(Un(zn(r,".toolnet","project.json")))return new V().detect(r);if(r===n)break;let s=Wn(r);if(s===r)break;r=s}}return null}import{homedir as Dt}from"node:os";import{join as Bs,resolve as Us}from"node:path";import{join as Hn}from"node:path";function St(t,e){let r=t.trim(),n=r.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(r).slice(0,12);if(!n||n==="."||n==="..")return`${e}--${s}`;let o=n.slice(0,100);return o===r&&r.length<=100?o:`${o.slice(0,85)}--${s}`}function vt(t,e,r){let n=e.trim(),s=r.trim();if(!n)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=St(n.toLowerCase(),"agent"),i=St(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:n,nativeSessionId:s,sessionKey:`${n}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:Hn(t.rootPath,".toolnet","sessions",o,i)}}function kt(t){return String(t).padStart(12,"0")}var de=class{constructor(e,r=100,n=512*1024){this.storage=e;this.maxEventsPerChunk=r;this.maxChunkBytes=n;if(r<1)throw new Error("maxEventsPerChunk must be positive");if(n<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let r=await this.storage.getText(e);return r?JSON.parse(r):null}async putJson(e,r){await this.storage.put(e,JSON.stringify(r,null,2)+`
97
+ `).trim()}async function St(t){let e=t.now??Date.now(),r=t.resumeAfterMs??360*60*1e3,n=$n(t.project,t.conversationId,t.markerDirectory),s=Dn(n),o=s?Date.parse(s.injectedAt):0,i=o?e-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let u=t.invocationNum===0,c=i>=r;if(s&&!u&&!c)return{};let a=await Bn({project:t.project,storage:t.storage});return a?(Rn(Ln(n),{recursive:!0}),A(n,{digest:k(a),injectedAt:new Date(e).toISOString()}),{injectSteps:[{ephemeralMessage:a}]}):{}}import{existsSync as Jn}from"node:fs";import{dirname as Vn,join as Hn,parse as Gn,resolve as Yn}from"node:path";function vt(t){for(let e of t){let r=Yn(e),n=Gn(r).root;for(;;){if(Jn(Hn(r,".toolnet","project.json")))return new Y().detect(r);if(r===n)break;let s=Vn(r);if(s===r)break;r=s}}return null}import{homedir as Bt}from"node:os";import{join as qs,resolve as Js}from"node:path";import{join as Qn}from"node:path";function bt(t,e){let r=t.trim(),n=r.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=k(r).slice(0,12);if(!n||n==="."||n==="..")return`${e}--${s}`;let o=n.slice(0,100);return o===r&&r.length<=100?o:`${o.slice(0,85)}--${s}`}function wt(t,e,r){let n=e.trim(),s=r.trim();if(!n)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=bt(n.toLowerCase(),"agent"),i=bt(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:n,nativeSessionId:s,sessionKey:`${n}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:Qn(t.rootPath,".toolnet","sessions",o,i)}}function xt(t){return String(t).padStart(12,"0")}var pe=class{constructor(e,r=100,n=512*1024){this.storage=e;this.maxEventsPerChunk=r;this.maxChunkBytes=n;if(r<1)throw new Error("maxEventsPerChunk must be positive");if(n<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let r=await this.storage.getText(e);return r?JSON.parse(r):null}async putJson(e,r){await this.storage.put(e,JSON.stringify(r,null,2)+`
86
98
  `,"application/json")}async scan(e){let r=`${e.remotePrefix}/events/`,n=await this.storage.list(r),s=[],o=0;for(let i of n){let u=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!u)continue;let c=Number(u[1]),a=Number(u[2]);!Number.isFinite(c)||!Number.isFinite(a)||(s.push({key:i.key,start:c,end:a}),o=Math.max(o,a))}return s.sort((i,u)=>i.start-u.start),{chunks:s,maxSequence:o}}split(e){let r=[],n=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
87
- `,"utf8");n.length>0&&(n.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(r.push(n),n=[],s=0),n.push(o),s+=i}return n.length>0&&r.push(n),r}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let r=await this.scan(e);return{maxSequence:r.maxSequence,chunkCount:r.chunks.length}}async append(e,r,n,s={}){let o=await this.loadManifest(e),i=await this.scan(e),u=r.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(u)){let S=g[0],b=g[g.length-1],_=g.map(M=>JSON.stringify(M)).join(`
99
+ `,"utf8");n.length>0&&(n.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(r.push(n),n=[],s=0),n.push(o),s+=i}return n.length>0&&r.push(n),r}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let r=await this.scan(e);return{maxSequence:r.maxSequence,chunkCount:r.chunks.length}}async append(e,r,n,s={}){let o=await this.loadManifest(e),i=await this.scan(e),u=r.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(u)){let S=g[0],b=g[g.length-1],M=g.map(N=>JSON.stringify(N)).join(`
88
100
  `)+`
89
- `,R=v(_).slice(0,16),O=[e.remotePrefix,"events",`${kt(S.sequence)}-${kt(b.sequence)}-${R}.jsonl`].join("/");await this.storage.exists(O)||await this.storage.put(O,_,"application/x-ndjson"),c+=g.length}let a=await this.scan(e),p=r[r.length-1],l=o?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?l="idle":p?.type==="error"?l="error":r.length>0&&(l="active");let f=new Date().toISOString(),d=r[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:a.maxSequence,chunkCount:a.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:r.length>0?r[r.length-1].sequence:a.maxSequence,lastRemoteSequence:a.maxSequence,sourceCursors:n,updatedAt:f};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,y),{uploadedEvents:c,lastRemoteSequence:a.maxSequence,eventCount:y.eventCount,chunkCount:y.chunkCount,status:l}}};import{closeSync as Ee,existsSync as Vn,fsyncSync as Gn,mkdirSync as Yn,openSync as Ie,readSync as Qn,rmSync as bt,statSync as wt,writeSync as Xn}from"node:fs";import{join as je}from"node:path";var Zn=12e4,es=80,ts=2e3;function rs(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var pe=class{constructor(e){this.identity=e;Yn(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 qe(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){A(this.stateFile,e)}acquireLock(){for(let e=0;e<es;e+=1)try{return Ie(this.lockFile,"wx",384)}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-wt(this.lockFile).mtimeMs>Zn){bt(this.lockFile,{force:!0});continue}}catch{}rs(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let r=this.acquireLock();try{return e()}finally{Ee(r),bt(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let r=this.loadStateUnsafe(),n=new Set(r.recentEventIds),s=r.lastSequence,o=[];for(let l of e){let f=l.timestamp??new Date().toISOString(),d=l.data??{},y=l.provenance?.rawDigest??v(ze(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(n.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),n.add(g)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
101
+ `,C=k(M).slice(0,16),O=[e.remotePrefix,"events",`${xt(S.sequence)}-${xt(b.sequence)}-${C}.jsonl`].join("/");await this.storage.exists(O)||await this.storage.put(O,M,"application/x-ndjson"),c+=g.length}let a=await this.scan(e),p=r[r.length-1],l=o?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?l="idle":p?.type==="error"?l="error":r.length>0&&(l="active");let f=new Date().toISOString(),d=r[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:a.maxSequence,chunkCount:a.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:r.length>0?r[r.length-1].sequence:a.maxSequence,lastRemoteSequence:a.maxSequence,sourceCursors:n,updatedAt:f};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,y),{uploadedEvents:c,lastRemoteSequence:a.maxSequence,eventCount:y.eventCount,chunkCount:y.chunkCount,status:l}}};import{closeSync as Oe,existsSync as Xn,fsyncSync as Zn,mkdirSync as es,openSync as Pe,readSync as ts,rmSync as At,statSync as jt,writeSync as rs}from"node:fs";import{join as Te}from"node:path";var ns=12e4,ss=80,os=2e3;function is(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var fe=class{constructor(e){this.identity=e;es(e.localDirectory,{recursive:!0}),this.eventsFile=Te(e.localDirectory,"events.jsonl"),this.stateFile=Te(e.localDirectory,"state.json"),this.lockFile=Te(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 He(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){A(this.stateFile,e)}acquireLock(){for(let e=0;e<ss;e+=1)try{return Pe(this.lockFile,"wx",384)}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-jt(this.lockFile).mtimeMs>ns){At(this.lockFile,{force:!0});continue}}catch{}is(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let r=this.acquireLock();try{return e()}finally{Oe(r),At(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let r=this.loadStateUnsafe(),n=new Set(r.recentEventIds),s=r.lastSequence,o=[];for(let l of e){let f=l.timestamp??new Date().toISOString(),d=l.data??{},y=l.provenance?.rawDigest??k(Ve(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=k(h).slice(0,32);if(n.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),n.add(g)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
90
102
  `)+`
91
- `,u=Ie(this.eventsFile,"a",384);try{Xn(u,i,null,"utf8"),Gn(u)}finally{Ee(u)}let c=o[o.length-1],a="active";c.type==="session_end"||c.type==="session_idle"?a="idle":c.type==="error"&&(a="error");let p=Array.from(n).slice(-ts);return this.saveStateUnsafe({...r,status:a,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:p}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Vn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let r=wt(this.eventsFile).size,n=Math.min(e.remoteByteOffset,r);if(r<=n)return{events:[],startOffset:n,endOffset:r};let s=r-n,o=Buffer.alloc(s),i=Ie(this.eventsFile,"r");try{Qn(i,o,0,s,n)}finally{Ee(i)}return{events:o.toString("utf8").split(`
92
- `).filter(Boolean).map(a=>JSON.parse(a)),startOffset:n,endOffset:r}})}markRemote(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,lastRemoteSequence:Math.max(n.lastRemoteSequence,e),remoteByteOffset:Math.max(n.remoteByteOffset,r),updatedAt:new Date().toISOString()})})}setSourceCursor(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,sourceCursors:{...n.sourceCursors,[e]:String(r)},updatedAt:new Date().toISOString()})})}};import{closeSync as Ss,existsSync as vs,openSync as ks,readSync as bs,statSync as ws}from"node:fs";function xt(t,e){let r=e.toLowerCase();return r.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||r.includes("tuy\u1EC7t \u0111\u1ED1i")||r.includes("must not")||r.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||r.includes("error")||r.includes("failed")||r.includes("exception")?"normal":"temporary"}var jt=[/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],ns=[/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],ss=[/\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],os=[/\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],is=[/đã 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],At=[/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],as=[/\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],cs=[/đườ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],us=[/\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],Et=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ls=new Set(["payload","data","content","message","messages","parts","summary"]);function I(t,e){return e.some(r=>r.test(t))}function Ot(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ds(t){return Ot(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function ps(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 Oe(t,e,r,n=0){if(!(n>6)){if(typeof t=="string"){(!e||Et.has(e))&&r.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))Oe(s,e,r,n+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Et.has(s)||ls.has(s))&&Oe(o,s,r,n+1)}}function fs(t){let e=[];Oe(t.data,void 0,e);let r=[],n=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=Ot(o);if(ps(i)&&!n.has(i)&&(n.add(i),r.push(i),r.length>=50))return r}return r}function It(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function ms(t,e,r){if(r.type==="decision")return{kind:"decision",confidence:1};if(r.type==="todo")return{kind:"todo",confidence:1};let n=e==="user"||r.type==="user_prompt",s=e==="assistant"||r.type==="assistant_message";return n&&I(t,jt)?{kind:"rule",confidence:.98}:n&&I(t,ns)?{kind:"rule",confidence:.92}:I(t,ss)?{kind:I(t,At)?"architecture":"decision",confidence:n?.93:.86}:n&&I(t,os)?{kind:"todo",confidence:.87}:I(t,At)&&I(t,as)?{kind:"architecture",confidence:n?.88:.82}:s&&I(t,is)?{kind:"fix",confidence:.8}:n&&I(t,cs)&&I(t,us)?{kind:"context",confidence:.79}:null}function gs(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function hs(t,e,r){return t==="rule"&&I(r,jt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":xt(e,r)}function Pt(t,e){let r=[],n=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,u=It(o);i&&u&&s.set(i,u)}for(let o of e){let i=It(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let c of fs(o)){let a=ms(c,i,o);if(!a||a.confidence<.75)continue;let p=gs(a.kind),l=ds(c),f=v([t.projectId,a.kind,l].join("|"));if(n.has(f))continue;n.add(f);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],y=o.sourceEventId?[o.sourceEventId]:[];r.push({version:1,fingerprint:f,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:a.kind,type:p,content:c,confidence:a.confidence,importance:hs(a.kind,p,c),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 r}function Tt(t){return String(t).padStart(12,"0")}function ys(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var fe=class{constructor(e){this.storage=e}storage;async write(e,r,n){if(n.length===0||r.length===0)return null;let s=Math.min(...r.map(p=>p.sequence)),o=Math.max(...r.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:n.length,candidates:n},u=JSON.stringify(i,null,2)+`
93
- `,c=v(n.map(p=>p.fingerprint).sort().join("|")).slice(0,16),a=[ys(e),"batches",`${Tt(s)}-${Tt(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,u,"application/json"),a}};function xs(t,e){if(!vs(t))return{events:[],nextOffset:e};let r=ws(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=ks(t,"r");try{bs(i,o,0,s,n)}finally{Ss(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
103
+ `,u=Pe(this.eventsFile,"a",384);try{rs(u,i,null,"utf8"),Zn(u)}finally{Oe(u)}let c=o[o.length-1],a="active";c.type==="session_end"||c.type==="session_idle"?a="idle":c.type==="error"&&(a="error");let p=Array.from(n).slice(-os);return this.saveStateUnsafe({...r,status:a,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:p}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Xn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let r=jt(this.eventsFile).size,n=Math.min(e.remoteByteOffset,r);if(r<=n)return{events:[],startOffset:n,endOffset:r};let s=r-n,o=Buffer.alloc(s),i=Pe(this.eventsFile,"r");try{ts(i,o,0,s,n)}finally{Oe(i)}return{events:o.toString("utf8").split(`
104
+ `).filter(Boolean).map(a=>JSON.parse(a)),startOffset:n,endOffset:r}})}markRemote(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,lastRemoteSequence:Math.max(n.lastRemoteSequence,e),remoteByteOffset:Math.max(n.remoteByteOffset,r),updatedAt:new Date().toISOString()})})}setSourceCursor(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,sourceCursors:{...n.sourceCursors,[e]:String(r)},updatedAt:new Date().toISOString()})})}};import{closeSync as ws,existsSync as xs,openSync as As,readSync as js,statSync as Es}from"node:fs";function Et(t,e){let r=e.toLowerCase();return r.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||r.includes("tuy\u1EC7t \u0111\u1ED1i")||r.includes("must not")||r.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||r.includes("error")||r.includes("failed")||r.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],as=[/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],cs=[/\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],us=[/\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],ls=[/đã 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],It=[/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],ds=[/\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],ps=[/đườ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],fs=[/\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],Ot=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ms=new Set(["payload","data","content","message","messages","parts","summary"]);function E(t,e){return e.some(r=>r.test(t))}function _t(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function gs(t){return _t(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function hs(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 _e(t,e,r,n=0){if(!(n>6)){if(typeof t=="string"){(!e||Ot.has(e))&&r.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))_e(s,e,r,n+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Ot.has(s)||ms.has(s))&&_e(o,s,r,n+1)}}function ys(t){let e=[];_e(t.data,void 0,e);let r=[],n=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=_t(o);if(hs(i)&&!n.has(i)&&(n.add(i),r.push(i),r.length>=50))return r}return r}function Pt(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Ss(t,e,r){if(r.type==="decision")return{kind:"decision",confidence:1};if(r.type==="todo")return{kind:"todo",confidence:1};let n=e==="user"||r.type==="user_prompt",s=e==="assistant"||r.type==="assistant_message";return n&&E(t,Tt)?{kind:"rule",confidence:.98}:n&&E(t,as)?{kind:"rule",confidence:.92}:E(t,cs)?{kind:E(t,It)?"architecture":"decision",confidence:n?.93:.86}:n&&E(t,us)?{kind:"todo",confidence:.87}:E(t,It)&&E(t,ds)?{kind:"architecture",confidence:n?.88:.82}:s&&E(t,ls)?{kind:"fix",confidence:.8}:n&&E(t,ps)&&E(t,fs)?{kind:"context",confidence:.79}:null}function ks(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function vs(t,e,r){return t==="rule"&&E(r,Tt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Et(e,r)}function Mt(t,e){let r=[],n=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,u=Pt(o);i&&u&&s.set(i,u)}for(let o of e){let i=Pt(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let c of ys(o)){let a=Ss(c,i,o);if(!a||a.confidence<.75)continue;let p=ks(a.kind),l=gs(c),f=k([t.projectId,a.kind,l].join("|"));if(n.has(f))continue;n.add(f);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],y=o.sourceEventId?[o.sourceEventId]:[];r.push({version:1,fingerprint:f,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:a.kind,type:p,content:c,confidence:a.confidence,importance:vs(a.kind,p,c),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 r}function Nt(t){return String(t).padStart(12,"0")}function bs(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var me=class{constructor(e){this.storage=e}storage;async write(e,r,n){if(n.length===0||r.length===0)return null;let s=Math.min(...r.map(p=>p.sequence)),o=Math.max(...r.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:n.length,candidates:n},u=JSON.stringify(i,null,2)+`
105
+ `,c=k(n.map(p=>p.fingerprint).sort().join("|")).slice(0,16),a=[bs(e),"batches",`${Nt(s)}-${Nt(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,u,"application/json"),a}};function Is(t,e){if(!xs(t))return{events:[],nextOffset:e};let r=Es(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=As(t,"r");try{js(i,o,0,s,n)}finally{ws(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
94
106
  `);if(c<0)return{events:[],nextOffset:n};let a=u.slice(0,c+1);return{events:a.split(`
95
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var me=class{constructor(e){this.options=e;this.journal=new fe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["memory.learner.offset"]??0),n=Number.isFinite(r)?r:0,s=xs(this.options.wal.eventsFile,n);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Pt(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}}};var ge=class{identity;wal;remote;sanitizer=new U;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=vt(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new pe(this.identity),this.remote=new de(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new me({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new ne({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 ie({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let r=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:r}}start(e={}){let r=this.wal.loadState();return this.record({type:r.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(r=>this.sanitizeEvent(r)))}setSourceCursor(e,r){this.wal.setSourceCursor(e,r)}async flush(){let e=this.wal.readPending(),r=this.wal.loadState(),n=await this.remote.append(this.identity,e.events,r.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 n}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 As,openSync as Es,closeSync as Is,readSync as js,statSync as Os}from"node:fs";function Ps(t){let e=typeof t.role=="string"?t.role:"",r=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||r.includes("user")?"user_prompt":e==="assistant"||r.includes("assistant")||r.includes("model")?"assistant_message":r.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":r.includes("error")?"error":"message"}function Ts(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let r of e){if(typeof r=="string"){let n=new Date(r);if(!Number.isNaN(n.getTime()))return n.toISOString()}if(typeof r=="number"){let n=r;n<1e11&&(n*=1e3);let s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function _t(t,e={offset:0}){if(!As(t))return{events:[],nextOffset:e.offset,reset:!1};let r=Os(t).size,n=e.offset>r,s=n?0:e.offset;if(s===r)return{events:[],nextOffset:r,reset:n};let o=r-s,i=Buffer.alloc(o),u=Es(t,"r");try{js(u,i,0,o,s)}finally{Is(u)}let c=i.toString("utf8"),a=c.lastIndexOf(`
107
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var ge=class{constructor(e){this.options=e;this.journal=new me(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["memory.learner.offset"]??0),n=Number.isFinite(r)?r:0,s=Is(this.options.wal.eventsFile,n);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Mt(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}}};var he=class{identity;wal;remote;sanitizer=new z;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=wt(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new fe(this.identity),this.remote=new pe(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new ge({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new se({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new ue({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new ae({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let r=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:r}}start(e={}){let r=this.wal.loadState();return this.record({type:r.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(r=>this.sanitizeEvent(r)))}setSourceCursor(e,r){this.wal.setSourceCursor(e,r)}async flush(){let e=this.wal.readPending(),r=this.wal.loadState(),n=await this.remote.append(this.identity,e.events,r.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 n}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 Os,openSync as Ps,closeSync as Ts,readSync as _s,statSync as Ms}from"node:fs";function Ns(t){let e=typeof t.role=="string"?t.role:"",r=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||r.includes("user")?"user_prompt":e==="assistant"||r.includes("assistant")||r.includes("model")?"assistant_message":r.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":r.includes("error")?"error":"message"}function Rs(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let r of e){if(typeof r=="string"){let n=new Date(r);if(!Number.isNaN(n.getTime()))return n.toISOString()}if(typeof r=="number"){let n=r;n<1e11&&(n*=1e3);let s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function Rt(t,e={offset:0}){if(!Os(t))return{events:[],nextOffset:e.offset,reset:!1};let r=Ms(t).size,n=e.offset>r,s=n?0:e.offset;if(s===r)return{events:[],nextOffset:r,reset:n};let o=r-s,i=Buffer.alloc(o),u=Ps(t,"r");try{_s(u,i,0,o,s)}finally{Ts(u)}let c=i.toString("utf8"),a=c.lastIndexOf(`
96
108
  `);if(a<0)return{events:[],nextOffset:s,reset:n};let p=c.slice(0,a+1),l=Buffer.byteLength(p,"utf8"),f=[],d=0;for(let y of p.split(`
97
109
  `)){if(!y)continue;let h=Buffer.byteLength(y+`
98
- `,"utf8"),g=s+d;d+=h;let S;try{S=JSON.parse(y)}catch{f.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:y},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}});continue}let b=S&&typeof S=="object"&&!Array.isArray(S)?S:{value:S};f.push({type:Ps(b),timestamp:Ts(b),role:typeof b.role=="string"?b.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:b,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}})}return{events:f,nextOffset:s+l,reset:n}}var _s=[/^<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*$/],Ms=[/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],Ns=["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 Rs(t){let e=t.toLowerCase();return Ns.some(r=>e.includes(r))}function Cs(t){if(!t.trim())return!0;for(let e of _s)if(e.test(t))return!0;return Rs(t),!1}function Ls(t){let e=t;for(let r of Ms)e=e.replace(r,n=>{let s=n.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function Pe(t){let e=t.trim();return e?Cs(e)?{content:"",filtered:!0,reason:"noise"}:{content:Ls(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function he(t){let e={};for(let[r,n]of Object.entries(t))if(typeof n=="string"){let s=Pe(n);s.filtered||(e[r]=s.content)}else n&&typeof n=="object"&&!Array.isArray(n)?e[r]=he(n):Array.isArray(n)?e[r]=n.map(s=>{if(typeof s=="string"){let o=Pe(s);return o.filtered?null:o.content}return s&&typeof s=="object"?he(s):s}).filter(s=>s!==null):e[r]=n;return e}function Mt(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 r=t.data,n=typeof r.content=="string"?r.content:"";if(n&&Pe(n).filtered)return!0}return!1}function N(){let t=J(),e=process.env.TOOLNET_SESSION_SAVE||"summary",r=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",n=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),u=r,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:r,memoryPromotion:n,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:u,archiveRemote:c}}function Nt(t){return(t||N()).rawTranscript}function Rt(t){return(t||N()).durableMemoryMaxItemsPerSession}function Ct(t){return(t||N()).sessionSummaryMaxTokens}function Lt(t){return(t||N()).archiveRemote}function $s(t){return t.replace(/\b[A-Za-z0-9_-]{20,}\b/g,"[REDACTED]").replace(/api[_-]?key[:\s=]+[^\s]+/gi,"api_key=[REDACTED]").replace(/token[:\s=]+[^\s]+/gi,"token=[REDACTED]").replace(/secret[:\s=]+[^\s]+/gi,"secret=[REDACTED]").replace(/password[:\s=]+[^\s]+/gi,"password=[REDACTED]")}function Ds(t,e){let r=t.toLowerCase(),n=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)r.includes(i)&&(n+=.15);e==="rule"||e==="architecture"||e==="blocker"?n+=.2:e==="decision"||e==="deploy"?n+=.15:(e==="fix"||e==="next_action")&&(n+=.1),t.length<20?n-=.3:t.length>500&&(n-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(n-=.4);return Math.max(0,Math.min(1,n))}function Fs(t,e){let r=[],n=new Set;for(let i of t){let u=i.split(`
99
- `).filter(c=>c.trim());for(let c of u){let a=c.trim();if(a.length<15)continue;let p=a.toLowerCase().replace(/\s+/g," ");if(n.has(p))continue;n.add(p);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(l="file");let f=Ds(a,l);if(f<.3)continue;let d=$s(a);r.push({category:l,text:d,importance:f,sourceSessionId:e})}}let s=N(),o=Rt(s);return r.sort((i,u)=>u.importance-i.importance).slice(0,o)}function Ks(t){let e=N(),r=Ct(e),o=t.join(`
110
+ `,"utf8"),g=s+d;d+=h;let S;try{S=JSON.parse(y)}catch{f.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:y},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}});continue}let b=S&&typeof S=="object"&&!Array.isArray(S)?S:{value:S};f.push({type:Ns(b),timestamp:Rs(b),role:typeof b.role=="string"?b.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:b,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}})}return{events:f,nextOffset:s+l,reset:n}}var Cs=[/^<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*$/],Ls=[/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],$s=["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 Ds(t){let e=t.toLowerCase();return $s.some(r=>e.includes(r))}function Fs(t){if(!t.trim())return!0;for(let e of Cs)if(e.test(t))return!0;return Ds(t),!1}function Ks(t){let e=t;for(let r of Ls)e=e.replace(r,n=>{let s=n.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function Me(t){let e=t.trim();return e?Fs(e)?{content:"",filtered:!0,reason:"noise"}:{content:Ks(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function ye(t){let e={};for(let[r,n]of Object.entries(t))if(typeof n=="string"){let s=Me(n);s.filtered||(e[r]=s.content)}else n&&typeof n=="object"&&!Array.isArray(n)?e[r]=ye(n):Array.isArray(n)?e[r]=n.map(s=>{if(typeof s=="string"){let o=Me(s);return o.filtered?null:o.content}return s&&typeof s=="object"?ye(s):s}).filter(s=>s!==null):e[r]=n;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 r=t.data,n=typeof r.content=="string"?r.content:"";if(n&&Me(n).filtered)return!0}return!1}function R(){let t=H(),e=process.env.TOOLNET_SESSION_SAVE||"summary",r=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",n=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),u=r,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:r,memoryPromotion:n,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:u,archiveRemote:c}}function Lt(t){return(t||R()).rawTranscript}function $t(t){return(t||R()).durableMemoryMaxItemsPerSession}function Dt(t){return(t||R()).sessionSummaryMaxTokens}function Ft(t){return(t||R()).archiveRemote}function Bs(t){return t.replace(/\b[A-Za-z0-9_-]{20,}\b/g,"[REDACTED]").replace(/api[_-]?key[:\s=]+[^\s]+/gi,"api_key=[REDACTED]").replace(/token[:\s=]+[^\s]+/gi,"token=[REDACTED]").replace(/secret[:\s=]+[^\s]+/gi,"secret=[REDACTED]").replace(/password[:\s=]+[^\s]+/gi,"password=[REDACTED]")}function Us(t,e){let r=t.toLowerCase(),n=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)r.includes(i)&&(n+=.15);e==="rule"||e==="architecture"||e==="blocker"?n+=.2:e==="decision"||e==="deploy"?n+=.15:(e==="fix"||e==="next_action")&&(n+=.1),t.length<20?n-=.3:t.length>500&&(n-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(n-=.4);return Math.max(0,Math.min(1,n))}function Ws(t,e){let r=[],n=new Set;for(let i of t){let u=i.split(`
111
+ `).filter(c=>c.trim());for(let c of u){let a=c.trim();if(a.length<15)continue;let p=a.toLowerCase().replace(/\s+/g," ");if(n.has(p))continue;n.add(p);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(l="file");let f=Us(a,l);if(f<.3)continue;let d=Bs(a);r.push({category:l,text:d,importance:f,sourceSessionId:e})}}let s=R(),o=$t(s);return r.sort((i,u)=>u.importance-i.importance).slice(0,o)}function zs(t){let e=R(),r=Dt(e),o=t.join(`
100
112
 
101
113
  `).split(`
102
114
  `).filter(i=>{let u=i.trim();return u.length>20&&!u.startsWith("npm")&&!u.startsWith("\u2713")&&!u.startsWith("Error:")}).slice(0,20).join(`
103
- `);return le(o,r)}function $t(t,e){let n=(Array.isArray(t)?t:t.split(`
115
+ `);return de(o,r)}function Kt(t,e){let n=(Array.isArray(t)?t:t.split(`
104
116
 
105
- `).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),s=Fs(n,e),o=s.filter(d=>d.category==="decision").map(d=>d.text),i=s.filter(d=>d.category==="rule").map(d=>d.text),u=s.filter(d=>d.category==="file").map(d=>d.text),c=s.filter(d=>d.category==="fix").map(d=>d.text),a=s.filter(d=>d.category==="blocker").map(d=>d.text),p=s.filter(d=>d.category==="next_action").map(d=>d.text),l=s.filter(d=>d.category==="deploy").map(d=>d.text);return{summary:Ks(n),decisions:o,projectRules:i,filesChanged:u,bugsFixed:c,commands:l,blockers:a,nextActions:p,durableFacts:s}}function Ws(t){return t==="~"?Dt():t.startsWith("~/")?Bs(Dt(),t.slice(2)):t}async function Ft(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let r=Us(Ws(t.transcriptPath)),n=new ge({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:r,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=n.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,u=_t(r,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:r,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:r}}),u.reset&&c.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${u.nextOffset}`,data:{event:"transcript_reset",transcriptPath:r},provenance:{source:"agy-transcript",sourcePath:r}});let a=u.events.filter(f=>!Mt(f.data)).map(f=>({...f,data:he(f.data)}));c.push(...a),t.phase==="stop"&&(t.error&&c.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",u.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",e,"idle",u.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let p=n.recordMany(c);if(n.setSourceCursor("agy.transcript.offset",u.nextOffset),t.phase&&n.setSourceCursor("agy.last.phase",t.phase),t.phase==="stop"&&a.length>0)try{let f=a.map(y=>JSON.stringify(y.data)),d=$t(f,e);n.setSourceCursor("agy.session.summary",d.summary),n.setSourceCursor("agy.session.facts_count",d.durableFacts.length),Nt()&&(Lt()||n.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await n.flush();return{conversationId:e,imported:p.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:u.nextOffset,reset:u.reset}}async function zs(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}function q(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function qs(t){let e=typeof t.common=="object"&&t.common!==null?t.common:{},r=typeof t.pre_invocation_hook_args=="object"&&t.pre_invocation_hook_args!==null?t.pre_invocation_hook_args:{},n=typeof t.post_invocation_hook_args=="object"&&t.post_invocation_hook_args!==null?t.post_invocation_hook_args:{},s=typeof t.stop_hook_args=="object"&&t.stop_hook_args!==null?t.stop_hook_args:{},o=(typeof e.conversation_id=="string"?e.conversation_id:"")||(typeof t.conversationId=="string"?t.conversationId:"")||(typeof t.conversation_id=="string"?t.conversation_id:""),i=(typeof e.transcript_path=="string"?e.transcript_path:"")||(typeof t.transcriptPath=="string"?t.transcriptPath:"")||(typeof t.transcript_path=="string"?t.transcript_path:""),u=q(e.workspace_paths).length>0?q(e.workspace_paths):q(t.workspacePaths).length>0?q(t.workspacePaths):q(t.workspace_paths),c=typeof r.invocation_num=="number"?r.invocation_num:typeof t.invocationNum=="number"?t.invocationNum:typeof t.invocation_num=="number"?t.invocation_num:void 0,a=(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||(typeof t.artifactDirectoryPath=="string"?t.artifactDirectoryPath:"")||(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||void 0,p=(typeof e.model_name=="string"?e.model_name:"")||(typeof t.modelName=="string"?t.modelName:"")||(typeof t.model_name=="string"?t.model_name:"")||void 0,l=s.fully_idle===!0||t.fullyIdle===!0||t.fully_idle===!0,f=(typeof s.termination_reason=="string"?s.termination_reason:"")||(typeof t.terminationReason=="string"?t.terminationReason:"")||(typeof t.termination_reason=="string"?t.termination_reason:"")||void 0,d=(typeof s.error=="string"&&s.error?s.error:"")||(typeof t.error=="string"&&t.error?t.error:"")||void 0;return{conversationId:o,transcriptPath:i,workspacePaths:u,invocationNum:c,artifactDirectoryPath:a,modelName:p,fullyIdle:l,terminationReason:f,error:d}}async function Js(){let t=process.argv[2]??"post",e=await zs(),r=qs(e),n=r.conversationId,s=r.transcriptPath,o=r.workspacePaths,i=yt(o),u={};if(i&&n)try{let c=J(),a=Be(Fe({provider:c.storage.provider,huggingface:c.storage.huggingface,localRoot:c.storage.localRoot}),{attempts:2}),p=new X(a,i.id,i.name,i.remote??i.name);if(s)try{await Ft({project:i,storage:p,conversationId:n,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:r.artifactDirectoryPath,modelName:r.modelName,phase:t,fullyIdle:r.fullyIdle,terminationReason:r.terminationReason,error:r.error})}catch{}if(t==="pre")try{u=await gt({project:i,storage:p,conversationId:n,invocationNum:r.invocationNum})}catch{u={}}if(t==="stop")try{await Ae(i,p,800)}catch{}}catch{}if(t==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(u))}Js().catch(()=>{process.argv[2]==="stop"?process.stdout.write('{"decision":"stop"}'):process.stdout.write("{}"),process.exitCode=0});export{qs as normalizeAgyInput};
117
+ `).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),s=Ws(n,e),o=s.filter(d=>d.category==="decision").map(d=>d.text),i=s.filter(d=>d.category==="rule").map(d=>d.text),u=s.filter(d=>d.category==="file").map(d=>d.text),c=s.filter(d=>d.category==="fix").map(d=>d.text),a=s.filter(d=>d.category==="blocker").map(d=>d.text),p=s.filter(d=>d.category==="next_action").map(d=>d.text),l=s.filter(d=>d.category==="deploy").map(d=>d.text);return{summary:zs(n),decisions:o,projectRules:i,filesChanged:u,bugsFixed:c,commands:l,blockers:a,nextActions:p,durableFacts:s}}function Vs(t){return t==="~"?Bt():t.startsWith("~/")?qs(Bt(),t.slice(2)):t}async function Ut(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let r=Js(Vs(t.transcriptPath)),n=new he({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:r,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=n.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,u=Rt(r,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:r,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:r}}),u.reset&&c.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${u.nextOffset}`,data:{event:"transcript_reset",transcriptPath:r},provenance:{source:"agy-transcript",sourcePath:r}});let a=u.events.filter(f=>!Ct(f.data)).map(f=>({...f,data:ye(f.data)}));c.push(...a),t.phase==="stop"&&(t.error&&c.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",u.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",e,"idle",u.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let p=n.recordMany(c);if(n.setSourceCursor("agy.transcript.offset",u.nextOffset),t.phase&&n.setSourceCursor("agy.last.phase",t.phase),t.phase==="stop"&&a.length>0)try{let f=a.map(y=>JSON.stringify(y.data)),d=Kt(f,e);n.setSourceCursor("agy.session.summary",d.summary),n.setSourceCursor("agy.session.facts_count",d.durableFacts.length),Lt()&&(Ft()||n.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await n.flush();return{conversationId:e,imported:p.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:u.nextOffset,reset:u.reset}}async function Hs(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}function V(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function Gs(t){let e=typeof t.common=="object"&&t.common!==null?t.common:{},r=typeof t.pre_invocation_hook_args=="object"&&t.pre_invocation_hook_args!==null?t.pre_invocation_hook_args:{},n=typeof t.post_invocation_hook_args=="object"&&t.post_invocation_hook_args!==null?t.post_invocation_hook_args:{},s=typeof t.stop_hook_args=="object"&&t.stop_hook_args!==null?t.stop_hook_args:{},o=(typeof e.conversation_id=="string"?e.conversation_id:"")||(typeof t.conversationId=="string"?t.conversationId:"")||(typeof t.conversation_id=="string"?t.conversation_id:""),i=(typeof e.transcript_path=="string"?e.transcript_path:"")||(typeof t.transcriptPath=="string"?t.transcriptPath:"")||(typeof t.transcript_path=="string"?t.transcript_path:""),u=V(e.workspace_paths).length>0?V(e.workspace_paths):V(t.workspacePaths).length>0?V(t.workspacePaths):V(t.workspace_paths),c=typeof r.invocation_num=="number"?r.invocation_num:typeof t.invocationNum=="number"?t.invocationNum:typeof t.invocation_num=="number"?t.invocation_num:void 0,a=(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||(typeof t.artifactDirectoryPath=="string"?t.artifactDirectoryPath:"")||(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||void 0,p=(typeof e.model_name=="string"?e.model_name:"")||(typeof t.modelName=="string"?t.modelName:"")||(typeof t.model_name=="string"?t.model_name:"")||void 0,l=s.fully_idle===!0||t.fullyIdle===!0||t.fully_idle===!0,f=(typeof s.termination_reason=="string"?s.termination_reason:"")||(typeof t.terminationReason=="string"?t.terminationReason:"")||(typeof t.termination_reason=="string"?t.termination_reason:"")||void 0,d=(typeof s.error=="string"&&s.error?s.error:"")||(typeof t.error=="string"&&t.error?t.error:"")||void 0;return{conversationId:o,transcriptPath:i,workspacePaths:u,invocationNum:c,artifactDirectoryPath:a,modelName:p,fullyIdle:l,terminationReason:f,error:d}}function Ys(t){let e=typeof t.toolCall=="object"&&t.toolCall!==null?t.toolCall:{},r=typeof e.args=="object"&&e.args!==null?e.args:{},n="";try{n=JSON.stringify(r).replace(/\\\\/g,"/").toLowerCase()}catch{n=""}return n.includes(".toolnet/sessions")?{decision:"deny",reason:"ToolNet continuity guard: do not replay raw .toolnet/sessions history. Use the injected continuity handoff. If deeper history is required, invoke memory_agent_ask directly."}:{decision:"allow"}}async function Qs(){let t=process.argv[2]??"post",e=await Hs();if(t==="pre-tool"){process.stdout.write(JSON.stringify(Ys(e)));return}let r=Gs(e),n=r.conversationId,s=r.transcriptPath,o=r.workspacePaths,i=vt(o),u={};if(i&&n)try{let c=H(),a=ze(Ue({provider:c.storage.provider,huggingface:c.storage.huggingface,localRoot:c.storage.localRoot}),{attempts:2}),p=new ee(a,i.id,i.name,i.remote??i.name);if(s)try{await Ut({project:i,storage:p,conversationId:n,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:r.artifactDirectoryPath,modelName:r.modelName,phase:t,fullyIdle:r.fullyIdle,terminationReason:r.terminationReason,error:r.error})}catch{}if(t==="pre")try{u=await St({project:i,storage:p,conversationId:n,invocationNum:r.invocationNum})}catch{u={}}if(t==="stop")try{await je(i,p,800)}catch{}}catch{}if(t==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(u))}Qs().catch(()=>{process.argv[2]==="stop"?process.stdout.write('{"decision":"stop"}'):process.argv[2]==="pre-tool"?process.stdout.write('{"decision":"allow"}'):process.stdout.write("{}"),process.exitCode=0});export{Ys as buildAgyPreToolUseOutput,Gs as normalizeAgyInput};