toolnet-memory 0.3.3 → 0.3.5

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