toolnet-memory 0.3.3 → 0.3.4

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 kr,readFileSync as Sr}from"node:fs";import{homedir as vr}from"node:os";import{join as wr}from"node:path";function br(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 xr(){let t=process.env.TOOLNET_GLOBAL_ENV??wr(vr(),".config","toolnet-memory",".env");if(!kr(t))return;let e=Sr(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=br(r.slice(s+1)))}}xr();function Y(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function Q(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function pe(){return{memory:{autoCapture:Y(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:Y(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:Y(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:Y(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:Q(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Q(process.env.MEMORY_RERANK_TOP,10),finalContext:Q(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Q(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:Y(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:Q(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Ar}from"node:crypto";import{existsSync as qe,mkdirSync as Ir,readFileSync as jr,renameSync as Pr,writeFileSync as Er}from"node:fs";import{basename as Mr,dirname as fe,join as ge,parse as St,resolve as X}from"node:path";var vt=".toolnet",Cr="project.json";function Tr(t){return Ar("sha256").update(t).digest("hex").slice(0,16)}function Ve(t){return ge(t,vt,Cr)}function Or(t){return qe(Ve(t))}function _r(t,e){let n=X(t),r=St(n).root;for(;;){if(Or(n))return n;if(n===r||e&&n===X(e))break;let s=fe(n);if(s===n)break;n=s}return null}function Rr(t){let e=X(t),n=St(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>qe(ge(e,o))))return e;if(e===n)break;let s=fe(e);if(s===e)break;e=s}return X(t)}function Nr(t){let e;try{e=JSON.parse(jr(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:fe(fe(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function ht(t,e){let n=ge(t,vt);Ir(n,{recursive:!0});let r=Ve(t),s=`${r}.tmp-${process.pid}`;Er(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Pr(s,r)}function kt(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 me=class{detect(e=process.cwd()){let n=X(e),r=Rr(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>qe(ge(r,p))),i=_r(n,o?r:void 0);if(i){let p=Ve(i),l=Nr(p);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),ht(i,l)),kt(l,i)}let a=new Date().toISOString(),c=Mr(r),u={version:1,id:Tr(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return ht(r,u),kt(u,r)}};var Lr=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],ye=class{scan(e){let n=[];for(let r of Lr){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var Z=class{scanner=new ye;sanitize(e){let n=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as os}from"node:os";import{join as is}from"node:path";import{DeleteObjectCommand as $r,GetObjectCommand as Kr,HeadObjectCommand as Dr,ListObjectsV2Command as Fr,PutObjectCommand as Wr,S3Client as Br}from"@aws-sdk/client-s3";import{getSignedUrl as zr}from"@aws-sdk/s3-request-presigner";var he=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Br({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Wr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await zr(this.client,new Kr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Dr({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new $r({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Fr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as wt,mkdir as Ur,readFile as qr,readdir as Vr,rm as Gr,stat as bt,writeFile as Hr}from"node:fs/promises";import{dirname as Jr,join as Yr,relative as xt,resolve as Qr}from"node:path";var ee=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Qr(this.root,n)}async put(e,n){let r=this.path(e);await Ur(Jr(r),{recursive:!0}),await Hr(r,n)}async get(e){try{return await qr(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await wt(this.path(e)),!0}catch{return!1}}async delete(e){await Gr(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await wt(n)}catch{return r}let s=async i=>{let a=await Vr(i,{withFileTypes:!0});for(let c of a){let u=Yr(i,c.name);if(c.isDirectory()){await s(u);continue}let p=await bt(u);r.push({key:xt(this.root,u),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await bt(n);return o.isDirectory()?await s(n):r.push({key:xt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Xr,GetObjectCommand as Zr,HeadObjectCommand as es,ListObjectsV2Command as ts,PutObjectCommand as ns,S3Client as rs}from"@aws-sdk/client-s3";import{getSignedUrl as ss}from"@aws-sdk/s3-request-presigner";var te=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new rs({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ns({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await ss(this.client,new Zr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new es({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Xr({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new ts({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function Ge(t,e){return console.warn(e),new ee(t)}function At(t){let e=t.localRoot??is(os(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new te({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ge(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new te({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ge(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new he({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ge(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ee(e)}function as(t){return new Promise(e=>setTimeout(e,t))}async function It(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await as(c+u)}throw o}var cs=new Set(["put","get","getText","delete","list"]);function jt(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:cs.has(r)?(...o)=>It(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Pt(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 Et(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var ke=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Pt(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Et(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{createHash as us}from"node:crypto";import{dirname as ls}from"node:path";import{mkdirSync as ds,readFileSync as ps,renameSync as fs,writeFileSync as ms}from"node:fs";function S(t){return us("sha256").update(t).digest("hex")}function He(t){if(Array.isArray(t))return t.map(He);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=He(e[r]);return n}return t}function Mt(t){return JSON.stringify(He(t))}function Ct(t){try{return JSON.parse(ps(t,"utf8"))}catch{return null}}function j(t,e){ds(ls(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;ms(n,JSON.stringify(e,null,2)+`
5
- `,{encoding:"utf8",mode:384}),fs(n,t)}var gs=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function q(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Ot(t){return q(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function U(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))U(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(gs.has(r)||["data","payload","parts","messages"].includes(r))&&U(s,e,n+1)}}function Se(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 Tt(t){let e=q(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function I(t,e,n,r,s={}){let o=q(r),i=s.key??Ot(o);return{version:1,id:S([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function ys(t,e,n){let r=q(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(I(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(I(t,e,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let f=Number(u[1]),d=q(u[2]??""),m=d&&!Tt(d)?`Phase ${f} - ${d}`:`Phase ${f}`;s.push(I(t,e,"phase",m,{key:`phase:${f}`,order:f,status:Se(r),confidence:.93}))}let p=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&s.push(I(t,e,"task",p[2],{status:p[1].trim()?"completed":Se(p[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let f=l[1]?Number(l[1]):void 0,d=q(l[2]),m=Tt(d);s.push(I(t,e,"task",m&&f!==void 0?`TODO ${f}`:d,{key:f!==void 0?`task:${f}`:Ot(d),order:f,status:Se(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let f=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");f&&s.push(I(t,e,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(I(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(I(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(I(t,e,"decision",r,{confidence:.9})),s}function _t(t,e){if(e.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of e){if(i.type==="decision"){let c=[];U(i.data,c);for(let u of c)s(I(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];U(i.data,c);for(let u of c)s(I(t,i,"task",u,{status:Se(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(I(t,i,"file",u,{confidence:1}))}if(i.type==="test"){let c=[];U(i.data,c);for(let u of c)s(I(t,i,"test",u,{confidence:1}))}let a=[];U(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let p of ys(t,i,u))s(p)}let o=e[e.length-1];return s(I(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Rt(t){return String(t).padStart(12,"0")}var ve=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
6
- `,a=S(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Rt(r)}-${Rt(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Nt}from"node:path";import{mkdirSync as hs}from"node:fs";function ks(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function V(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=ks(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function Ss(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Lt(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&Ss(e)?t.title:e.text;return{id:t?.id??S(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function vs(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function we(t,e){let r=(await vs(t,e)).flatMap(k=>k.observations).sort((k,x)=>{let de=k.occurredAt.localeCompare(x.occurredAt);if(de!==0)return de;let yt=k.sequence-x.sequence;return yt!==0?yt:k.id.localeCompare(x.id)}),s=new Map,o=new Map,i,a,c,u=[],p=[],l=[],f=[],d=[],m=[];for(let k of r)switch(k.kind){case"goal":i=k.text;break;case"plan":a=k.text;break;case"phase":s.set(k.key,Lt(s.get(k.key),k));break;case"task":o.set(k.key,Lt(o.get(k.key),k));break;case"decision":u.push(k.text);break;case"blocker":p.push(k.text);break;case"warning":l.push(k.text);break;case"next_action":f.push(k.text);break;case"file":d.push(k.text);break;case"test":m.push(k.text);break;case"session":c={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let h=Array.from(s.values()).sort((k,x)=>(k.order??Number.MAX_SAFE_INTEGER)-(x.order??Number.MAX_SAFE_INTEGER)),y=Array.from(o.values()).sort((k,x)=>(k.order??Number.MAX_SAFE_INTEGER)-(x.order??Number.MAX_SAFE_INTEGER)),g=h.find(k=>k.status==="in_progress")??h.find(k=>k.status==="blocked")??h.find(k=>k.status==="pending"),v=y.find(k=>k.status==="in_progress")??y.find(k=>k.status==="blocked")??y.find(k=>k.status==="pending"),P=V([...f,...v?[v.title]:[],...!v&&g?[g.title]:[],...y.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),T=V([...p,...h.filter(k=>k.status==="blocked").map(k=>k.title),...y.filter(k=>k.status==="blocked").map(k=>k.title)],20),A={version:1,projectId:t.id,projectName:t.name,goal:i,plan:a,phases:h,tasks:y,decisions:V(u,20),blockers:T,warnings:V(l,20),nextActions:P,filesTouched:V(d,30),tests:V(m,20),currentPhase:g,currentTask:v,progress:{phasesTotal:h.length,phasesCompleted:h.filter(k=>k.status==="completed").length,tasksTotal:y.length,tasksCompleted:y.filter(k=>k.status==="completed").length,blocked:h.filter(k=>k.status==="blocked").length+y.filter(k=>k.status==="blocked").length},lastSession:c,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},R=Nt(t.rootPath,".toolnet","work");return hs(R,{recursive:!0}),j(Nt(R,"current.json"),A),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(A,null,2)+`
7
- `,"application/json"),A}async function G(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{closeSync as ws,existsSync as bs,openSync as xs,readSync as As,statSync as Is}from"node:fs";function js(t,e){if(!bs(t))return{events:[],nextOffset:e};let n=Is(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=xs(t,"r");try{As(i,o,0,s,r)}finally{ws(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
8
- `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
9
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var be=class{constructor(e){this.options=e;this.journal=new ve(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=js(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=_t(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await we(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{mkdirSync as Ks}from"node:fs";import{join as Je}from"node:path";import{existsSync as Dt,mkdirSync as Ps,readFileSync as Es,statSync as $t,writeFileSync as Ms}from"node:fs";import{dirname as Cs,join as Ts}from"node:path";var Kt=64*1024,Os=`# ToolNet Project Operating Manual
1
+ import{existsSync as Lt,readFileSync as Dt}from"node:fs";import{homedir as Kt}from"node:os";import{join as Ft}from"node:path";function Wt(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 zt(){let t=process.env.TOOLNET_GLOBAL_ENV??Ft(Kt(),".config","toolnet-memory",".env");if(!Lt(t))return;let e=Dt(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]=Wt(n.slice(s+1)))}}zt();function K(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function F(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function V(){return{memory:{autoCapture:K(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:K(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:K(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:K(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:F(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:F(process.env.MEMORY_RERANK_TOP,10),finalContext:F(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:F(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:K(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:F(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Bt}from"node:crypto";import{existsSync as ye,mkdirSync as qt,readFileSync as Jt,renameSync as Vt,writeFileSync as Ut}from"node:fs";import{basename as Ht,dirname as U,join as Y,parse as Ne,resolve as W}from"node:path";var _e=".toolnet",Yt="project.json";function Gt(t){return Bt("sha256").update(t).digest("hex").slice(0,16)}function Se(t){return Y(t,_e,Yt)}function Qt(t){return ye(Se(t))}function Xt(t,e){let r=W(t),n=Ne(r).root;for(;;){if(Qt(r))return r;if(r===n||e&&r===W(e))break;let s=U(r);if(s===r)break;r=s}return null}function Zt(t){let e=W(t),r=Ne(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(o=>ye(Y(e,o))))return e;if(e===r)break;let s=U(e);if(s===e)break;e=s}return W(t)}function er(t){let e;try{e=JSON.parse(Jt(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:U(U(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 Re(t,e){let r=Y(t,_e);qt(r,{recursive:!0});let n=Se(t),s=`${n}.tmp-${process.pid}`;Ut(s,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),Vt(s,n)}function Ce(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 H=class{detect(e=process.cwd()){let r=W(e),n=Zt(r),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>ye(Y(n,d))),i=Xt(r,o?n:void 0);if(i){let d=Se(i),l=er(d);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Re(i,l)),Ce(l,i)}let u=new Date().toISOString(),c=Ht(n),a={version:1,id:Gt(n),name:c,remote:c,rootPath:n,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Re(n,a),Ce(a,n)}};var tr=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],G=class{scan(e){let r=[];for(let n of tr){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 G;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 xr}from"node:os";import{join as Ir}from"node:path";import{DeleteObjectCommand as rr,GetObjectCommand as nr,HeadObjectCommand as sr,ListObjectsV2Command as or,PutObjectCommand as ir,S3Client as ar}from"@aws-sdk/client-s3";import{getSignedUrl as cr}from"@aws-sdk/s3-request-presigner";var Q=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new ar({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 ir({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await cr(this.client,new nr({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 sr({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 rr({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new or({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 $e,mkdir as ur,readFile as lr,readdir as pr,rm as dr,stat as Le,writeFile as fr}from"node:fs/promises";import{dirname as mr,join as gr,relative as De,resolve as hr}from"node:path";var B=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return hr(this.root,r)}async put(e,r){let n=this.path(e);await ur(mr(n),{recursive:!0}),await fr(n,r)}async get(e){try{return await lr(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 $e(this.path(e)),!0}catch{return!1}}async delete(e){await dr(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),n=[];try{await $e(r)}catch{return n}let s=async i=>{let u=await pr(i,{withFileTypes:!0});for(let c of u){let a=gr(i,c.name);if(c.isDirectory()){await s(a);continue}let d=await Le(a);n.push({key:De(this.root,a),size:d.size,updatedAt:d.mtime.toISOString()})}},o=await Le(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 yr,GetObjectCommand as Sr,HeadObjectCommand as vr,ListObjectsV2Command as br,PutObjectCommand as kr,S3Client as wr}from"@aws-sdk/client-s3";import{getSignedUrl as jr}from"@aws-sdk/s3-request-presigner";var q=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new wr({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 kr({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await jr(this.client,new Sr({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 vr({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 yr({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new br({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 B(t)}function Ke(t){let e=t.localRoot??Ir(xr(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new q({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 q({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 B(e)}function Pr(t){return new Promise(e=>setTimeout(e,t))}async function Fe(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 Or=new Set(["put","get","getText","delete","list"]);function We(t,e={}){return new Proxy(t,{get(r,n){let s=Reflect.get(r,n,r);return typeof s!="function"?s:Or.has(n)?(...o)=>Fe(()=>Promise.resolve(s.apply(r,o)),e):s.bind(r)}})}function ze(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 Be(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=ze(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=Be(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 Er}from"node:crypto";import{dirname as Ar}from"node:path";import{mkdirSync as Tr,readFileSync as Mr,renameSync as Rr,writeFileSync as Cr}from"node:fs";function v(t){return Er("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 qe(t){return JSON.stringify(be(t))}function Je(t){try{return JSON.parse(Mr(t,"utf8"))}catch{return null}}function x(t,e){Tr(Ar(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;Cr(r,JSON.stringify(e,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),Rr(r,t)}var Nr=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 Ue(t){return $(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(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))_(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(Nr.has(n)||["data","payload","parts","messages"].includes(n))&&_(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 Ve(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??Ue(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 _r(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]),p=$(a[2]??""),y=p&&!Ve(p)?`Phase ${f} - ${p}`:`Phase ${f}`;s.push(w(t,e,"phase",y,{key:`phase:${f}`,order:f,status:Z(n),confidence:.93}))}let d=r.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);d?.[2]&&s.push(w(t,e,"task",d[2],{status:d[1].trim()?"completed":Z(d[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,p=$(l[2]),y=Ve(p);s.push(w(t,e,"task",y&&f!==void 0?`TODO ${f}`:p,{key:f!==void 0?`task:${f}`:Ue(p),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 He(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=[];_(i.data,c);for(let a of c)s(w(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let 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=[];_(i.data,c);for(let a of c)s(w(t,i,"test",a,{confidence:1}))}let u=[];_(i.data,u);for(let c of u)for(let a of c.split(/\n+/u))for(let d of _r(t,i,a))s(d)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),r}function Ye(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,`${Ye(n)}-${Ye(s)}-${u}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Ge}from"node:path";import{mkdirSync as $r}from"node:fs";function Lr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(t,e=20){let r=[],n=new Set;for(let s of t.slice().reverse()){let o=Lr(s);if(!(!o||n.has(o))&&(n.add(o),r.push(s),r.length>=e))break}return r.reverse()}function Dr(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&&Dr(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 Kr(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 Kr(t,e)).flatMap(m=>m.observations).sort((m,j)=>{let Te=m.occurredAt.localeCompare(j.occurredAt);if(Te!==0)return Te;let Me=m.sequence-j.sequence;return Me!==0?Me:m.id.localeCompare(j.id)}),s=new Map,o=new Map,i,u,c,a=[],d=[],l=[],f=[],p=[],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":d.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":f.push(m.text);break;case"file":p.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,j)=>(m.order??Number.MAX_SAFE_INTEGER)-(j.order??Number.MAX_SAFE_INTEGER)),g=Array.from(o.values()).sort((m,j)=>(m.order??Number.MAX_SAFE_INTEGER)-(j.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"),k=g.find(m=>m.status==="in_progress")??g.find(m=>m.status==="blocked")??g.find(m=>m.status==="pending"),M=L([...f,...k?[k.title]:[],...!k&&S?[S.title]:[],...g.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),N=L([...d,...h.filter(m=>m.status==="blocked").map(m=>m.title),...g.filter(m=>m.status==="blocked").map(m=>m.title)],20),E={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:g,decisions:L(a,20),blockers:N,warnings:L(l,20),nextActions:M,filesTouched:L(p,30),tests:L(y,20),currentPhase:S,currentTask:k,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()},R=Ge(t.rootPath,".toolnet","work");return $r(R,{recursive:!0}),x(Ge(R,"current.json"),E),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(E,null,2)+`
7
+ `,"application/json"),E}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 Fr,existsSync as Wr,openSync as zr,readSync as Br,statSync as qr}from"node:fs";function Jr(t,e){if(!Wr(t))return{events:[],nextOffset:e};let r=qr(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=zr(t,"r");try{Br(i,o,0,s,n)}finally{Fr(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
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=Jr(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=He(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 tn}from"node:fs";import{join as ke}from"node:path";import{existsSync as et,mkdirSync as Vr,readFileSync as Ur,statSync as Xe,writeFileSync as Hr}from"node:fs";import{dirname as Yr,join as Gr}from"node:path";var Ze=64*1024,Qr=`# ToolNet Project Operating Manual
10
10
 
11
11
  This file contains persistent instructions for AI agents working on this project.
12
12
 
@@ -49,90 +49,41 @@ Things an AI agent should always remember.
49
49
  <!--
50
50
  - [advisory] Prefer small focused files.
51
51
  -->
52
- `;function xe(t){return Ts(t.rootPath,".toolnet","PROJECT.md")}function _s(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Rs(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=_s(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:S(a).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Ns(t){let e=xe(t);return Dt(e)||(Ps(Cs(e),{recursive:!0}),Ms(e,Os,{encoding:"utf8",mode:384})),e}function Ae(t,e=!1){let n=e?Ns(t):xe(t);if(!Dt(n))return null;if($t(n).size>Kt)throw new Error(`PROJECT.md exceeds ${Kt} bytes`);let s=Es(n,"utf8");return{path:n,content:s,digest:S(s),rules:Rs(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date($t(n).mtimeMs).toISOString()}}function E(t,e){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function Ft(t){if(t)return{id:t.id,title:t.title,status:t.status}}function Ls(t){let e=t.slice(-10).join(`
53
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(e)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(e)?"passing":"unknown"}function $s(t){return S(JSON.stringify(t))}function Wt(t){let{project:e,identity:n,state:r}=t,s=r.filesTouched.at(-1),o=r.phases.filter(g=>g.status==="completed").map(g=>g.title),i=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),a=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),c=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),u=E(r.nextActions,10),p=E([...c,...u],15),l=E(r.tests.slice().reverse(),10),f=E(r.filesTouched.slice().reverse(),20),d={schema:"toolnet.handoff.v2",version:2,project:{id:e.id,name:e.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:t.sequence,reason:t.reason},capturedAt:t.capturedAt??new Date().toISOString(),goal:r.goal,current:{phase:Ft(r.currentPhase),task:Ft(r.currentTask),file:s},completed:{phases:E(o,20),tasks:E(i,30)},remaining:{phases:E(a,20),tasks:E(c,30),todos:p},nextAction:u[0],blockers:E(r.blockers.slice().reverse(),10),decisions:E(r.decisions.slice().reverse(),10),files:{current:s,recent:f},tests:{status:Ls(r.tests),recent:l},attention:E(t.attention??[],20),progress:r.progress},{capturedAt:m,source:h,...y}=d;return{...d,stateDigest:$s(y)}}function Ds(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,n){let r=await G(this.options.project,this.options.storage);if(r||(r=await we(this.options.project,this.options.storage)),!Ds(r))return null;let s=Ae(this.options.project,!1),i=[...s?s.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...r.warnings].slice(0,20),a=Wt({project:this.options.project,identity:this.options.identity,state:r,reason:e,sequence:n,attention:i}),c=a.stateDigest,u=S([this.options.project.id,this.options.identity.sessionKey,c].join("|")).slice(0,24),p=new Date().toISOString(),l={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:p,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:n},goal:r.goal,plan:r.plan,progress:r.progress,currentPhase:r.currentPhase,currentTask:r.currentTask,incompletePhases:r.phases.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:r.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:i,filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:c,continuity:a},f=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(f)||await this.options.storage.put(f,JSON.stringify(l,null,2)+`
54
- `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(l,null,2)+`
55
- `,"application/json");let d=Je(this.options.project.rootPath,".toolnet","work","handoffs");return Ks(d,{recursive:!0}),j(Je(d,`${u}.json`),l),j(Je(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),l),l}};async function Bt(t,e){let n=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{mkdirSync as Fs}from"node:fs";import{join as zt}from"node:path";function Ws(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Bs(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function L(t,e){return Bs(e,t)?e:t}function $(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function zs(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function Us(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Ut(t,e){let r=(await zs(t,e)).flatMap(h=>h.observations).sort((h,y)=>{let g=h.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return g!==0?g:h.evidence.sessionKey===y.evidence.sessionKey?h.evidence.sequence-y.evidence.sequence:h.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,p=[],l=[],f=[];for(let h of r){let y=Ws(h);if(h.scope==="phase"&&h.scopeKey){let g=u.get(h.scopeKey)??Us(h);switch(h.kind){case"phase_objective":g.objective=L(g.objective,y);break;case"phase_why":g.why=L(g.why,y);break;case"phase_deliverable":g.deliverable=L(g.deliverable,y);break;case"acceptance_criterion":g.acceptanceCriteria.push(y);break;case"dependency":g.dependencies.push(y);break;case"open_question":g.openQuestions.push(y);break;case"constraint":g.constraints.push(y);break;case"note":g.notes.push(y);break}u.set(g.key,g);continue}switch(h.kind){case"mission":s=L(s,y);break;case"objective":o=L(o,y);break;case"why":i=L(i,y);break;case"desired_outcome":a=L(a,y);break;case"plan_rationale":c=L(c,y);break;case"open_question":p.push(y);break;case"constraint":l.push(y);break;case"note":f.push(y);break}}for(let h of u.values())h.acceptanceCriteria=$(h.acceptanceCriteria,20),h.dependencies=$(h.dependencies,15),h.openQuestions=$(h.openQuestions,15),h.constraints=$(h.constraints,15),h.notes=$(h.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((h,y)=>h.order-y.order),openQuestions:$(p,20),constraints:$(l,20),notes:$(f,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=zt(t.rootPath,".toolnet","work");return Fs(m,{recursive:!0}),j(zt(m,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
56
- `,"application/json"),d}async function qt(t,e){let n=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Ye(t){if(!t)return 0;let e=Array.from(t).length,n=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,n*1.3))}function w(t,e){let n=t.replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function qs(t){let e=[],n=!1;for(let r of t.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&e.push(w(s,280)),e.length>=16))break}return e}function Vs(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),a=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>o.startsWith(u));if(!a)continue;let c=s.slice(a.length).trim();c&&(a.includes("enforce")?e.push(c):n.push(c))}return{enforce:e,advisory:n}}function Gs(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
57
- `);if(Ye(s)<=e){n.push(r);continue}let o=Ye(n.join(`
58
- `)),i=Math.max(0,e-o);if(i>=16){let a=Math.floor(i*3.2),c=w(r,a);c&&n.push(c)}break}return n.join(`
59
- `).trim()}async function Vt(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=Ae(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=Vs(r),o=n?n.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=n?n.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,a=r?qs(r):[],c=await G(t.project,t.storage),u=await qt(t.project,t.storage),p=await Bt(t.project,t.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${t.project.name}`),l.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&l.push(`Full operating manual: ${xe(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${w(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${w(d,220)}`)}if(u&&(u.mission&&l.push("","MISSION",w(u.mission.value,420)),u.activeObjective&&l.push("","CURRENT OBJECTIVE",w(u.activeObjective.value,420)),u.why&&l.push("","WHY THIS WORK MATTERS",w(u.why.value,420)),u.desiredOutcome&&l.push("","DESIRED OUTCOME",w(u.desiredOutcome.value,420)),u.planRationale&&l.push("","WHY THIS APPROACH",w(u.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${w(c.goal,320)}`),c.plan&&l.push(`Plan: ${w(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&&u){let d=u.phases.find(m=>m.order===c.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${w(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${w(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${w(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(m=>w(m.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(m=>{l.push(`- ${w(m.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(m=>{l.push(`- ${w(m.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,m)=>{l.push(`${m+1}. ${w(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${w(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${w(d,260)}`)})),c.lastSession&&l.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${w(d.value,260)}`)})),p&&l.push(`Latest handoff: ${p.reason} / ${p.sourceSession.agent}`),a.length){l.push("","OPERATING NOTES");for(let d of a)l.push(`- ${d}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let f=Gs(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:f,estimatedTokens:Ye(f),maxTokens:e,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!p,generatedAt:new Date().toISOString()}}var Hs=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function H(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Qe(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))Qe(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Hs.has(r)||["data","payload","parts","messages"].includes(r))&&Qe(s,e,n+1)}}function M(t,e,n,r,s,o=.95){let i=H(r);return{version:1,id:S([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function O(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return H(t.slice(r.length+1))}return null}function Js(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Ys(t){return H(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Gt(t,e){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of e){let i=[];Qe(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let p of a.split(/\r?\n/u)){let l=H(p);if(!l){u=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:H(f[2]??"")},u=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:H(d[2]??"")},u=null;continue}let m=O(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){s(M(t,o,"mission",m,{type:"project"},.99)),u=null;continue}let h=O(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(M(t,o,c.type==="phase"?"phase_objective":"objective",h,c,.98)),u=null;continue}let y=O(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(M(t,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let g=O(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(g){s(M(t,o,"desired_outcome",g,{type:"project"},.98)),u=null;continue}let v=O(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(v){s(M(t,o,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let P=O(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(P){s(M(t,o,"phase_deliverable",P,c,.97)),u=null;continue}let T=O(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(T){s(M(t,o,"acceptance_criterion",T,c,.98)),u="acceptance_criterion";continue}let A=O(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(A){s(M(t,o,"dependency",A,c,.97)),u="dependency";continue}let R=O(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){s(M(t,o,"open_question",R,c,.95)),u="open_question";continue}let k=O(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(k){s(M(t,o,"constraint",k,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){u="constraint";continue}if(u&&Js(p)){s(M(t,o,u,Ys(p),c,.96));continue}u=null}}}return n}function Ht(t){return String(t).padStart(12,"0")}var je=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=S(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${Ht(r)}-${Ht(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
60
- `,"application/json"),a}};import{closeSync as Qs,existsSync as Xs,openSync as Zs,readSync as eo,statSync as to}from"node:fs";function no(t,e){if(!Xs(t))return{events:[],nextOffset:e};let n=to(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=Zs(t,"r");try{eo(o,s,0,s.length,r)}finally{Qs(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
61
- `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
62
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Pe=class{constructor(e){this.options=e;this.journal=new je(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=no(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Gt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ut(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as ro,mkdirSync as so,readFileSync as oo,writeFileSync as io}from"node:fs";import{dirname as ao,join as Jt}from"node:path";function Ee(t){return t?Math.ceil(t.length/3.5):0}function Me(t,e){if(!t)return"";if(Ee(t)<=e)return t;let r=Math.floor(e*3.5),s=t.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
63
- `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function Yt(t){return Jt(t.rootPath,".toolnet","context","startup.md")}function co(t){return Jt(t.rootPath,".toolnet","context","startup.json")}function Qt(t,e){let n=Yt(t);so(ao(n),{recursive:!0}),io(n,e.text.endsWith(`
52
+ `;function se(t){return Gr(t.rootPath,".toolnet","PROJECT.md")}function Xr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Zr(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=Xr(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 en(t){let e=se(t);return et(e)||(Vr(Yr(e),{recursive:!0}),Hr(e,Qr,{encoding:"utf8",mode:384})),e}function oe(t,e=!1){let r=e?en(t):se(t);if(!et(r))return null;if(Xe(r).size>Ze)throw new Error(`PROJECT.md exceeds ${Ze} bytes`);let s=Ur(r,"utf8");return{path:r,content:s,digest:v(s),rules:Zr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(Xe(r).mtimeMs).toISOString()}}function rn(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 nn(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)),!nn(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(rn(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},d=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(d)||await this.options.storage.put(d,JSON.stringify(a,null,2)+`
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=ke(this.options.project.rootPath,".toolnet","work","handoffs");return tn(l,{recursive:!0}),x(ke(l,`${u}.json`),a),x(ke(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 sn}from"node:fs";import{join as rt}from"node:path";function on(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function an(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 A(t,e){return an(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 cn(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 un(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 cn(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,d=[],l=[],f=[];for(let h of n){let g=on(h);if(h.scope==="phase"&&h.scopeKey){let S=a.get(h.scopeKey)??un(h);switch(h.kind){case"phase_objective":S.objective=A(S.objective,g);break;case"phase_why":S.why=A(S.why,g);break;case"phase_deliverable":S.deliverable=A(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=A(s,g);break;case"objective":o=A(o,g);break;case"why":i=A(i,g);break;case"desired_outcome":u=A(u,g);break;case"plan_rationale":c=A(c,g);break;case"open_question":d.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 p={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(d,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 sn(y,{recursive:!0}),x(rt(y,"semantic-current.json"),p),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(p,null,2)+`
55
+ `,"application/json"),p}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 b(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 ln(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(b(s,280)),e.length>=16))break}return e}function pn(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 dn(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=b(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=pn(n),o=r?r.rules.filter(p=>p.mode==="enforce").map(p=>p.text):s.enforce,i=r?r.rules.filter(p=>p.mode==="advisory").map(p=>p.text):s.advisory,u=n?ln(n):[],c=await re(t.project,t.storage),a=await st(t.project,t.storage),d=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 p of o.slice(0,24))l.push(`- [ENFORCE] ${b(p,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let p of i.slice(0,10))l.push(`- ${b(p,220)}`)}if(a&&(a.mission&&l.push("","MISSION",b(a.mission.value,420)),a.activeObjective&&l.push("","CURRENT OBJECTIVE",b(a.activeObjective.value,420)),a.why&&l.push("","WHY THIS WORK MATTERS",b(a.why.value,420)),a.desiredOutcome&&l.push("","DESIRED OUTCOME",b(a.desiredOutcome.value,420)),a.planRationale&&l.push("","WHY THIS APPROACH",b(a.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${b(c.goal,320)}`),c.plan&&l.push(`Plan: ${b(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 p=a.phases.find(y=>y.order===c.currentPhase?.order);p&&(p.objective&&l.push(`Phase objective: ${b(p.objective.value,340)}`),p.why?l.push(`Why this phase: ${b(p.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),p.deliverable&&l.push(`Deliverable: ${b(p.deliverable.value,340)}`),p.dependencies.length&&l.push(`Depends on: ${p.dependencies.slice(0,4).map(y=>b(y.value,180)).join("; ")}`),p.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),p.acceptanceCriteria.slice(0,6).forEach(y=>{l.push(`- ${b(y.value,260)}`)})),p.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),p.openQuestions.slice(0,4).forEach(y=>{l.push(`- ${b(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((p,y)=>{l.push(`${y+1}. ${b(p,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(p=>{l.push(`- ${b(p,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(p=>{l.push(`- ${b(p,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(p=>{l.push(`- ${b(p,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(p=>{l.push(`- ${b(p.value,260)}`)})),d&&l.push(`Latest handoff: ${d.reason} / ${d.sourceSession.agent}`),u.length){l.push("","OPERATING NOTES");for(let p of u)l.push(`- ${p}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let f=dn(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:!!d,generatedAt:new Date().toISOString()}}var fn=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 je(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))je(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(fn.has(n)||["data","payload","parts","messages"].includes(n))&&je(s,e,r+1)}}function I(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 O(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 mn(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function gn(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=[];je(o.data,i);for(let u of i){let c={type:"project"},a=null;for(let d of u.split(/\r?\n/u)){let l=D(d);if(!l){a=null;continue}let f=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let j=Number(f[1]);c={type:"phase",key:`phase:${j}`,order:j,title:D(f[2]??"")},a=null;continue}let p=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let j=Number(p[1]);c={type:"task",key:`task:${j}`,order:j,title:D(p[2]??"")},a=null;continue}let y=O(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(I(t,o,"mission",y,{type:"project"},.99)),a=null;continue}let h=O(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(I(t,o,c.type==="phase"?"phase_objective":"objective",h,c,.98)),a=null;continue}let g=O(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(I(t,o,c.type==="phase"?"phase_why":"why",g,c,.98)),a=null;continue}let S=O(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){s(I(t,o,"desired_outcome",S,{type:"project"},.98)),a=null;continue}let k=O(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(I(t,o,"plan_rationale",k,{type:"project"},.98)),a=null;continue}let M=O(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(I(t,o,"phase_deliverable",M,c,.97)),a=null;continue}let N=O(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(N){s(I(t,o,"acceptance_criterion",N,c,.98)),a="acceptance_criterion";continue}let E=O(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(E){s(I(t,o,"dependency",E,c,.97)),a="dependency";continue}let R=O(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){s(I(t,o,"open_question",R,c,.95)),a="open_question";continue}let m=O(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(m){s(I(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&&mn(d)){s(I(t,o,a,gn(d),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 hn,existsSync as yn,openSync as Sn,readSync as vn,statSync as bn}from"node:fs";function kn(t,e){if(!yn(t))return{events:[],nextOffset:e};let r=bn(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=Sn(t,"r");try{vn(o,s,0,s.length,n)}finally{hn(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
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=kn(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 wn,mkdirSync as jn,readFileSync as xn,writeFileSync as In}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 On(t){return ct(t.rootPath,".toolnet","context","startup.json")}function lt(t,e){let r=ut(t);jn(Pn(r),{recursive:!0}),In(r,e.text.endsWith(`
64
63
  `)?e.text:e.text+`
65
- `,{encoding:"utf8",mode:384}),j(co(t),e)}async function Xe(t,e,n=800){let s=(await Vt({project:t,storage:e,maxTokens:n})).text;Ee(s)>n&&(s=Me(s,n),s+=`
64
+ `,{encoding:"utf8",mode:384}),x(On(t),e)}async function xe(t,e,r=800){let s=(await ot({project:t,storage:e,maxTokens:r})).text;ue(s)>r&&(s=le(s,r),s+=`
66
65
 
67
66
  [Context trimmed by ToolNet Memory token budget]
68
- `);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:S(s),estimatedTokens:Ee(s),generatedAt:new Date().toISOString()};return Qt(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:v(s),estimatedTokens:ue(s),generatedAt:new Date().toISOString()};return lt(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
69
68
  `,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(i,null,2)+`
70
- `,"application/json"),i}async function Xt(t,e,n=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:S(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return Qt(t,i),i}}catch{}let r=Yt(t);if(ro(r))try{let s=oo(r,"utf8").trim();if(s)return{version:1,projectId:t.id,projectName:t.name,text:s,digest:S(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await Xe(t,e,n)}catch{return null}}import{existsSync as dn,mkdirSync as Po,readFileSync as pn}from"node:fs";import{homedir as Eo}from"node:os";import{dirname as Mo,join as rt}from"node:path";var Ze="memory_agent_ask";function Zt(){return`
71
- [TOOLNET MEMORY AGENT]
72
-
73
- Tool:
74
- - ${Ze}
75
-
76
- For resume/continue requests:
77
-
78
- 1. Use the injected ToolNet continuity handoff FIRST.
79
- 2. If the handoff is missing or ambiguous, invoke
80
- ${Ze} directly BEFORE repository/history exploration.
81
- 3. NEVER reconstruct prior work from:
82
- - .toolnet/sessions/**
83
- - state.json
84
- - events.jsonl
85
- - raw transcripts
86
- 4. NEVER search for the implementation/schema of
87
- ${Ze}; invoke the MCP tool directly.
88
- 5. Inspect git/source only AFTER continuity context is known.
89
-
90
- Use:
91
- - mode="local" for current task, last file, blocker or next action.
92
- - mode="ai" for ambiguous or combined continuity questions.
93
-
94
- Current repository evidence overrides stale memory.
95
- `.trim()}import{createHash as uo}from"node:crypto";import{chmodSync as tn,existsSync as lo,mkdirSync as po,readFileSync as fo,renameSync as mo,writeFileSync as nn}from"node:fs";import{dirname as rn,join as Ce}from"node:path";var nt="toolnet.context-offload.v1",go="toolnet.context-offload-asset.v1",yo=256,ho=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function sn(t){return Ce(t,".toolnet","offload")}function ko(t){return Ce(sn(t),"assets")}function on(t){return Ce(sn(t),"graph.json")}function an(t){po(t,{recursive:!0,mode:448});try{tn(t,448)}catch{}}function So(t,e){an(rn(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;nn(n,e,{encoding:"utf8",mode:384}),mo(n,t);try{tn(t,384)}catch{}}function tt(t){return Array.isArray(t)?t.map(tt):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,tt(n)])):t}function vo(t){return uo("sha256").update(JSON.stringify(tt(t)),"utf8").digest("hex")}function et(){return{schema:nt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function cn(t){let e=on(t);if(!lo(e))return et();try{let n=JSON.parse(fo(e,"utf8"));return n.schema!==nt||n.version!==1||!Array.isArray(n.nodes)?et():n}catch{return et()}}function wo(t,e){So(on(t),JSON.stringify(e,null,2)+`
96
- `)}function bo(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function xo(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let s=bo(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Ao(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Io(t,e){an(rn(t));try{return nn(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function jo(t,e){let n=t.nodes.find(s=>s.id===e.id),r=n?{...n,kind:e.kind,bytes:e.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...e.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...e.files])).slice(0,6)}:e;return{schema:nt,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(s=>s.id!==e.id),r].slice(-yo)}}function un(t,e){let n=cn(t),r=0,s=0,o=0,i=[];for(let a of e){if(!ho.has(a.type))continue;r+=1;let c=vo({type:a.type,data:a.data}),u={schema:go,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},p=JSON.stringify(u,null,2)+`
97
- `;Io(Ce(ko(t),`${c}.json`),p)?s+=1:o+=1,i.push(c),n=jo(n,{id:c,kind:a.type,bytes:Buffer.byteLength(p,"utf8"),createdAt:a.timestamp,sourceRefs:[Ao(a)],files:xo(a)})}return r>0&&wo(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function en(t,e){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,e-1).trimEnd()+"\u2026"}function ln(t,e={}){let n=cn(t);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,e.maxAssets??6)),s=Math.max(320,Math.min(2400,e.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let a=en(i.sourceRefs.at(-1)??"unknown",72),c=i.files.length>0?` files=${en(i.files.join(","),120)}`:"",u=`event:${a} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${c}`;if([...o,u].join(`
98
- `).length>s)break;o.push(u)}return o.join(`
99
- `)}function Co(t,e,n){let r=n??rt(Eo(),".config","toolnet-memory","injections","agy");return rt(r,`${t.id}-${e}.json`)}function To(t){if(!dn(t))return null;try{return JSON.parse(pn(t,"utf8"))}catch{return null}}function K(t,e=280){let n=(t??"").replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function Oo(t){let e=rt(t.rootPath,".toolnet","work","current.json");if(!dn(e))return null;try{let n=JSON.parse(pn(e,"utf8"));if(n.version===1&&n.projectId===t.id)return n}catch{}return null}function _o(t,e){let n=e.tasks.filter(i=>i.status==="completed").slice(-3).map(i=>K(i.title,220)),r=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=>K(i,220)).filter(Boolean))),s=e.filesTouched.at(-1),o=["[TOOLNET CONTINUITY HANDOFF]",`Project: ${t.name}`];return e.currentTask?.title?o.push(`Task: ${K(e.currentTask.title)}`):e.currentPhase?.title?o.push(`Task: ${K(e.currentPhase.title)}`):e.goal&&o.push(`Task: ${K(e.goal)}`),n.length&&o.push(`Completed: ${n.join("; ")}`),s&&o.push(`Current file: ${K(s,260)}`),r.length&&o.push(`TODO: ${r.join("; ")}`),e.nextActions.length&&o.push(`Next action: ${K(e.nextActions[0])}`),e.blockers.length&&o.push(`Blocker: ${K(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(`
100
- `)}async function Ro(t){let e=Oo(t.project);if(!e)try{e=await G(t.project,t.storage)}catch{e=null}let n=e?_o(t.project,e):"";if(!n)try{n=(await Xt(t.project,t.storage,700))?.text??""}catch{n=""}let r=ln(t.project.rootPath,{maxAssets:6,maxChars:900});return[n,r,Zt()].filter(Boolean).join(`
101
-
102
- `).trim()}async function fn(t){let e=t.now??Date.now(),n=t.resumeAfterMs??360*60*1e3,r=Co(t.project,t.conversationId,t.markerDirectory),s=To(r),o=s?Date.parse(s.injectedAt):0,i=o?e-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let a=t.invocationNum===0,c=i>=n;if(s&&!a&&!c)return{};let u=await Ro({project:t.project,storage:t.storage});return u?(Po(Mo(r),{recursive:!0}),j(r,{digest:S(u),injectedAt:new Date(e).toISOString()}),{injectSteps:[{ephemeralMessage:u}]}):{}}import{existsSync as Fo}from"node:fs";import{dirname as Wo,join as Bo,parse as zo,resolve as Uo}from"node:path";function gn(t){for(let e of t){let n=Uo(e),r=zo(n).root;for(;;){if(Fo(Bo(n,".toolnet","project.json")))return new me().detect(n);if(n===r)break;let s=Wo(n);if(s===n)break;n=s}}return null}import{homedir as yr}from"node:os";import{join as qa,resolve as Va}from"node:path";import{join as qo}from"node:path";function yn(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=S(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function hn(t,e,n){let r=e.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=yn(r.toLowerCase(),"agent"),i=yn(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:qo(t.rootPath,".toolnet","sessions",o,i)}}function kn(t){return String(t).padStart(12,"0")}var Te=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
103
- `,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
104
- `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let g=y[0],v=y[y.length-1],P=y.map(R=>JSON.stringify(R)).join(`
69
+ `,"application/json"),i}async function pt(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(wn(n))try{let s=xn(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 xe(t,e,r)}catch{return null}}import{existsSync as En,mkdirSync as An,readFileSync as Tn}from"node:fs";import{homedir as Mn}from"node:os";import{dirname as Rn,join as dt}from"node:path";function Cn(t,e,r){let n=r??dt(Mn(),".config","toolnet-memory","injections","agy");return dt(n,`${t.id}-${e}.json`)}function Nn(t){if(!En(t))return null;try{return JSON.parse(Tn(t,"utf8"))}catch{return null}}async function ft(t){let e=t.now??Date.now(),r=t.resumeAfterMs??360*60*1e3,n=Cn(t.project,t.conversationId,t.markerDirectory),s=Nn(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 pt(t.project,t.storage,900);return a?.text?(An(Rn(n),{recursive:!0}),x(n,{digest:a.digest,injectedAt:new Date(e).toISOString()}),{injectSteps:[{userMessage:a.text}]}):{}}import{existsSync as _n}from"node:fs";import{dirname as $n,join as Ln,parse as Dn,resolve as Kn}from"node:path";function mt(t){for(let e of t){let r=Kn(e),n=Dn(r).root;for(;;){if(_n(Ln(r,".toolnet","project.json")))return new H().detect(r);if(r===n)break;let s=$n(r);if(s===r)break;r=s}}return null}import{homedir as _t}from"node:os";import{join as Ns,resolve as _s}from"node:path";import{join as Fn}from"node:path";function gt(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 ht(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=gt(n.toLowerCase(),"agent"),i=gt(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:Fn(t.rootPath,".toolnet","sessions",o,i)}}function yt(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)+`
70
+ `,"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)+`
71
+ `,"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],k=g[g.length-1],M=g.map(R=>JSON.stringify(R)).join(`
105
72
  `)+`
106
- `,T=S(P).slice(0,16),A=[e.remotePrefix,"events",`${kn(g.sequence)}-${kn(v.sequence)}-${T}.jsonl`].join("/");await this.storage.exists(A)||await this.storage.put(A,P,"application/x-ndjson"),c+=y.length}let u=await this.scan(e),p=n[n.length-1],l=o?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?l="idle":p?.type==="error"?l="error":n.length>0&&(l="active");let f=new Date().toISOString(),d=n[0],m={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:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(m.title=s.title??o?.title);let h={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:f};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:l}}};import{closeSync as st,existsSync as Vo,fsyncSync as Go,mkdirSync as Ho,openSync as ot,readSync as Jo,rmSync as Sn,statSync as vn,writeSync as Yo}from"node:fs";import{join as it}from"node:path";var Qo=12e4,Xo=80,Zo=2e3;function ei(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var Oe=class{constructor(e){this.identity=e;Ho(e.localDirectory,{recursive:!0}),this.eventsFile=it(e.localDirectory,"events.jsonl"),this.stateFile=it(e.localDirectory,"state.json"),this.lockFile=it(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 Ct(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){j(this.stateFile,e)}acquireLock(){for(let e=0;e<Xo;e+=1)try{return ot(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-vn(this.lockFile).mtimeMs>Qo){Sn(this.lockFile,{force:!0});continue}}catch{}ei(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{st(n),Sn(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let f=l.timestamp??new Date().toISOString(),d=l.data??{},m=l.provenance?.rawDigest??S(Mt(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,m].join("|"),y=S(h).slice(0,32);if(r.has(y))continue;s+=1;let g={version:1,id:y,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:m}};l.role!==void 0&&(g.role=l.role),l.sourceEventId!==void 0&&(g.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(g.sourceSequence=l.sourceSequence),o.push(g),r.add(y)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
73
+ `,N=v(M).slice(0,16),E=[e.remotePrefix,"events",`${yt(S.sequence)}-${yt(k.sequence)}-${N}.jsonl`].join("/");await this.storage.exists(E)||await this.storage.put(E,M,"application/x-ndjson"),c+=g.length}let a=await this.scan(e),d=r[r.length-1],l=o?.status??"active";d?.type==="session_end"||d?.type==="session_idle"?l="idle":d?.type==="error"?l="error":r.length>0&&(l="active");let f=new Date().toISOString(),p=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??p?.timestamp??f,updatedAt:d?.timestamp??f,firstEventAt:o?.firstEventAt??p?.timestamp,lastEventAt:d?.timestamp??o?.lastEventAt,eventCount:a.maxSequence,chunkCount:a.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(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 Ie,existsSync as Wn,fsyncSync as zn,mkdirSync as Bn,openSync as Pe,readSync as qn,rmSync as St,statSync as vt,writeSync as Jn}from"node:fs";import{join as Oe}from"node:path";var Vn=12e4,Un=80,Hn=2e3;function Yn(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var de=class{constructor(e){this.identity=e;Bn(e.localDirectory,{recursive:!0}),this.eventsFile=Oe(e.localDirectory,"events.jsonl"),this.stateFile=Oe(e.localDirectory,"state.json"),this.lockFile=Oe(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 Je(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){x(this.stateFile,e)}acquireLock(){for(let e=0;e<Un;e+=1)try{return Pe(this.lockFile,"wx",384)}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-vt(this.lockFile).mtimeMs>Vn){St(this.lockFile,{force:!0});continue}}catch{}Yn(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let r=this.acquireLock();try{return e()}finally{Ie(r),St(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(),p=l.data??{},y=l.provenance?.rawDigest??v(qe(p)),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:p,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(`
107
74
  `)+`
108
- `,a=ot(this.eventsFile,"a",384);try{Yo(a,i,null,"utf8"),Go(a)}finally{st(a)}let c=o[o.length-1],u="active";c.type==="session_end"||c.type==="session_idle"?u="idle":c.type==="error"&&(u="error");let p=Array.from(r).slice(-Zo);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:p}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Vo(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=vn(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=ot(this.eventsFile,"r");try{Jo(i,o,0,s,r)}finally{st(i)}return{events:o.toString("utf8").split(`
109
- `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),updatedAt:new Date().toISOString()})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ja,existsSync as Pa,openSync as Ea,readSync as Ma,statSync as Ca}from"node:fs";function wn(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var In=[/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],ti=[/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],ni=[/\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],ri=[/\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],si=[/đã 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],bn=[/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],oi=[/\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],ii=[/đườ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],ai=[/\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],xn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ci=new Set(["payload","data","content","message","messages","parts","summary"]);function C(t,e){return e.some(n=>n.test(t))}function jn(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ui(t){return jn(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function li(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 at(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||xn.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))at(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(xn.has(s)||ci.has(s))&&at(o,s,n,r+1)}}function di(t){let e=[];at(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=jn(o);if(li(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function An(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function pi(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&C(t,In)?{kind:"rule",confidence:.98}:r&&C(t,ti)?{kind:"rule",confidence:.92}:C(t,ni)?{kind:C(t,bn)?"architecture":"decision",confidence:r?.93:.86}:r&&C(t,ri)?{kind:"todo",confidence:.87}:C(t,bn)&&C(t,oi)?{kind:"architecture",confidence:r?.88:.82}:s&&C(t,si)?{kind:"fix",confidence:.8}:r&&C(t,ii)&&C(t,ai)?{kind:"context",confidence:.79}:null}function fi(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function mi(t,e,n){return t==="rule"&&C(n,In)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":wn(e,n)}function Pn(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=An(o);i&&a&&s.set(i,a)}for(let o of e){let i=An(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of di(o)){let u=pi(c,i,o);if(!u||u.confidence<.75)continue;let p=fi(u.kind),l=ui(c),f=S([t.projectId,u.kind,l].join("|"));if(r.has(f))continue;r.add(f);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],m=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:f,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:p,content:c,confidence:u.confidence,importance:mi(u.kind,p,c),tags:[p],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:m,sourcePaths:d,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as gi}from"node:crypto";var yi=["project-knowledge","implementation","continuation","session-context"],hi={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function ct(t){return gi("sha256").update(t).digest("hex")}function _e(t,e){return`${t}:${ct(e).slice(0,24)}`}function ki(t){try{return ct(JSON.stringify(t))}catch{return ct(String(t))}}function F(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function Mn(t,e=420){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:`${n.slice(0,Math.max(0,e-1)).trimEnd()}\u2026`}function Si(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function En(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function vi(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,5).map(e=>Mn(e.content)).join(" | ")}function wi(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,6).map(e=>Mn(e.content)).join(`
110
- `)}function Cn(t,e){let n=t.slice().sort((f,d)=>f.sequence-d.sequence||f.timestamp.localeCompare(d.timestamp)||f.id.localeCompare(d.id)),r=n.map(f=>({id:_e("raw",[f.projectId,f.agent,f.nativeSessionId,f.id,String(f.sequence)].join("|")),level:"raw",eventId:f.id,sourceEventId:f.sourceEventId,sequence:f.sequence,type:f.type,role:f.role,timestamp:f.timestamp,sourcePath:f.provenance.sourcePath,payloadDigest:ki(f.data)})),s=new Map,o=new Map;n.forEach((f,d)=>{let m=r[d];m&&(s.set(f.id,m.id),f.sourceEventId&&o.set(f.sourceEventId,m.id))});let i=e.map(f=>{let d=F([...f.provenance.eventIds.map(m=>s.get(m)),...f.provenance.sourceEventIds.map(m=>o.get(m))]);return{id:_e("fact",f.fingerprint),level:"fact",fingerprint:f.fingerprint,kind:f.kind,type:f.type,content:f.content,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,confidence:f.confidence,tags:F([...f.tags,"level:fact",`class:${f.knowledgeClass}`,`kind:${f.kind}`]),rawIds:d,sourcePaths:F(f.provenance.sourcePaths)}}),a=new Map;for(let f of i){let d=Si(f.kind),m=a.get(d)??[];m.push(f),a.set(d,m)}let c=[];for(let f of yi){let d=a.get(f);if(!d?.length)continue;let m=d.slice().sort((y,g)=>g.importanceScore-y.importanceScore||g.confidence-y.confidence||y.id.localeCompare(g.id)),h=m.map(y=>y.id);c.push({id:_e("scene",`${f}|${h.join("|")}`),level:"scene",kind:f,title:hi[f],summary:vi(m),factIds:h,importanceScore:Math.max(...m.map(y=>y.importanceScore)),confidence:En(m.map(y=>y.confidence)),tags:F(["level:scene",`scene:${f}`,...m.flatMap(y=>y.tags)]),sourcePaths:F(m.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(f=>[f.id,f])),p=[];for(let f of c){let m=f.factIds.map(g=>u.get(g)).filter(g=>!!g).filter(g=>(g.knowledgeClass==="permanent"||g.knowledgeClass==="task")&&g.importanceScore>=.55);if(m.length===0)continue;let h=m.some(g=>g.knowledgeClass==="permanent")?"permanent":"task",y=wi(m);p.push({id:_e("knowledge",`${f.id}|${h}|${m.map(g=>g.id).join("|")}`),level:"knowledge",knowledgeClass:h,title:f.title,content:y,sceneIds:[f.id],factIds:m.map(g=>g.id),importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:En(m.map(g=>g.confidence)),tags:F(["level:knowledge",`class:${h}`,`scene:${f.kind}`,...m.flatMap(g=>g.tags)]),sourcePaths:F(m.flatMap(g=>g.sourcePaths))})}let l=[];for(let f of i)for(let d of f.rawIds)l.push({from:d,to:f.id,type:"supports"});for(let f of c)for(let d of f.factIds)l.push({from:d,to:f.id,type:"belongs_to"});for(let f of p)for(let d of f.sceneIds)l.push({from:d,to:f.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:p,links:l,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:p.length,links:l.length}}}function W(){let t=pe(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function Tn(t){return(t||W()).rawTranscript}function On(t){return(t||W()).durableMemoryMaxItemsPerSession}function _n(t){return(t||W()).sessionSummaryMaxTokens}function Rn(t){return(t||W()).archiveRemote}function bi(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 xi(t,e){let n=t.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Ai(t,e){let n=[],r=new Set;for(let i of t){let a=i.split(`
111
- `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let p=u.toLowerCase().replace(/\s+/g," ");if(r.has(p))continue;r.add(p);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(l="file");let f=xi(u,l);if(f<.3)continue;let d=bi(u);n.push({category:l,text:d,importance:f,sourceSessionId:e})}}let s=W(),o=On(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function Ii(t){let e=W(),n=_n(e),o=t.join(`
75
+ `,u=Pe(this.eventsFile,"a",384);try{Jn(u,i,null,"utf8"),zn(u)}finally{Ie(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 d=Array.from(n).slice(-Hn);return this.saveStateUnsafe({...r,status:a,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:d}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Wn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let r=vt(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{qn(i,o,0,s,n)}finally{Ie(i)}return{events:o.toString("utf8").split(`
76
+ `).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 ps,existsSync as ds,openSync as fs,readSync as ms,statSync as gs}from"node:fs";function bt(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 xt=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],Gn=[/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],Qn=[/\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],Xn=[/\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],Zn=[/đã 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],kt=[/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],es=[/\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],ts=[/đườ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],rs=[/\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],wt=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ns=new Set(["payload","data","content","message","messages","parts","summary"]);function P(t,e){return e.some(r=>r.test(t))}function It(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ss(t){return It(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function os(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 Ee(t,e,r,n=0){if(!(n>6)){if(typeof t=="string"){(!e||wt.has(e))&&r.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))Ee(s,e,r,n+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(wt.has(s)||ns.has(s))&&Ee(o,s,r,n+1)}}function is(t){let e=[];Ee(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=It(o);if(os(i)&&!n.has(i)&&(n.add(i),r.push(i),r.length>=50))return r}return r}function jt(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function as(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&&P(t,xt)?{kind:"rule",confidence:.98}:n&&P(t,Gn)?{kind:"rule",confidence:.92}:P(t,Qn)?{kind:P(t,kt)?"architecture":"decision",confidence:n?.93:.86}:n&&P(t,Xn)?{kind:"todo",confidence:.87}:P(t,kt)&&P(t,es)?{kind:"architecture",confidence:n?.88:.82}:s&&P(t,Zn)?{kind:"fix",confidence:.8}:n&&P(t,ts)&&P(t,rs)?{kind:"context",confidence:.79}:null}function cs(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function us(t,e,r){return t==="rule"&&P(r,xt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":bt(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=jt(o);i&&u&&s.set(i,u)}for(let o of e){let i=jt(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let c of is(o)){let a=as(c,i,o);if(!a||a.confidence<.75)continue;let d=cs(a.kind),l=ss(c),f=v([t.projectId,a.kind,l].join("|"));if(n.has(f))continue;n.add(f);let p=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:d,content:c,confidence:a.confidence,importance:us(a.kind,d,c),tags:[d],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:y,sourcePaths:p,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return r}function Ot(t){return String(t).padStart(12,"0")}function ls(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(d=>d.sequence)),o=Math.max(...r.map(d=>d.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:n.length,candidates:n},u=JSON.stringify(i,null,2)+`
77
+ `,c=v(n.map(d=>d.fingerprint).sort().join("|")).slice(0,16),a=[ls(e),"batches",`${Ot(s)}-${Ot(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,u,"application/json"),a}};function hs(t,e){if(!ds(t))return{events:[],nextOffset:e};let r=gs(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=fs(t,"r");try{ms(i,o,0,s,n)}finally{ps(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
78
+ `);if(c<0)return{events:[],nextOffset:n};let a=u.slice(0,c+1);return{events:a.split(`
79
+ `).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=hs(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 z;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=ht(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new de(this.identity),this.remote=new pe(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 ys,openSync as Ss,closeSync as vs,readSync as bs,statSync as ks}from"node:fs";function ws(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 js(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 Et(t,e={offset:0}){if(!ys(t))return{events:[],nextOffset:e.offset,reset:!1};let r=ks(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=Ss(t,"r");try{bs(u,i,0,o,s)}finally{vs(u)}let c=i.toString("utf8"),a=c.lastIndexOf(`
80
+ `);if(a<0)return{events:[],nextOffset:s,reset:n};let d=c.slice(0,a+1),l=Buffer.byteLength(d,"utf8"),f=[],p=0;for(let y of d.split(`
81
+ `)){if(!y)continue;let h=Buffer.byteLength(y+`
82
+ `,"utf8"),g=s+p;p+=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 k=S&&typeof S=="object"&&!Array.isArray(S)?S:{value:S};f.push({type:ws(k),timestamp:js(k),role:typeof k.role=="string"?k.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:k,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}})}return{events:f,nextOffset:s+l,reset:n}}var xs=[/^<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*$/],Is=[/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],Ps=["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 Os(t){let e=t.toLowerCase();return Ps.some(r=>e.includes(r))}function Es(t){if(!t.trim())return!0;for(let e of xs)if(e.test(t))return!0;return Os(t),!1}function As(t){let e=t;for(let r of Is)e=e.replace(r,n=>{let s=n.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function Ae(t){let e=t.trim();return e?Es(e)?{content:"",filtered:!0,reason:"noise"}:{content:As(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=Ae(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=Ae(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 At(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&&Ae(n).filtered)return!0}return!1}function C(){let t=V(),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 Tt(t){return(t||C()).rawTranscript}function Mt(t){return(t||C()).durableMemoryMaxItemsPerSession}function Rt(t){return(t||C()).sessionSummaryMaxTokens}function Ct(t){return(t||C()).archiveRemote}function Ts(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 Ms(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 Rs(t,e){let r=[],n=new Set;for(let i of t){let u=i.split(`
83
+ `).filter(c=>c.trim());for(let c of u){let a=c.trim();if(a.length<15)continue;let d=a.toLowerCase().replace(/\s+/g," ");if(n.has(d))continue;n.add(d);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(l="file");let f=Ms(a,l);if(f<.3)continue;let p=Ts(a);r.push({category:l,text:p,importance:f,sourceSessionId:e})}}let s=C(),o=Mt(s);return r.sort((i,u)=>u.importance-i.importance).slice(0,o)}function Cs(t){let e=C(),r=Rt(e),o=t.join(`
112
84
 
113
85
  `).split(`
114
- `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).join(`
115
- `);return Me(o,n)}function Re(t,e){let r=(Array.isArray(t)?t:t.split(`
116
-
117
- `).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),s=Ai(r,e),o=s.filter(d=>d.category==="decision").map(d=>d.text),i=s.filter(d=>d.category==="rule").map(d=>d.text),a=s.filter(d=>d.category==="file").map(d=>d.text),c=s.filter(d=>d.category==="fix").map(d=>d.text),u=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:Ii(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:l,blockers:u,nextActions:p,durableFacts:s}}function D(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function ji(t){let e=new Map;for(let n of t){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=e.get(r);(!s||n.sequence>s.sequence)&&e.set(r,n)}return[...e.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Pi(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Ei(t){let e=Pi(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function Mi(t){return t.importance==="temporary"||t.confidence<.78?"transient":t.kind==="rule"||t.kind==="architecture"?"permanent":t.kind==="decision"||t.kind==="todo"||t.kind==="fix"?"task":"session"}function Ci(t){let e=t.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of e)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function Ti(t){let e=Mi(t),n=Ei(t),r=Ci(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:D([...t.tags,"level:fact",`class:${e}`,`kind:${t.kind}`])}}function Oi(t){return t.map(e=>{try{return JSON.stringify({type:e.type,role:e.role,data:e.data,provenance:{sourcePath:e.provenance.sourcePath,files:e.provenance.files}})}catch{return""}}).filter(Boolean)}function _i(t,e,n){let r=Re(Oi(e),t.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=D([...s,...r.nextActions]),c=D([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:D(r.decisions),files:D([...r.filesChanged,...o]),todos:a,completed:D(r.bugsFixed),blockers:D(r.blockers),nextActions:c,architecture:D(i)}}}function Nn(t,e){let n=ji(e),r=Pn(t,n).map(Ti),s=r.filter(p=>p.knowledgeClass!=="transient").sort((p,l)=>l.importanceScore-p.importanceScore),{summary:o,state:i}=_i(t,n,s),a=s.map(p=>({fingerprint:p.fingerprint,kind:p.kind,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,content:p.content,terms:p.retrievalTerms})),c=Cn(n,s),u=p=>r.filter(l=>l.knowledgeClass===p).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:e.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as Wi}from"node:crypto";import{existsSync as Bi,readdirSync as zi,readFileSync as Ui}from"node:fs";import{basename as qi,join as Xn}from"node:path";import{randomUUID as Kn}from"node:crypto";var b=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function ne(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function z(t){let e=t.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new b("Invalid Wiki slug",400);return e}function Ln(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(z(r))}return ne(e)}function Ri(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function $n(t){return{id:`revision-${Kn()}`,pageId:t.id,slug:t.slug,revision:t.revision,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...t.tags],links:[...t.links],createdAt:t.updatedAt}}function B(t){return structuredClone(t)}var Ne=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let e=await this.ensureState(),n=new Set(e.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:ne(e.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:e.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:e.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:e.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return B([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=z(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new b(`Wiki page not found: ${e}`,404);return B(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new b("Wiki title is required",400);let o=z(e.slug??r);if(n.pages.some(c=>c.slug===o))throw new b(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Kn()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:ne(e.tags??[]),links:Ln(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push($n(a)),B(a)})}async updatePage(e,n){return this.mutate(r=>{let s=z(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new b(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new b("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=Ln(o.content)),n.tags!==void 0&&(o.tags=ne(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push($n(o)),B(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return B(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(e){let n=await this.getPage(e),r=await this.ensureState();return B(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(e,n=10){let r=await this.ensureState(),s=ne(Ri(e));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),p=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),f=a.tags.map(m=>m.toLowerCase()),d=0;for(let m of s)u===m&&(d+=12),c===m&&(d+=10),c.includes(m)&&(d+=6),u.includes(m)&&(d+=5),f.some(h=>h===m)?d+=5:f.some(h=>h.includes(m))&&(d+=3),p.includes(m)&&(d+=2),l.includes(m)&&(d+=1);d>0&&i.push({page:B(a),score:d})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Dn="wiki/state.v1.json";function Ni(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function Li(t,e){let n=JSON.parse(t);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==e.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var Le=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Dn);if(!e){let n=Ni(this.project);return await this.save(n),n}return Li(e,this.project)}async save(e){await this.storage.put(Dn,JSON.stringify(e,null,2),"application/json")}};import{createHash as $i,randomUUID as Fn}from"node:crypto";var Wn="wiki/governance.v1.json",qn="toolnet.knowledge-governance.v1",Bn=500,re={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Ki(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function ut(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function zn(t){return $i("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Di(t){let e=[t.title,t.summary??"",t.content.slice(0,2e3),...t.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function Fi(t){let e=t.sourceType==="skill"?.96:t.sourceType==="memory"?.94:.88,n=t.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(e+=.03),t.content.length>=200&&(e+=.02),t.content.length<80&&(e-=.05),t.title.length<4&&(e-=.05),Ki(e)}function Un(t){let e=new Date().toISOString();return{schema:qn,version:1,projectId:t,policy:{...re},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Vn(t){let e=t.autoApproveThreshold??re.autoApproveThreshold,n=t.criticalApproveThreshold??re.criticalApproveThreshold,r=t.staleAfterDays??re.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new b("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new b("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new b("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var $e=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Wn);if(!e){let n=Un(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==qn||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Vn(n.policy??re)}}catch{let n=Un(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(Wn,JSON.stringify(e,null,2),"application/json")}},Ke=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,n,r,s={}){e.audit.push({id:Fn(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),e.audit.length>Bn&&(e.audit=e.audit.slice(-Bn))}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,n){return this.mutate(r=>(r.policy=Vn({...r.policy,...e}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let e=await this.ensureState(),n=r=>e.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!e||r.status===e).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(e=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(n.audit.slice(-r).reverse())}async assess(e,n){let r=await this.ensureState(),s=Fi(e),o=ut(e.title),i=n.filter(p=>p.slug!==e.slug&&ut(p.title)===o&&zn(p.content)!==zn(e.content)).map(p=>p.slug),a=Di(e),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,n){let r=await this.assess(e,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:Fn(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(e,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===e&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:e}))})}async decide(e,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===e);if(!o)throw new b(`Governance review not found: ${e}`,404);if(o.status!=="pending")throw new b("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new b("targetReviewId is required for merge",400);let u=s.reviews.find(p=>p.id===n.targetReviewId);if(!u)throw new b("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new b(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(e){let n=await this.ensureState(),r=await e.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(p=>{let l=s-Date.parse(p.updatedAt);return{slug:p.slug,title:p.title,updatedAt:p.updatedAt,ageDays:Math.max(0,Math.floor(l/864e5)),stale:Number.isFinite(l)&&l>o}}).filter(p=>p.stale).map(({stale:p,...l})=>l),a=new Map;for(let p of r){let l=ut(p.title),f=a.get(l)??[];f.push(p),a.set(l,f)}let c=[...a.entries()].filter(([,p])=>p.length>1).map(([p,l])=>({title:p,pages:l.map(f=>f.slug)})),u=n.reviews.filter(p=>p.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(p=>p.tags.some(l=>l.startsWith("toolnet-auto-"))).length,manualPages:r.filter(p=>!p.tags.some(l=>l.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(p=>p.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(p=>p.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Zn="wiki/automation.v1.json",er="toolnet.wiki-automation.v1",pt=8e3,Gn=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function oe(t){return Wi("sha256").update(JSON.stringify(t)).digest("hex")}function se(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Hn(t){return Array.isArray(t)?t:[]}function tr(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function lt(t){return Array.isArray(t)?t.map(tr).filter(e=>!!e):[]}function _(t,e){for(let n of e){let r=tr(t[n]);if(r)return r}}function ie(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function De(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Gn.has(r))return[];if(typeof t=="string"){let i=t.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(t))return t.flatMap(i=>De(i,e+1,n));let s=se(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Gn.has(c)||o.push(...De(a,e+1,i))}return o}function Jn(t){let n=ie(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>De(t[s],0,s)));return(n.length>0?n:ie(De(t))).join(`
118
-
119
- `).slice(0,pt)}function Yn(t,e){return _(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function Qn(t,e){return _(t,["title","name","topic","label","task","kind","type"])??e}function Vi(t){return(_(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Gi(t){return(_(t,["kind","sceneKind","type"])??"").toLowerCase()}function Hi(t){let e=se(t);if(!e)return[];let n=[],r=Hn(e.knowledge);for(let[o,i]of r.entries()){let a=se(i);if(!a)continue;let c=Vi(a);if(c==="session"||c==="transient")continue;let u=Jn(a);if(u.length<20)continue;let p=Yn(a,oe(a).slice(0,16)),l=Qn(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${p}`,sourceType:"memory",title:l,summary:_(a,["summary","description"]),content:u,tags:ie(["toolnet","auto","memory",...c?[c]:[]])})}let s=Hn(e.scenes);for(let[o,i]of s.entries()){let a=se(i);if(!a)continue;let c=Gi(a);if(c==="session-context")continue;let u=Jn(a);if(u.length<20)continue;let p=Yn(a,oe(a).slice(0,16)),l=Qn(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${p}`,sourceType:"scene",title:l,summary:_(a,["summary","description"]),content:u,tags:ie(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Ji(t){return Xn(t,".toolnet","memory","skills")}function Yi(t){let e=Ji(t);if(!Bi(e))return{candidates:[],failed:0};let n=[],r=0,s=zi(e).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Ui(Xn(e,o),"utf8")),a=se(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=_(a,["id","fingerprint"])??qi(o,".json"),u=_(a,["task"])??"",p=_(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,l=_(a,["summary"])??void 0,f=lt(a.steps),d=lt(a.verification),m=lt(a.files),h=[];u&&h.push(`## Task
120
- ${u}`),l&&h.push(`## Summary
121
- ${l}`),f.length>0&&h.push(`## Procedure
122
- ${f.map((g,v)=>`${v+1}. ${g}`).join(`
123
- `)}`),d.length>0&&h.push(`## Verification
124
- ${d.map(g=>`- ${g}`).join(`
125
- `)}`),m.length>0&&h.push(`## Relevant Files
126
- ${m.map(g=>`- \`${g}\``).join(`
127
- `)}`);let y=h.join(`
128
-
129
- `).slice(0,pt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:p,summary:l,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function dt(t){let e=new Date().toISOString();return{schema:er,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function Qi(t,e){let n=await t.getText(Zn);if(!n)return dt(e);try{let r=JSON.parse(n);return r.schema!==er||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?dt(e):r}catch{return dt(e)}}async function Xi(t,e){await t.put(Zn,JSON.stringify(e,null,2),"application/json")}function Zi(t){return`toolnet-auto-${oe(t).slice(0,12)}`}function ea(t){let e=z(t.title).slice(0,72),n=oe(t.sourceKey).slice(0,10);return z(`auto-${t.sourceType}-${e}-${n}`)}function ta(t){return[`> Auto-generated by ToolNet Knowledge Automation from ${t.sourceType==="skill"?"reusable Skill Memory":t.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",t.content].join(`
130
- `).slice(0,pt)}function na(t){return oe({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function ra(t,e){return t.tags.includes(e)}async function nr(t){let e=Hi(t.hierarchy),n=Yi(t.project.rootPath),r=new Map;for(let d of[...e,...n.candidates])r.set(d.sourceKey,d);let s=[...r.values()].sort((d,m)=>d.sourceKey.localeCompare(m.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:e.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new Ne(new Le(t.storage,t.project));await i.initialize();let a=new Ke(new $e(t.storage,t.project));await a.initialize();let c=await Qi(t.storage,t.project.id),u=await i.listPages(),p=new Map(u.map(d=>[d.slug,d])),l=new Map(c.entries.map(d=>[d.sourceKey,d]));for(let d of s)try{let m=Zi(d.sourceKey),h=na(d),y=l.get(d.sourceKey),g=y?.slug??ea(d),v=p.get(g);if(v&&!ra(v,m)){o.skipped+=1;continue}let P=ie([...d.tags,m]),T=ta(d),A=await a.gate({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:g,marker:m,digest:h,title:d.title,...d.summary?{summary:d.summary}:{},content:T,tags:P},[...p.values()]);if(!A.allowed){A.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}A.mode==="auto-approved"?o.autoApproved+=1:A.mode==="review-approved"&&(o.reviewApproved+=1),v?y?.digest!==h?(v=await i.updatePage(g,{title:d.title,summary:d.summary??"",content:T,tags:P}),p.set(v.slug,v),o.updated+=1,o.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:v.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:g,action:"unchanged"})):(v=await i.createPage({slug:g,title:d.title,summary:d.summary,content:T,tags:P}),p.set(v.slug,v),o.created+=1,o.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:v.slug,action:"created"}));let R=new Date().toISOString(),k={sourceKey:d.sourceKey,sourceType:d.sourceType,slug:g,digest:h,marker:m,updatedAt:R},x=c.entries.findIndex(de=>de.sourceKey===d.sourceKey);x>=0?c.entries[x]=k:c.entries.push(k),l.set(d.sourceKey,k),await a.markApplied(d.sourceKey,h)}catch(m){if(m instanceof b&&m.statusCode===409){o.skipped+=1;continue}o.failed+=1}let f=new Date().toISOString();return c.updatedAt=f,c.lastRunAt=f,c.entries.sort((d,m)=>d.sourceKey.localeCompare(m.sourceKey)),await Xi(t.storage,c),o}import{createHash as sa}from"node:crypto";import{chmodSync as sr,existsSync as oa,mkdirSync as ia,readFileSync as Of,readdirSync as _f,renameSync as aa,statSync as Rf,writeFileSync as ca}from"node:fs";import{join as or}from"node:path";var ua="toolnet.skill-memory.v1",rr=5,la=16,da=24,pa=32;function fa(t){return sa("sha256").update(t).digest("hex")}function ce(t,e=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function ft(t,e=360){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function ma(t){return t.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function N(t,e=360){return t&&ft(ma(t),e)||void 0}function ue(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function ir(t,e){for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function ar(t,e){for(let n of e){let r=t[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function cr(t){let e=t.data??{};if(ar(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=ir(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=ue(e,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ae(t){let e=t.data??{};if(cr(t))return!1;if(ar(e,["passed","pass","success","succeeded","ok"])===!0||ir(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=ue(e,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:t.type==="commit"||t.type==="deploy"}function ur(t){let e=t.data??{},n=ue(e,["path","file","filePath","filename","target"]);if(n)return N(n,260);let r=t.provenance?.files;return N(r?.[0],260)}function mt(t){return N(ue(t.data??{},["command","cmd","script"]),420)}function J(t){return N(ue(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function ga(t){let e=[];for(let n of[...t].sort((r,s)=>r.sequence-s.sequence))if(ae(n)){if(n.type==="test"){let r=J(n)??mt(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=J(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=J(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return ce(e,10)}function ya(t,e){let n=[];for(let r of[...t].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=ur(r);s&&n.push(`Update ${s}`);break}case"command":{if(cr(r))break;let s=mt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ae(r))break;let s=J(r)??mt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!ae(r))break;let s=J(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!ae(r))break;let s=J(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of e.files.slice(0,8)){let s=N(r,260);s&&n.push(`Update ${s}`)}return ce(n,la)}function ha(t,e){let n=[...e.files];for(let r of t){let s=ur(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=N(o,260);i&&n.push(i)}}return ce(n,da)}function ka(t){return ce(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),pa)}function Sa(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function lr(t,e,n){if(e.length===0)return[];let r=ga(e),s=ce(n.completed.map(m=>N(m,280)??""),rr);if(!(s.length>0||e.some(m=>["test","commit","deploy"].includes(m.type)&&ae(m))))return[];let i=N(n.task,280)??N(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=ya(e,n);if(c.length===0)return[];let u=ha(e,n),p=ka(e),l=Math.min(...e.map(m=>m.sequence)),f=Math.max(...e.map(m=>m.sequence)),d=Sa(e);return a.slice(0,rr).map(m=>{let h=[`Reusable procedure learned from successful task: ${m}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),y=JSON.stringify({projectId:t.projectId,task:m,steps:c,verification:r,files:u}),g=fa(y);return{schema:ua,version:1,id:`skill-${g.slice(0,24)}`,fingerprint:g,projectId:t.projectId,title:ft(`SOP: ${m}`,180),task:m,summary:ft(h.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:l,lastSequence:f,eventIds:p},createdAt:d}})}function va(t){return or(t.rootPath,".toolnet","memory","skills")}function wa(t){let e=va(t);return ia(e,{recursive:!0,mode:448}),sr(e,448),e}function dr(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=wa(t),r=0,s=0,o=[];for(let i of e){if(i.projectId!==t.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${t.id}`);let a=or(n,`${i.id}.json`);if(o.push(a),oa(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;ca(c,JSON.stringify(i,null,2)+`
131
- `,{encoding:"utf8",mode:384}),aa(c,a),sr(a,384),r+=1}return{written:r,deduped:s,files:o}}function pr(t){return String(t).padStart(12,"0")}function ba(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Fe=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(p=>p.sequence)),o=Math.max(...n.map(p=>p.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
132
- `,c=S(r.map(p=>p.fingerprint).sort().join("|")).slice(0,16),u=[ba(e),"batches",`${pr(s)}-${pr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as xa}from"node:crypto";function fr(t){return String(t).padStart(12,"0")}function Aa(t){return xa("sha256").update(t).digest("hex")}function Ia(t){return t.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var We=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=Aa([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[Ia(e),"batches",`${fr(s)}-${fr(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
133
- `,"application/json"),c}};function Ta(t,e){if(!Pa(t))return{events:[],nextOffset:e};let n=Ca(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Ea(t,"r");try{Ma(i,o,0,s,r)}finally{ja(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
134
- `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
135
- `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Be=class{constructor(e){this.options=e;this.journal=new Fe(e.storage),this.hierarchyJournal=new We(e.storage)}options;journal;hierarchyJournal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=Ta(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Nn(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=lr(this.options.identity,s.events,o.state),p=dr(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",p.written),this.options.wal.setSourceCursor("memory.skill.deduped",p.deduped);try{let l=un(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",l.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",l.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",l.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",l.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let l=await nr({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",l.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",l.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",l.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",l.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",l.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",l.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",l.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",l.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",l.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",l.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:a,nextOffset:s.nextOffset}}};var ze=class{identity;wal;remote;sanitizer=new Z;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=hn(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new Oe(this.identity),this.remote=new Te(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new Be({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new be({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Pe({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 n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){return this.wal.append([this.sanitizeEvent(e)])[0]}recordMany(e){return this.wal.append(e.map(n=>this.sanitizeEvent(n)))}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as Oa,openSync as _a,closeSync as Ra,readSync as Na,statSync as La}from"node:fs";function $a(t){let e=typeof t.role=="string"?t.role:"",n=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||n.includes("user")?"user_prompt":e==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":n.includes("error")?"error":"message"}function Ka(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let n of e){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function mr(t,e={offset:0}){if(!Oa(t))return{events:[],nextOffset:e.offset,reset:!1};let n=La(t).size,r=e.offset>n,s=r?0:e.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),a=_a(t,"r");try{Na(a,i,0,o,s)}finally{Ra(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
136
- `);if(u<0)return{events:[],nextOffset:s,reset:r};let p=c.slice(0,u+1),l=Buffer.byteLength(p,"utf8"),f=[],d=0;for(let m of p.split(`
137
- `)){if(!m)continue;let h=Buffer.byteLength(m+`
138
- `,"utf8"),y=s+d;d+=h;let g;try{g=JSON.parse(m)}catch{f.push({type:"custom",sourceEventId:`transcript:${y}`,sourceSequence:y,data:{format:"raw-line",content:m},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:y}});continue}let v=g&&typeof g=="object"&&!Array.isArray(g)?g:{value:g};f.push({type:$a(v),timestamp:Ka(v),role:typeof v.role=="string"?v.role:void 0,sourceEventId:`transcript:${y}`,sourceSequence:y,data:v,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:y}})}return{events:f,nextOffset:s+l,reset:r}}var Da=[/^<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*$/],Fa=[/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],Wa=["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 Ba(t){let e=t.toLowerCase();return Wa.some(n=>e.includes(n))}function za(t){if(!t.trim())return!0;for(let e of Da)if(e.test(t))return!0;return Ba(t),!1}function Ua(t){let e=t;for(let n of Fa)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function gt(t){let e=t.trim();return e?za(e)?{content:"",filtered:!0,reason:"noise"}:{content:Ua(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function Ue(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=gt(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=Ue(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=gt(s);return o.filtered?null:o.content}return s&&typeof s=="object"?Ue(s):s}).filter(s=>s!==null):e[n]=r;return e}function gr(t){let e=typeof t.type=="string"?t.type.toLowerCase():"";if(e.includes("system")||e.includes("ephemeral")||e==="tool_call"&&!t.result)return!0;if(t.data&&typeof t.data=="object"){let n=t.data,r=typeof n.content=="string"?n.content:"";if(r&&gt(r).filtered)return!0}return!1}function Ga(t){return t==="~"?yr():t.startsWith("~/")?qa(yr(),t.slice(2)):t}async function hr(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let n=Va(Ga(t.transcriptPath)),r=new ze({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,a=mr(n,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:n,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(f=>!gr(f.data)).map(f=>({...f,data:Ue(f.data)}));c.push(...u),t.phase==="stop"&&(t.error&&c.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",a.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",e,"idle",a.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let p=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),t.phase&&r.setSourceCursor("agy.last.phase",t.phase),t.phase==="stop"&&u.length>0)try{let f=u.map(m=>JSON.stringify(m.data)),d=Re(f,e);r.setSourceCursor("agy.session.summary",d.summary),r.setSourceCursor("agy.session.facts_count",d.durableFacts.length),Tn()&&(Rn()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await r.flush();return{conversationId:e,imported:p.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:a.nextOffset,reset:a.reset}}async function Ha(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}function le(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function Ja(t){let e=typeof t.common=="object"&&t.common!==null?t.common:{},n=typeof t.pre_invocation_hook_args=="object"&&t.pre_invocation_hook_args!==null?t.pre_invocation_hook_args:{},r=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:""),a=le(e.workspace_paths).length>0?le(e.workspace_paths):le(t.workspacePaths).length>0?le(t.workspacePaths):le(t.workspace_paths),c=typeof n.invocation_num=="number"?n.invocation_num:typeof t.invocationNum=="number"?t.invocationNum:typeof t.invocation_num=="number"?t.invocation_num:void 0,u=(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:a,invocationNum:c,artifactDirectoryPath:u,modelName:p,fullyIdle:l,terminationReason:f,error:d}}function Ya(t){let e=typeof t.toolCall=="object"&&t.toolCall!==null?t.toolCall:{},n=typeof e.args=="object"&&e.args!==null?e.args:{},r="";try{r=JSON.stringify(n).replace(/\\\\/g,"/").toLowerCase()}catch{r=""}return r.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 Qa(){let t=process.argv[2]??"post",e=await Ha();if(t==="pre-tool"){process.stdout.write(JSON.stringify(Ya(e)));return}let n=Ja(e),r=n.conversationId,s=n.transcriptPath,o=n.workspacePaths,i=gn(o),a={};if(i&&r)try{let c=pe(),u=jt(At({provider:c.storage.provider,huggingface:c.storage.huggingface,localRoot:c.storage.localRoot}),{attempts:2}),p=new ke(u,i.id,i.name,i.remote??i.name);if(s)try{await hr({project:i,storage:p,conversationId:r,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:n.artifactDirectoryPath,modelName:n.modelName,phase:t,fullyIdle:n.fullyIdle,terminationReason:n.terminationReason,error:n.error})}catch{}if(t==="pre")try{a=await fn({project:i,storage:p,conversationId:r,invocationNum:n.invocationNum})}catch{a={}}if(t==="stop")try{await Xe(i,p,800)}catch{}}catch{}if(t==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(a))}Qa().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{Ya as buildAgyPreToolUseOutput,Ja as normalizeAgyInput};
86
+ `).filter(i=>{let u=i.trim();return u.length>20&&!u.startsWith("npm")&&!u.startsWith("\u2713")&&!u.startsWith("Error:")}).slice(0,20).join(`
87
+ `);return le(o,r)}function Nt(t,e){let n=(Array.isArray(t)?t:t.split(`
88
+
89
+ `).filter(p=>p.trim())).map(p=>typeof p=="string"?p:JSON.stringify(p)).filter(p=>p.trim()),s=Rs(n,e),o=s.filter(p=>p.category==="decision").map(p=>p.text),i=s.filter(p=>p.category==="rule").map(p=>p.text),u=s.filter(p=>p.category==="file").map(p=>p.text),c=s.filter(p=>p.category==="fix").map(p=>p.text),a=s.filter(p=>p.category==="blocker").map(p=>p.text),d=s.filter(p=>p.category==="next_action").map(p=>p.text),l=s.filter(p=>p.category==="deploy").map(p=>p.text);return{summary:Cs(n),decisions:o,projectRules:i,filesChanged:u,bugsFixed:c,commands:l,blockers:a,nextActions:d,durableFacts:s}}function $s(t){return t==="~"?_t():t.startsWith("~/")?Ns(_t(),t.slice(2)):t}async function $t(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let r=_s($s(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=Et(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=>!At(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 d=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)),p=Nt(f,e);n.setSourceCursor("agy.session.summary",p.summary),n.setSourceCursor("agy.session.facts_count",p.durableFacts.length),Tt()&&(Ct()||n.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await n.flush();return{conversationId:e,imported:d.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:u.nextOffset,reset:u.reset}}async function Ls(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}function J(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function Ds(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=J(e.workspace_paths).length>0?J(e.workspace_paths):J(t.workspacePaths).length>0?J(t.workspacePaths):J(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,d=(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,p=(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:d,fullyIdle:l,terminationReason:f,error:p}}async function Ks(){let t=process.argv[2]??"post",e=await Ls(),r=Ds(e),n=r.conversationId,s=r.transcriptPath,o=r.workspacePaths,i=mt(o),u={};if(i&&n)try{let c=V(),a=We(Ke({provider:c.storage.provider,huggingface:c.storage.huggingface,localRoot:c.storage.localRoot}),{attempts:2}),d=new X(a,i.id,i.name,i.remote??i.name);if(s)try{await $t({project:i,storage:d,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 ft({project:i,storage:d,conversationId:n,invocationNum:r.invocationNum})}catch{u={}}if(t==="stop")try{await xe(i,d,800)}catch{}}catch{}if(t==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(u))}Ks().catch(()=>{process.argv[2]==="stop"?process.stdout.write('{"decision":"stop"}'):process.stdout.write("{}"),process.exitCode=0});export{Ds as normalizeAgyInput};