toolnet-memory 0.3.10 → 0.3.12

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,4 +1,4 @@
1
- import{existsSync as Xs,mkdirSync as Zs,readFileSync as Qs,renameSync as eo,rmSync as to,writeFileSync as no}from"node:fs";import{isAbsolute as ro,join as rn,relative as so}from"node:path";import{existsSync as un,readFileSync as ln}from"node:fs";import{homedir as dn}from"node:os";import{join as fn}from"node:path";function mn(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
1
+ import{existsSync as Zs,mkdirSync as Qs,readFileSync as eo,renameSync as to,rmSync as no,writeFileSync as ro}from"node:fs";import{isAbsolute as so,join as rn,relative as oo}from"node:path";import{existsSync as un,readFileSync as ln}from"node:fs";import{homedir as dn}from"node:os";import{join as fn}from"node:path";function mn(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
2
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 pn(){let e=process.env.TOOLNET_GLOBAL_ENV??fn(dn(),".config","toolnet-memory",".env");if(!un(e))return;let t=ln(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]=mn(r.slice(s+1)))}}pn();function D(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function K(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Te(){return{memory:{autoCapture:D(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:D(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:D(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:D(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:K(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:K(process.env.MEMORY_RERANK_TOP,10),finalContext:K(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:K(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:D(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:K(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as gn}from"node:crypto";import{existsSync as oe,mkdirSync as hn,readFileSync as yn,renameSync as kn,writeFileSync as Sn}from"node:fs";import{basename as bn,dirname as U,join as X,parse as Pe,resolve as z}from"node:path";var Re=".toolnet",xn="project.json";function wn(e){return gn("sha256").update(e).digest("hex").slice(0,16)}function ie(e){return X(e,Re,xn)}function vn(e){return oe(ie(e))}function In(e,t){let n=z(e),r=Pe(n).root;for(;;){if(vn(n))return n;if(n===r||t&&n===z(t))break;let s=U(n);if(s===n)break;n=s}return null}function An(e){let t=z(e),n=Pe(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>oe(X(t,o))))return t;if(t===n)break;let s=U(t);if(s===t)break;t=s}return z(e)}function Mn(e){let t;try{t=JSON.parse(yn(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:U(U(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 je(e,t){let n=X(e,Re);hn(n,{recursive:!0});let r=ie(e),s=`${r}.tmp-${process.pid}`;Sn(s,JSON.stringify(t,null,2)+`
3
3
  `,{encoding:"utf8",mode:384}),kn(s,r)}function Oe(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 Y=class{detect(t=process.cwd()){let n=z(t),r=An(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>oe(X(r,f))),i=In(n,o?r:void 0);if(i){let f=ie(i),m=Mn(f);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),je(i,m)),Oe(m,i)}let d=new Date().toISOString(),u=bn(r),a={version:1,id:wn(r),name:u,remote:u,rootPath:r,createdAt:d,updatedAt:d,graphVersion:0,memoryVersion:0};return je(r,a),Oe(a,r)}};var Cn=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Z=class{scan(t){let n=[];for(let r of Cn){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 q=class{scanner=new Z;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*as C from"fs";import*as I from"path";function ce(e){return e?Math.ceil(e.length/3.5):0}function ae(e,t){if(!e)return"";if(ce(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
4
4
  `),d=Math.max(o,i);return d>r*.7?s.slice(0,d+1):s}function Ne(e,t){if(!e)return"";let n=e.split(`
@@ -11,7 +11,7 @@ ${r}
11
11
 
12
12
  ---
13
13
 
14
- `)}function _e(e,t){let n=[{title:"Profile",content:Ne(e,10),priority:100},{title:"Current Work",content:Ne(t,15),priority:90}];return En(n,{maxTokens:800})}import{chmodSync as ti,existsSync as Tn,mkdirSync as ni,readFileSync as jn,renameSync as ri,writeFileSync as si}from"node:fs";import{dirname as ii,join as Le}from"node:path";var $e="toolnet.context-offload.v1";function On(e){return Le(e,".toolnet","offload")}function Pn(e){return Le(On(e),"graph.json")}function ue(){return{schema:$e,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Rn(e){let t=Pn(e);if(!Tn(t))return ue();try{let n=JSON.parse(jn(t,"utf8"));return n.schema!==$e||n.version!==1||!Array.isArray(n.nodes)?ue():n}catch{return ue()}}function Fe(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function We(e,t={}){let n=Rn(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 d=Fe(i.sourceRefs.at(-1)??"unknown",72),u=i.files.length>0?` files=${Fe(i.files.join(","),120)}`:"",a=`event:${d} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${u}`;if([...o,a].join(`
14
+ `)}function _e(e,t){let n=[{title:"Profile",content:Ne(e,10),priority:100},{title:"Current Work",content:Ne(t,15),priority:90}];return En(n,{maxTokens:800})}import{chmodSync as ni,existsSync as Tn,mkdirSync as ri,readFileSync as jn,renameSync as si,writeFileSync as oi}from"node:fs";import{dirname as ci,join as Le}from"node:path";var $e="toolnet.context-offload.v1";function On(e){return Le(e,".toolnet","offload")}function Pn(e){return Le(On(e),"graph.json")}function ue(){return{schema:$e,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Rn(e){let t=Pn(e);if(!Tn(t))return ue();try{let n=JSON.parse(jn(t,"utf8"));return n.schema!==$e||n.version!==1||!Array.isArray(n.nodes)?ue():n}catch{return ue()}}function Fe(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function We(e,t={}){let n=Rn(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 d=Fe(i.sourceRefs.at(-1)??"unknown",72),u=i.files.length>0?` files=${Fe(i.files.join(","),120)}`:"",a=`event:${d} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${u}`;if([...o,a].join(`
15
15
  `).length>s)break;o.push(a)}return o.join(`
16
16
  `)}import{existsSync as ze,mkdirSync as Dn,readFileSync as qe,renameSync as Kn,writeFileSync as zn}from"node:fs";import{dirname as qn,join as He}from"node:path";import{createHash as Nn}from"node:crypto";import{dirname as _n}from"node:path";import{mkdirSync as Fn,readFileSync as Ln,renameSync as $n,writeFileSync as Wn}from"node:fs";function S(e){return Nn("sha256").update(e).digest("hex")}function le(e){if(Array.isArray(e))return e.map(le);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=le(t[r]);return n}return e}function De(e){return JSON.stringify(le(e))}function Ke(e){try{return JSON.parse(Ln(e,"utf8"))}catch{return null}}function T(e,t){Fn(_n(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;Wn(n,JSON.stringify(t,null,2)+`
17
17
  `,{encoding:"utf8",mode:384}),$n(n,e)}function Je(e){return He(e.rootPath,".toolnet","context","handoff.md")}function Be(e){return He(e.rootPath,".toolnet","context","handoff.json")}function Ve(e,t){Dn(qn(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;zn(n,t.endsWith(`
@@ -86,7 +86,7 @@ Forbidden At Startup:
86
86
  `):d=r.trim()?`${r.trim()}
87
87
 
88
88
  ${s}`:s,Jr(n,`${d.trim()}
89
- `,{encoding:"utf8",mode:384})}import{existsSync as os,mkdirSync as is}from"node:fs";import{join as xe}from"node:path";import{existsSync as Mt,mkdirSync as Gr,readFileSync as Ur,statSync as It,writeFileSync as Yr}from"node:fs";import{dirname as Xr,join as Zr}from"node:path";var At=64*1024,Qr=`# ToolNet Project Operating Manual
89
+ `,{encoding:"utf8",mode:384})}import{existsSync as is,mkdirSync as cs}from"node:fs";import{join as xe}from"node:path";import{existsSync as Mt,mkdirSync as Gr,readFileSync as Ur,statSync as It,writeFileSync as Yr}from"node:fs";import{dirname as Xr,join as Zr}from"node:path";var At=64*1024,Qr=`# ToolNet Project Operating Manual
90
90
 
91
91
  This file contains persistent instructions for AI agents working on this project.
92
92
 
@@ -130,15 +130,15 @@ Things an AI agent should always remember.
130
130
  - [advisory] Prefer small focused files.
131
131
  -->
132
132
  `;function Ct(e){return Zr(e.rootPath,".toolnet","PROJECT.md")}function es(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function ts(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=es(s[2]);if(!i)continue;let d=`${o}:${i.toLowerCase()}`;n.has(d)||(n.add(d),t.push({id:S(d).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function ns(e){let t=Ct(e);return Mt(t)||(Gr(Xr(t),{recursive:!0}),Yr(t,Qr,{encoding:"utf8",mode:384})),t}function Et(e,t=!1){let n=t?ns(e):Ct(e);if(!Mt(n))return null;if(It(n).size>At)throw new Error(`PROJECT.md exceeds ${At} bytes`);let s=Ur(n,"utf8");return{path:n,content:s,digest:S(s),rules:ts(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(It(n).mtimeMs).toISOString()}}function w(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 Tt(e){if(e)return{id:e.id,title:e.title,status:e.status}}function rs(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(`
133
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function ss(e){return S(JSON.stringify(e))}function jt(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(y=>y.status==="completed").map(y=>y.title),i=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),d=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),u=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),a=new Set(r.tasks.filter(y=>y.status==="completed").map(y=>y.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),f=w(r.nextActions.filter(y=>!a.has(y.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),m=w([...u,...f],15),c=w(r.tests.slice().reverse(),10),l=w([...(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:Tt(r.currentPhase),task:Tt(r.currentTask),file:s},completed:{phases:w(o,20),tasks:w(i,30)},remaining:{phases:w(d,20),tasks:w(u,30),todos:m},nextAction:f[0],blockers:w(r.blockers.slice().reverse(),10),decisions:w(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:w(r.activeFiles??[],10),modified:w(r.modifiedFiles??[],20),created:w(r.createdFiles??[],20),deleted:w(r.deletedFiles??[],20)},tests:{status:rs(r.tests,r.checks),recent:c,checks:(r.checks??[]).slice(-10).map(y=>({kind:y.kind,status:y.status,command:y.command}))},attention:w(e.attention??[],20),progress:r.progress},{capturedAt:b,source:h,...k}=g;return{...g,stateDigest:ss(k)}}function cs(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 as(e,t,n,r,s){if(!cs(n))return null;let o=Et(e,!1),d=[...o?o.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...n.warnings].slice(0,20),u=jt({project:e,identity:t,state:n,reason:r,sequence:s,attention:d}),a=u.stateDigest;return{version:1,id:S([e.id,t.sessionKey,a].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(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:n.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:u.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:d,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:a,continuity:u}}function us(e,t){let n=xe(e.rootPath,".toolnet","work","handoffs");is(n,{recursive:!0});let r=xe(n,`${t.id}.json`);os(r)||T(r,t),T(xe(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function Ot(e){let t=as(e.project,e.identity,e.state,e.reason,e.sequence);return t?(us(e.project,t),t):null}import{existsSync as Gt,mkdirSync as zs,readFileSync as qs}from"node:fs";import{join as Ie}from"node:path";function Pt(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 Ft=[/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],ls=[/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],ds=[/\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],fs=[/\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],ms=[/đã 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],Rt=[/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],ps=[/\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],gs=[/đườ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],hs=[/\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],Nt=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ys=new Set(["payload","data","content","message","messages","parts","summary"]);function M(e,t){return t.some(n=>n.test(e))}function Lt(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ks(e){return Lt(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Ss(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 we(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||Nt.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))we(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(Nt.has(s)||ys.has(s))&&we(o,s,n,r+1)}}function bs(e){let t=[];we(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=Lt(o);if(Ss(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function _t(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function xs(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&&M(e,Ft)?{kind:"rule",confidence:.98}:r&&M(e,ls)?{kind:"rule",confidence:.92}:M(e,ds)?{kind:M(e,Rt)?"architecture":"decision",confidence:r?.93:.86}:r&&M(e,fs)?{kind:"todo",confidence:.87}:M(e,Rt)&&M(e,ps)?{kind:"architecture",confidence:r?.88:.82}:s&&M(e,ms)?{kind:"fix",confidence:.8}:r&&M(e,gs)&&M(e,hs)?{kind:"context",confidence:.79}:null}function ws(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function vs(e,t,n){return e==="rule"&&M(n,Ft)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Pt(t,n)}function $t(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,d=_t(o);i&&d&&s.set(i,d)}for(let o of t){let i=_t(o),d=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&d&&(i=s.get(d)??"");for(let u of bs(o)){let a=xs(u,i,o);if(!a||a.confidence<.75)continue;let f=ws(a.kind),m=ks(u),c=S([e.projectId,a.kind,m].join("|"));if(r.has(c))continue;r.add(c);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:c,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:a.kind,type:f,content:u,confidence:a.confidence,importance:vs(a.kind,f,u),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 Is}from"node:crypto";var As=["project-knowledge","implementation","continuation","session-context"],Ms={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function ve(e){return Is("sha256").update(e).digest("hex")}function re(e,t){return`${e}:${ve(t).slice(0,24)}`}function Cs(e){try{return ve(JSON.stringify(e))}catch{return ve(String(e))}}function _(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 Dt(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 Es(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function Wt(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Ts(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=>Dt(t.content)).join(" | ")}function js(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=>Dt(t.content)).join(`
134
- `)}function Kt(e,t){let n=e.slice().sort((c,l)=>c.sequence-l.sequence||c.timestamp.localeCompare(l.timestamp)||c.id.localeCompare(l.id)),r=n.map(c=>({id:re("raw",[c.projectId,c.agent,c.nativeSessionId,c.id,String(c.sequence)].join("|")),level:"raw",eventId:c.id,sourceEventId:c.sourceEventId,sequence:c.sequence,type:c.type,role:c.role,timestamp:c.timestamp,sourcePath:c.provenance.sourcePath,payloadDigest:Cs(c.data)})),s=new Map,o=new Map;n.forEach((c,l)=>{let g=r[l];g&&(s.set(c.id,g.id),c.sourceEventId&&o.set(c.sourceEventId,g.id))});let i=t.map(c=>{let l=_([...c.provenance.eventIds.map(g=>s.get(g)),...c.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:re("fact",c.fingerprint),level:"fact",fingerprint:c.fingerprint,kind:c.kind,type:c.type,content:c.content,knowledgeClass:c.knowledgeClass,importanceScore:c.importanceScore,confidence:c.confidence,tags:_([...c.tags,"level:fact",`class:${c.knowledgeClass}`,`kind:${c.kind}`]),rawIds:l,sourcePaths:_(c.provenance.sourcePaths)}}),d=new Map;for(let c of i){let l=Es(c.kind),g=d.get(l)??[];g.push(c),d.set(l,g)}let u=[];for(let c of As){let l=d.get(c);if(!l?.length)continue;let g=l.slice().sort((h,k)=>k.importanceScore-h.importanceScore||k.confidence-h.confidence||h.id.localeCompare(k.id)),b=g.map(h=>h.id);u.push({id:re("scene",`${c}|${b.join("|")}`),level:"scene",kind:c,title:Ms[c],summary:Ts(g),factIds:b,importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:Wt(g.map(h=>h.confidence)),tags:_(["level:scene",`scene:${c}`,...g.flatMap(h=>h.tags)]),sourcePaths:_(g.flatMap(h=>h.sourcePaths))})}let a=new Map(i.map(c=>[c.id,c])),f=[];for(let c of u){let g=c.factIds.map(k=>a.get(k)).filter(k=>!!k).filter(k=>(k.knowledgeClass==="permanent"||k.knowledgeClass==="task")&&k.importanceScore>=.55);if(g.length===0)continue;let b=g.some(k=>k.knowledgeClass==="permanent")?"permanent":"task",h=js(g);f.push({id:re("knowledge",`${c.id}|${b}|${g.map(k=>k.id).join("|")}`),level:"knowledge",knowledgeClass:b,title:c.title,content:h,sceneIds:[c.id],factIds:g.map(k=>k.id),importanceScore:Math.max(...g.map(k=>k.importanceScore)),confidence:Wt(g.map(k=>k.confidence)),tags:_(["level:knowledge",`class:${b}`,`scene:${c.kind}`,...g.flatMap(k=>k.tags)]),sourcePaths:_(g.flatMap(k=>k.sourcePaths))})}let m=[];for(let c of i)for(let l of c.rawIds)m.push({from:l,to:c.id,type:"supports"});for(let c of u)for(let l of c.factIds)m.push({from:l,to:c.id,type:"belongs_to"});for(let c of f)for(let l of c.sceneIds)m.push({from:l,to:c.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:u,knowledge:f,links:m,stats:{raw:r.length,facts:i.length,scenes:u.length,knowledge:f.length,links:m.length}}}function B(){let e=Te(),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),d=n,u=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:d,archiveRemote:u}}function zt(e){return(e||B()).durableMemoryMaxItemsPerSession}function qt(e){return(e||B()).sessionSummaryMaxTokens}var Ht=new q;function Jt(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(Ht.sanitizeValue(r))}catch{}let n=Ht.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 Os(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 Ps(e,t){let n=[],r=new Set;for(let i of e){let d=i.split(`
135
- `).filter(u=>u.trim());for(let u of d){let a=u.trim();if(a.length<15)continue;let f=a.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let m="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?m="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?m="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?m="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?m="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?m="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?m="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(m="file");let c=Os(a,m);if(c<.3)continue;let l=Jt(a);n.push({category:m,text:l,importance:c,sourceSessionId:t})}}let s=B(),o=zt(s);return n.sort((i,d)=>d.importance-i.importance).slice(0,o)}function Rs(e){let t=B(),n=qt(t),o=e.join(`
133
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function ss(e){return S(JSON.stringify(e))}function os(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let s of r){let o=s.replace(/[.,;:!?]+$/gu,"").trim();o&&t.push(o)}}return w(t,30)}function jt(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(y=>y.status==="completed").map(y=>y.title),i=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),d=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),u=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),a=new Set(r.tasks.filter(y=>y.status==="completed").map(y=>y.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),f=w(r.nextActions.filter(y=>!a.has(y.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),m=w([...u,...f],15),c=w(r.tests.slice().reverse(),10),l=w([...(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:Tt(r.currentPhase),task:Tt(r.currentTask),file:s},completed:{phases:w(o,20),tasks:w(i,30)},remaining:{phases:w(d,20),tasks:w(u,30),todos:m},nextAction:f[0],blockers:w(r.blockers.slice().reverse(),10),decisions:w(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:w(r.activeFiles??[],10),modified:w(r.modifiedFiles??[],20),created:w(r.createdFiles??[],20),deleted:w(r.deletedFiles??[],20)},tests:{status:rs(r.tests,r.checks),recent:c,checks:(r.checks??[]).slice(-10).map(y=>({kind:y.kind,status:y.status,command:y.command}))},evidence:{commands:w((r.commands??[]).slice().reverse(),20),references:os([r.currentRequest,r.currentActivity,r.goal,r.plan,...r.decisions,...r.blockers,...r.warnings,...r.nextActions,...r.filesTouched,...r.commands??[],...r.tests,...(r.checks??[]).map(y=>y.command)])},attention:w(e.attention??[],20),progress:r.progress},{capturedAt:b,source:h,...k}=g;return{...g,stateDigest:ss(k)}}function as(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 us(e,t,n,r,s){if(!as(n))return null;let o=Et(e,!1),d=[...o?o.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...n.warnings].slice(0,20),u=jt({project:e,identity:t,state:n,reason:r,sequence:s,attention:d}),a=u.stateDigest;return{version:1,id:S([e.id,t.sessionKey,a].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(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:n.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:u.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:d,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:a,continuity:u}}function ls(e,t){let n=xe(e.rootPath,".toolnet","work","handoffs");cs(n,{recursive:!0});let r=xe(n,`${t.id}.json`);is(r)||T(r,t),T(xe(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function Ot(e){let t=us(e.project,e.identity,e.state,e.reason,e.sequence);return t?(ls(e.project,t),t):null}import{existsSync as Gt,mkdirSync as qs,readFileSync as Hs}from"node:fs";import{join as Ie}from"node:path";function Pt(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 Ft=[/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],ds=[/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],fs=[/\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],ms=[/\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],ps=[/đã 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],Rt=[/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],gs=[/\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],hs=[/đườ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],ys=[/\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],Nt=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ks=new Set(["payload","data","content","message","messages","parts","summary"]);function M(e,t){return t.some(n=>n.test(e))}function Lt(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ss(e){return Lt(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function bs(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 we(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||Nt.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))we(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(Nt.has(s)||ks.has(s))&&we(o,s,n,r+1)}}function xs(e){let t=[];we(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=Lt(o);if(bs(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function _t(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function ws(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&&M(e,Ft)?{kind:"rule",confidence:.98}:r&&M(e,ds)?{kind:"rule",confidence:.92}:M(e,fs)?{kind:M(e,Rt)?"architecture":"decision",confidence:r?.93:.86}:r&&M(e,ms)?{kind:"todo",confidence:.87}:M(e,Rt)&&M(e,gs)?{kind:"architecture",confidence:r?.88:.82}:s&&M(e,ps)?{kind:"fix",confidence:.8}:r&&M(e,hs)&&M(e,ys)?{kind:"context",confidence:.79}:null}function vs(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Is(e,t,n){return e==="rule"&&M(n,Ft)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Pt(t,n)}function $t(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,d=_t(o);i&&d&&s.set(i,d)}for(let o of t){let i=_t(o),d=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&d&&(i=s.get(d)??"");for(let u of xs(o)){let a=ws(u,i,o);if(!a||a.confidence<.75)continue;let f=vs(a.kind),m=Ss(u),c=S([e.projectId,a.kind,m].join("|"));if(r.has(c))continue;r.add(c);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:c,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:a.kind,type:f,content:u,confidence:a.confidence,importance:Is(a.kind,f,u),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 As}from"node:crypto";var Ms=["project-knowledge","implementation","continuation","session-context"],Cs={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function ve(e){return As("sha256").update(e).digest("hex")}function re(e,t){return`${e}:${ve(t).slice(0,24)}`}function Es(e){try{return ve(JSON.stringify(e))}catch{return ve(String(e))}}function _(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 Dt(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 Ts(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function Wt(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function js(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=>Dt(t.content)).join(" | ")}function Os(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=>Dt(t.content)).join(`
134
+ `)}function Kt(e,t){let n=e.slice().sort((c,l)=>c.sequence-l.sequence||c.timestamp.localeCompare(l.timestamp)||c.id.localeCompare(l.id)),r=n.map(c=>({id:re("raw",[c.projectId,c.agent,c.nativeSessionId,c.id,String(c.sequence)].join("|")),level:"raw",eventId:c.id,sourceEventId:c.sourceEventId,sequence:c.sequence,type:c.type,role:c.role,timestamp:c.timestamp,sourcePath:c.provenance.sourcePath,payloadDigest:Es(c.data)})),s=new Map,o=new Map;n.forEach((c,l)=>{let g=r[l];g&&(s.set(c.id,g.id),c.sourceEventId&&o.set(c.sourceEventId,g.id))});let i=t.map(c=>{let l=_([...c.provenance.eventIds.map(g=>s.get(g)),...c.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:re("fact",c.fingerprint),level:"fact",fingerprint:c.fingerprint,kind:c.kind,type:c.type,content:c.content,knowledgeClass:c.knowledgeClass,importanceScore:c.importanceScore,confidence:c.confidence,tags:_([...c.tags,"level:fact",`class:${c.knowledgeClass}`,`kind:${c.kind}`]),rawIds:l,sourcePaths:_(c.provenance.sourcePaths)}}),d=new Map;for(let c of i){let l=Ts(c.kind),g=d.get(l)??[];g.push(c),d.set(l,g)}let u=[];for(let c of Ms){let l=d.get(c);if(!l?.length)continue;let g=l.slice().sort((h,k)=>k.importanceScore-h.importanceScore||k.confidence-h.confidence||h.id.localeCompare(k.id)),b=g.map(h=>h.id);u.push({id:re("scene",`${c}|${b.join("|")}`),level:"scene",kind:c,title:Cs[c],summary:js(g),factIds:b,importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:Wt(g.map(h=>h.confidence)),tags:_(["level:scene",`scene:${c}`,...g.flatMap(h=>h.tags)]),sourcePaths:_(g.flatMap(h=>h.sourcePaths))})}let a=new Map(i.map(c=>[c.id,c])),f=[];for(let c of u){let g=c.factIds.map(k=>a.get(k)).filter(k=>!!k).filter(k=>(k.knowledgeClass==="permanent"||k.knowledgeClass==="task")&&k.importanceScore>=.55);if(g.length===0)continue;let b=g.some(k=>k.knowledgeClass==="permanent")?"permanent":"task",h=Os(g);f.push({id:re("knowledge",`${c.id}|${b}|${g.map(k=>k.id).join("|")}`),level:"knowledge",knowledgeClass:b,title:c.title,content:h,sceneIds:[c.id],factIds:g.map(k=>k.id),importanceScore:Math.max(...g.map(k=>k.importanceScore)),confidence:Wt(g.map(k=>k.confidence)),tags:_(["level:knowledge",`class:${b}`,`scene:${c.kind}`,...g.flatMap(k=>k.tags)]),sourcePaths:_(g.flatMap(k=>k.sourcePaths))})}let m=[];for(let c of i)for(let l of c.rawIds)m.push({from:l,to:c.id,type:"supports"});for(let c of u)for(let l of c.factIds)m.push({from:l,to:c.id,type:"belongs_to"});for(let c of f)for(let l of c.sceneIds)m.push({from:l,to:c.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:u,knowledge:f,links:m,stats:{raw:r.length,facts:i.length,scenes:u.length,knowledge:f.length,links:m.length}}}function B(){let e=Te(),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),d=n,u=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:d,archiveRemote:u}}function zt(e){return(e||B()).durableMemoryMaxItemsPerSession}function qt(e){return(e||B()).sessionSummaryMaxTokens}var Ht=new q;function Jt(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(Ht.sanitizeValue(r))}catch{}let n=Ht.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 Ps(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 Rs(e,t){let n=[],r=new Set;for(let i of e){let d=i.split(`
135
+ `).filter(u=>u.trim());for(let u of d){let a=u.trim();if(a.length<15)continue;let f=a.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let m="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?m="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?m="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?m="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?m="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?m="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?m="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(m="file");let c=Ps(a,m);if(c<.3)continue;let l=Jt(a);n.push({category:m,text:l,importance:c,sourceSessionId:t})}}let s=B(),o=zt(s);return n.sort((i,d)=>d.importance-i.importance).slice(0,o)}function Ns(e){let t=B(),n=qt(t),o=e.join(`
136
136
 
137
137
  `).split(`
138
138
  `).filter(i=>{let d=i.trim();return d.length>20&&!d.startsWith("npm")&&!d.startsWith("\u2713")&&!d.startsWith("Error:")}).slice(0,20).map(i=>Jt(i)).join(`
139
139
  `);return ae(o,n)}function Bt(e,t){let r=(Array.isArray(e)?e:e.split(`
140
140
 
141
- `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Ps(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),d=s.filter(l=>l.category==="file").map(l=>l.text),u=s.filter(l=>l.category==="fix").map(l=>l.text),a=s.filter(l=>l.category==="blocker").map(l=>l.text),f=s.filter(l=>l.category==="next_action").map(l=>l.text),m=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Rs(r),decisions:o,projectRules:i,filesChanged:d,bugsFixed:u,commands:m,blockers:a,nextActions:f,durableFacts:s}}function j(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 Ns(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 _s(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Fs(e){let t=_s(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function Ls(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 $s(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 Ws(e){let t=Ls(e),n=Fs(e),r=$s(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:j([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Ds(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 Ks(e,t,n){let r=Bt(Ds(t),e.nativeSessionId),s=n.filter(a=>a.kind==="todo").map(a=>a.content),o=n.flatMap(a=>a.provenance.sourcePaths),i=n.filter(a=>a.kind==="architecture").map(a=>a.content),d=j([...s,...r.nextActions]),u=j([...r.nextActions,...s]);return{summary:r.summary,state:{task:u[0]??d[0],decisions:j(r.decisions),files:j([...r.filesChanged,...o]),todos:d,completed:j(r.bugsFixed),blockers:j(r.blockers),nextActions:u,architecture:j(i)}}}function Vt(e,t){let n=Ns(t),r=$t(e,n).map(Ws),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,m)=>m.importanceScore-f.importanceScore),{summary:o,state:i}=Ks(e,n,s),d=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),u=Kt(n,s),a=f=>r.filter(m=>m.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:d,hierarchy:u,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:a("permanent"),task:a("task"),session:a("session"),transient:a("transient")}}}function Ut(e){return Ie(e.rootPath,".toolnet","memory","checkpoints")}function Yt(e){return Ie(Ut(e),"latest.json")}function Hs(e){let t=Yt(e);if(!Gt(t))return null;try{let n=JSON.parse(qs(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Js(e){return["rule","architecture","decision","fix"].includes(e)}function Bs(e,t){return t.length===0?[]:Vt(e,t).candidates.filter(r=>Js(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 Vs(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 Gs(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 Xt(e,t,n,r){let s=Hs(e),o=Vs(s?.durableFacts??[],Bs(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,d=r.phases.filter(h=>h.status==="completed").map(h=>h.title),u=r.tasks.filter(h=>h.status==="completed").map(h=>h.title),a=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),m={work:Gs(r),durableFacts:o.map(h=>h.fingerprint).sort()},c=S(JSON.stringify(m)).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:d,tasks:u},remaining:{phases:a,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:c},g=Ut(e);zs(g,{recursive:!0,mode:448});let b=Ie(g,`${c}.json`);return Gt(b)||T(b,l),T(Yt(e),l),l}function Zt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ft(t,n);if(r.length===0)return{updated:!1,observations:0};let s=bt(e,r);vt(e,s),tt(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Xt(e,t,n,s)}catch{}try{Ot({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}function Us(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function F(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ys(e){let t=F(e.timestamp);if(t){let n=new Date(t);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Qt(e,t){let n=F(e.hook_event_name);if(!n)return[];let r=F(e.session_id)??"claude",s=F(e.cwd)??t.rootPath,o=F(e.tool_name),i=F(e.tool_use_id),d=Us(e.tool_input),u=F(d.file_path),a=["claude",r,n,i??"",u??""].join(":"),f={timestamp:Ys(e),cwd:s,source:"claude",provenance:{source:"claude-hook"}};return n==="SessionStart"?[{...f,type:"session_start",sourceEventId:`${a}:start`,data:{sessionId:r,cwd:s}}]:n==="PostToolUse"?(o==="Edit"||o==="Write")&&u?[{...f,type:o==="Edit"?"file_edit":"file_write",sourceEventId:`${a}:file`,data:{tool:o,filePath:u},provenance:{source:"claude-hook",files:[u]}}]:[{...f,type:"tool_result",sourceEventId:`${a}:tool-result`,data:{tool:o}}]:n==="Stop"?[{...f,type:"session_idle",sourceEventId:`${a}:idle`,data:{sessionId:r}}]:[{...f,type:"custom",sourceEventId:`${a}:custom`,data:{hookEvent:n}}]}var en=3200;function tn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function oo(e){return e.length<=en?e:`${e.slice(0,en)}
141
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Rs(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),d=s.filter(l=>l.category==="file").map(l=>l.text),u=s.filter(l=>l.category==="fix").map(l=>l.text),a=s.filter(l=>l.category==="blocker").map(l=>l.text),f=s.filter(l=>l.category==="next_action").map(l=>l.text),m=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Ns(r),decisions:o,projectRules:i,filesChanged:d,bugsFixed:u,commands:m,blockers:a,nextActions:f,durableFacts:s}}function j(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 _s(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 Fs(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Ls(e){let t=Fs(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function $s(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 Ws(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 Ds(e){let t=$s(e),n=Ls(e),r=Ws(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:j([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Ks(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 zs(e,t,n){let r=Bt(Ks(t),e.nativeSessionId),s=n.filter(a=>a.kind==="todo").map(a=>a.content),o=n.flatMap(a=>a.provenance.sourcePaths),i=n.filter(a=>a.kind==="architecture").map(a=>a.content),d=j([...s,...r.nextActions]),u=j([...r.nextActions,...s]);return{summary:r.summary,state:{task:u[0]??d[0],decisions:j(r.decisions),files:j([...r.filesChanged,...o]),todos:d,completed:j(r.bugsFixed),blockers:j(r.blockers),nextActions:u,architecture:j(i)}}}function Vt(e,t){let n=_s(t),r=$t(e,n).map(Ds),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,m)=>m.importanceScore-f.importanceScore),{summary:o,state:i}=zs(e,n,s),d=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),u=Kt(n,s),a=f=>r.filter(m=>m.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:d,hierarchy:u,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:a("permanent"),task:a("task"),session:a("session"),transient:a("transient")}}}function Ut(e){return Ie(e.rootPath,".toolnet","memory","checkpoints")}function Yt(e){return Ie(Ut(e),"latest.json")}function Js(e){let t=Yt(e);if(!Gt(t))return null;try{let n=JSON.parse(Hs(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Bs(e){return["rule","architecture","decision","fix"].includes(e)}function Vs(e,t){return t.length===0?[]:Vt(e,t).candidates.filter(r=>Bs(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 Gs(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 Us(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 Xt(e,t,n,r){let s=Js(e),o=Gs(s?.durableFacts??[],Vs(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,d=r.phases.filter(h=>h.status==="completed").map(h=>h.title),u=r.tasks.filter(h=>h.status==="completed").map(h=>h.title),a=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),m={work:Us(r),durableFacts:o.map(h=>h.fingerprint).sort()},c=S(JSON.stringify(m)).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:d,tasks:u},remaining:{phases:a,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:c},g=Ut(e);qs(g,{recursive:!0,mode:448});let b=Ie(g,`${c}.json`);return Gt(b)||T(b,l),T(Yt(e),l),l}function Zt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ft(t,n);if(r.length===0)return{updated:!1,observations:0};let s=bt(e,r);vt(e,s),tt(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Xt(e,t,n,s)}catch{}try{Ot({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}function Ys(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function F(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Xs(e){let t=F(e.timestamp);if(t){let n=new Date(t);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Qt(e,t){let n=F(e.hook_event_name);if(!n)return[];let r=F(e.session_id)??"claude",s=F(e.cwd)??t.rootPath,o=F(e.tool_name),i=F(e.tool_use_id),d=Ys(e.tool_input),u=F(d.file_path),a=["claude",r,n,i??"",u??""].join(":"),f={timestamp:Xs(e),cwd:s,source:"claude",provenance:{source:"claude-hook"}};return n==="SessionStart"?[{...f,type:"session_start",sourceEventId:`${a}:start`,data:{sessionId:r,cwd:s}}]:n==="PostToolUse"?(o==="Edit"||o==="Write")&&u?[{...f,type:o==="Edit"?"file_edit":"file_write",sourceEventId:`${a}:file`,data:{tool:o,filePath:u},provenance:{source:"claude-hook",files:[u]}}]:[{...f,type:"tool_result",sourceEventId:`${a}:tool-result`,data:{tool:o}}]:n==="Stop"?[{...f,type:"session_idle",sourceEventId:`${a}:idle`,data:{sessionId:r}}]:[{...f,type:"custom",sourceEventId:`${a}:custom`,data:{hookEvent:n}}]}var en=3200;function tn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function io(e){return e.length<=en?e:`${e.slice(0,en)}
142
142
 
143
- [ToolNet startup context truncated]`}function io(e){let t=me(e);return t?new Y().detect(t)??null:null}function co(e){return rn(e.rootPath,".toolnet","context","session-origin.json")}function ao(e,t){if(!ro(t))return t;let n=so(e.rootPath,t);return n.startsWith("..")?t:n}function uo(e,t){let n=typeof t.session_id=="string"&&t.session_id.trim()?t.session_id.trim():"claude",r=Qt(t,e);if(r.length===0)return;let s=st(e,"claude",n),i=new ee(s,{source:"claude",cwd:typeof t.cwd=="string"?t.cwd:e.rootPath}).append(r);Zt(e,s,i)}function nn(e,t){let n=co(e),r={};if(Xs(n))try{let a=JSON.parse(Qs(n,"utf8"));tn(a)&&a.projectId===e.id&&(r=a)}catch{}let s,o=t.tool_input;tn(o)&&typeof o.file_path=="string"&&(s=ao(e,o.file_path));let i=typeof t.session_id=="string"?t.session_id:typeof r.nativeSessionId=="string"?r.nativeSessionId:"claude",d={...r,version:1,projectId:e.id,agent:"claude",nativeSessionId:i,updatedAt:new Date().toISOString()};s&&(d.lastTouchedFile=s),Zs(rn(e.rootPath,".toolnet","context"),{recursive:!0,mode:448});let u=`${n}.tmp-${process.pid}-${Date.now()}`;try{no(u,JSON.stringify(d,null,2)+`
144
- `,{encoding:"utf8",mode:384}),eo(u,n)}finally{to(u,{force:!0})}}function sn(e){let t=typeof e.hook_event_name=="string"?e.hook_event_name:"",n=typeof e.cwd=="string"?e.cwd:"";if(!n)return{};let r=io(n);if(!r)return{};try{try{uo(r,e)}catch{}if(t==="SessionStart"){let s=Qe({projectPath:n});return s?.trim()?{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:oo(s)}}:{}}if(t==="PostToolUse"){nn(r,e);try{pe(r)}catch{}return{}}if(t==="Stop"){nn(r,e);try{pe(r)}catch{}return{}}return{}}catch{return{}}}async function lo(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function fo(){let e=await lo(),t=sn(e);process.stdout.write(JSON.stringify(t))}fo().catch(()=>{process.stdout.write("{}"),process.exitCode=0});
143
+ [ToolNet startup context truncated]`}function co(e){let t=me(e);return t?new Y().detect(t)??null:null}function ao(e){return rn(e.rootPath,".toolnet","context","session-origin.json")}function uo(e,t){if(!so(t))return t;let n=oo(e.rootPath,t);return n.startsWith("..")?t:n}function lo(e,t){let n=typeof t.session_id=="string"&&t.session_id.trim()?t.session_id.trim():"claude",r=Qt(t,e);if(r.length===0)return;let s=st(e,"claude",n),i=new ee(s,{source:"claude",cwd:typeof t.cwd=="string"?t.cwd:e.rootPath}).append(r);Zt(e,s,i)}function nn(e,t){let n=ao(e),r={};if(Zs(n))try{let a=JSON.parse(eo(n,"utf8"));tn(a)&&a.projectId===e.id&&(r=a)}catch{}let s,o=t.tool_input;tn(o)&&typeof o.file_path=="string"&&(s=uo(e,o.file_path));let i=typeof t.session_id=="string"?t.session_id:typeof r.nativeSessionId=="string"?r.nativeSessionId:"claude",d={...r,version:1,projectId:e.id,agent:"claude",nativeSessionId:i,updatedAt:new Date().toISOString()};s&&(d.lastTouchedFile=s),Qs(rn(e.rootPath,".toolnet","context"),{recursive:!0,mode:448});let u=`${n}.tmp-${process.pid}-${Date.now()}`;try{ro(u,JSON.stringify(d,null,2)+`
144
+ `,{encoding:"utf8",mode:384}),to(u,n)}finally{no(u,{force:!0})}}function sn(e){let t=typeof e.hook_event_name=="string"?e.hook_event_name:"",n=typeof e.cwd=="string"?e.cwd:"";if(!n)return{};let r=co(n);if(!r)return{};try{try{lo(r,e)}catch{}if(t==="SessionStart"){let s=Qe({projectPath:n});return s?.trim()?{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:io(s)}}:{}}if(t==="PostToolUse"){nn(r,e);try{pe(r)}catch{}return{}}if(t==="Stop"){nn(r,e);try{pe(r)}catch{}return{}}return{}}catch{return{}}}async function fo(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function mo(){let e=await fo(),t=sn(e);process.stdout.write(JSON.stringify(t))}mo().catch(()=>{process.stdout.write("{}"),process.exitCode=0});