toolnet-memory 0.3.16 → 0.3.17

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.
Files changed (45) hide show
  1. package/.env.example +74 -0
  2. package/.release-target +1 -1
  3. package/README.md +165 -7
  4. package/bin/toolnet-memory +12 -0
  5. package/bundle/agy-hook.js +59 -59
  6. package/bundle/agy.js +58 -58
  7. package/bundle/api.js +15 -15
  8. package/bundle/audit.js +2 -0
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/code-capabilities.js +2 -0
  11. package/bundle/codex.js +63 -63
  12. package/bundle/context-runtime.js +41 -41
  13. package/bundle/context.js +15 -15
  14. package/bundle/copilot-hook.js +73 -73
  15. package/bundle/cursor-hook.js +73 -73
  16. package/bundle/docker-healthcheck.js +3 -0
  17. package/bundle/doctor.js +4 -4
  18. package/bundle/full-index.js +20 -19
  19. package/bundle/gc.js +5 -3
  20. package/bundle/graph-cli.js +1 -1
  21. package/bundle/graph-index.js +5 -4
  22. package/bundle/graph-ui.js +4 -3
  23. package/bundle/grok-hook.js +52 -52
  24. package/bundle/handoff-refresh.js +2 -2
  25. package/bundle/help-cli.js +4 -4
  26. package/bundle/impact.js +5 -4
  27. package/bundle/incremental.js +5 -5
  28. package/bundle/init.js +35 -35
  29. package/bundle/kiro-hook.js +74 -74
  30. package/bundle/learner.js +8 -6
  31. package/bundle/mcp.js +19 -17
  32. package/bundle/memory-agent.js +4 -4
  33. package/bundle/memory-query.js +3 -3
  34. package/bundle/opencode.js +73 -73
  35. package/bundle/project-manual.js +7 -7
  36. package/bundle/public/index.html +51 -2
  37. package/bundle/runtime.js +16 -13
  38. package/bundle/semantic.js +6 -5
  39. package/bundle/service.js +11 -6
  40. package/bundle/snapshot.js +6 -4
  41. package/bundle/status-cli.js +4 -4
  42. package/bundle/toolnet-cli.js +49 -49
  43. package/bundle/work-continuity.js +7 -7
  44. package/package.json +26 -2
  45. package/release-manifest.json +94 -5
@@ -1,35 +1,35 @@
1
- import{existsSync as fs,mkdirSync as ms,readFileSync as gs,renameSync as ys,rmSync as hs,writeFileSync as Ss}from"node:fs";import{dirname as ks}from"node:path";import{homedir as ps}from"node:os";import{join as In}from"node:path";function Cn(e={}){return In(e.home??ps(),".toolnetcli")}function Fe(e={}){let t=e.cwd??process.cwd();return In(t,".toolnet","mcp.json")}function Et(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function vs(e){if(!fs(e))return{};let t=gs(e,"utf8").trim();if(!t)return{};let n;try{n=JSON.parse(t)}catch{throw new Error(`Invalid existing ToolNet CLI MCP config at ${e}: parse error. Not overwriting.`)}if(!Et(n))throw new Error(`Invalid existing ToolNet CLI MCP config at ${e}: root must be a JSON object. Not overwriting.`);return n}function ws(e,t){ms(ks(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;try{Ss(n,`${JSON.stringify(t,null,2)}
2
- `,{encoding:"utf8",mode:384}),ys(n,e)}finally{hs(n,{force:!0})}}function jn(e={}){let t=e.binary??"toolnet-memory",n=e.configFile??Fe({cwd:e.cwd}),r=vs(n),o="toolnet-memory";if(Et(r.mcpServers)&&r.mcpServers[o]!=null&&!e.force)return{installed:!0,changed:!1,configFile:n};let i=Et(r.mcpServers)?{...r.mcpServers}:{};return i[o]={command:t,args:["mcp"]},r.mcpServers=i,ws(n,r),{installed:!0,changed:!0,configFile:n}}function An(e={}){let t=e.binary??"toolnet-memory",n=jn({binary:t,configFile:e.configFile,force:e.force,cwd:e.cwd});return{installed:n.installed,changed:n.changed,mcp:{...n,configured:n.installed},files:[n.configFile]}}import{existsSync as Sn}from"node:fs";import{spawnSync as Il}from"node:child_process";var bs={mcp:!0,continuityRead:!0,nativeCapture:!1,lifecycleHooks:!1,sharedJournalWrite:!1,level:"mcp-only"},Ot={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!1,sharedJournalWrite:!0,level:"native-capture"},X={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!0,sharedJournalWrite:!0,level:"native-capture"},xs={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!0,sharedJournalWrite:!0,level:"native-capture"};function K(e,t,n){return{agent:e,...t,refreshMode:n}}var Cd={agy:K("agy",X,"native-lifecycle"),opencode:K("opencode",xs,"persistent-plugin"),codex:K("codex",X,"native-lifecycle"),claude:K("claude",X,"native-lifecycle"),kiro:K("kiro",X,"native-lifecycle"),cursor:K("cursor",X,"native-lifecycle"),copilot:K("copilot",X,"native-lifecycle"),grok:K("grok",X,"native-lifecycle"),"toolnet-cli":K("toolnet-cli",Ot,"native-session"),kilo:K("kilo",bs,"mcp-only")};import{existsSync as gl,readFileSync as yl}from"node:fs";import{homedir as hl}from"node:os";import{join as gn}from"node:path";var Is=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],Cs=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function Mn(e){return e.normalize("NFKC").trim().toLowerCase()}function js(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let o=r/e.length;n-=o*Math.log2(o)}return n}function As(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function Ms(e,t,n){let r=e.slice(Math.max(0,t-48),t),o=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function Ps(e,t){return e.start<t.end&&t.start<e.end}function Pn(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var We=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=Mn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of Is){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=Pn(n),o=[];for(let s of r)o.some(i=>Ps(i,s))||o.push(s);return Pn(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=Mn(t);return Cs.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of t.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||As(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Ms(t,o.index,o.index+s.length)&&(js(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var B=class{scanner;constructor(t={}){this.scanner=new We(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,o=[...n].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...s].sort()}}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,o]of Object.entries(t)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(o)}return n}return t}};import{join as Ks}from"node:path";import{createHash as Ts}from"node:crypto";import{dirname as Es}from"node:path";import{mkdirSync as Os,readFileSync as Ns,renameSync as Rs,writeFileSync as _s}from"node:fs";function w(e){return Ts("sha256").update(e).digest("hex")}function Nt(e){if(Array.isArray(e))return e.map(Nt);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=Nt(t[r]);return n}return e}function De(e){return JSON.stringify(Nt(e))}function ze(e){try{return JSON.parse(Ns(e,"utf8"))}catch{return null}}function O(e,t){Os(Es(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;_s(n,JSON.stringify(t,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Rs(n,e)}function Tn(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),o=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${o}`;let s=r.slice(0,100);return s===n&&n.length<=100?s:`${s.slice(0,85)}--${o}`}function En(e,t,n){let r=t.trim(),o=n.trim();if(!r)throw new Error("Session agent is required");if(!o)throw new Error("Native session ID is required");let s=Tn(r.toLowerCase(),"agent"),i=Tn(o,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:o,sessionKey:`${r}:${o}`,remotePrefix:["projects",e.id,"runtime","sources",s,i].join("/"),localDirectory:Ks(e.rootPath,".toolnet","runtime","sources",s,i)}}function On(e){return String(e).padStart(12,"0")}var qe=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)+`
1
+ import{existsSync as Ns,mkdirSync as Rs,readFileSync as _s,renameSync as Ks,rmSync as Ls,writeFileSync as $s}from"node:fs";import{dirname as Fs}from"node:path";import{homedir as Os}from"node:os";import{join as Rn}from"node:path";function _n(e={}){return Rn(e.home??Os(),".toolnetcli")}function Be(e={}){let t=e.cwd??process.cwd();return Rn(t,".toolnet","mcp.json")}function Kt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ds(e){if(!Ns(e))return{};let t=_s(e,"utf8").trim();if(!t)return{};let n;try{n=JSON.parse(t)}catch{throw new Error(`Invalid existing ToolNet CLI MCP config at ${e}: parse error. Not overwriting.`)}if(!Kt(n))throw new Error(`Invalid existing ToolNet CLI MCP config at ${e}: root must be a JSON object. Not overwriting.`);return n}function Ws(e,t){Rs(Fs(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;try{$s(n,`${JSON.stringify(t,null,2)}
2
+ `,{encoding:"utf8",mode:384}),Ks(n,e)}finally{Ls(n,{force:!0})}}function Kn(e={}){let t=e.binary??"toolnet-memory",n=e.configFile??Be({cwd:e.cwd}),r=Ds(n),o="toolnet-memory";if(Kt(r.mcpServers)&&r.mcpServers[o]!=null&&!e.force)return{installed:!0,changed:!1,configFile:n};let i=Kt(r.mcpServers)?{...r.mcpServers}:{};return i[o]={command:t,args:["mcp"]},r.mcpServers=i,Ws(n,r),{installed:!0,changed:!0,configFile:n}}function Ln(e={}){let t=e.binary??"toolnet-memory",n=Kn({binary:t,configFile:e.configFile,force:e.force,cwd:e.cwd});return{installed:n.installed,changed:n.changed,mcp:{...n,configured:n.installed},files:[n.configFile]}}import{existsSync as xn}from"node:fs";import{spawnSync as Bl}from"node:child_process";var zs={mcp:!0,continuityRead:!0,nativeCapture:!1,lifecycleHooks:!1,sharedJournalWrite:!1,level:"mcp-only"},Lt={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!1,sharedJournalWrite:!0,level:"native-capture"},Q={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!0,sharedJournalWrite:!0,level:"native-capture"},qs={mcp:!0,continuityRead:!0,nativeCapture:!0,lifecycleHooks:!0,sharedJournalWrite:!0,level:"native-capture"};function L(e,t,n){return{agent:e,...t,refreshMode:n}}var Zd={agy:L("agy",Q,"native-lifecycle"),opencode:L("opencode",qs,"persistent-plugin"),codex:L("codex",Q,"native-lifecycle"),claude:L("claude",Q,"native-lifecycle"),kiro:L("kiro",Q,"native-lifecycle"),cursor:L("cursor",Q,"native-lifecycle"),copilot:L("copilot",Q,"native-lifecycle"),grok:L("grok",Q,"native-lifecycle"),"toolnet-cli":L("toolnet-cli",Lt,"native-session"),kilo:L("kilo",zs,"mcp-only")};import{existsSync as _l,readFileSync as Kl}from"node:fs";import{homedir as Ll}from"node:os";import{join as vn}from"node:path";var Bs=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],Vs=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function $n(e){return e.normalize("NFKC").trim().toLowerCase()}function Js(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let o=r/e.length;n-=o*Math.log2(o)}return n}function Hs(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function Gs(e,t,n){let r=e.slice(Math.max(0,t-48),t),o=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function Us(e,t){return e.start<t.end&&t.start<e.end}function Fn(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var Ve=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=$n(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of Bs){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=Fn(n),o=[];for(let s of r)o.some(i=>Us(i,s))||o.push(s);return Fn(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=$n(t);return Vs.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of t.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||Hs(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Gs(t,o.index,o.index+s.length)&&(Js(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var J=class{scanner;constructor(t={}){this.scanner=new Ve(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,o=[...n].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...s].sort()}}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,o]of Object.entries(t)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(o)}return n}return t}};import{join as ni}from"node:path";import{createHash as Ys}from"node:crypto";import{dirname as Xs}from"node:path";import{mkdirSync as Qs,readFileSync as Zs,renameSync as ei,writeFileSync as ti}from"node:fs";function w(e){return Ys("sha256").update(e).digest("hex")}function $t(e){if(Array.isArray(e))return e.map($t);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=$t(t[r]);return n}return e}function Je(e){return JSON.stringify($t(e))}function He(e){try{return JSON.parse(Zs(e,"utf8"))}catch{return null}}function N(e,t){Qs(Xs(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;ti(n,JSON.stringify(t,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),ei(n,e)}function Dn(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),o=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${o}`;let s=r.slice(0,100);return s===n&&n.length<=100?s:`${s.slice(0,85)}--${o}`}function Wn(e,t,n){let r=t.trim(),o=n.trim();if(!r)throw new Error("Session agent is required");if(!o)throw new Error("Native session ID is required");let s=Dn(r.toLowerCase(),"agent"),i=Dn(o,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:o,sessionKey:`${r}:${o}`,remotePrefix:["projects",e.id,"runtime","sources",s,i].join("/"),localDirectory:ni(e.rootPath,".toolnet","runtime","sources",s,i)}}function zn(e){return String(e).padStart(12,"0")}var Ge=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)+`
4
4
  `,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),o=[],s=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)||(o.push({key:i.key,start:c,end:u}),s=Math.max(s,u))}return o.sort((i,a)=>i.start-a.start),{chunks:o,maxSequence:s}}split(t){let n=[],r=[],o=0;for(let s of t){let i=Buffer.byteLength(JSON.stringify(s)+`
5
- `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||o+i>this.maxChunkBytes)&&(n.push(r),r=[],o=0),r.push(s),o+=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,o={}){let s=await this.loadManifest(t),i=await this.scan(t),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let S=g[0],v=g[g.length-1],x=g.map(E=>JSON.stringify(E)).join(`
5
+ `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||o+i>this.maxChunkBytes)&&(n.push(r),r=[],o=0),r.push(s),o+=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,o={}){let s=await this.loadManifest(t),i=await this.scan(t),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let S=g[0],v=g[g.length-1],x=g.map(O=>JSON.stringify(O)).join(`
6
6
  `)+`
7
- `,T=w(x).slice(0,16),M=[t.remotePrefix,"events",`${On(S.sequence)}-${On(v.sequence)}-${T}.jsonl`].join("/");await this.storage.exists(M)||await this.storage.put(M,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(t),l=n[n.length-1],d=s?.status??"active";l?.type==="session_end"||l?.type==="session_idle"?d="idle":l?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),f=n[0],m={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:s?.createdAt??f?.timestamp??p,updatedAt:l?.timestamp??p,firstEventAt:s?.firstEventAt??f?.timestamp,lastEventAt:l?.timestamp??s?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...s?.metadata,...o.metadata}};(o.title??s?.title)&&(m.title=o.title??s?.title);let h={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`,h),await this.putJson(`${t.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:d}}};import{closeSync as Se,existsSync as Ge,fsyncSync as Dt,mkdirSync as ei,openSync as ke,readFileSync as Hn,readSync as ti,rmSync as Vn,statSync as Ft,truncateSync as ni,writeSync as ri}from"node:fs";import{join as Wt}from"node:path";var Ls=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),$s=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Fs(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Ws(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if($s.has(r))return n}}return null}function Rt(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(s=>Rt(s,t+1));if(!e||typeof e!="object")return e;let n=e,r=Ws(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))Ls.has(Fs(s))||(o[s]=Rt(i,t+1));return o}function Ds(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 Nn(e,t={}){let n={...e.provenance??{}},r=Z(e.source)??Z(t.source)??Z(n.source);return{...e,timestamp:Ds(e.timestamp),source:r,turnId:Z(e.turnId)??Z(t.turnId),cwd:Z(e.cwd)??Z(t.cwd),data:Rt(e.data??{}),provenance:n}}var zs=new B;function ge(e){return zs.sanitizeValue(e)}import{randomUUID as _t}from"node:crypto";import{closeSync as ie,existsSync as ae,fsyncSync as ye,mkdirSync as Kt,openSync as he,readFileSync as Lt,readdirSync as qs,renameSync as Vs,rmSync as Ve,statSync as Bs,writeSync as Be}from"node:fs";import{join as J}from"node:path";var Js=12e4,Hs=80,Gs="reconcile-required";function Us(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function ce(e){return J(e,".toolnet","journal")}function Kn(e){return J(ce(e),"events.jsonl")}function Je(e){return J(ce(e),Gs)}function Ys(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Ln(e){if(!ae(e))return null;try{let t=JSON.parse(Lt(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function Xs(e){if(!ae(e))return!1;let t=0;try{t=Date.now()-Bs(e).mtimeMs}catch{return!1}if(t<=Js)return!1;let n=Ln(e);return n?!Ys(n.pid):!0}function Zs(e){if(!Xs(e))return!1;try{return Ve(e,{force:!0}),!0}catch{return!1}}function $n(e){for(let t=0;t<Hs;t+=1){let n=_t();try{let r=he(e,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return Be(r,`${JSON.stringify(o)}
8
- `,null,"utf8"),ye(r),{fd:r,token:n}}catch(s){throw ie(r),Ve(e,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(Zs(e))continue;Us(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function Fn(e,t){ie(t.fd),Ln(e)?.token===t.token&&Ve(e,{force:!0})}function Rn(e){if(!ae(e))return[];let t="";try{t=Lt(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=r.trim();if(o)try{let s=JSON.parse(o);if(s.version!==1||typeof s.id!="string"||s.id.length===0||typeof s.projectId!="string"||s.projectId.length===0)continue;n.push(s)}catch{}}return n}function Wn(e){if(!ae(e))return[];let t=[];for(let n of qs(e,{withFileTypes:!0})){let r=J(e,n.name);if(n.isDirectory()){t.push(...Wn(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function He(e){let t=null;try{t=he(e,"r"),ye(t)}catch{}finally{if(t===null)return;ie(t)}}function _n(e){let t=Je(e);if(!ae(t))return null;try{return Lt(t,"utf8").trim()||null}catch{return null}}function $t(e){let t=ce(e);Kt(t,{recursive:!0,mode:448});let n=Je(e),r=[_t(),new Date().toISOString()].join("|"),o=he(n,"w",384);try{Be(o,`${r}
9
- `,null,"utf8"),ye(o)}finally{ie(o)}He(t)}function Qs(e,t,n){let r=J(e,`.events.jsonl.tmp-${process.pid}-${_t()}`),o=he(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
7
+ `,T=w(x).slice(0,16),M=[t.remotePrefix,"events",`${zn(S.sequence)}-${zn(v.sequence)}-${T}.jsonl`].join("/");await this.storage.exists(M)||await this.storage.put(M,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(t),d=n[n.length-1],l=s?.status??"active";d?.type==="session_end"||d?.type==="session_idle"?l="idle":d?.type==="error"?l="error":n.length>0&&(l="active");let p=new Date().toISOString(),f=n[0],m={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:l,createdAt:s?.createdAt??f?.timestamp??p,updatedAt:d?.timestamp??p,firstEventAt:s?.firstEventAt??f?.timestamp,lastEventAt:d?.timestamp??s?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...s?.metadata,...o.metadata}};(o.title??s?.title)&&(m.title=o.title??s?.title);let h={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`,h),await this.putJson(`${t.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:l}}};import{closeSync as ve,existsSync as Ze,fsyncSync as Jt,mkdirSync as vi,openSync as we,readFileSync as rr,readSync as wi,rmSync as er,statSync as Bt,truncateSync as bi,writeSync as xi}from"node:fs";import{join as Vt}from"node:path";var ri=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),oi=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function si(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function ii(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(oi.has(r))return n}}return null}function Ft(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(s=>Ft(s,t+1));if(!e||typeof e!="object")return e;let n=e,r=ii(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))ri.has(si(s))||(o[s]=Ft(i,t+1));return o}function ai(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 qn(e,t={}){let n={...e.provenance??{}},r=Z(e.source)??Z(t.source)??Z(n.source);return{...e,timestamp:ai(e.timestamp),source:r,turnId:Z(e.turnId)??Z(t.turnId),cwd:Z(e.cwd)??Z(t.cwd),data:Ft(e.data??{}),provenance:n}}var ci=new J;function ce(e){return ci.sanitizeValue(e)}import{randomUUID as Dt}from"node:crypto";import{closeSync as ue,existsSync as le,fsyncSync as Se,mkdirSync as Wt,openSync as ke,readFileSync as zt,readdirSync as ui,renameSync as li,rmSync as Ue,statSync as di,writeSync as Ye}from"node:fs";import{join as H}from"node:path";var pi=12e4,fi=80,mi="reconcile-required";function gi(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function de(e){return H(e,".toolnet","journal")}function Jn(e){return H(de(e),"events.jsonl")}function Xe(e){return H(de(e),mi)}function yi(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Hn(e){if(!le(e))return null;try{let t=JSON.parse(zt(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function hi(e){if(!le(e))return!1;let t=0;try{t=Date.now()-di(e).mtimeMs}catch{return!1}if(t<=pi)return!1;let n=Hn(e);return n?!yi(n.pid):!0}function Si(e){if(!hi(e))return!1;try{return Ue(e,{force:!0}),!0}catch{return!1}}function Gn(e){for(let t=0;t<fi;t+=1){let n=Dt();try{let r=ke(e,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return Ye(r,`${JSON.stringify(o)}
8
+ `,null,"utf8"),Se(r),{fd:r,token:n}}catch(s){throw ue(r),Ue(e,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(Si(e))continue;gi(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function Un(e,t){ue(t.fd),Hn(e)?.token===t.token&&Ue(e,{force:!0})}function Bn(e){if(!le(e))return[];let t="";try{t=zt(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=r.trim();if(o)try{let s=JSON.parse(o);if(s.version!==1||typeof s.id!="string"||s.id.length===0||typeof s.projectId!="string"||s.projectId.length===0)continue;n.push(s)}catch{}}return n}function Yn(e){if(!le(e))return[];let t=[];for(let n of ui(e,{withFileTypes:!0})){let r=H(e,n.name);if(n.isDirectory()){t.push(...Yn(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function Qe(e){let t=null;try{t=ke(e,"r"),Se(t)}catch{}finally{if(t===null)return;ue(t)}}function Vn(e){let t=Xe(e);if(!le(t))return null;try{return zt(t,"utf8").trim()||null}catch{return null}}function qt(e){let t=de(e);Wt(t,{recursive:!0,mode:448});let n=Xe(e),r=[Dt(),new Date().toISOString()].join("|"),o=ke(n,"w",384);try{Ye(o,`${r}
9
+ `,null,"utf8"),Se(o)}finally{ue(o)}Qe(t)}function ki(e,t,n){let r=H(e,`.events.jsonl.tmp-${process.pid}-${Dt()}`),o=ke(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
10
10
  `)}
11
- `;s&&Be(o,s,null,"utf8"),ye(o)}finally{ie(o)}Vs(r,t),He(e)}function Dn(e){let t=ce(e),n=Kn(e),r=J(e,".toolnet","runtime","sources"),o=_n(e),s=Wn(r),i=[],a=new Set;for(let d of Rn(n))a.has(d.id)||(a.add(d.id),i.push(d));let c=i.length,u=[];for(let d of s)for(let p of Rn(d))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((d,p)=>{let f=d.timestamp.localeCompare(p.timestamp);return f!==0?f:d.id.localeCompare(p.id)}),i.push(...u),Qs(t,n,i);let l=_n(e);return o&&l===o&&(Ve(Je(e),{force:!0}),He(t)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function zn(e){let t=ce(e);Kt(t,{recursive:!0,mode:448});let n=J(t,"journal.lock"),r=$n(n);try{return Dn(e)}finally{Fn(n,r)}}function qn(e,t){if(t.length===0)return;let n=ce(e);Kt(n,{recursive:!0,mode:448});let r=Kn(e),o=J(n,"journal.lock"),s=$n(o);try{if(ae(Je(e))){Dn(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
11
+ `;s&&Ye(o,s,null,"utf8"),Se(o)}finally{ue(o)}li(r,t),Qe(e)}function Xn(e){let t=de(e),n=Jn(e),r=H(e,".toolnet","runtime","sources"),o=Vn(e),s=Yn(r),i=[],a=new Set;for(let l of Bn(n))a.has(l.id)||(a.add(l.id),i.push(l));let c=i.length,u=[];for(let l of s)for(let p of Bn(l))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((l,p)=>{let f=l.timestamp.localeCompare(p.timestamp);return f!==0?f:l.id.localeCompare(p.id)}),i.push(...u),ki(t,n,i);let d=Vn(e);return o&&d===o&&(Ue(Xe(e),{force:!0}),Qe(t)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function Qn(e){let t=de(e);Wt(t,{recursive:!0,mode:448});let n=H(t,"journal.lock"),r=Gn(n);try{return Xn(e)}finally{Un(n,r)}}function Zn(e,t){if(t.length===0)return;let n=de(e);Wt(n,{recursive:!0,mode:448});let r=Jn(e),o=H(n,"journal.lock"),s=Gn(o);try{if(le(Xe(e))){Xn(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
12
12
  `)}
13
- `,a=he(r,"a",384);try{Be(a,i,null,"utf8"),ye(a)}finally{ie(a)}He(n)}finally{Fn(o,s)}}var oi=12e4,si=80,Bn=2e3;function ii(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Gn(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let o=ri(e,n,r,n.length-r);if(o<=0)throw new Error("Unable to write session WAL");r+=o}}function zt(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function ai(e){if(!Ge(e))return[];let t="";try{t=Hn(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=zt(r);o&&n.push(o)}return n}function Jn(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function ci(e){if(!Ge(e))return!1;let t;try{t=Hn(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,o=t.subarray(r).toString("utf8").trim();if(zt(o)){let i=ke(e,"a");try{Gn(i,`
14
- `),Dt(i)}finally{Se(i)}return!0}ni(e,r);let s=ke(e,"a");try{Dt(s)}finally{Se(s)}return!0}function ui(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var Ue=class{constructor(t,n={}){this.identity=t;this.eventContext=n;ei(t.localDirectory,{recursive:!0}),this.eventsFile=Wt(t.localDirectory,"events.jsonl"),this.stateFile=Wt(t.localDirectory,"state.json"),this.lockFile=Wt(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 ze(this.stateFile)??this.initialState()}recoverStateUnsafe(){ci(this.eventsFile);let t=this.loadStateUnsafe(),n=ai(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let d of n)d.sequence<=r.sequence||(r=d);let o=n.slice(-Bn).map(d=>d.id),s=Ge(this.eventsFile)?Ft(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,s),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!ui(t.recentEventIds,o)||t.lastLocalEventAt!==r.timestamp))return t;let l={...t,status:Jn(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(l),!c)return l;try{$t(this.identity.projectRoot)}catch{return l}try{zn(this.identity.projectRoot)}catch{}return l}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){O(this.stateFile,t)}acquireLock(){for(let t=0;t<si;t+=1)try{return ke(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Ft(this.lockFile).mtimeMs>oi){Vn(this.lockFile,{force:!0});continue}}catch{}ii(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Se(n),Vn(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),o=n.lastSequence,s=[];for(let d of t){let p=Nn(d,this.eventContext),f=p.timestamp??new Date().toISOString(),m=p.data??{},h=p.provenance?.rawDigest??w(De(m)),g=ge(m),S=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,o+1,p.type,f,h].join("|"),v=w(S).slice(0,32);if(r.has(v))continue;o+=1;let x={version:1,id:v,sequence:o,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:h}};p.role!==void 0&&(x.role=p.role),p.turnId!==void 0&&(x.turnId=p.turnId),p.cwd!==void 0&&(x.cwd=p.cwd),p.sourceEventId!==void 0&&(x.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(x.sourceSequence=p.sourceSequence),s.push(x),r.add(v)}if(s.length===0)return[];let i=s.map(d=>JSON.stringify(d)).join(`
13
+ `,a=ke(r,"a",384);try{Ye(a,i,null,"utf8"),Se(a)}finally{ue(a)}Qe(n)}finally{Un(o,s)}}var Ii=12e4,Ci=80,tr=2e3;function Ai(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function or(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let o=xi(e,n,r,n.length-r);if(o<=0)throw new Error("Unable to write session WAL");r+=o}}function Ht(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function Ei(e){if(!Ze(e))return[];let t="";try{t=rr(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=Ht(r);o&&n.push(o)}return n}function nr(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function ji(e){if(!Ze(e))return!1;let t;try{t=rr(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,o=t.subarray(r).toString("utf8").trim();if(Ht(o)){let i=we(e,"a");try{or(i,`
14
+ `),Jt(i)}finally{ve(i)}return!0}bi(e,r);let s=we(e,"a");try{Jt(s)}finally{ve(s)}return!0}function Mi(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var et=class{constructor(t,n={}){this.identity=t;this.eventContext=n;vi(t.localDirectory,{recursive:!0}),this.eventsFile=Vt(t.localDirectory,"events.jsonl"),this.stateFile=Vt(t.localDirectory,"state.json"),this.lockFile=Vt(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 He(this.stateFile)??this.initialState()}recoverStateUnsafe(){ji(this.eventsFile);let t=this.loadStateUnsafe(),n=Ei(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let l of n)l.sequence<=r.sequence||(r=l);let o=n.slice(-tr).map(l=>l.id),s=Ze(this.eventsFile)?Bt(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,s),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!Mi(t.recentEventIds,o)||t.lastLocalEventAt!==r.timestamp))return t;let d={...t,status:nr(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(d),!c)return d;try{qt(this.identity.projectRoot)}catch{return d}try{Qn(this.identity.projectRoot)}catch{}return d}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){N(this.stateFile,t)}acquireLock(){for(let t=0;t<Ci;t+=1)try{return we(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Bt(this.lockFile).mtimeMs>Ii){er(this.lockFile,{force:!0});continue}}catch{}Ai(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{ve(n),er(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),o=n.lastSequence,s=[];for(let l of t){let p=qn(l,this.eventContext),f=p.timestamp??new Date().toISOString(),m=p.data??{},h=p.provenance?.rawDigest??w(Je(m)),g=ce(m),S=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,o+1,p.type,f,h].join("|"),v=w(S).slice(0,32);if(r.has(v))continue;o+=1;let x={version:1,id:v,sequence:o,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:h}};p.role!==void 0&&(x.role=p.role),p.turnId!==void 0&&(x.turnId=p.turnId),p.cwd!==void 0&&(x.cwd=p.cwd),p.sourceEventId!==void 0&&(x.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(x.sourceSequence=p.sourceSequence),s.push(x),r.add(v)}if(s.length===0)return[];let i=s.map(l=>JSON.stringify(l)).join(`
15
15
  `)+`
16
- `,a=ke(this.eventsFile,"a",384);try{Gn(a,i),Dt(a)}finally{Se(a)}try{qn(this.identity.projectRoot,s)}catch{try{$t(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=Jn(c),l=Array.from(r).slice(-Bn);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:l}),s})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!Ge(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Ft(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let o=n-r,s=Buffer.alloc(o),i=ke(this.eventsFile,"r");try{ti(i,s,0,o,r)}finally{Se(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=zt(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),o=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:o,updatedAt:o})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as dc,existsSync as pc,openSync as fc,readSync as mc,statSync as gc}from"node:fs";var li=new Set(["rule","blocker","architecture","deploy"]),di=new Set(["fix","todo","context","next_action"]);function qt(e){return e<0?0:e>1?1:e}function Un(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function pi(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function Vt(){return{mode:pi(process.env.TOOLNET_MEMORY_PROMOTION),minScore:qt(Un(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:qt(Un(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function fi(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function mi(e){let t=qt(fi(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function gi(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function yi(e,t=Vt()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=gi(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="next_action"||e.kind==="fix"?"task":"session"}function hi(e,t=Vt()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return li.has(e)&&(r=Math.max(.5,r-.1)),di.has(e)&&(r=Math.max(.5,r-.05)),r}function Bt(e,t=Vt()){let n=yi(e,t),r=mi(e),o=hi(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:{knowledgeClass:n,score:r,threshold:o,persist:r>=o}}function Yn(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 er=[/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],Si=[/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],ki=[/\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],vi=[/\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],wi=[/tiếp theo/iu,/bước tiếp theo/iu,/việc tiếp theo/iu,/sau đó cần/iu,/next step/iu,/next action/iu,/follow[- ]?up/iu],bi=[/đã 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],Xn=[/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],xi=[/\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],Ci=[/\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],Zn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ji=new Set(["payload","data","content","message","messages","parts","summary"]);function N(e,t){return t.some(n=>n.test(e))}function tr(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ai(e){return tr(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Mi(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 Jt(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!Zn.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let o of e.slice(0,50))Jt(o,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[o,s]of Object.entries(e))(Zn.has(o)||ji.has(o))&&Jt(s,o,n,r+1)}}function Pi(e){let t=[];Jt(e.data,void 0,t);let n=[],r=new Set;for(let o of t)for(let s of o.split(/\n+|(?<=[.!?])\s+/u)){let i=tr(s);if(Mi(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Qn(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Ti(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",o=t==="assistant"||n.type==="assistant_message";return r&&N(e,er)?{kind:"rule",confidence:.98}:r&&N(e,Si)?{kind:"rule",confidence:.92}:N(e,ki)?{kind:N(e,Xn)?"architecture":"decision",confidence:r?.93:.86}:r&&N(e,wi)?{kind:"next_action",confidence:.88}:r&&N(e,vi)?{kind:"todo",confidence:.87}:N(e,Xn)&&N(e,xi)?{kind:"architecture",confidence:r?.88:.82}:o&&N(e,bi)?{kind:"fix",confidence:.8}:r&&N(e,Ii)&&N(e,Ci)?{kind:"context",confidence:.79}:null}function Ei(e,t,n){let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message",s=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:s,testVerified:i,crossSessionConfirmations:1,assistantDerived:o}}function Oi(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":case"next_action":return"todo";case"fix":case"context":return"code"}}function Ni(e,t,n){return e==="rule"&&N(n,er)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Yn(t,n)}function nr(e,t){let n=[],r=new Set,o=new Map;for(let s of t){let i=typeof s.data.messageId=="string"?s.data.messageId:void 0,a=Qn(s);i&&a&&o.set(i,a)}for(let s of t){let i=Qn(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of Pi(s)){let u=Ti(c,i,s);if(!u||u.confidence<.75)continue;let l=Oi(u.kind),d=Ai(c),p=w([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let f=s.provenance.sourcePath?[s.provenance.sourcePath]:[],m=s.sourceEventId?[s.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:l,content:c,confidence:u.confidence,importance:Ni(u.kind,l,c),evidence:Ei(u.kind,i,s),tags:[l],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:f,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as Ri}from"node:crypto";var _i=["project-knowledge","implementation","continuation","session-context"],Ki={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Ht(e){return Ri("sha256").update(e).digest("hex")}function Ye(e,t){return`${e}:${Ht(t).slice(0,24)}`}function Li(e){try{return Ht(JSON.stringify(e))}catch{return Ht(String(e))}}function Q(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function or(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 $i(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function rr(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Fi(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=>or(t.content)).join(" | ")}function Wi(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=>or(t.content)).join(`
17
- `)}function sr(e,t){let n=e.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:Ye("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:Li(p.data)})),o=new Map,s=new Map;n.forEach((p,f)=>{let m=r[f];m&&(o.set(p.id,m.id),p.sourceEventId&&s.set(p.sourceEventId,m.id))});let i=t.map(p=>{let f=Q([...p.provenance.eventIds.map(m=>o.get(m)),...p.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:Ye("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:f,sourcePaths:Q(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=$i(p.kind),m=a.get(f)??[];m.push(p),a.set(f,m)}let c=[];for(let p of _i){let f=a.get(p);if(!f?.length)continue;let m=f.slice().sort((g,S)=>S.importanceScore-g.importanceScore||S.confidence-g.confidence||g.id.localeCompare(S.id)),h=m.map(g=>g.id);c.push({id:Ye("scene",`${p}|${h.join("|")}`),level:"scene",kind:p,title:Ki[p],summary:Fi(m),factIds:h,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:rr(m.map(g=>g.confidence)),tags:Q(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:Q(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),l=[];for(let p of c){let m=p.factIds.map(S=>u.get(S)).filter(S=>!!S).filter(S=>(S.knowledgeClass==="permanent"||S.knowledgeClass==="task")&&S.importanceScore>=.55);if(m.length===0)continue;let h=m.some(S=>S.knowledgeClass==="permanent")?"permanent":"task",g=Wi(m);l.push({id:Ye("knowledge",`${p.id}|${h}|${m.map(S=>S.id).join("|")}`),level:"knowledge",knowledgeClass:h,title:p.title,content:g,sceneIds:[p.id],factIds:m.map(S=>S.id),importanceScore:Math.max(...m.map(S=>S.importanceScore)),confidence:rr(m.map(S=>S.confidence)),tags:Q(["level:knowledge",`class:${h}`,`scene:${p.kind}`,...m.flatMap(S=>S.tags)]),sourcePaths:Q(m.flatMap(S=>S.sourcePaths))})}let d=[];for(let p of i)for(let f of p.rawIds)d.push({from:f,to:p.id,type:"supports"});for(let p of c)for(let f of p.factIds)d.push({from:f,to:p.id,type:"belongs_to"});for(let p of l)for(let f of p.sceneIds)d.push({from:f,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:l,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:l.length,links:d.length}}}function Di(e){return e?Math.ceil(e.length/3.5):0}function ir(e,t){if(!e)return"";if(Di(e)<=t)return e;let r=Math.floor(t*3.5),o=e.slice(0,r),s=o.lastIndexOf("."),i=o.lastIndexOf(`
18
- `),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}import{existsSync as zi,readFileSync as qi}from"node:fs";import{homedir as Vi}from"node:os";import{join as Bi}from"node:path";function Ji(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
19
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function Hi(){let e=process.env.TOOLNET_GLOBAL_ENV??Bi(Vi(),".config","toolnet-memory",".env");if(!zi(e))return;let t=qi(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 o=r.indexOf("=");if(o<=0)continue;let s=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Ji(r.slice(o+1)))}}Hi();function ve(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function we(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Xe(){return{memory:{autoCapture:ve(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ve(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ve(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ve(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:we(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:we(process.env.MEMORY_RERANK_TOP,10),finalContext:we(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:we(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:ve(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:we(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}function be(){let e=Xe(),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",o=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),s=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"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:o,sessionSummaryMaxTokens:s,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function ar(e){return(e||be()).durableMemoryMaxItemsPerSession}function cr(e){return(e||be()).sessionSummaryMaxTokens}var ur=new B;function lr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(ur.sanitizeValue(r))}catch{}let n=ur.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 Gi(e,t){let n=e.toLowerCase(),r=.5,o=["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 o)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 s=[/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 s)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Ui(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
20
- `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let l=u.toLowerCase().replace(/\s+/g," ");if(r.has(l))continue;r.add(l);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=Gi(u,d);if(p<.3)continue;let f=lr(u);n.push({category:d,text:f,importance:p,sourceSessionId:t})}}let o=be(),s=ar(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function Yi(e){let t=be(),n=cr(t),s=e.join(`
16
+ `,a=we(this.eventsFile,"a",384);try{or(a,i),Jt(a)}finally{ve(a)}try{Zn(this.identity.projectRoot,s)}catch{try{qt(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=nr(c),d=Array.from(r).slice(-tr);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:d}),s})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!Ze(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Bt(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let o=n-r,s=Buffer.alloc(o),i=we(this.eventsFile,"r");try{wi(i,s,0,o,r)}finally{ve(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=Ht(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),o=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:o,updatedAt:o})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as Tc,existsSync as Oc,openSync as Nc,readSync as Rc,statSync as _c}from"node:fs";var Pi=new Set(["rule","blocker","architecture","deploy"]),Ti=new Set(["fix","todo","context","next_action"]);function Gt(e){return e<0?0:e>1?1:e}function sr(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function Oi(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function Ut(){return{mode:Oi(process.env.TOOLNET_MEMORY_PROMOTION),minScore:Gt(sr(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:Gt(sr(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Ni(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Ri(e){let t=Gt(Ni(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function _i(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Ki(e,t=Ut()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=_i(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="next_action"||e.kind==="fix"?"task":"session"}function Li(e,t=Ut()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return Pi.has(e)&&(r=Math.max(.5,r-.1)),Ti.has(e)&&(r=Math.max(.5,r-.05)),r}function Yt(e,t=Ut()){let n=Ki(e,t),r=Ri(e),o=Li(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:{knowledgeClass:n,score:r,threshold:o,persist:r>=o}}function ir(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 lr=[/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],$i=[/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],Fi=[/\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],Di=[/\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],Wi=[/tiếp theo/iu,/bước tiếp theo/iu,/việc tiếp theo/iu,/sau đó cần/iu,/next step/iu,/next action/iu,/follow[- ]?up/iu],zi=[/đã 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],ar=[/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],qi=[/\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],Bi=[/đườ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],Vi=[/\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],cr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Ji=new Set(["payload","data","content","message","messages","parts","summary"]);function R(e,t){return t.some(n=>n.test(e))}function dr(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Hi(e){return dr(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Gi(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 Xt(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!cr.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let o of e.slice(0,50))Xt(o,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[o,s]of Object.entries(e))(cr.has(o)||Ji.has(o))&&Xt(s,o,n,r+1)}}function Ui(e){let t=[];Xt(e.data,void 0,t);let n=[],r=new Set;for(let o of t)for(let s of o.split(/\n+|(?<=[.!?])\s+/u)){let i=dr(s);if(Gi(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function ur(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Yi(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",o=t==="assistant"||n.type==="assistant_message";return r&&R(e,lr)?{kind:"rule",confidence:.98}:r&&R(e,$i)?{kind:"rule",confidence:.92}:R(e,Fi)?{kind:R(e,ar)?"architecture":"decision",confidence:r?.93:.86}:r&&R(e,Wi)?{kind:"next_action",confidence:.88}:r&&R(e,Di)?{kind:"todo",confidence:.87}:R(e,ar)&&R(e,qi)?{kind:"architecture",confidence:r?.88:.82}:o&&R(e,zi)?{kind:"fix",confidence:.8}:r&&R(e,Bi)&&R(e,Vi)?{kind:"context",confidence:.79}:null}function Xi(e,t,n){let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message",s=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:s,testVerified:i,crossSessionConfirmations:1,assistantDerived:o}}function Qi(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":case"next_action":return"todo";case"fix":case"context":return"code"}}function Zi(e,t,n){return e==="rule"&&R(n,lr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":ir(t,n)}function pr(e,t){let n=[],r=new Set,o=new Map;for(let s of t){let i=typeof s.data.messageId=="string"?s.data.messageId:void 0,a=ur(s);i&&a&&o.set(i,a)}for(let s of t){let i=ur(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of Ui(s)){let u=Yi(c,i,s);if(!u||u.confidence<.75)continue;let d=Qi(u.kind),l=Hi(c),p=w([e.projectId,u.kind,l].join("|"));if(r.has(p))continue;r.add(p);let f=s.provenance.sourcePath?[s.provenance.sourcePath]:[],m=s.sourceEventId?[s.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:d,content:c,confidence:u.confidence,importance:Zi(u.kind,d,c),evidence:Xi(u.kind,i,s),tags:[d],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:f,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as ea}from"node:crypto";var ta=["project-knowledge","implementation","continuation","session-context"],na={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Qt(e){return ea("sha256").update(e).digest("hex")}function tt(e,t){return`${e}:${Qt(t).slice(0,24)}`}function ra(e){try{return Qt(JSON.stringify(e))}catch{return Qt(String(e))}}function ee(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function mr(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 oa(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function fr(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function sa(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=>mr(t.content)).join(" | ")}function ia(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=>mr(t.content)).join(`
17
+ `)}function gr(e,t){let n=e.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:tt("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:ra(p.data)})),o=new Map,s=new Map;n.forEach((p,f)=>{let m=r[f];m&&(o.set(p.id,m.id),p.sourceEventId&&s.set(p.sourceEventId,m.id))});let i=t.map(p=>{let f=ee([...p.provenance.eventIds.map(m=>o.get(m)),...p.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:tt("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:ee([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:f,sourcePaths:ee(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=oa(p.kind),m=a.get(f)??[];m.push(p),a.set(f,m)}let c=[];for(let p of ta){let f=a.get(p);if(!f?.length)continue;let m=f.slice().sort((g,S)=>S.importanceScore-g.importanceScore||S.confidence-g.confidence||g.id.localeCompare(S.id)),h=m.map(g=>g.id);c.push({id:tt("scene",`${p}|${h.join("|")}`),level:"scene",kind:p,title:na[p],summary:sa(m),factIds:h,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:fr(m.map(g=>g.confidence)),tags:ee(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:ee(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),d=[];for(let p of c){let m=p.factIds.map(S=>u.get(S)).filter(S=>!!S).filter(S=>(S.knowledgeClass==="permanent"||S.knowledgeClass==="task")&&S.importanceScore>=.55);if(m.length===0)continue;let h=m.some(S=>S.knowledgeClass==="permanent")?"permanent":"task",g=ia(m);d.push({id:tt("knowledge",`${p.id}|${h}|${m.map(S=>S.id).join("|")}`),level:"knowledge",knowledgeClass:h,title:p.title,content:g,sceneIds:[p.id],factIds:m.map(S=>S.id),importanceScore:Math.max(...m.map(S=>S.importanceScore)),confidence:fr(m.map(S=>S.confidence)),tags:ee(["level:knowledge",`class:${h}`,`scene:${p.kind}`,...m.flatMap(S=>S.tags)]),sourcePaths:ee(m.flatMap(S=>S.sourcePaths))})}let l=[];for(let p of i)for(let f of p.rawIds)l.push({from:f,to:p.id,type:"supports"});for(let p of c)for(let f of p.factIds)l.push({from:f,to:p.id,type:"belongs_to"});for(let p of d)for(let f of p.sceneIds)l.push({from:f,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:d,links:l,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:d.length,links:l.length}}}function aa(e){return e?Math.ceil(e.length/3.5):0}function yr(e,t){if(!e)return"";if(aa(e)<=t)return e;let r=Math.floor(t*3.5),o=e.slice(0,r),s=o.lastIndexOf("."),i=o.lastIndexOf(`
18
+ `),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}import{existsSync as ca,readFileSync as ua}from"node:fs";import{homedir as la}from"node:os";import{join as da}from"node:path";function pa(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
19
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function fa(){let e=process.env.TOOLNET_GLOBAL_ENV??da(la(),".config","toolnet-memory",".env");if(!ca(e))return;let t=ua(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 o=r.indexOf("=");if(o<=0)continue;let s=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=pa(r.slice(o+1)))}}fa();function be(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function xe(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function nt(){return{memory:{autoCapture:be(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:be(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:be(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:be(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:xe(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:xe(process.env.MEMORY_RERANK_TOP,10),finalContext:xe(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:xe(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:be(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:xe(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}function Ie(){let e=nt(),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",o=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),s=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"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:o,sessionSummaryMaxTokens:s,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function hr(e){return(e||Ie()).durableMemoryMaxItemsPerSession}function Sr(e){return(e||Ie()).sessionSummaryMaxTokens}var kr=new J;function vr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(kr.sanitizeValue(r))}catch{}let n=kr.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 ma(e,t){let n=e.toLowerCase(),r=.5,o=["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 o)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 s=[/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 s)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function ga(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
20
+ `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let d=u.toLowerCase().replace(/\s+/g," ");if(r.has(d))continue;r.add(d);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 p=ma(u,l);if(p<.3)continue;let f=vr(u);n.push({category:l,text:f,importance:p,sourceSessionId:t})}}let o=Ie(),s=hr(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function ya(e){let t=Ie(),n=Sr(t),s=e.join(`
21
21
 
22
22
  `).split(`
23
- `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>lr(i)).join(`
24
- `);return ir(s,n)}function dr(e,t){let r=(Array.isArray(e)?e:e.split(`
23
+ `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>vr(i)).join(`
24
+ `);return yr(s,n)}function wr(e,t){let r=(Array.isArray(e)?e:e.split(`
25
25
 
26
- `).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=Ui(r,t),s=o.filter(f=>f.category==="decision").map(f=>f.text),i=o.filter(f=>f.category==="rule").map(f=>f.text),a=o.filter(f=>f.category==="file").map(f=>f.text),c=o.filter(f=>f.category==="fix").map(f=>f.text),u=o.filter(f=>f.category==="blocker").map(f=>f.text),l=o.filter(f=>f.category==="next_action").map(f=>f.text),d=o.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:Yi(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:o}}function H(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function Xi(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,o=t.get(r);(!o||n.sequence>o.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Zi(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 Qi(e){let t=Bt(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:Zi(e.content),tags:H([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function ea(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 ta(e,t,n){let r=dr(ea(t),e.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=H([...o,...r.nextActions]),c=H([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:H(r.decisions),files:H([...r.filesChanged,...s]),todos:a,completed:H(r.bugsFixed),blockers:H(r.blockers),nextActions:c,architecture:H(i)}}}function Ze(e,t){let n=Xi(t),r=nr(e,n).map(Qi),o=r.filter(l=>Bt(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:s,state:i}=ta(e,n,o),a=o.map(l=>({fingerprint:l.fingerprint,kind:l.kind,knowledgeClass:l.knowledgeClass,importanceScore:l.importanceScore,content:l.content,terms:l.retrievalTerms})),c=sr(n,o),u=l=>r.filter(d=>d.knowledgeClass===l).length;return{version:2,normalizedEvents:n,summary:s,state:i,candidates:o,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:o.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as na}from"node:crypto";import{chmodSync as pr,existsSync as ra,mkdirSync as oa,readFileSync as sa,renameSync as ia,writeFileSync as fr}from"node:fs";import{dirname as mr,join as Qe}from"node:path";var Yt="toolnet.context-offload.v1",aa="toolnet.context-offload-asset.v1",ca=256,ua=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function gr(e){return Qe(e,".toolnet","offload")}function la(e){return Qe(gr(e),"assets")}function yr(e){return Qe(gr(e),"graph.json")}function hr(e){oa(e,{recursive:!0,mode:448});try{pr(e,448)}catch{}}function da(e,t){hr(mr(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;fr(n,t,{encoding:"utf8",mode:384}),ia(n,e);try{pr(e,384)}catch{}}function Ut(e){return Array.isArray(e)?e.map(Ut):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Ut(n)])):e}function pa(e){return na("sha256").update(JSON.stringify(Ut(e)),"utf8").digest("hex")}function Gt(){return{schema:Yt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function fa(e){let t=yr(e);if(!ra(t))return Gt();try{let n=JSON.parse(sa(t,"utf8"));return n.schema!==Yt||n.version!==1||!Array.isArray(n.nodes)?Gt():n}catch{return Gt()}}function ma(e,t){da(yr(e),JSON.stringify(t,null,2)+`
27
- `)}function ga(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function ya(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let o=ga(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function ha(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Sa(e,t){hr(mr(e));try{return fr(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function ka(e,t){let n=e.nodes.find(o=>o.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:Yt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(o=>o.id!==t.id),r].slice(-ca)}}function Sr(e,t){let n=fa(e),r=0,o=0,s=0,i=[];for(let a of t){if(!ua.has(a.type))continue;r+=1;let c=pa({type:a.type,data:a.data}),u={schema:aa,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}},l=JSON.stringify(u,null,2)+`
28
- `;Sa(Qe(la(e),`${c}.json`),l)?o+=1:s+=1,i.push(c),n=ka(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[ha(a)],files:ya(a)})}return r>0&&ma(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Aa}from"node:crypto";import{existsSync as Ma,readdirSync as Pa,readFileSync as Ta}from"node:fs";import{basename as Ea,join as _r}from"node:path";import{randomUUID as wr}from"node:crypto";var C=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function xe(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}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 C("Invalid Wiki slug",400);return t}function kr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(te(r))}return xe(t)}function va(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function vr(e){return{id:`revision-${wr()}`,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 et=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 o=await this.ensureState();n=t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});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:xe(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.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(o=>o.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),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new C(`Wiki page not found: ${t}`,404);return ee(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new C("Wiki title is required",400);let s=te(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new C(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${wr()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:xe(t.tags??[]),links:kr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(vr(a)),ee(a)})}async updatePage(t,n){return this.mutate(r=>{let o=te(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new C(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new C("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=kr(s.content)),n.tags!==void 0&&(s.tags=xe(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(vr(s)),ee(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return ee(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return ee(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=xe(va(t));if(o.length===0)return[];let s=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(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),f=0;for(let m of o)u===m&&(f+=12),c===m&&(f+=10),c.includes(m)&&(f+=6),u.includes(m)&&(f+=5),p.some(h=>h===m)?f+=5:p.some(h=>h.includes(m))&&(f+=3),l.includes(m)&&(f+=2),d.includes(m)&&(f+=1);f>0&&i.push({page:ee(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var br="wiki/state.v1.json";function wa(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function ba(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 tt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(br);if(!t){let n=wa(this.project);return await this.save(n),n}return ba(t,this.project)}async save(t){await this.storage.put(br,JSON.stringify(t,null,2),"application/json")}};import{createHash as xa,randomUUID as xr}from"node:crypto";var Ir="wiki/governance.v1.json",Mr="toolnet.knowledge-governance.v1",Cr=500,Ie={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Ia(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Xt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function jr(e){return xa("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Ca(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 ja(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),Ia(t)}function Ar(e){let t=new Date().toISOString();return{schema:Mr,version:1,projectId:e,policy:{...Ie},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Pr(e){let t=e.autoApproveThreshold??Ie.autoApproveThreshold,n=e.criticalApproveThreshold??Ie.criticalApproveThreshold,r=e.staleAfterDays??Ie.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new C("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new C("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new C("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var nt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Ir);if(!t){let n=Ar(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Mr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Pr(n.policy??Ie)}}catch{let n=Ar(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Ir,JSON.stringify(t,null,2),"application/json")}},rt=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,o={}){t.audit.push({id:xr(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),t.audit.length>Cr&&(t.audit=t.audit.slice(-Cr))}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});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=Pr({...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(o=>o.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,o)=>o.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(),o=ja(t),s=Xt(t.title),i=n.filter(l=>l.slug!==t.slug&&Xt(l.title)===s&&jr(l.content)!==jr(t.content)).map(l=>l.slug),a=Ca(t),c=[];o<r.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<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:o,risk:u,requiresReview:i.length>0||o<r.policy.autoApproveThreshold||a&&o<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(s)};if(!r.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:xr(),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 o.reviews.push(a),this.audit(o,"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(t,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===t&&s.digest===n&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(r,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===t);if(!s)throw new C(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new C("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=n.principal,s.updatedAt=i,n.note?.trim()&&(s.reviewNote=n.note.trim()),n.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s);if(n.action==="supersede")return s.status="superseded",n.targetReviewId&&(s.supersededBy=n.targetReviewId),this.audit(o,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(s);if(n.action==="merge"){if(!n.targetReviewId)throw new C("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new C("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await r.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new C(`Wiki page '${s.slug}' is manually managed`,409);return c?await r.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await r.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),o=Date.now(),s=n.policy.staleAfterDays*864e5,i=r.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of r){let d=Xt(l.title),p=a.get(d)??[];p.push(l),a.set(d,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(p=>p.slug)})),u=n.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Kr="wiki/automation.v1.json",Lr="toolnet.wiki-automation.v1",en=8e3,Tr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function je(e){return Aa("sha256").update(JSON.stringify(e)).digest("hex")}function Ce(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Er(e){return Array.isArray(e)?e:[]}function $r(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Zt(e){return Array.isArray(e)?e.map($r).filter(t=>!!t):[]}function L(e,t){for(let n of t){let r=$r(e[n]);if(r)return r}}function Ae(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function ot(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Tr.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=>ot(i,t+1,n));let o=Ce(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Tr.has(c)||s.push(...ot(a,t+1,i))}return s}function Or(e){let n=Ae(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>ot(e[o],0,o)));return(n.length>0?n:Ae(ot(e))).join(`
26
+ `).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=ga(r,t),s=o.filter(f=>f.category==="decision").map(f=>f.text),i=o.filter(f=>f.category==="rule").map(f=>f.text),a=o.filter(f=>f.category==="file").map(f=>f.text),c=o.filter(f=>f.category==="fix").map(f=>f.text),u=o.filter(f=>f.category==="blocker").map(f=>f.text),d=o.filter(f=>f.category==="next_action").map(f=>f.text),l=o.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:ya(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:l,blockers:u,nextActions:d,durableFacts:o}}function G(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function ha(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,o=t.get(r);(!o||n.sequence>o.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Sa(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 ka(e){let t=Yt(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:Sa(e.content),tags:G([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function va(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=wr(va(t),e.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=G([...o,...r.nextActions]),c=G([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:G(r.decisions),files:G([...r.filesChanged,...s]),todos:a,completed:G(r.bugsFixed),blockers:G(r.blockers),nextActions:c,architecture:G(i)}}}function rt(e,t){let n=ha(t),r=pr(e,n).map(ka),o=r.filter(d=>Yt(d).persist).sort((d,l)=>l.importanceScore-d.importanceScore),{summary:s,state:i}=wa(e,n,o),a=o.map(d=>({fingerprint:d.fingerprint,kind:d.kind,knowledgeClass:d.knowledgeClass,importanceScore:d.importanceScore,content:d.content,terms:d.retrievalTerms})),c=gr(n,o),u=d=>r.filter(l=>l.knowledgeClass===d).length;return{version:2,normalizedEvents:n,summary:s,state:i,candidates:o,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:o.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as ba}from"node:crypto";import{chmodSync as br,existsSync as xa,mkdirSync as Ia,readFileSync as Ca,renameSync as Aa,writeFileSync as xr}from"node:fs";import{dirname as Ir,join as ot}from"node:path";var tn="toolnet.context-offload.v1",Ea="toolnet.context-offload-asset.v1",ja=256,Ma=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Cr(e){return ot(e,".toolnet","offload")}function Pa(e){return ot(Cr(e),"assets")}function Ar(e){return ot(Cr(e),"graph.json")}function Er(e){Ia(e,{recursive:!0,mode:448});try{br(e,448)}catch{}}function Ta(e,t){Er(Ir(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;xr(n,t,{encoding:"utf8",mode:384}),Aa(n,e);try{br(e,384)}catch{}}function en(e){return Array.isArray(e)?e.map(en):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,en(n)])):e}function Oa(e){return ba("sha256").update(JSON.stringify(en(e)),"utf8").digest("hex")}function Zt(){return{schema:tn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Na(e){let t=Ar(e);if(!xa(t))return Zt();try{let n=JSON.parse(Ca(t,"utf8"));return n.schema!==tn||n.version!==1||!Array.isArray(n.nodes)?Zt():n}catch{return Zt()}}function Ra(e,t){Ta(Ar(e),JSON.stringify(t,null,2)+`
27
+ `)}function _a(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Ka(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let o=_a(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function La(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function $a(e,t){Er(Ir(e));try{return xr(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Fa(e,t){let n=e.nodes.find(o=>o.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:tn,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(o=>o.id!==t.id),r].slice(-ja)}}function jr(e,t){let n=Na(e),r=0,o=0,s=0,i=[];for(let a of t){if(!Ma.has(a.type))continue;r+=1;let c=Oa({type:a.type,data:a.data}),u={schema:Ea,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}},d=JSON.stringify(u,null,2)+`
28
+ `;$a(ot(Pa(e),`${c}.json`),d)?o+=1:s+=1,i.push(c),n=Fa(n,{id:c,kind:a.type,bytes:Buffer.byteLength(d,"utf8"),createdAt:a.timestamp,sourceRefs:[La(a)],files:Ka(a)})}return r>0&&Ra(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Ha}from"node:crypto";import{existsSync as Ga,readdirSync as Ua,readFileSync as Ya}from"node:fs";import{basename as Xa,join as Vr}from"node:path";import{randomUUID as Tr}from"node:crypto";var C=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Ce(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function ne(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 C("Invalid Wiki slug",400);return t}function Mr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(ne(r))}return Ce(t)}function Da(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Pr(e){return{id:`revision-${Tr()}`,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 te(e){return structuredClone(e)}var st=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 o=await this.ensureState();n=t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});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:Ce(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.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(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return te([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=ne(t),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new C(`Wiki page not found: ${t}`,404);return te(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new C("Wiki title is required",400);let s=ne(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new C(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${Tr()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:Ce(t.tags??[]),links:Mr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Pr(a)),te(a)})}async updatePage(t,n){return this.mutate(r=>{let o=ne(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new C(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new C("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=Mr(s.content)),n.tags!==void 0&&(s.tags=Ce(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(Pr(s)),te(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return te(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return te(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=Ce(Da(t));if(o.length===0)return[];let s=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(),d=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),f=0;for(let m of o)u===m&&(f+=12),c===m&&(f+=10),c.includes(m)&&(f+=6),u.includes(m)&&(f+=5),p.some(h=>h===m)?f+=5:p.some(h=>h.includes(m))&&(f+=3),d.includes(m)&&(f+=2),l.includes(m)&&(f+=1);f>0&&i.push({page:te(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var Or="wiki/state.v1.json";function Wa(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function za(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 it=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=Wa(this.project);return await this.save(n),n}return za(t,this.project)}async save(t){await this.storage.put(Or,JSON.stringify(t,null,2),"application/json")}};import{createHash as qa,randomUUID as Nr}from"node:crypto";var Rr="wiki/governance.v1.json",$r="toolnet.knowledge-governance.v1",_r=500,Ae={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Ba(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function nn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Kr(e){return qa("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Va(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 Ja(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),Ba(t)}function Lr(e){let t=new Date().toISOString();return{schema:$r,version:1,projectId:e,policy:{...Ae},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Fr(e){let t=e.autoApproveThreshold??Ae.autoApproveThreshold,n=e.criticalApproveThreshold??Ae.criticalApproveThreshold,r=e.staleAfterDays??Ae.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new C("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new C("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new C("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var at=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Rr);if(!t){let n=Lr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==$r||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Fr(n.policy??Ae)}}catch{let n=Lr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Rr,JSON.stringify(t,null,2),"application/json")}},ct=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,o={}){t.audit.push({id:Nr(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),t.audit.length>_r&&(t.audit=t.audit.slice(-_r))}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});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=Fr({...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(o=>o.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,o)=>o.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(),o=Ja(t),s=nn(t.title),i=n.filter(d=>d.slug!==t.slug&&nn(d.title)===s&&Kr(d.content)!==Kr(t.content)).map(d=>d.slug),a=Va(t),c=[];o<r.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<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:o,risk:u,requiresReview:i.length>0||o<r.policy.autoApproveThreshold||a&&o<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(s)};if(!r.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:Nr(),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 o.reviews.push(a),this.audit(o,"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(t,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===t&&s.digest===n&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(r,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===t);if(!s)throw new C(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new C("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=n.principal,s.updatedAt=i,n.note?.trim()&&(s.reviewNote=n.note.trim()),n.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s);if(n.action==="supersede")return s.status="superseded",n.targetReviewId&&(s.supersededBy=n.targetReviewId),this.audit(o,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(s);if(n.action==="merge"){if(!n.targetReviewId)throw new C("targetReviewId is required for merge",400);let u=o.reviews.find(d=>d.id===n.targetReviewId);if(!u)throw new C("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await r.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new C(`Wiki page '${s.slug}' is manually managed`,409);return c?await r.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await r.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),o=Date.now(),s=n.policy.staleAfterDays*864e5,i=r.map(d=>{let l=o-Date.parse(d.updatedAt);return{slug:d.slug,title:d.title,updatedAt:d.updatedAt,ageDays:Math.max(0,Math.floor(l/864e5)),stale:Number.isFinite(l)&&l>s}}).filter(d=>d.stale).map(({stale:d,...l})=>l),a=new Map;for(let d of r){let l=nn(d.title),p=a.get(l)??[];p.push(d),a.set(l,p)}let c=[...a.entries()].filter(([,d])=>d.length>1).map(([d,l])=>({title:d,pages:l.map(p=>p.slug)})),u=n.reviews.filter(d=>d.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(d=>d.tags.some(l=>l.startsWith("toolnet-auto-"))).length,manualPages:r.filter(d=>!d.tags.some(l=>l.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(d=>d.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(d=>d.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Jr="wiki/automation.v1.json",Hr="toolnet.wiki-automation.v1",sn=8e3,Dr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function je(e){return Ha("sha256").update(JSON.stringify(e)).digest("hex")}function Ee(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Wr(e){return Array.isArray(e)?e:[]}function Gr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function rn(e){return Array.isArray(e)?e.map(Gr).filter(t=>!!t):[]}function $(e,t){for(let n of t){let r=Gr(e[n]);if(r)return r}}function Me(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function ut(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Dr.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=>ut(i,t+1,n));let o=Ee(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Dr.has(c)||s.push(...ut(a,t+1,i))}return s}function zr(e){let n=Me(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>ut(e[o],0,o)));return(n.length>0?n:Me(ut(e))).join(`
29
29
 
30
- `).slice(0,en)}function Nr(e,t){return L(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Rr(e,t){return L(e,["title","name","topic","label","task","kind","type"])??t}function Oa(e){return(L(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Na(e){return(L(e,["kind","sceneKind","type"])??"").toLowerCase()}function Ra(e){let t=Ce(e);if(!t)return[];let n=[],r=Er(t.knowledge);for(let[s,i]of r.entries()){let a=Ce(i);if(!a)continue;let c=Oa(a);if(c==="session"||c==="transient")continue;let u=Or(a);if(u.length<20)continue;let l=Nr(a,je(a).slice(0,16)),d=Rr(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${l}`,sourceType:"memory",title:d,summary:L(a,["summary","description"]),content:u,tags:Ae(["toolnet","auto","memory",...c?[c]:[]])})}let o=Er(t.scenes);for(let[s,i]of o.entries()){let a=Ce(i);if(!a)continue;let c=Na(a);if(c==="session-context")continue;let u=Or(a);if(u.length<20)continue;let l=Nr(a,je(a).slice(0,16)),d=Rr(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${l}`,sourceType:"scene",title:d,summary:L(a,["summary","description"]),content:u,tags:Ae(["toolnet","auto","scene",...c?[c]:[]])})}return n}function _a(e){return _r(e,".toolnet","memory","skills")}function Ka(e){let t=_a(e);if(!Ma(t))return{candidates:[],failed:0};let n=[],r=0,o=Pa(t).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(Ta(_r(t,s),"utf8")),a=Ce(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=L(a,["id","fingerprint"])??Ea(s,".json"),u=L(a,["task"])??"",l=L(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=L(a,["summary"])??void 0,p=Zt(a.steps),f=Zt(a.verification),m=Zt(a.files),h=[];u&&h.push(`## Task
31
- ${u}`),d&&h.push(`## Summary
32
- ${d}`),p.length>0&&h.push(`## Procedure
30
+ `).slice(0,sn)}function qr(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 Qa(e){return($(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Za(e){return($(e,["kind","sceneKind","type"])??"").toLowerCase()}function ec(e){let t=Ee(e);if(!t)return[];let n=[],r=Wr(t.knowledge);for(let[s,i]of r.entries()){let a=Ee(i);if(!a)continue;let c=Qa(a);if(c==="session"||c==="transient")continue;let u=zr(a);if(u.length<20)continue;let d=qr(a,je(a).slice(0,16)),l=Br(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${d}`,sourceType:"memory",title:l,summary:$(a,["summary","description"]),content:u,tags:Me(["toolnet","auto","memory",...c?[c]:[]])})}let o=Wr(t.scenes);for(let[s,i]of o.entries()){let a=Ee(i);if(!a)continue;let c=Za(a);if(c==="session-context")continue;let u=zr(a);if(u.length<20)continue;let d=qr(a,je(a).slice(0,16)),l=Br(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${d}`,sourceType:"scene",title:l,summary:$(a,["summary","description"]),content:u,tags:Me(["toolnet","auto","scene",...c?[c]:[]])})}return n}function tc(e){return Vr(e,".toolnet","memory","skills")}function nc(e){let t=tc(e);if(!Ga(t))return{candidates:[],failed:0};let n=[],r=0,o=Ua(t).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(Ya(Vr(t,s),"utf8")),a=Ee(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??Xa(s,".json"),u=$(a,["task"])??"",d=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,l=$(a,["summary"])??void 0,p=rn(a.steps),f=rn(a.verification),m=rn(a.files),h=[];u&&h.push(`## Task
31
+ ${u}`),l&&h.push(`## Summary
32
+ ${l}`),p.length>0&&h.push(`## Procedure
33
33
  ${p.map((S,v)=>`${v+1}. ${S}`).join(`
34
34
  `)}`),f.length>0&&h.push(`## Verification
35
35
  ${f.map(S=>`- ${S}`).join(`
@@ -37,24 +37,24 @@ ${f.map(S=>`- ${S}`).join(`
37
37
  ${m.map(S=>`- \`${S}\``).join(`
38
38
  `)}`);let g=h.join(`
39
39
 
40
- `).slice(0,en);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:l,summary:d,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Qt(e){let t=new Date().toISOString();return{schema:Lr,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function La(e,t){let n=await e.getText(Kr);if(!n)return Qt(t);try{let r=JSON.parse(n);return r.schema!==Lr||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Qt(t):r}catch{return Qt(t)}}async function $a(e,t){await e.put(Kr,JSON.stringify(t,null,2),"application/json")}function Fa(e){return`toolnet-auto-${je(e).slice(0,12)}`}function Wa(e){let t=te(e.title).slice(0,72),n=je(e.sourceKey).slice(0,10);return te(`auto-${e.sourceType}-${t}-${n}`)}function Da(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(`
41
- `).slice(0,en)}function za(e){return je({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function qa(e,t){return e.tags.includes(t)}async function Fr(e){let t=Ra(e.hierarchy),n=Ka(e.project.rootPath),r=new Map;for(let f of[...t,...n.candidates])r.set(f.sourceKey,f);let o=[...r.values()].sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),s={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:o.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new et(new tt(e.storage,e.project));await i.initialize();let a=new rt(new nt(e.storage,e.project));await a.initialize();let c=await La(e.storage,e.project.id),u=await i.listPages(),l=new Map(u.map(f=>[f.slug,f])),d=new Map(c.entries.map(f=>[f.sourceKey,f]));for(let f of o)try{let m=Fa(f.sourceKey),h=za(f),g=d.get(f.sourceKey),S=g?.slug??Wa(f),v=l.get(S);if(v&&!qa(v,m)){s.skipped+=1;continue}let x=Ae([...f.tags,m]),T=Da(f),M=await a.gate({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,marker:m,digest:h,title:f.title,...f.summary?{summary:f.summary}:{},content:T,tags:x},[...l.values()]);if(!M.allowed){M.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}M.mode==="auto-approved"?s.autoApproved+=1:M.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==h?(v=await i.updatePage(S,{title:f.title,summary:f.summary??"",content:T,tags:x}),l.set(v.slug,v),s.updated+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"updated"})):(s.unchanged+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,action:"unchanged"})):(v=await i.createPage({slug:S,title:f.title,summary:f.summary,content:T,tags:x}),l.set(v.slug,v),s.created+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"created"}));let E=new Date().toISOString(),I={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,digest:h,marker:m,updatedAt:E},b=c.entries.findIndex(D=>D.sourceKey===f.sourceKey);b>=0?c.entries[b]=I:c.entries.push(I),d.set(f.sourceKey,I),await a.markApplied(f.sourceKey,h)}catch(m){if(m instanceof C&&m.statusCode===409){s.skipped+=1;continue}s.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),await $a(e.storage,c),s}import{createHash as Va}from"node:crypto";import{chmodSync as Dr,existsSync as Ba,mkdirSync as Ja,readFileSync as Hp,readdirSync as Gp,renameSync as Ha,statSync as Up,writeFileSync as Ga}from"node:fs";import{join as zr}from"node:path";var Ua="toolnet.skill-memory.v1",Wr=5,Ya=16,Xa=24,Za=32;function Qa(e){return Va("sha256").update(e).digest("hex")}function Pe(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function tn(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 ec(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 q(e,t=360){return e&&tn(ec(e),t)||void 0}function Te(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 Vr(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let o=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(o))return!0;if(["false","no","fail","failed","error"].includes(o))return!1}}}function Br(e){let t=e.data??{};if(Vr(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 o=Te(t,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function Me(e){let t=e.data??{};if(Br(e))return!1;if(Vr(t,["passed","pass","success","succeeded","ok"])===!0||qr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=Te(t,["status","result","outcome"]);return o&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(o)?!0:e.type==="commit"||e.type==="deploy"}function Jr(e){let t=e.data??{},n=Te(t,["path","file","filePath","filename","target"]);if(n)return q(n,260);let r=e.provenance?.files;return q(r?.[0],260)}function nn(e){return q(Te(e.data??{},["command","cmd","script"]),420)}function ue(e){return q(Te(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function tc(e){let t=[];for(let n of[...e].sort((r,o)=>r.sequence-o.sequence))if(Me(n)){if(n.type==="test"){let r=ue(n)??nn(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=ue(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=ue(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return Pe(t,10)}function nc(e,t){let n=[];for(let r of[...e].sort((o,s)=>o.sequence-s.sequence))switch(r.type){case"file_write":case"file_edit":{let o=Jr(r);o&&n.push(`Update ${o}`);break}case"command":{if(Br(r))break;let o=nn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!Me(r))break;let o=ue(r)??nn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!Me(r))break;let o=ue(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!Me(r))break;let o=ue(r);n.push(o?`Deploy: ${o}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let o=q(r,260);o&&n.push(`Update ${o}`)}return Pe(n,Ya)}function rc(e,t){let n=[...t.files];for(let r of e){let o=Jr(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=q(s,260);i&&n.push(i)}}return Pe(n,Xa)}function oc(e){return Pe(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Za)}function sc(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Hr(e,t,n){if(t.length===0)return[];let r=tc(t),o=Pe(n.completed.map(m=>q(m,280)??""),Wr);if(!(o.length>0||t.some(m=>["test","commit","deploy"].includes(m.type)&&Me(m))))return[];let i=q(n.task,280)??q(n.nextActions[0],280),a=o.length>0?o:i?[i]:[];if(a.length===0)return[];let c=nc(t,n);if(c.length===0)return[];let u=rc(t,n),l=oc(t),d=Math.min(...t.map(m=>m.sequence)),p=Math.max(...t.map(m=>m.sequence)),f=sc(t);return a.slice(0,Wr).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),g=JSON.stringify({projectId:e.projectId,task:m,steps:c,verification:r,files:u}),S=Qa(g);return{schema:Ua,version:1,id:`skill-${S.slice(0,24)}`,fingerprint:S,projectId:e.projectId,title:tn(`SOP: ${m}`,180),task:m,summary:tn(h.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:l},createdAt:f}})}function ic(e){return zr(e.rootPath,".toolnet","memory","skills")}function ac(e){let t=ic(e);return Ja(t,{recursive:!0,mode:448}),Dr(t,448),t}function Gr(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=ac(e),r=0,o=0,s=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=zr(n,`${i.id}.json`);if(s.push(a),Ba(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Ga(c,JSON.stringify(i,null,2)+`
42
- `,{encoding:"utf8",mode:384}),Ha(c,a),Dr(a,384),r+=1}return{written:r,deduped:o,files:s}}function Ur(e){return String(e).padStart(12,"0")}function cc(e){return`projects/${e.projectId}/memory/learned`}var st=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let o=Math.min(...n.map(d=>d.sequence)),s=Math.max(...n.map(d=>d.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
43
- `,c=w(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),l=[cc(t),"batches",`${Ur(o)}-${Ur(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(l)||await this.storage.put(l,a,"application/json"),l}};import{createHash as uc}from"node:crypto";function Yr(e){return String(e).padStart(12,"0")}function Xr(e){return uc("sha256").update(e).digest("hex")}function lc(e){return`projects/${e.projectId}/memory/hierarchy`}var it=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let o=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.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:o,lastSequence:s,hierarchy:r},a=Xr([...r.facts.map(l=>l.id),...r.knowledge.map(l=>l.id)].sort().join("|")).slice(0,16),c=Xr(t.sessionKey).slice(0,12),u=[lc(t),"batches",`${Yr(o)}-${Yr(s)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
44
- `,"application/json"),u}};function yc(e,t){if(!pc(e))return{events:[],nextOffset:t};let n=gc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=fc(e,"r");try{mc(i,s,0,o,r)}finally{dc(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
40
+ `).slice(0,sn);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:d,summary:l,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function on(e){let t=new Date().toISOString();return{schema:Hr,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function rc(e,t){let n=await e.getText(Jr);if(!n)return on(t);try{let r=JSON.parse(n);return r.schema!==Hr||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?on(t):r}catch{return on(t)}}async function oc(e,t){await e.put(Jr,JSON.stringify(t,null,2),"application/json")}function sc(e){return`toolnet-auto-${je(e).slice(0,12)}`}function ic(e){let t=ne(e.title).slice(0,72),n=je(e.sourceKey).slice(0,10);return ne(`auto-${e.sourceType}-${t}-${n}`)}function ac(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(`
41
+ `).slice(0,sn)}function cc(e){return je({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function uc(e,t){return e.tags.includes(t)}async function Ur(e){let t=ec(e.hierarchy),n=nc(e.project.rootPath),r=new Map;for(let f of[...t,...n.candidates])r.set(f.sourceKey,f);let o=[...r.values()].sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),s={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:o.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new st(new it(e.storage,e.project));await i.initialize();let a=new ct(new at(e.storage,e.project));await a.initialize();let c=await rc(e.storage,e.project.id),u=await i.listPages(),d=new Map(u.map(f=>[f.slug,f])),l=new Map(c.entries.map(f=>[f.sourceKey,f]));for(let f of o)try{let m=sc(f.sourceKey),h=cc(f),g=l.get(f.sourceKey),S=g?.slug??ic(f),v=d.get(S);if(v&&!uc(v,m)){s.skipped+=1;continue}let x=Me([...f.tags,m]),T=ac(f),M=await a.gate({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,marker:m,digest:h,title:f.title,...f.summary?{summary:f.summary}:{},content:T,tags:x},[...d.values()]);if(!M.allowed){M.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}M.mode==="auto-approved"?s.autoApproved+=1:M.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==h?(v=await i.updatePage(S,{title:f.title,summary:f.summary??"",content:T,tags:x}),d.set(v.slug,v),s.updated+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"updated"})):(s.unchanged+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,action:"unchanged"})):(v=await i.createPage({slug:S,title:f.title,summary:f.summary,content:T,tags:x}),d.set(v.slug,v),s.created+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"created"}));let O=new Date().toISOString(),I={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:S,digest:h,marker:m,updatedAt:O},b=c.entries.findIndex(z=>z.sourceKey===f.sourceKey);b>=0?c.entries[b]=I:c.entries.push(I),l.set(f.sourceKey,I),await a.markApplied(f.sourceKey,h)}catch(m){if(m instanceof C&&m.statusCode===409){s.skipped+=1;continue}s.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),await oc(e.storage,c),s}import{createHash as lc}from"node:crypto";import{chmodSync as Xr,existsSync as dc,mkdirSync as pc,readFileSync as bf,readdirSync as xf,renameSync as fc,statSync as If,writeFileSync as mc}from"node:fs";import{join as Qr}from"node:path";var gc="toolnet.skill-memory.v1",Yr=5,yc=16,hc=24,Sc=32;function kc(e){return lc("sha256").update(e).digest("hex")}function Te(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function an(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 vc(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&&an(vc(e),t)||void 0}function Oe(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Zr(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 eo(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let o=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(o))return!0;if(["false","no","fail","failed","error"].includes(o))return!1}}}function to(e){let t=e.data??{};if(eo(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Zr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let o=Oe(t,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function Pe(e){let t=e.data??{};if(to(e))return!1;if(eo(t,["passed","pass","success","succeeded","ok"])===!0||Zr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=Oe(t,["status","result","outcome"]);return o&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(o)?!0:e.type==="commit"||e.type==="deploy"}function no(e){let t=e.data??{},n=Oe(t,["path","file","filePath","filename","target"]);if(n)return B(n,260);let r=e.provenance?.files;return B(r?.[0],260)}function cn(e){return B(Oe(e.data??{},["command","cmd","script"]),420)}function pe(e){return B(Oe(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function wc(e){let t=[];for(let n of[...e].sort((r,o)=>r.sequence-o.sequence))if(Pe(n)){if(n.type==="test"){let r=pe(n)??cn(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=pe(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=pe(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return Te(t,10)}function bc(e,t){let n=[];for(let r of[...e].sort((o,s)=>o.sequence-s.sequence))switch(r.type){case"file_write":case"file_edit":{let o=no(r);o&&n.push(`Update ${o}`);break}case"command":{if(to(r))break;let o=cn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!Pe(r))break;let o=pe(r)??cn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!Pe(r))break;let o=pe(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!Pe(r))break;let o=pe(r);n.push(o?`Deploy: ${o}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let o=B(r,260);o&&n.push(`Update ${o}`)}return Te(n,yc)}function xc(e,t){let n=[...t.files];for(let r of e){let o=no(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=B(s,260);i&&n.push(i)}}return Te(n,hc)}function Ic(e){return Te(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Sc)}function Cc(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function ro(e,t,n){if(t.length===0)return[];let r=wc(t),o=Te(n.completed.map(m=>B(m,280)??""),Yr);if(!(o.length>0||t.some(m=>["test","commit","deploy"].includes(m.type)&&Pe(m))))return[];let i=B(n.task,280)??B(n.nextActions[0],280),a=o.length>0?o:i?[i]:[];if(a.length===0)return[];let c=bc(t,n);if(c.length===0)return[];let u=xc(t,n),d=Ic(t),l=Math.min(...t.map(m=>m.sequence)),p=Math.max(...t.map(m=>m.sequence)),f=Cc(t);return a.slice(0,Yr).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),g=JSON.stringify({projectId:e.projectId,task:m,steps:c,verification:r,files:u}),S=kc(g);return{schema:gc,version:1,id:`skill-${S.slice(0,24)}`,fingerprint:S,projectId:e.projectId,title:an(`SOP: ${m}`,180),task:m,summary:an(h.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:l,lastSequence:p,eventIds:d},createdAt:f}})}function Ac(e){return Qr(e.rootPath,".toolnet","memory","skills")}function Ec(e){let t=Ac(e);return pc(t,{recursive:!0,mode:448}),Xr(t,448),t}function oo(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=Ec(e),r=0,o=0,s=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=Qr(n,`${i.id}.json`);if(s.push(a),dc(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;mc(c,JSON.stringify(i,null,2)+`
42
+ `,{encoding:"utf8",mode:384}),fc(c,a),Xr(a,384),r+=1}return{written:r,deduped:o,files:s}}var im="0".repeat(64);function so(e){return String(e).padStart(12,"0")}function jc(e){return`projects/${e.projectId}/memory/learned`}var lt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let o=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
43
+ `,c=w(r.map(l=>l.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),d=[jc(t),"batches",`${so(o)}-${so(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(d)||await this.storage.put(d,a,"application/json"),d}};import{createHash as Mc}from"node:crypto";function io(e){return String(e).padStart(12,"0")}function ao(e){return Mc("sha256").update(e).digest("hex")}function Pc(e){return`projects/${e.projectId}/memory/hierarchy`}var dt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let o=Math.min(...n.map(d=>d.sequence)),s=Math.max(...n.map(d=>d.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:o,lastSequence:s,hierarchy:r},a=ao([...r.facts.map(d=>d.id),...r.knowledge.map(d=>d.id)].sort().join("|")).slice(0,16),c=ao(t.sessionKey).slice(0,12),u=[Pc(t),"batches",`${io(o)}-${io(s)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
44
+ `,"application/json"),u}};function Kc(e,t){if(!Oc(e))return{events:[],nextOffset:t};let n=_c(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=Nc(e,"r");try{Rc(i,s,0,o,r)}finally{Tc(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
45
45
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
46
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var at=class{constructor(t){this.options=t;this.journal=new st(t.storage),this.hierarchyJournal=new it(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,o=yc(this.options.wal.eventsFile,r);if(o.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:o.nextOffset};let s=Ze(this.options.identity,o.events),i=s.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,o.events,i));let c=!1;s.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,o.events,s.hierarchy));let u=Hr(this.options.identity,o.events,s.state),l=Gr(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",s.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",s.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",s.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",s.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",s.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",s.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",s.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",s.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",s.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",s.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",s.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",l.written),this.options.wal.setSourceCursor("memory.skill.deduped",l.deduped);try{let d=Sr(this.options.project.rootPath,o.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 Fr({project:this.options.project,storage:this.options.storage,hierarchy:s.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",o.nextOffset),{scannedEvents:o.events.length,candidates:i.length,journalWritten:a,nextOffset:o.nextOffset}}};import{closeSync as Nc,existsSync as Rc,openSync as _c,readSync as Kc,statSync as Lc}from"node:fs";function Zr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Oe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Ee(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let o of e.slice(0,50))Ee(o,t,n+1);return}let r=Zr(e);if(r)for(let[o,s]of Object.entries(r))t(o,s,r),Ee(s,t,n+1)}function le(e,t){let n=[];return Ee(e,(r,o)=>{t.has(Oe(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function hc(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Zr(JSON.parse(t))}catch{return null}}function Sc(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let o=t[r];if(typeof o=="string"&&o.trim())return o.trim().toLowerCase()}let n="";return Ee(t,(r,o,s)=>{if(n)return;let i=Oe(r);if(["tool","toolname"].includes(i)&&typeof o=="string"){n=o.trim().toLowerCase();return}if(i!=="name"||typeof o!="string")return;let a=typeof s.type=="string"?s.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=o.trim().toLowerCase())}),n}function kc(e){let t=le(e.data,new Set(["command","cmd","script"])),n=le(e.data,new Set(["arguments","args"]));for(let r of n){let o=hc(r);if(o)for(let s of le(o,new Set(["command","cmd","script"])))t.push(s)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function vc(e){let t=le(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(Oe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
47
- `))))}function wc(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 bc(e){let t=le(e.data,new Set(["patch","diff","arguments","input"].map(Oe))),n=[];for(let r of t){let o=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let s of o)for(let i of r.matchAll(s.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:s.action,confidence:.99})}}return n}function xc(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 Ic(e){let t=null;return Ee(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(Oe(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let o=Number(r);Number.isFinite(o)&&(t=o)}}}),t}function Cc(e){return le(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function jc(e){let t=Ic(e.data);if(t!==null)return t===0?"passed":"failed";let n=Cc(e.data).join(`
48
- `).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 Ac(e){let t=[],n=new Set;for(let r of e){let o=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(o)||(n.add(o),t.push(r))}return t}function Qr(e){let t=[],n=Sc(e),r=wc(e,n);if(r)for(let o of vc(e))t.push({kind:"file",text:o,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...bc(e));for(let o of kc(e)){t.push({kind:"command",text:o,confidence:.98});let s=xc(o);s&&t.push({kind:"test",text:o,checkKind:s,checkStatus:jc(e),confidence:.98})}return Ac(t)}var Mc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function re(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function to(e){return re(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function ne(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))ne(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Mc.has(r)||["data","payload","parts","messages"].includes(r))&&ne(o,t,n+1)}}function ct(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 eo(e){let t=re(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,o={}){let s=re(r),i=o.key??to(s);return{version:1,id:w([e.projectId,n,i,t.id,s,o.status??"",o.fileAction??"",o.checkKind??"",o.checkStatus??"",o.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:s,status:o.status,fileAction:o.fileAction,checkKind:o.checkKind,checkStatus:o.checkStatus,order:o.order,confidence:o.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function Pc(e,t,n){let r=re(n);if(r.length<5||r.length>1200)return[];let o=[],s=/^(?: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]&&o.push(j(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(j(e,t,"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(;!s&&(u=c.exec(r));){let p=Number(u[1]),f=re(u[2]??""),m=f&&!eo(f)?`Phase ${p} - ${f}`:`Phase ${p}`;o.push(j(e,t,"phase",m,{key:`phase:${p}`,order:p,status:ct(r),confidence:.93}))}let l=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);l?.[2]&&o.push(j(e,t,"task",l[2],{status:l[1].trim()?"completed":ct(l[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,f=re(d[2]),m=eo(f);o.push(j(e,t,"task",m&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:to(f),order:p,status:ct(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&&o.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)&&o.push(j(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(j(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.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)&&o.push(j(e,t,"activity",r,{confidence:.86})),o}function ut(e,t){if(t.length===0)return[];let n=[],r=new Set;function o(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 c=[];ne(i.data,c);let u=c.map(l=>re(l)).find(l=>l.length>=8&&l.length<=1200&&!/^\[?toolnet\b/iu.test(l));u&&o(j(e,i,"request",u,{confidence:.96}))}for(let c of Qr(i))o(j(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];ne(i.data,c);for(let u of c)o(j(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];ne(i.data,c);for(let u of c)o(j(e,i,"task",u,{status:ct(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&&o(j(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];ne(i.data,c);for(let u of c)o(j(e,i,"test",u,{confidence:1}))}let a=[];ne(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let l of Pc(e,i,u))o(l)}let s=t[t.length-1];return o(j(e,s,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function no(e){return String(e).padStart(12,"0")}var lt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(l=>l.sequence)),o=Math.max(...n.map(l=>l.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(l=>l.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:o,observations:n},i=JSON.stringify(s,null,2)+`
49
- `,a=w(n.map(l=>JSON.stringify(l)).sort().join(`
50
- `)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${no(r)}-${no(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as ro}from"node:path";import{mkdirSync as Tc}from"node:fs";function so(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(e,t=20){let n=[],r=new Set;for(let o of e.slice().reverse()){let s=so(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=t))break}return n.reverse()}function Ec(e,t=20){let n=new Map;for(let r of e){let o=`${r.kind}|${so(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-t)}function Oc(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 oo(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 o=e&&Oc(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:o,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 io(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}async function Ne(e,t){let r=(await io(e,t)).flatMap(y=>y.observations).sort((y,k)=>{let P=y.occurredAt.localeCompare(k.occurredAt);if(P!==0)return P;let V=y.sequence-k.sequence;return V!==0?V:y.id.localeCompare(k.id)}),o=new Map,s=new Map,i,a,c,u,l,d=[],p=[],f=[],m=[],h=[],g=new Map,S=[],v=[],x=[],T=[],M=[],E=[];for(let y of r)switch(y.kind){case"request":i=y.text;break;case"activity":a=y.text;break;case"goal":c=y.text;break;case"plan":u=y.text;break;case"phase":o.set(y.key,oo(o.get(y.key),y));break;case"task":s.set(y.key,oo(s.get(y.key),y));break;case"decision":d.push(y.text);break;case"blocker":p.push(y.text);break;case"warning":f.push(y.text);break;case"next_action":m.push(y.text);break;case"file":{h.push(y.text);let k=y.fileAction??"active";g.delete(y.text),g.set(y.text,k),k==="modified"?S.push(y.text):k==="created"?v.push(y.text):k==="deleted"&&x.push(y.text);break}case"command":T.push(y.text);break;case"test":M.push(y.text),y.checkKind&&E.push({kind:y.checkKind,command:y.text,status:y.checkStatus??"unknown",updatedAt:y.occurredAt,agent:y.agent,nativeSessionId:y.nativeSessionId});break;case"session":l={agent:y.agent,nativeSessionId:y.nativeSessionId,sessionKey:y.sessionKey,updatedAt:y.occurredAt};break}let I=Array.from(o.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),b=Array.from(s.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),D=I.find(y=>y.status==="in_progress")??I.find(y=>y.status==="blocked")??I.find(y=>y.status==="pending"),z=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),Pt=$([...m,...z?[z.title]:[],...!z&&D?[D.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),Tt=$([...p,...I.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),me={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:I,tasks:b,decisions:$(d,20),blockers:Tt,warnings:$(f,20),nextActions:Pt,filesTouched:$(h,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:$(S,30),createdFiles:$(v,30),deletedFiles:$(x,30),commands:$(T,20),tests:$(M,20),checks:Ec(E,20),currentPhase:D,currentTask:z,progress:{phasesTotal:I.length,phasesCompleted:I.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:I.filter(y=>y.status==="blocked").length+b.filter(y=>y.status==="blocked").length},lastSession:l,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},$e=ro(e.rootPath,".toolnet","work");return Tc($e,{recursive:!0}),O(ro($e,"current.json"),me),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(me,null,2)+`
51
- `,"application/json"),me}async function ao(e,t){if((await io(e,t)).length>0)return Ne(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function $c(e,t){if(!Rc(e))return{events:[],nextOffset:t};let n=Lc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=_c(e,"r");try{Kc(i,s,0,o,r)}finally{Nc(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
46
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var pt=class{constructor(t){this.options=t;this.journal=new lt(t.storage),this.hierarchyJournal=new dt(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,o=Kc(this.options.wal.eventsFile,r);if(o.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:o.nextOffset};let s=rt(this.options.identity,o.events),i=s.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,o.events,i));let c=!1;s.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,o.events,s.hierarchy));let u=ro(this.options.identity,o.events,s.state),d=oo(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",s.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",s.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",s.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",s.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",s.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",s.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",s.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",s.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",s.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",s.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",s.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",d.written),this.options.wal.setSourceCursor("memory.skill.deduped",d.deduped);try{let l=jr(this.options.project.rootPath,o.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 Ur({project:this.options.project,storage:this.options.storage,hierarchy:s.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",o.nextOffset),{scannedEvents:o.events.length,candidates:i.length,journalWritten:a,nextOffset:o.nextOffset}}};import{closeSync as Zc,existsSync as eu,openSync as tu,readSync as nu,statSync as ru}from"node:fs";function co(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Re(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Ne(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let o of e.slice(0,50))Ne(o,t,n+1);return}let r=co(e);if(r)for(let[o,s]of Object.entries(r))t(o,s,r),Ne(s,t,n+1)}function fe(e,t){let n=[];return Ne(e,(r,o)=>{t.has(Re(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function Lc(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return co(JSON.parse(t))}catch{return null}}function $c(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let o=t[r];if(typeof o=="string"&&o.trim())return o.trim().toLowerCase()}let n="";return Ne(t,(r,o,s)=>{if(n)return;let i=Re(r);if(["tool","toolname"].includes(i)&&typeof o=="string"){n=o.trim().toLowerCase();return}if(i!=="name"||typeof o!="string")return;let a=typeof s.type=="string"?s.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=o.trim().toLowerCase())}),n}function Fc(e){let t=fe(e.data,new Set(["command","cmd","script"])),n=fe(e.data,new Set(["arguments","args"]));for(let r of n){let o=Lc(r);if(o)for(let s of fe(o,new Set(["command","cmd","script"])))t.push(s)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function Dc(e){let t=fe(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(Re)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
47
+ `))))}function Wc(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 zc(e){let t=fe(e.data,new Set(["patch","diff","arguments","input"].map(Re))),n=[];for(let r of t){let o=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let s of o)for(let i of r.matchAll(s.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:s.action,confidence:.99})}}return n}function qc(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 Bc(e){let t=null;return Ne(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(Re(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let o=Number(r);Number.isFinite(o)&&(t=o)}}}),t}function Vc(e){return fe(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function Jc(e){let t=Bc(e.data);if(t!==null)return t===0?"passed":"failed";let n=Vc(e.data).join(`
48
+ `).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 Hc(e){let t=[],n=new Set;for(let r of e){let o=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(o)||(n.add(o),t.push(r))}return t}function uo(e){let t=[],n=$c(e),r=Wc(e,n);if(r)for(let o of Dc(e))t.push({kind:"file",text:o,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...zc(e));for(let o of Fc(e)){t.push({kind:"command",text:o,confidence:.98});let s=qc(o);s&&t.push({kind:"test",text:o,checkKind:s,checkStatus:Jc(e),confidence:.98})}return Hc(t)}var Gc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function oe(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function po(e){return oe(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function re(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))re(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Gc.has(r)||["data","payload","parts","messages"].includes(r))&&re(o,t,n+1)}}function ft(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 lo(e){let t=oe(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 E(e,t,n,r,o={}){let s=oe(r),i=o.key??po(s);return{version:1,id:w([e.projectId,n,i,t.id,s,o.status??"",o.fileAction??"",o.checkKind??"",o.checkStatus??"",o.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:s,status:o.status,fileAction:o.fileAction,checkKind:o.checkKind,checkStatus:o.checkStatus,order:o.order,confidence:o.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function Uc(e,t,n){let r=oe(n);if(r.length<5||r.length>1200)return[];let o=[],s=/^(?: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]&&o.push(E(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(E(e,t,"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(;!s&&(u=c.exec(r));){let p=Number(u[1]),f=oe(u[2]??""),m=f&&!lo(f)?`Phase ${p} - ${f}`:`Phase ${p}`;o.push(E(e,t,"phase",m,{key:`phase:${p}`,order:p,status:ft(r),confidence:.93}))}let d=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);d?.[2]&&o.push(E(e,t,"task",d[2],{status:d[1].trim()?"completed":ft(d[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let p=l[1]?Number(l[1]):void 0,f=oe(l[2]),m=lo(f);o.push(E(e,t,"task",m&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:po(f),order:p,status:ft(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&&o.push(E(e,t,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&o.push(E(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(E(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.push(E(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)&&o.push(E(e,t,"activity",r,{confidence:.86})),o}function mt(e,t){if(t.length===0)return[];let n=[],r=new Set;function o(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 c=[];re(i.data,c);let u=c.map(d=>oe(d)).find(d=>d.length>=8&&d.length<=1200&&!/^\[?toolnet\b/iu.test(d));u&&o(E(e,i,"request",u,{confidence:.96}))}for(let c of uo(i))o(E(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];re(i.data,c);for(let u of c)o(E(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];re(i.data,c);for(let u of c)o(E(e,i,"task",u,{status:ft(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&&o(E(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];re(i.data,c);for(let u of c)o(E(e,i,"test",u,{confidence:1}))}let a=[];re(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let d of Uc(e,i,u))o(d)}let s=t[t.length-1];return o(E(e,s,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function fo(e){return String(e).padStart(12,"0")}var gt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(d=>d.sequence)),o=Math.max(...n.map(d=>d.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(d=>d.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:o,observations:n},i=JSON.stringify(s,null,2)+`
49
+ `,a=w(n.map(d=>JSON.stringify(d)).sort().join(`
50
+ `)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${fo(r)}-${fo(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as mo}from"node:path";import{mkdirSync as Yc}from"node:fs";function yo(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function F(e,t=20){let n=[],r=new Set;for(let o of e.slice().reverse()){let s=yo(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=t))break}return n.reverse()}function Xc(e,t=20){let n=new Map;for(let r of e){let o=`${r.kind}|${yo(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-t)}function Qc(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 go(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 o=e&&Qc(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:o,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 ho(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}async function _e(e,t){let r=(await ho(e,t)).flatMap(y=>y.observations).sort((y,k)=>{let P=y.occurredAt.localeCompare(k.occurredAt);if(P!==0)return P;let V=y.sequence-k.sequence;return V!==0?V:y.id.localeCompare(k.id)}),o=new Map,s=new Map,i,a,c,u,d,l=[],p=[],f=[],m=[],h=[],g=new Map,S=[],v=[],x=[],T=[],M=[],O=[];for(let y of r)switch(y.kind){case"request":i=y.text;break;case"activity":a=y.text;break;case"goal":c=y.text;break;case"plan":u=y.text;break;case"phase":o.set(y.key,go(o.get(y.key),y));break;case"task":s.set(y.key,go(s.get(y.key),y));break;case"decision":l.push(y.text);break;case"blocker":p.push(y.text);break;case"warning":f.push(y.text);break;case"next_action":m.push(y.text);break;case"file":{h.push(y.text);let k=y.fileAction??"active";g.delete(y.text),g.set(y.text,k),k==="modified"?S.push(y.text):k==="created"?v.push(y.text):k==="deleted"&&x.push(y.text);break}case"command":T.push(y.text);break;case"test":M.push(y.text),y.checkKind&&O.push({kind:y.checkKind,command:y.text,status:y.checkStatus??"unknown",updatedAt:y.occurredAt,agent:y.agent,nativeSessionId:y.nativeSessionId});break;case"session":d={agent:y.agent,nativeSessionId:y.nativeSessionId,sessionKey:y.sessionKey,updatedAt:y.occurredAt};break}let I=Array.from(o.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),b=Array.from(s.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),z=I.find(y=>y.status==="in_progress")??I.find(y=>y.status==="blocked")??I.find(y=>y.status==="pending"),q=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),Rt=F([...m,...q?[q.title]:[],...!q&&z?[z.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),_t=F([...p,...I.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),he={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:I,tasks:b,decisions:F(l,20),blockers:_t,warnings:F(f,20),nextActions:Rt,filesTouched:F(h,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:F(S,30),createdFiles:F(v,30),deletedFiles:F(x,30),commands:F(T,20),tests:F(M,20),checks:Xc(O,20),currentPhase:z,currentTask:q,progress:{phasesTotal:I.length,phasesCompleted:I.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:I.filter(y=>y.status==="blocked").length+b.filter(y=>y.status==="blocked").length},lastSession:d,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},qe=mo(e.rootPath,".toolnet","work");return Yc(qe,{recursive:!0}),N(mo(qe,"current.json"),he),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(he,null,2)+`
51
+ `,"application/json"),he}async function So(e,t){if((await ho(e,t)).length>0)return _e(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function ou(e,t){if(!eu(e))return{events:[],nextOffset:t};let n=ru(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=tu(e,"r");try{nu(i,s,0,o,r)}finally{Zc(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
52
52
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
53
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var dt=class{constructor(t){this.options=t;this.journal=new lt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=$c(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 o=ut(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await Ne(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Hc,existsSync as Gc,openSync as Uc,readSync as Yc,statSync as Xc}from"node:fs";var Fc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function de(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function rn(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))rn(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Fc.has(r)||["data","payload","parts","messages"].includes(r))&&rn(o,t,n+1)}}function R(e,t,n,r,o,s=.95){let i=de(r);return{version:1,id:w([e.projectId,n,o.type,o.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:o.type,scopeKey:o.key,scopeOrder:o.order,confidence:s,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function F(e,t){let n=e.toLowerCase();for(let r of t){let o=r.toLowerCase();if(n.startsWith(`${o}:`)||n.startsWith(`${o} -`)||n.startsWith(`${o} \u2014`))return de(e.slice(r.length+1))}return null}function Wc(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Dc(e){return de(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function co(e,t){let n=[],r=new Set;function o(s){!s.value||s.value.length<3||r.has(s.id)||(r.add(s.id),n.push(s))}for(let s of t){let i=[];rn(s.data,i);for(let a of i){let c={type:"project"},u=null;for(let l of a.split(/\r?\n/u)){let d=de(l);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let b=Number(p[1]);c={type:"phase",key:`phase:${b}`,order:b,title:de(p[2]??"")},u=null;continue}let f=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let b=Number(f[1]);c={type:"task",key:`task:${b}`,order:b,title:de(f[2]??"")},u=null;continue}let m=F(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o(R(e,s,"mission",m,{type:"project"},.99)),u=null;continue}let h=F(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){o(R(e,s,c.type==="phase"?"phase_objective":"objective",h,c,.98)),u=null;continue}let g=F(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o(R(e,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let S=F(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(S){o(R(e,s,"desired_outcome",S,{type:"project"},.98)),u=null;continue}let v=F(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(v){o(R(e,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=F(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){o(R(e,s,"phase_deliverable",x,c,.97)),u=null;continue}let T=F(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(T){o(R(e,s,"acceptance_criterion",T,c,.98)),u="acceptance_criterion";continue}let M=F(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(M){o(R(e,s,"dependency",M,c,.97)),u="dependency";continue}let E=F(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(E){o(R(e,s,"open_question",E,c,.95)),u="open_question";continue}let I=F(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(I){o(R(e,s,"constraint",I,c,.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&&Wc(l)){o(R(e,s,u,Dc(l),c,.96));continue}u=null}}}return n}function uo(e){return String(e).padStart(12,"0")}var pt=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.evidence.sequence)),o=Math.max(...n.map(u=>u.evidence.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:o,createdAt:new Date().toISOString(),observations:n},i=w(n.map(u=>u.id).sort().join("|")).slice(0,16),a=w(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${uo(r)}-${uo(o)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(s,null,2)+`
54
- `,"application/json"),c}};import{mkdirSync as zc}from"node:fs";import{join as lo}from"node:path";function qc(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function Vc(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 G(e,t){return Vc(t,e)?t:e}function U(e,t=30){let n=new Set,r=[];for(let o of e){let s=o.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!s||n.has(s)||(n.add(s),r.push(o))}return r.slice(-t)}async function Bc(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}function Jc(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function po(e,t){let r=(await Bc(e,t)).flatMap(h=>h.observations).sort((h,g)=>{let S=h.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===g.evidence.sessionKey?h.evidence.sequence-g.evidence.sequence:h.id.localeCompare(g.id)}),o,s,i,a,c,u=new Map,l=[],d=[],p=[];for(let h of r){let g=qc(h);if(h.scope==="phase"&&h.scopeKey){let S=u.get(h.scopeKey)??Jc(h);switch(h.kind){case"phase_objective":S.objective=G(S.objective,g);break;case"phase_why":S.why=G(S.why,g);break;case"phase_deliverable":S.deliverable=G(S.deliverable,g);break;case"acceptance_criterion":S.acceptanceCriteria.push(g);break;case"dependency":S.dependencies.push(g);break;case"open_question":S.openQuestions.push(g);break;case"constraint":S.constraints.push(g);break;case"note":S.notes.push(g);break}u.set(S.key,S);continue}switch(h.kind){case"mission":o=G(o,g);break;case"objective":s=G(s,g);break;case"why":i=G(i,g);break;case"desired_outcome":a=G(a,g);break;case"plan_rationale":c=G(c,g);break;case"open_question":l.push(g);break;case"constraint":d.push(g);break;case"note":p.push(g);break}}for(let h of u.values())h.acceptanceCriteria=U(h.acceptanceCriteria,20),h.dependencies=U(h.dependencies,15),h.openQuestions=U(h.openQuestions,15),h.constraints=U(h.constraints,15),h.notes=U(h.notes,20);let f={version:1,projectId:e.id,projectName:e.name,mission:o,activeObjective:s,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((h,g)=>h.order-g.order),openQuestions:U(l,20),constraints:U(d,20),notes:U(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=lo(e.rootPath,".toolnet","work");return zc(m,{recursive:!0}),O(lo(m,"semantic-current.json"),f),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
55
- `,"application/json"),f}function Zc(e,t){if(!Gc(e))return{events:[],nextOffset:t};let n=Xc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=Buffer.alloc(n-r),s=Uc(e,"r");try{Yc(s,o,0,o.length,r)}finally{Hc(s)}let i=o.toString("utf8"),a=i.lastIndexOf(`
53
+ `).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var yt=class{constructor(t){this.options=t;this.journal=new gt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=ou(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 o=mt(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await _e(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as fu,existsSync as mu,openSync as gu,readSync as yu,statSync as hu}from"node:fs";var su=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function me(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function un(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))un(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(su.has(r)||["data","payload","parts","messages"].includes(r))&&un(o,t,n+1)}}function _(e,t,n,r,o,s=.95){let i=me(r);return{version:1,id:w([e.projectId,n,o.type,o.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:o.type,scopeKey:o.key,scopeOrder:o.order,confidence:s,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function D(e,t){let n=e.toLowerCase();for(let r of t){let o=r.toLowerCase();if(n.startsWith(`${o}:`)||n.startsWith(`${o} -`)||n.startsWith(`${o} \u2014`))return me(e.slice(r.length+1))}return null}function iu(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function au(e){return me(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function ko(e,t){let n=[],r=new Set;function o(s){!s.value||s.value.length<3||r.has(s.id)||(r.add(s.id),n.push(s))}for(let s of t){let i=[];un(s.data,i);for(let a of i){let c={type:"project"},u=null;for(let d of a.split(/\r?\n/u)){let l=me(d);if(!l){u=null;continue}let p=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let b=Number(p[1]);c={type:"phase",key:`phase:${b}`,order:b,title:me(p[2]??"")},u=null;continue}let f=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let b=Number(f[1]);c={type:"task",key:`task:${b}`,order:b,title:me(f[2]??"")},u=null;continue}let m=D(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o(_(e,s,"mission",m,{type:"project"},.99)),u=null;continue}let h=D(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){o(_(e,s,c.type==="phase"?"phase_objective":"objective",h,c,.98)),u=null;continue}let g=D(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o(_(e,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let S=D(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){o(_(e,s,"desired_outcome",S,{type:"project"},.98)),u=null;continue}let v=D(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){o(_(e,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=D(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){o(_(e,s,"phase_deliverable",x,c,.97)),u=null;continue}let T=D(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(T){o(_(e,s,"acceptance_criterion",T,c,.98)),u="acceptance_criterion";continue}let M=D(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(M){o(_(e,s,"dependency",M,c,.97)),u="dependency";continue}let O=D(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(O){o(_(e,s,"open_question",O,c,.95)),u="open_question";continue}let I=D(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(I){o(_(e,s,"constraint",I,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&&iu(d)){o(_(e,s,u,au(d),c,.96));continue}u=null}}}return n}function vo(e){return String(e).padStart(12,"0")}var ht=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.evidence.sequence)),o=Math.max(...n.map(u=>u.evidence.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:o,createdAt:new Date().toISOString(),observations:n},i=w(n.map(u=>u.id).sort().join("|")).slice(0,16),a=w(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${vo(r)}-${vo(o)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(s,null,2)+`
54
+ `,"application/json"),c}};import{mkdirSync as cu}from"node:fs";import{join as wo}from"node:path";function uu(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function lu(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 U(e,t){return lu(t,e)?t:e}function Y(e,t=30){let n=new Set,r=[];for(let o of e){let s=o.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!s||n.has(s)||(n.add(s),r.push(o))}return r.slice(-t)}async function du(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}function pu(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function bo(e,t){let r=(await du(e,t)).flatMap(h=>h.observations).sort((h,g)=>{let S=h.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===g.evidence.sessionKey?h.evidence.sequence-g.evidence.sequence:h.id.localeCompare(g.id)}),o,s,i,a,c,u=new Map,d=[],l=[],p=[];for(let h of r){let g=uu(h);if(h.scope==="phase"&&h.scopeKey){let S=u.get(h.scopeKey)??pu(h);switch(h.kind){case"phase_objective":S.objective=U(S.objective,g);break;case"phase_why":S.why=U(S.why,g);break;case"phase_deliverable":S.deliverable=U(S.deliverable,g);break;case"acceptance_criterion":S.acceptanceCriteria.push(g);break;case"dependency":S.dependencies.push(g);break;case"open_question":S.openQuestions.push(g);break;case"constraint":S.constraints.push(g);break;case"note":S.notes.push(g);break}u.set(S.key,S);continue}switch(h.kind){case"mission":o=U(o,g);break;case"objective":s=U(s,g);break;case"why":i=U(i,g);break;case"desired_outcome":a=U(a,g);break;case"plan_rationale":c=U(c,g);break;case"open_question":d.push(g);break;case"constraint":l.push(g);break;case"note":p.push(g);break}}for(let h of u.values())h.acceptanceCriteria=Y(h.acceptanceCriteria,20),h.dependencies=Y(h.dependencies,15),h.openQuestions=Y(h.openQuestions,15),h.constraints=Y(h.constraints,15),h.notes=Y(h.notes,20);let f={version:1,projectId:e.id,projectName:e.name,mission:o,activeObjective:s,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((h,g)=>h.order-g.order),openQuestions:Y(d,20),constraints:Y(l,20),notes:Y(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=wo(e.rootPath,".toolnet","work");return cu(m,{recursive:!0}),N(wo(m,"semantic-current.json"),f),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
55
+ `,"application/json"),f}function Su(e,t){if(!mu(e))return{events:[],nextOffset:t};let n=hu(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=Buffer.alloc(n-r),s=gu(e,"r");try{yu(s,o,0,o.length,r)}finally{fu(s)}let i=o.toString("utf8"),a=i.lastIndexOf(`
56
56
  `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
57
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ft=class{constructor(t){this.options=t;this.journal=new pt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=Zc(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 o=co(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await po(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as Bu,mkdirSync as Ju}from"node:fs";import{join as sn}from"node:path";import{existsSync as go,mkdirSync as Qc,readFileSync as eu,statSync as fo,writeFileSync as tu}from"node:fs";import{dirname as nu,join as ru}from"node:path";var mo=64*1024,ou=`# ToolNet Project Operating Manual
57
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var St=class{constructor(t){this.options=t;this.journal=new ht(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=Su(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 o=ko(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await bo(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as dl,mkdirSync as pl}from"node:fs";import{join as dn}from"node:path";import{existsSync as Co,mkdirSync as ku,readFileSync as vu,statSync as xo,writeFileSync as wu}from"node:fs";import{dirname as bu,join as xu}from"node:path";var Io=64*1024,Iu=`# ToolNet Project Operating Manual
58
58
 
59
59
  This file contains persistent instructions for AI agents working on this project.
60
60
 
@@ -97,18 +97,18 @@ Things an AI agent should always remember.
97
97
  <!--
98
98
  - [advisory] Prefer small focused files.
99
99
  -->
100
- `;function yo(e){return ru(e.rootPath,".toolnet","PROJECT.md")}function su(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function iu(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,o;for(;o=r.exec(e);){let s=o[1].toLowerCase(),i=su(o[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:s,text:i,source:"manual"}))}return t}function au(e){let t=yo(e);return go(t)||(Qc(nu(t),{recursive:!0}),tu(t,ou,{encoding:"utf8",mode:384})),t}function ho(e,t=!1){let n=t?au(e):yo(e);if(!go(n))return null;if(fo(n).size>mo)throw new Error(`PROJECT.md exceeds ${mo} bytes`);let o=eu(n,"utf8");return{path:n,content:o,digest:w(o),rules:iu(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(fo(n).mtimeMs).toISOString()}}import{randomUUID as cu}from"node:crypto";import{closeSync as uu,existsSync as So,fsyncSync as lu,mkdirSync as du,openSync as pu,readFileSync as fu,statSync as mu,unlinkSync as ko,writeFileSync as gu}from"node:fs";import{dirname as yu,join as hu}from"node:path";var Su=new Int32Array(new SharedArrayBuffer(4));function ku(e){e<=0||Atomics.wait(Su,0,0,e)}function vu(e){return hu(e.rootPath,".toolnet","work",".current.lock")}function wu(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function vo(e){if(!So(e))return null;try{let t=JSON.parse(fu(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function bu(e){try{return Date.now()-mu(e).mtimeMs}catch{return 0}}function xu(e,t){if(!So(e)||bu(e)<t)return!1;let n=vo(e);return n?!wu(n.pid):!0}function Iu(e,t){if(!xu(e,t))return!1;try{return ko(e),!0}catch{return!1}}function Cu(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=pu(e,"wx",384);try{gu(r,`${JSON.stringify(n,null,2)}
101
- `,{encoding:"utf8"}),lu(r)}finally{uu(r)}}function ju(e,t){if(vo(e)?.token===t)try{ko(e)}catch{}}function Au(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),o=Math.max(n*2,t.staleMs??3e4),s=vu(e);du(yu(s),{recursive:!0});let i=cu(),a=Date.now()+n;for(;;)try{Cu(s,i);let c=!1;return()=>{c||(c=!0,ju(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(Iu(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);ku(r)}}function wo(e,t,n={}){let r=Au(e,n);try{return t()}finally{r()}}import{closeSync as Mu,existsSync as Pu,fsyncSync as Tu,mkdirSync as Eu,openSync as Ou,readFileSync as Nu,renameSync as Ru,writeFileSync as _u}from"node:fs";import{dirname as Ku,join as Lu}from"node:path";function $u(e,t){Eu(Ku(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=Ou(n,"w",384);try{_u(r,`${JSON.stringify(t,null,2)}
102
- `,{encoding:"utf8"}),Tu(r)}finally{Mu(r)}Ru(n,e)}function Ao(e){return Lu(e.rootPath,".toolnet","work","current.json")}function on(e){let t=Ao(e);if(!Pu(t))return null;try{let n=JSON.parse(Nu(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function mt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(e,t,n){let r=[],o=new Set;for(let s of[...e,...t].reverse()){let i=mt(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function Fu(e,t,n=20){let r=new Map;for(let o of[...e,...t]){let s=`${o.kind}|${mt(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function Wu(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 bo(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 o=e&&Wu(t)?e.title:t.text;return{id:e?.id??t.id,title:o,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 xo(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:mt(n.title);t.set(r,n)}return t}function Io(e){return e.order!==void 0?`order:${e.order}`:mt(e.key||e.text)}function Co(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,o=n.order??Number.MAX_SAFE_INTEGER;return r!==o?r-o:t.updatedAt.localeCompare(n.updatedAt)})}function jo(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function Du(e,t){let n=on(e),r=xo(n?.phases??[]),o=xo(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,l=[],d=[],p=[],f=[],m=[],h=[...n?.activeFiles??[]],g=[],S=[],v=[],x=[],T=[],M=[],E=[...t].sort((k,P)=>{let V=k.occurredAt.localeCompare(P.occurredAt);return V!==0?V:k.sequence-P.sequence});for(let k of E)switch(k.kind){case"request":s=k.text;break;case"activity":i=k.text;break;case"goal":a=k.text;break;case"plan":c=k.text;break;case"phase":{let P=Io(k);r.set(P,bo(r.get(P),k));break}case"task":{let P=Io(k);o.set(P,bo(o.get(P),k));break}case"decision":l.push(k.text);break;case"blocker":d.push(k.text);break;case"warning":p.push(k.text);break;case"next_action":f.push(k.text);break;case"file":{m.push(k.text);let P=k.fileAction??"active",V=h.indexOf(k.text);V>=0&&h.splice(V,1),P!=="deleted"&&h.push(k.text),P==="modified"?g.push(k.text):P==="created"?S.push(k.text):P==="deleted"&&v.push(k.text);break}case"command":x.push(k.text);break;case"test":T.push(k.text),k.checkKind&&M.push({kind:k.checkKind,command:k.text,status:k.checkStatus??"unknown",updatedAt:k.occurredAt,agent:k.agent,nativeSessionId:k.nativeSessionId});break;case"session":u={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let I=Co(r.values()),b=Co(o.values()),D=jo(I),z=jo(b),Pt=_(n?.nextActions??[],[...f,...z?[z.title]:[],...!z&&D?[D.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),Tt=_(n?.blockers??[],[...d,...I.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),me=E.length>0?E[E.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),$e={version:1,projectId:e.id,projectName:e.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:I,tasks:b,decisions:_(n?.decisions??[],l,20),blockers:Tt,warnings:_(n?.warnings??[],p,20),nextActions:Pt,filesTouched:_(n?.filesTouched??[],m,30),activeFiles:_([],h,5),modifiedFiles:_(n?.modifiedFiles??[],g,30),createdFiles:_(n?.createdFiles??[],S,30),deletedFiles:_(n?.deletedFiles??[],v,30),commands:_(n?.commands??[],x,20),tests:_(n?.tests??[],T,20),checks:Fu(n?.checks??[],M,20),currentPhase:D,currentTask:z,progress:{phasesTotal:I.length,phasesCompleted:I.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:I.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:me},y=ge($e);return $u(Ao(e),y),y}function Mo(e,t){return wo(e,()=>Du(e,t))}function A(e,t){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/g," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function Po(e){if(e)return{id:e.id,title:e.title,status:e.status}}function zu(e,t=[]){let n=t.slice(-10);if(n.some(o=>o.status==="failed"))return"failing";if(n.some(o=>o.status==="passed"))return"passing";let r=e.slice(-10).join(`
103
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function qu(e){return w(JSON.stringify(e))}function Vu(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let o of r){let s=o.replace(/[.,;:!?]+$/gu,"").trim();s&&t.push(s)}}return A(t,30)}function To(e){let{project:t,identity:n,state:r}=e,o=r.activeFiles?.at(-1)??r.filesTouched.at(-1),s=r.phases.filter(v=>v.status==="completed").map(v=>v.title),i=r.tasks.filter(v=>v.status==="completed").map(v=>v.title),a=r.phases.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),c=r.tasks.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),u=new Set(r.tasks.filter(v=>v.status==="completed").map(v=>v.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),l=A(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=A([...c,...l],15),p=A(r.tests.slice().reverse(),10),f=A([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),m={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:Po(r.currentPhase),task:Po(r.currentTask),file:o},completed:{phases:A(s,20),tasks:A(i,30)},remaining:{phases:A(a,20),tasks:A(c,30),todos:d},nextAction:l[0],blockers:A(r.blockers.slice().reverse(),10),decisions:A(r.decisions.slice().reverse(),10),files:{current:o,recent:f,active:A(r.activeFiles??[],10),modified:A(r.modifiedFiles??[],20),created:A(r.createdFiles??[],20),deleted:A(r.deletedFiles??[],20)},tests:{status:zu(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:A((r.commands??[]).slice().reverse(),20),references:Vu([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(v=>v.command)])},attention:A(e.attention??[],20),progress:r.progress},{capturedAt:h,source:g,...S}=m;return{...m,stateDigest:qu(S)}}function Hu(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 Eo(e,t,n,r,o){if(!Hu(n))return null;let s=ho(e,!1),a=[...s?s.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=To({project:e,identity:t,state:n,reason:r,sequence:o,attention:a}),u=c.stateDigest;return{version:1,id:w([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:o},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:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,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:c}}function Oo(e,t){let n=sn(e.rootPath,".toolnet","work","handoffs");Ju(n,{recursive:!0});let r=sn(n,`${t.id}.json`);Bu(r)||O(r,t),O(sn(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function No(e){let t=Eo(e.project,e.identity,e.state,e.reason,e.sequence);return t?(Oo(e.project,t),t):null}var gt=class{constructor(t){this.options=t}options;async capture(t,n){let r=on(this.options.project);r||(r=await ao(this.options.project,this.options.storage)),r||(r=await Ne(this.options.project,this.options.storage));let o=Eo(this.options.project,this.options.identity,r,t,n);if(!o)return null;Oo(this.options.project,o);let s=`projects/${this.options.project.id}/work/handoffs/${o.id}.json`;return await this.options.storage.exists(s)||await this.options.storage.put(s,JSON.stringify(o,null,2)+`
100
+ `;function Ao(e){return xu(e.rootPath,".toolnet","PROJECT.md")}function Cu(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Au(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,o;for(;o=r.exec(e);){let s=o[1].toLowerCase(),i=Cu(o[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:s,text:i,source:"manual"}))}return t}function Eu(e){let t=Ao(e);return Co(t)||(ku(bu(t),{recursive:!0}),wu(t,Iu,{encoding:"utf8",mode:384})),t}function Eo(e,t=!1){let n=t?Eu(e):Ao(e);if(!Co(n))return null;if(xo(n).size>Io)throw new Error(`PROJECT.md exceeds ${Io} bytes`);let o=vu(n,"utf8");return{path:n,content:o,digest:w(o),rules:Au(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(xo(n).mtimeMs).toISOString()}}import{randomUUID as ju}from"node:crypto";import{closeSync as Mu,existsSync as jo,fsyncSync as Pu,mkdirSync as Tu,openSync as Ou,readFileSync as Nu,statSync as Ru,unlinkSync as Mo,writeFileSync as _u}from"node:fs";import{dirname as Ku,join as Lu}from"node:path";var $u=new Int32Array(new SharedArrayBuffer(4));function Fu(e){e<=0||Atomics.wait($u,0,0,e)}function Du(e){return Lu(e.rootPath,".toolnet","work",".current.lock")}function Wu(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Po(e){if(!jo(e))return null;try{let t=JSON.parse(Nu(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function zu(e){try{return Date.now()-Ru(e).mtimeMs}catch{return 0}}function qu(e,t){if(!jo(e)||zu(e)<t)return!1;let n=Po(e);return n?!Wu(n.pid):!0}function Bu(e,t){if(!qu(e,t))return!1;try{return Mo(e),!0}catch{return!1}}function Vu(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=Ou(e,"wx",384);try{_u(r,`${JSON.stringify(n,null,2)}
101
+ `,{encoding:"utf8"}),Pu(r)}finally{Mu(r)}}function Ju(e,t){if(Po(e)?.token===t)try{Mo(e)}catch{}}function Hu(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),o=Math.max(n*2,t.staleMs??3e4),s=Du(e);Tu(Ku(s),{recursive:!0});let i=ju(),a=Date.now()+n;for(;;)try{Vu(s,i);let c=!1;return()=>{c||(c=!0,Ju(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(Bu(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);Fu(r)}}function To(e,t,n={}){let r=Hu(e,n);try{return t()}finally{r()}}import{closeSync as Gu,existsSync as Uu,fsyncSync as Yu,mkdirSync as Xu,openSync as Qu,readFileSync as Zu,renameSync as el,writeFileSync as tl}from"node:fs";import{dirname as nl,join as rl}from"node:path";function ol(e,t){Xu(nl(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=Qu(n,"w",384);try{tl(r,`${JSON.stringify(t,null,2)}
102
+ `,{encoding:"utf8"}),Yu(r)}finally{Gu(r)}el(n,e)}function Lo(e){return rl(e.rootPath,".toolnet","work","current.json")}function ln(e){let t=Lo(e);if(!Uu(t))return null;try{let n=JSON.parse(Zu(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function kt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function K(e,t,n){let r=[],o=new Set;for(let s of[...e,...t].reverse()){let i=kt(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function sl(e,t,n=20){let r=new Map;for(let o of[...e,...t]){let s=`${o.kind}|${kt(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function il(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 Oo(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 o=e&&il(t)?e.title:t.text;return{id:e?.id??t.id,title:o,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 No(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:kt(n.title);t.set(r,n)}return t}function Ro(e){return e.order!==void 0?`order:${e.order}`:kt(e.key||e.text)}function _o(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,o=n.order??Number.MAX_SAFE_INTEGER;return r!==o?r-o:t.updatedAt.localeCompare(n.updatedAt)})}function Ko(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function al(e,t){let n=ln(e),r=No(n?.phases??[]),o=No(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,d=[],l=[],p=[],f=[],m=[],h=[...n?.activeFiles??[]],g=[],S=[],v=[],x=[],T=[],M=[],O=[...t].sort((k,P)=>{let V=k.occurredAt.localeCompare(P.occurredAt);return V!==0?V:k.sequence-P.sequence});for(let k of O)switch(k.kind){case"request":s=k.text;break;case"activity":i=k.text;break;case"goal":a=k.text;break;case"plan":c=k.text;break;case"phase":{let P=Ro(k);r.set(P,Oo(r.get(P),k));break}case"task":{let P=Ro(k);o.set(P,Oo(o.get(P),k));break}case"decision":d.push(k.text);break;case"blocker":l.push(k.text);break;case"warning":p.push(k.text);break;case"next_action":f.push(k.text);break;case"file":{m.push(k.text);let P=k.fileAction??"active",V=h.indexOf(k.text);V>=0&&h.splice(V,1),P!=="deleted"&&h.push(k.text),P==="modified"?g.push(k.text):P==="created"?S.push(k.text):P==="deleted"&&v.push(k.text);break}case"command":x.push(k.text);break;case"test":T.push(k.text),k.checkKind&&M.push({kind:k.checkKind,command:k.text,status:k.checkStatus??"unknown",updatedAt:k.occurredAt,agent:k.agent,nativeSessionId:k.nativeSessionId});break;case"session":u={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let I=_o(r.values()),b=_o(o.values()),z=Ko(I),q=Ko(b),Rt=K(n?.nextActions??[],[...f,...q?[q.title]:[],...!q&&z?[z.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),_t=K(n?.blockers??[],[...l,...I.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),he=O.length>0?O[O.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),qe={version:1,projectId:e.id,projectName:e.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:I,tasks:b,decisions:K(n?.decisions??[],d,20),blockers:_t,warnings:K(n?.warnings??[],p,20),nextActions:Rt,filesTouched:K(n?.filesTouched??[],m,30),activeFiles:K([],h,5),modifiedFiles:K(n?.modifiedFiles??[],g,30),createdFiles:K(n?.createdFiles??[],S,30),deletedFiles:K(n?.deletedFiles??[],v,30),commands:K(n?.commands??[],x,20),tests:K(n?.tests??[],T,20),checks:sl(n?.checks??[],M,20),currentPhase:z,currentTask:q,progress:{phasesTotal:I.length,phasesCompleted:I.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:I.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:he},y=ce(qe);return ol(Lo(e),y),y}function $o(e,t){return To(e,()=>al(e,t))}function j(e,t){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/g," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function Fo(e){if(e)return{id:e.id,title:e.title,status:e.status}}function cl(e,t=[]){let n=t.slice(-10);if(n.some(o=>o.status==="failed"))return"failing";if(n.some(o=>o.status==="passed"))return"passing";let r=e.slice(-10).join(`
103
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function ul(e){return w(JSON.stringify(e))}function ll(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let o of r){let s=o.replace(/[.,;:!?]+$/gu,"").trim();s&&t.push(s)}}return j(t,30)}function Do(e){let{project:t,identity:n,state:r}=e,o=r.activeFiles?.at(-1)??r.filesTouched.at(-1),s=r.phases.filter(v=>v.status==="completed").map(v=>v.title),i=r.tasks.filter(v=>v.status==="completed").map(v=>v.title),a=r.phases.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),c=r.tasks.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),u=new Set(r.tasks.filter(v=>v.status==="completed").map(v=>v.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),d=j(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),l=j([...c,...d],15),p=j(r.tests.slice().reverse(),10),f=j([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),m={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:Fo(r.currentPhase),task:Fo(r.currentTask),file:o},completed:{phases:j(s,20),tasks:j(i,30)},remaining:{phases:j(a,20),tasks:j(c,30),todos:l},nextAction:d[0],blockers:j(r.blockers.slice().reverse(),10),decisions:j(r.decisions.slice().reverse(),10),files:{current:o,recent:f,active:j(r.activeFiles??[],10),modified:j(r.modifiedFiles??[],20),created:j(r.createdFiles??[],20),deleted:j(r.deletedFiles??[],20)},tests:{status:cl(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:j((r.commands??[]).slice().reverse(),20),references:ll([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(v=>v.command)])},attention:j(e.attention??[],20),progress:r.progress},{capturedAt:h,source:g,...S}=m;return{...m,stateDigest:ul(S)}}function fl(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 Wo(e,t,n,r,o){if(!fl(n))return null;let s=Eo(e,!1),a=[...s?s.rules.filter(l=>l.mode==="enforce").map(l=>l.text):[],...n.warnings].slice(0,20),c=Do({project:e,identity:t,state:n,reason:r,sequence:o,attention:a}),u=c.stateDigest;return{version:1,id:w([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:o},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(l=>l.status!=="completed"&&l.status!=="cancelled"),incompleteTasks:n.tasks.filter(l=>l.status!=="completed"&&l.status!=="cancelled"),nextActions:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,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:c}}function zo(e,t){let n=dn(e.rootPath,".toolnet","work","handoffs");pl(n,{recursive:!0});let r=dn(n,`${t.id}.json`);dl(r)||N(r,t),N(dn(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function qo(e){let t=Wo(e.project,e.identity,e.state,e.reason,e.sequence);return t?(zo(e.project,t),t):null}var vt=class{constructor(t){this.options=t}options;async capture(t,n){let r=ln(this.options.project);r||(r=await So(this.options.project,this.options.storage)),r||(r=await _e(this.options.project,this.options.storage));let o=Wo(this.options.project,this.options.identity,r,t,n);if(!o)return null;zo(this.options.project,o);let s=`projects/${this.options.project.id}/work/handoffs/${o.id}.json`;return await this.options.storage.exists(s)||await this.options.storage.put(s,JSON.stringify(o,null,2)+`
104
104
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(o,null,2)+`
105
- `,"application/json"),o}};import{existsSync as Gu,readFileSync as Uu,writeFileSync as Yu}from"node:fs";import{join as Xu}from"node:path";var _o="<!-- TOOLNET:STABLE-WORK:BEGIN -->",an="<!-- TOOLNET:STABLE-WORK:END -->";function cn(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Ro(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${cn(n)} ${n.title}`)]:[]}function Zu(e){let t=[_o,"# 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:",`${cn(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${cn(e.currentTask)} ${e.currentTask.title}`),t.push(...Ro("Phases",e.phases)),t.push(...Ro("TODO / Tasks",e.tasks)),t.push(...W("Next actions",e.nextActions)),t.push(...W("Blockers",e.blockers)),t.push(...W("Important decisions",e.decisions)),t.push(...W("Active files",e.activeFiles??[])),t.push(...W("Modified files",e.modifiedFiles??[])),t.push(...W("Created files",e.createdFiles??[])),t.push(...W("Deleted files",e.deletedFiles??[])),t.push(...W("Files touched",e.filesTouched)),t.push(...W("Recent commands",e.commands??[])),t.push(...W("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.",an),t.join(`
106
- `)}function Ko(e,t){let n=Xu(e.rootPath,".toolnet","current.md"),r="";if(Gu(n))try{r=Uu(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=Zu(t),s=r.indexOf(_o),i=r.indexOf(an),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+an.length).trimStart()].filter(Boolean).join(`
105
+ `,"application/json"),o}};import{existsSync as ml,readFileSync as gl,writeFileSync as yl}from"node:fs";import{join as hl}from"node:path";var Vo="<!-- TOOLNET:STABLE-WORK:BEGIN -->",pn="<!-- TOOLNET:STABLE-WORK:END -->";function fn(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Bo(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${fn(n)} ${n.title}`)]:[]}function Sl(e){let t=[Vo,"# 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:",`${fn(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${fn(e.currentTask)} ${e.currentTask.title}`),t.push(...Bo("Phases",e.phases)),t.push(...Bo("TODO / Tasks",e.tasks)),t.push(...W("Next actions",e.nextActions)),t.push(...W("Blockers",e.blockers)),t.push(...W("Important decisions",e.decisions)),t.push(...W("Active files",e.activeFiles??[])),t.push(...W("Modified files",e.modifiedFiles??[])),t.push(...W("Created files",e.createdFiles??[])),t.push(...W("Deleted files",e.deletedFiles??[])),t.push(...W("Files touched",e.filesTouched)),t.push(...W("Recent commands",e.commands??[])),t.push(...W("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.",pn),t.join(`
106
+ `)}function Jo(e,t){let n=hl(e.rootPath,".toolnet","current.md"),r="";if(ml(n))try{r=gl(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=Sl(t),s=r.indexOf(Vo),i=r.indexOf(pn),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+pn.length).trimStart()].filter(Boolean).join(`
107
107
 
108
108
  `):a=r.trim()?`${r.trim()}
109
109
 
110
- ${o}`:o,Yu(n,`${a.trim()}
111
- `,{encoding:"utf8",mode:384})}import{existsSync as Gm,mkdirSync as Qu,readFileSync as Um,renameSync as el,writeFileSync as tl}from"node:fs";import{dirname as nl,join as rl}from"node:path";function ol(e){return rl(e.rootPath,".toolnet","context","session-origin.json")}function sl(e,t){Qu(nl(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;tl(n,`${JSON.stringify(t,null,2)}
112
- `,{encoding:"utf8",mode:384}),el(n,e)}function yt(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let o=n.occurredAt.localeCompare(r.occurredAt);return o!==0?o:n.sequence-r.sequence}).at(-1)}function Lo(e,t){let n=yt(t.observations,"file"),r=yt(t.observations,"next_action"),o=yt(t.observations,"blocker"),s=yt(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:o?.text??t.workState.blockers.at(-1),latestDecision:s?.text??t.workState.decisions.at(-1)};return sl(ol(e),i),i}import{existsSync as $o,mkdirSync as il,readFileSync as al}from"node:fs";import{join as un}from"node:path";function Fo(e){return un(e.rootPath,".toolnet","memory","checkpoints")}function Wo(e){return un(Fo(e),"latest.json")}function cl(e){let t=Wo(e);if(!$o(t))return null;try{let n=JSON.parse(al(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function ul(e){return["rule","architecture","decision","fix"].includes(e)}function ll(e,t){return t.length===0?[]:Ze(e,t).candidates.filter(r=>ul(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 dl(e,t){let n=new Map;for(let r of[...e,...t]){let o=n.get(r.fingerprint);(!o||r.importanceScore>o.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,o)=>o.importanceScore-r.importanceScore||o.createdAt.localeCompare(r.createdAt)).slice(0,80)}function pl(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 Do(e,t,n,r){let o=cl(e),s=dl(o?.durableFacts??[],ll(t,n)),i=n.at(-1)?.sequence??o?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),d={work:pl(r),durableFacts:s.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(d)).slice(0,32),f={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:a,tasks:c},remaining:{phases:u,tasks:l},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:s,stateDigest:p},m=Fo(e);il(m,{recursive:!0,mode:448});let h=un(m,`${p}.json`);return $o(h)||O(h,f),O(Wo(e),f),f}function zo(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ut(t,n);if(r.length===0)return{updated:!1,observations:0};let o=Mo(e,r);Ko(e,o),Lo(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{Do(e,t,n,o)}catch{}try{No({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var ht=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=En(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new Ue(this.identity,t.eventContext),this.remote=new qe(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new at({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new dt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new ft({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new gt({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{zo(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 o=t.events[t.events.length-1];this.wal.markRemote(o.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 o=t.events[t.events.length-1],s=["session_idle","session_end","session_compact"].includes(o.type)?o.type:"checkpoint";await this.handoff.capture(s,o.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{homedir as fl}from"node:os";import{join as qo,resolve as St}from"node:path";function ln(){let e=process.env.XDG_CONFIG_HOME??qo(fl(),".config");return qo(e,"toolnet-memory","toolnet-cli-bindings.json")}function Vo(e){return e.endsWith(".json")?e.slice(0,-5):e}function ml(){return{version:1,sessions:{}}}function dn(e){let t=ze(e);if(!t)return ml();if(t.version!==1||!t.sessions||typeof t.sessions!="object")throw new Error(`Invalid ToolNet CLI binding registry: ${e}`);return t}function pn(e){return St(e.rootPath)}function fn(e,t,n={}){let r=Vo(t);if(!r)throw new Error("ToolNet CLI native session ID is required.");let o=n.bindingFile??ln(),s=dn(o),i=s.sessions[r],a=pn(e);if(i){if(i.projectId!==e.id||St(i.projectRoot)!==a)throw new Error(`ToolNet CLI session ${r} is already bound to another project: ${i.projectRoot}`);return i}let c={nativeSessionId:r,projectId:e.id,projectRoot:a,boundAt:new Date().toISOString()};return s.sessions[r]=c,O(o,s),c}function mn(e,t,n={}){let r=Vo(t),o=n.bindingFile??ln(),i=dn(o).sessions[r];if(!i)throw new Error(`ToolNet CLI session ${r} is not bound to this project. Run sync once with --bind.`);let a=pn(e);if(i.projectId!==e.id||St(i.projectRoot)!==a)throw new Error(`ToolNet CLI session ${r} belongs to another project: ${i.projectRoot}`);return i}function Bo(e,t={}){let n=t.bindingFile??ln(),r=dn(n),o=pn(e);return Object.values(r.sessions).filter(s=>s.projectId===e.id&&St(s.projectRoot)===o).sort((s,i)=>s.nativeSessionId.localeCompare(i.nativeSessionId))}function yn(){return process.env.TOOLNETCLI_SESSIONS_DIR?process.env.TOOLNETCLI_SESSIONS_DIR:process.env.TOOLNETAPI_SESSIONS_DIR?process.env.TOOLNETAPI_SESSIONS_DIR:process.env.DATA_DIR?gn(process.env.DATA_DIR,"sessions"):gn(hl(),".toolnetcli","sessions")}function Jo(e){return e.endsWith(".json")?e.slice(0,-5):e}function hn(e,t=yn()){return gn(t,`${Jo(e)}.json`)}function Sl(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function kl(e){return Array.isArray(e)?e.filter(t=>!!t&&typeof t=="object"&&!Array.isArray(t)):[]}function kt(e){return typeof e=="string"?e:void 0}function vl(e){if(typeof e!="string")return;let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}function wl(e,t,n){let r=w(De({nativeSessionId:e,index:t,message:n})).slice(0,20);return`toolnet-cli:message:${t}:${r}`}function bl(e,t,n,r,o){let s=kt(o.role),i="message";s==="user"&&(i="user_prompt"),s==="assistant"&&(i="assistant_message");let a={index:r,content:kt(o.content)??""};return o.tool_calls!==void 0&&(a.toolCalls=o.tool_calls),o.tool_call_id!==void 0&&(a.toolCallId=o.tool_call_id),o.name!==void 0&&(a.name=o.name),{type:i,timestamp:n,role:s,source:"toolnet-cli",sourceEventId:wl(e,r,o),sourceSequence:r,data:a,provenance:{source:"toolnet-cli",sourcePath:t,sourceOffset:r,metadata:{nativeSessionId:e}}}}function xl(e){if(!gl(e))throw new Error(`ToolNet CLI session not found: ${e}`);let t;try{t=JSON.parse(yl(e,"utf8"))}catch{throw new Error(`Invalid ToolNet CLI session JSON: ${e}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid ToolNet CLI session root: ${e}`);return t}async function vt(e){let t=Jo(e.nativeSessionId);if(!t)throw new Error("ToolNet CLI native session ID is required.");e.bind?fn(e.project,t,{bindingFile:e.bindingFile}):mn(e.project,t,{bindingFile:e.bindingFile}),e.bind?fn(e.project,e.nativeSessionId,{bindingFile:e.bindingFile}):mn(e.project,e.nativeSessionId,{bindingFile:e.bindingFile});let n=hn(t,e.sessionsDir),r=xl(n),o=kt(r.sessionId);if(o&&o!==t)throw new Error(`ToolNet CLI session ID mismatch: requested=${t}, file=${o}`);let s=kl(r.messages),i=Sl(r.metadata),a=vl(r.updatedAt),c=new ht({project:e.project,storage:e.storage,agent:"toolnet-cli",nativeSessionId:t,title:kt(i.name),metadata:{nativeSource:"toolnet-cli-session-json",sourceFile:n,model:i.model,agentMode:i.agentMode},eventContext:{source:"toolnet-cli",cwd:e.project.rootPath}});c.status().lastSequence===0&&c.start({nativeSource:"toolnet-cli-session-json",sourceFile:n});let l="toolnet-cli.message-count",d=c.status().sourceCursors[l],p=Number(d),f=Number.isInteger(p)&&p>=0?p:0;f>s.length&&(f=0);let m=s.slice(f).map((S,v)=>bl(t,n,a,f+v,S)),h=c.recordMany(m);if(c.setSourceCursor(l,s.length),e.localOnly){let S=c.status();return{nativeSessionId:t,sourceFile:n,importedMessages:m.length,recordedEvents:h.length,eventCount:S.lastSequence,durability:"local"}}e.idle?await c.idle({nativeSource:"toolnet-cli-session-json",sourceFile:n}):await c.flush();let g=c.status();return{nativeSessionId:t,sourceFile:n,importedMessages:m.length,recordedEvents:h.length,eventCount:g.lastSequence,durability:"remote"}}function Cl(){return Il("sh",["-lc","command -v toolnet >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function wt(e={}){let t=Cn(),n=Fe({cwd:e.cwd}),r=yn(),o=Sn(t),s=Cl(),i=Sn(n),a=Sn(r),c=[];return o||c.push(`Config directory missing: ${t}`),s||c.push("ToolNet CLI binary not found (toolnet)"),{installed:o&&s,state:o?s?"installed":"missing-binary":"missing-config",mcp:{configured:i,configFile:n},nativeSource:{available:a,sessionsDir:r},capabilities:{...Ot},errors:c}}import{existsSync as jl}from"node:fs";async function bt(e){let t=Bo(e.project,{bindingFile:e.bindingFile}),n=[],r=0,o=0,s=0,i=0,a=0;for(let c of t){let u=c.nativeSessionId,l=hn(u,e.sessionsDir);if(!jl(l)){o+=1,n.push({nativeSessionId:u,status:"missing"});continue}try{let d=await vt({project:e.project,storage:e.storage,nativeSessionId:u,sessionsDir:e.sessionsDir,bindingFile:e.bindingFile,localOnly:e.localOnly,idle:e.idle});r+=1,i+=d.importedMessages,a+=d.recordedEvents,n.push({nativeSessionId:u,status:"synced",result:d})}catch(d){s+=1,n.push({nativeSessionId:u,status:"error",error:d instanceof Error?d.message:String(d)})}}return{bound:t.length,synced:r,missing:o,failed:s,importedMessages:i,recordedEvents:a,sessions:n}}function Ho(e){let t=e.intervalMs&&e.intervalMs>=250?e.intervalMs:2e3,n=!0,r=!1,o=0,s=0,i=0,a=0,c=0,u,l;async function d(){if(r)return{bound:0,synced:0,missing:0,failed:0,importedMessages:0,recordedEvents:0,sessions:[]};r=!0,o+=1,u=new Date().toISOString();try{let p=await bt({project:e.project,storage:e.storage,sessionsDir:e.sessionsDir,bindingFile:e.bindingFile,localOnly:e.localOnly});return s+=1,a+=p.importedMessages,c+=p.recordedEvents,e.onSync?.(p),p}catch(p){i+=1;let f=p instanceof Error?p:new Error(String(p));throw e.onError?.(f),f}finally{r=!1}}return l=setInterval(()=>{!n||r||d().catch(()=>{})},t),{runOnce:d,stop(){n&&(n=!1,l&&(clearInterval(l),l=void 0))},status(){return{running:n,intervalMs:t,runs:o,successfulRuns:s,failedRuns:i,importedMessages:a,recordedEvents:c,lastRunAt:u}}}}import{createHash as Nl}from"node:crypto";import{existsSync as Ct,mkdirSync as Rl,readFileSync as _l,renameSync as Kl,writeFileSync as Ll}from"node:fs";import{basename as $l,dirname as jt,join as _e,parse as ts,resolve as se}from"node:path";import{createHash as Yo}from"node:crypto";import{spawnSync as Al}from"node:child_process";var Re="git-remote-v1",Ml=new Set(["github.com","gitlab.com","bitbucket.org"]);function Xo(e,t){let n=t.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!n||n==="."||n===".."||n.split("/").some(r=>!r||r==="."||r==="..")?null:(Ml.has(e)&&(n=n.toLowerCase()),n)}function Pl(e){let t;try{t=new URL(e)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(t.protocol))return null;let n=t.hostname.trim().toLowerCase();if(!n)return null;let r=t.protocol==="https:"&&t.port==="443"||t.protocol==="http:"&&t.port==="80"||t.protocol==="ssh:"&&t.port==="22",o=t.port&&!r?`${n}:${t.port}`:n,s=Xo(n,t.pathname);return s?`${o}/${s}`:null}function Tl(e){let t=e.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!t)return null;let n=t[1]?.trim().toLowerCase();if(!n||n.length===1)return null;let r=Xo(n,t[2]??"");return r?`${n}/${r}`:null}function Go(e){let t=e.trim();return t?t.includes("://")?Pl(t):Tl(t):null}function El(e){return Yo("sha256").update(`${Re}:${e}`).digest("hex")}function Zo(e){return Yo("sha256").update(`toolnet-project:${Re}:${e}`).digest("hex").slice(0,16)}function Ol(e){return e.split("/").filter(Boolean).at(-1)?.trim()||null}function kn(e,t){let n=Al("git",["-C",e,...t],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function Uo(e,t){let n=Ol(e);return n?{scheme:Re,canonicalRemote:e,fingerprint:El(e),repositoryName:n,source:t}:null}function Qo(e){let t=kn(e,["remote","get-url","origin"]);if(t){let o=Go(t);if(o)return Uo(o,"origin")}let n=kn(e,["remote"]);if(!n)return null;let r=new Set;for(let o of n.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=kn(e,["remote","get-url",o]);if(!s)continue;let i=Go(s);i&&r.add(i)}return r.size!==1?null:Uo([...r][0],"unique-remote")}var ns=".toolnet",Fl="project.json";function Wl(e){return Nl("sha256").update(e).digest("hex").slice(0,16)}function pe(e){return _e(e,ns,Fl)}function rs(e){return Ct(pe(e))}function es(e,t){let n=se(e),r=ts(n).root;for(;;){if(rs(n))return n;if(n===r||t&&n===se(t))break;let o=jt(n);if(o===n)break;n=o}return null}function vn(e){let t=se(e),n=ts(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>Ct(_e(t,s))))return t;if(t===n)break;let o=jt(t);if(o===t)break;t=o}return se(e)}function xt(e){let t;try{t=JSON.parse(_l(e,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${e}: ${o instanceof Error?o.message:String(o)}`)}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:jt(jt(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 It(e,t){let n=_e(e,ns);Rl(n,{recursive:!0});let r=pe(e),o=`${r}.tmp-${process.pid}`;Ll(o,JSON.stringify(t,null,2)+`
113
- `,{encoding:"utf8",mode:384}),Kl(o,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}}function wn(e){return{version:1,scheme:Re,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function Dl(e){let t=e.metadata?.toolnetIdentity;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return typeof n.fingerprint=="string"?n.fingerprint:null}var fe=class{adopt(t,n){let r=vn(se(t));if(!n.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!n.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!n.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(rs(r)){let a=xt(pe(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return oe(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=wn(n.gitIdentity));let i={version:1,id:n.id.trim(),name:n.name.trim(),remote:n.remote.trim(),rootPath:r,createdAt:n.createdAt??o,updatedAt:o,graphVersion:n.graphVersion??0,memoryVersion:n.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return It(r,i),oe(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=pe(o.rootPath),i=xt(s),a=Dl(i);if(a&&a!==n.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${n.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===n.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:wn(n)},i.updatedAt=new Date().toISOString(),It(o.rootPath,i)),oe(i,o.rootPath)}findExisting(t=process.cwd()){let n=se(t),r=vn(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Ct(_e(r,c))),i=es(n,s?r:void 0);if(!i)return null;let a=xt(pe(i));return oe(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=se(t),r=vn(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>Ct(_e(r,d))),i=es(n,s?r:void 0);if(i){let d=pe(i),p=xt(d);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),It(i,p)),oe(p,i)}let a=new Date().toISOString(),c=$l(r),u=Qo(r),l={version:1,id:u?Zo(u.canonicalRemote):Wl(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:wn(u)}:void 0};return It(r,l),oe(l,r)}};import{homedir as ld}from"node:os";import{join as dd}from"node:path";import{DeleteObjectCommand as zl,GetObjectCommand as ql,HeadObjectCommand as Vl,ListObjectsV2Command as Bl,PutObjectCommand as Jl,S3Client as Hl}from"@aws-sdk/client-s3";import{getSignedUrl as Gl}from"@aws-sdk/s3-request-presigner";var At=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Hl({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 o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Jl({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Gl(this.client,new ql({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 Vl({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 zl({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Bl({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{access as os,mkdir as Ul,readFile as Yl,readdir as Xl,rm as Zl,stat as ss,writeFile as Ql}from"node:fs/promises";import{dirname as ed,join as td,relative as is,resolve as nd}from"node:path";var Ke=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return nd(this.root,n)}async put(t,n){let r=this.path(t);await Ul(ed(r),{recursive:!0}),await Ql(r,n)}async get(t){try{return await Yl(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 os(this.path(t)),!0}catch{return!1}}async delete(t){await Zl(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await os(n)}catch{return r}let o=async i=>{let a=await Xl(i,{withFileTypes:!0});for(let c of a){let u=td(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await ss(u);r.push({key:is(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await ss(n);return s.isDirectory()?await o(n):r.push({key:is(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as rd,GetObjectCommand as od,HeadObjectCommand as sd,ListObjectsV2Command as id,PutObjectCommand as ad,S3Client as cd}from"@aws-sdk/client-s3";import{getSignedUrl as ud}from"@aws-sdk/s3-request-presigner";var Le=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new cd({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 o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ad({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await ud(this.client,new od({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 sd({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 rd({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new id({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};function bn(e,t){return console.warn(t),new Ke(e)}function as(e){let t=e.localRoot??dd(ld(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Le({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bn(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 Le({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bn(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 At({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bn(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new Ke(t)}function pd(e){return new Promise(t=>setTimeout(t,e))}async function cs(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,o=t.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(s=a,i>=n)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await pd(c+u)}throw s}var fd=new Set(["put","get","getText","delete","list"]);function us(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:fd.has(r)?(...s)=>cs(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function ls(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 ds(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 o=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:t))}var Mt=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=ls(o??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,o=await this.provider.getText(t);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${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 s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(s,null,2)+`
114
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=ds(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))}};function Y(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function xn(e){let t=Xe(),n=us(as({provider:t.storage.provider,huggingface:t.storage.huggingface,localRoot:t.storage.localRoot}),{attempts:3});return new Mt(n,e.id,e.name,e.remote??e.name)}function md(){let e=wt({cwd:process.cwd()});console.log("ToolNet CLI Integration"),console.log("======================="),console.log(""),console.log(`State : ${e.state}`),console.log(`MCP : ${e.mcp.configured?"ready":"missing"} \u2014 ${e.mcp.configFile}`),console.log(`Memory: ${e.capabilities.level}`),console.log(`Capture: ${e.capabilities.nativeCapture?"native":"not available"}`),console.log(`Native source: ${e.nativeSource.available?"available":"missing"} \u2014 ${e.nativeSource.sessionsDir}`);for(let t of e.errors)console.log(`Error : ${t}`);return console.log(""),e.installed}async function gd(){let e=process.argv.slice(2),t=e[0],n=e.includes("--json");if(t==="watch-bound"){let a=Y(e,"--project")??process.cwd(),c=new fe().detect(a),u=xn(c),l=Y(e,"--interval-ms"),d=l!==void 0?Number(l):void 0,p=Number.isFinite(d)&&d!==void 0?d:void 0,f=Ho({project:c,storage:u,sessionsDir:Y(e,"--sessions-dir"),localOnly:e.includes("--local-only"),intervalMs:p,onSync(g){g.importedMessages===0&&g.recordedEvents===0&&g.failed===0||console.log(JSON.stringify({event:"toolnet-cli-bound-sync",...g},null,2))},onError(g){console.error(`ToolNet CLI watcher error: ${g.message}`)}}),m=await f.runOnce();console.log(JSON.stringify({event:"toolnet-cli-watcher-started",first:m,watcher:f.status()},null,2));let h=()=>{f.stop(),console.log(JSON.stringify({event:"toolnet-cli-watcher-stopped",watcher:f.status()},null,2))};process.once("SIGINT",h),process.once("SIGTERM",h);return}if(t==="sync-bound"){let a=Y(e,"--project")??process.cwd(),c=new fe().detect(a),u=xn(c),l=await bt({project:c,storage:u,sessionsDir:Y(e,"--sessions-dir"),localOnly:e.includes("--local-only"),idle:e.includes("--idle")});console.log(JSON.stringify(l,null,2)),l.failed>0&&(process.exitCode=1);return}if(t==="sync"){let a=e[1];if(!a)throw new Error("Usage: toolnet-memory integrate:toolnet-cli sync <session-id> --bind [--project PATH]");let c=Y(e,"--project")??process.cwd(),u=new fe().detect(c),l=xn(u),d=await vt({project:u,storage:l,nativeSessionId:a,sessionsDir:Y(e,"--sessions-dir"),localOnly:e.includes("--local-only"),idle:e.includes("--idle"),bind:e.includes("--bind"),bindingFile:Y(e,"--binding-file")});console.log(JSON.stringify(d,null,2));return}if(e.includes("--status")||e[0]==="status"){let a=wt({cwd:process.cwd()});n?console.log(JSON.stringify(a,null,2)):md(),a.installed||(process.exitCode=1);return}let o=e.includes("--force"),s=An({force:o,cwd:process.cwd()}),i=wt({cwd:process.cwd()});if(!i.installed)throw new Error(`ToolNet CLI integration installation did not verify successfully (state=${i.state}).`);if(n){console.log(JSON.stringify({installed:!0,changed:s.changed,files:s.files,status:i},null,2));return}console.log(`ToolNet CLI MCP: ${s.mcp.configured?"configured":"not configured"}`),console.log(`Memory: ${i.capabilities.level}`),console.log(`Native source: ${i.nativeSource.available?"available":"missing"}`),s.changed?console.log(`Config updated: ${s.mcp.configFile}`):console.log("Config unchanged (already configured)"),console.log(""),console.log("ToolNet CLI integration ready.")}gd().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});
110
+ ${o}`:o,yl(n,`${a.trim()}
111
+ `,{encoding:"utf8",mode:384})}import{existsSync as Eg,mkdirSync as kl,readFileSync as jg,renameSync as vl,writeFileSync as wl}from"node:fs";import{dirname as bl,join as xl}from"node:path";function Il(e){return xl(e.rootPath,".toolnet","context","session-origin.json")}function Cl(e,t){kl(bl(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;wl(n,`${JSON.stringify(t,null,2)}
112
+ `,{encoding:"utf8",mode:384}),vl(n,e)}function wt(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let o=n.occurredAt.localeCompare(r.occurredAt);return o!==0?o:n.sequence-r.sequence}).at(-1)}function Ho(e,t){let n=wt(t.observations,"file"),r=wt(t.observations,"next_action"),o=wt(t.observations,"blocker"),s=wt(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:o?.text??t.workState.blockers.at(-1),latestDecision:s?.text??t.workState.decisions.at(-1)};return Cl(Il(e),i),i}import{existsSync as Go,mkdirSync as Al,readFileSync as El}from"node:fs";import{join as mn}from"node:path";function Uo(e){return mn(e.rootPath,".toolnet","memory","checkpoints")}function Yo(e){return mn(Uo(e),"latest.json")}function jl(e){let t=Yo(e);if(!Go(t))return null;try{let n=JSON.parse(El(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Ml(e){return["rule","architecture","decision","fix"].includes(e)}function Pl(e,t){return t.length===0?[]:rt(e,t).candidates.filter(r=>Ml(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 Tl(e,t){let n=new Map;for(let r of[...e,...t]){let o=n.get(r.fingerprint);(!o||r.importanceScore>o.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,o)=>o.importanceScore-r.importanceScore||o.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Ol(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 Xo(e,t,n,r){let o=jl(e),s=Tl(o?.durableFacts??[],Pl(t,n)),i=n.at(-1)?.sequence??o?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),d=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l={work:Ol(r),durableFacts:s.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(l)).slice(0,32),f={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:a,tasks:c},remaining:{phases:u,tasks:d},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:s,stateDigest:p},m=Uo(e);Al(m,{recursive:!0,mode:448});let h=mn(m,`${p}.json`);return Go(h)||N(h,f),N(Yo(e),f),f}function Qo(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=mt(t,n);if(r.length===0)return{updated:!1,observations:0};let o=$o(e,r);Jo(e,o),Ho(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{Xo(e,t,n,o)}catch{}try{qo({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var bt=class{identity;wal;remote;sanitizer=new J;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=Wn(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new et(this.identity,t.eventContext),this.remote=new Ge(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new pt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new yt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new St({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new vt({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{Qo(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 o=t.events[t.events.length-1];this.wal.markRemote(o.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 o=t.events[t.events.length-1],s=["session_idle","session_end","session_compact"].includes(o.type)?o.type:"checkpoint";await this.handoff.capture(s,o.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{homedir as Nl}from"node:os";import{join as Zo,resolve as xt}from"node:path";function gn(){let e=process.env.XDG_CONFIG_HOME??Zo(Nl(),".config");return Zo(e,"toolnet-memory","toolnet-cli-bindings.json")}function es(e){return e.endsWith(".json")?e.slice(0,-5):e}function Rl(){return{version:1,sessions:{}}}function yn(e){let t=He(e);if(!t)return Rl();if(t.version!==1||!t.sessions||typeof t.sessions!="object")throw new Error(`Invalid ToolNet CLI binding registry: ${e}`);return t}function hn(e){return xt(e.rootPath)}function Sn(e,t,n={}){let r=es(t);if(!r)throw new Error("ToolNet CLI native session ID is required.");let o=n.bindingFile??gn(),s=yn(o),i=s.sessions[r],a=hn(e);if(i){if(i.projectId!==e.id||xt(i.projectRoot)!==a)throw new Error(`ToolNet CLI session ${r} is already bound to another project: ${i.projectRoot}`);return i}let c={nativeSessionId:r,projectId:e.id,projectRoot:a,boundAt:new Date().toISOString()};return s.sessions[r]=c,N(o,s),c}function kn(e,t,n={}){let r=es(t),o=n.bindingFile??gn(),i=yn(o).sessions[r];if(!i)throw new Error(`ToolNet CLI session ${r} is not bound to this project. Run sync once with --bind.`);let a=hn(e);if(i.projectId!==e.id||xt(i.projectRoot)!==a)throw new Error(`ToolNet CLI session ${r} belongs to another project: ${i.projectRoot}`);return i}function ts(e,t={}){let n=t.bindingFile??gn(),r=yn(n),o=hn(e);return Object.values(r.sessions).filter(s=>s.projectId===e.id&&xt(s.projectRoot)===o).sort((s,i)=>s.nativeSessionId.localeCompare(i.nativeSessionId))}function wn(){return process.env.TOOLNETCLI_SESSIONS_DIR?process.env.TOOLNETCLI_SESSIONS_DIR:process.env.TOOLNETAPI_SESSIONS_DIR?process.env.TOOLNETAPI_SESSIONS_DIR:process.env.DATA_DIR?vn(process.env.DATA_DIR,"sessions"):vn(Ll(),".toolnetcli","sessions")}function ns(e){return e.endsWith(".json")?e.slice(0,-5):e}function bn(e,t=wn()){return vn(t,`${ns(e)}.json`)}function $l(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function Fl(e){return Array.isArray(e)?e.filter(t=>!!t&&typeof t=="object"&&!Array.isArray(t)):[]}function It(e){return typeof e=="string"?e:void 0}function Dl(e){if(typeof e!="string")return;let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}function Wl(e,t,n){let r=w(Je({nativeSessionId:e,index:t,message:n})).slice(0,20);return`toolnet-cli:message:${t}:${r}`}function zl(e,t,n,r,o){let s=It(o.role),i="message";s==="user"&&(i="user_prompt"),s==="assistant"&&(i="assistant_message");let a={index:r,content:It(o.content)??""};return o.tool_calls!==void 0&&(a.toolCalls=o.tool_calls),o.tool_call_id!==void 0&&(a.toolCallId=o.tool_call_id),o.name!==void 0&&(a.name=o.name),{type:i,timestamp:n,role:s,source:"toolnet-cli",sourceEventId:Wl(e,r,o),sourceSequence:r,data:a,provenance:{source:"toolnet-cli",sourcePath:t,sourceOffset:r,metadata:{nativeSessionId:e}}}}function ql(e){if(!_l(e))throw new Error(`ToolNet CLI session not found: ${e}`);let t;try{t=JSON.parse(Kl(e,"utf8"))}catch{throw new Error(`Invalid ToolNet CLI session JSON: ${e}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid ToolNet CLI session root: ${e}`);return t}async function Ct(e){let t=ns(e.nativeSessionId);if(!t)throw new Error("ToolNet CLI native session ID is required.");e.bind?Sn(e.project,t,{bindingFile:e.bindingFile}):kn(e.project,t,{bindingFile:e.bindingFile}),e.bind?Sn(e.project,e.nativeSessionId,{bindingFile:e.bindingFile}):kn(e.project,e.nativeSessionId,{bindingFile:e.bindingFile});let n=bn(t,e.sessionsDir),r=ql(n),o=It(r.sessionId);if(o&&o!==t)throw new Error(`ToolNet CLI session ID mismatch: requested=${t}, file=${o}`);let s=Fl(r.messages),i=$l(r.metadata),a=Dl(r.updatedAt),c=new bt({project:e.project,storage:e.storage,agent:"toolnet-cli",nativeSessionId:t,title:It(i.name),metadata:{nativeSource:"toolnet-cli-session-json",sourceFile:n,model:i.model,agentMode:i.agentMode},eventContext:{source:"toolnet-cli",cwd:e.project.rootPath}});c.status().lastSequence===0&&c.start({nativeSource:"toolnet-cli-session-json",sourceFile:n});let d="toolnet-cli.message-count",l=c.status().sourceCursors[d],p=Number(l),f=Number.isInteger(p)&&p>=0?p:0;f>s.length&&(f=0);let m=s.slice(f).map((S,v)=>zl(t,n,a,f+v,S)),h=c.recordMany(m);if(c.setSourceCursor(d,s.length),e.localOnly){let S=c.status();return{nativeSessionId:t,sourceFile:n,importedMessages:m.length,recordedEvents:h.length,eventCount:S.lastSequence,durability:"local"}}e.idle?await c.idle({nativeSource:"toolnet-cli-session-json",sourceFile:n}):await c.flush();let g=c.status();return{nativeSessionId:t,sourceFile:n,importedMessages:m.length,recordedEvents:h.length,eventCount:g.lastSequence,durability:"remote"}}function Vl(){return Bl("sh",["-lc","command -v toolnet >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function At(e={}){let t=_n(),n=Be({cwd:e.cwd}),r=wn(),o=xn(t),s=Vl(),i=xn(n),a=xn(r),c=[];return o||c.push(`Config directory missing: ${t}`),s||c.push("ToolNet CLI binary not found (toolnet)"),{installed:o&&s,state:o?s?"installed":"missing-binary":"missing-config",mcp:{configured:i,configFile:n},nativeSource:{available:a,sessionsDir:r},capabilities:{...Lt},errors:c}}import{existsSync as Jl}from"node:fs";async function Et(e){let t=ts(e.project,{bindingFile:e.bindingFile}),n=[],r=0,o=0,s=0,i=0,a=0;for(let c of t){let u=c.nativeSessionId,d=bn(u,e.sessionsDir);if(!Jl(d)){o+=1,n.push({nativeSessionId:u,status:"missing"});continue}try{let l=await Ct({project:e.project,storage:e.storage,nativeSessionId:u,sessionsDir:e.sessionsDir,bindingFile:e.bindingFile,localOnly:e.localOnly,idle:e.idle});r+=1,i+=l.importedMessages,a+=l.recordedEvents,n.push({nativeSessionId:u,status:"synced",result:l})}catch(l){s+=1,n.push({nativeSessionId:u,status:"error",error:l instanceof Error?l.message:String(l)})}}return{bound:t.length,synced:r,missing:o,failed:s,importedMessages:i,recordedEvents:a,sessions:n}}function rs(e){let t=e.intervalMs&&e.intervalMs>=250?e.intervalMs:2e3,n=!0,r=!1,o=0,s=0,i=0,a=0,c=0,u,d;async function l(){if(r)return{bound:0,synced:0,missing:0,failed:0,importedMessages:0,recordedEvents:0,sessions:[]};r=!0,o+=1,u=new Date().toISOString();try{let p=await Et({project:e.project,storage:e.storage,sessionsDir:e.sessionsDir,bindingFile:e.bindingFile,localOnly:e.localOnly});return s+=1,a+=p.importedMessages,c+=p.recordedEvents,e.onSync?.(p),p}catch(p){i+=1;let f=p instanceof Error?p:new Error(String(p));throw e.onError?.(f),f}finally{r=!1}}return d=setInterval(()=>{!n||r||l().catch(()=>{})},t),{runOnce:l,stop(){n&&(n=!1,d&&(clearInterval(d),d=void 0))},status(){return{running:n,intervalMs:t,runs:o,successfulRuns:s,failedRuns:i,importedMessages:a,recordedEvents:c,lastRunAt:u}}}}import{createHash as Zl}from"node:crypto";import{existsSync as Pt,mkdirSync as ed,readFileSync as td,renameSync as nd,writeFileSync as rd}from"node:fs";import{basename as od,dirname as Tt,join as Le,parse as ds,resolve as ie}from"node:path";import{createHash as is}from"node:crypto";import{spawnSync as Hl}from"node:child_process";var Ke="git-remote-v1",Gl=new Set(["github.com","gitlab.com","bitbucket.org"]);function as(e,t){let n=t.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!n||n==="."||n===".."||n.split("/").some(r=>!r||r==="."||r==="..")?null:(Gl.has(e)&&(n=n.toLowerCase()),n)}function Ul(e){let t;try{t=new URL(e)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(t.protocol))return null;let n=t.hostname.trim().toLowerCase();if(!n)return null;let r=t.protocol==="https:"&&t.port==="443"||t.protocol==="http:"&&t.port==="80"||t.protocol==="ssh:"&&t.port==="22",o=t.port&&!r?`${n}:${t.port}`:n,s=as(n,t.pathname);return s?`${o}/${s}`:null}function Yl(e){let t=e.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!t)return null;let n=t[1]?.trim().toLowerCase();if(!n||n.length===1)return null;let r=as(n,t[2]??"");return r?`${n}/${r}`:null}function os(e){let t=e.trim();return t?t.includes("://")?Ul(t):Yl(t):null}function Xl(e){return is("sha256").update(`${Ke}:${e}`).digest("hex")}function cs(e){return is("sha256").update(`toolnet-project:${Ke}:${e}`).digest("hex").slice(0,16)}function Ql(e){return e.split("/").filter(Boolean).at(-1)?.trim()||null}function In(e,t){let n=Hl("git",["-C",e,...t],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function ss(e,t){let n=Ql(e);return n?{scheme:Ke,canonicalRemote:e,fingerprint:Xl(e),repositoryName:n,source:t}:null}function us(e){let t=In(e,["remote","get-url","origin"]);if(t){let o=os(t);if(o)return ss(o,"origin")}let n=In(e,["remote"]);if(!n)return null;let r=new Set;for(let o of n.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=In(e,["remote","get-url",o]);if(!s)continue;let i=os(s);i&&r.add(i)}return r.size!==1?null:ss([...r][0],"unique-remote")}var ps=".toolnet",sd="project.json";function id(e){return Zl("sha256").update(e).digest("hex").slice(0,16)}function ge(e){return Le(e,ps,sd)}function fs(e){return Pt(ge(e))}function ls(e,t){let n=ie(e),r=ds(n).root;for(;;){if(fs(n))return n;if(n===r||t&&n===ie(t))break;let o=Tt(n);if(o===n)break;n=o}return null}function Cn(e){let t=ie(e),n=ds(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>Pt(Le(t,s))))return t;if(t===n)break;let o=Tt(t);if(o===t)break;t=o}return ie(e)}function jt(e){let t;try{t=JSON.parse(td(e,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${e}: ${o instanceof Error?o.message:String(o)}`)}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:Tt(Tt(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 Mt(e,t){let n=Le(e,ps);ed(n,{recursive:!0});let r=ge(e),o=`${r}.tmp-${process.pid}`;rd(o,JSON.stringify(t,null,2)+`
113
+ `,{encoding:"utf8",mode:384}),nd(o,r)}function se(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}}function An(e){return{version:1,scheme:Ke,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function ad(e){let t=e.metadata?.toolnetIdentity;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return typeof n.fingerprint=="string"?n.fingerprint:null}var ye=class{adopt(t,n){let r=Cn(ie(t));if(!n.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!n.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!n.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(fs(r)){let a=jt(ge(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return se(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=An(n.gitIdentity));let i={version:1,id:n.id.trim(),name:n.name.trim(),remote:n.remote.trim(),rootPath:r,createdAt:n.createdAt??o,updatedAt:o,graphVersion:n.graphVersion??0,memoryVersion:n.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return Mt(r,i),se(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=ge(o.rootPath),i=jt(s),a=ad(i);if(a&&a!==n.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${n.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===n.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:An(n)},i.updatedAt=new Date().toISOString(),Mt(o.rootPath,i)),se(i,o.rootPath)}findExisting(t=process.cwd()){let n=ie(t),r=Cn(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Pt(Le(r,c))),i=ls(n,s?r:void 0);if(!i)return null;let a=jt(ge(i));return se(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=ie(t),r=Cn(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Pt(Le(r,l))),i=ls(n,s?r:void 0);if(i){let l=ge(i),p=jt(l);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Mt(i,p)),se(p,i)}let a=new Date().toISOString(),c=od(r),u=us(r),d={version:1,id:u?cs(u.canonicalRemote):id(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:An(u)}:void 0};return Mt(r,d),se(d,r)}};import{homedir as $d}from"node:os";import{join as Fd}from"node:path";import{DeleteObjectCommand as cd,GetObjectCommand as ud,HeadObjectCommand as ld,ListObjectsV2Command as dd,PutObjectCommand as pd,S3Client as fd}from"@aws-sdk/client-s3";import{getSignedUrl as md}from"@aws-sdk/s3-request-presigner";var Ot=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new fd({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 o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new pd({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await md(this.client,new ud({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 ld({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 cd({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new dd({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{access as ms,mkdir as gd,readFile as yd,readdir as hd,rm as Sd,stat as gs,writeFile as kd}from"node:fs/promises";import{dirname as vd,join as wd,relative as ys,resolve as bd}from"node:path";var $e=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return bd(this.root,n)}async put(t,n){let r=this.path(t);await gd(vd(r),{recursive:!0}),await kd(r,n)}async get(t){try{return await yd(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 ms(this.path(t)),!0}catch{return!1}}async delete(t){await Sd(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await ms(n)}catch{return r}let o=async i=>{let a=await hd(i,{withFileTypes:!0});for(let c of a){let u=wd(i,c.name);if(c.isDirectory()){await o(u);continue}let d=await gs(u);r.push({key:ys(this.root,u),size:d.size,updatedAt:d.mtime.toISOString()})}},s=await gs(n);return s.isDirectory()?await o(n):r.push({key:ys(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as xd,GetObjectCommand as Id,HeadObjectCommand as Cd,ListObjectsV2Command as Ad,PutObjectCommand as Ed,S3Client as jd}from"@aws-sdk/client-s3";import{getSignedUrl as Md}from"@aws-sdk/s3-request-presigner";var Fe=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new jd({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 o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Ed({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Md(this.client,new Id({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 Cd({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 xd({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Ad({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{createCipheriv as Pd,createDecipheriv as Td,createHash as Od,randomBytes as Nd,timingSafeEqual as Rd}from"node:crypto";import{readFileSync as _d}from"node:fs";var ae=Buffer.from("TNMEME01","ascii"),Ss=1,De=8,We=12,En=16,ks=ae.length+1+De+We+En,Kd="toolnet-memory:remote-encryption:v1:",vs="aes-256-gcm",jn=32,A=class extends Error{constructor(n,r){super(r);this.code=n;this.name="RemoteEncryptionError"}code};function Ld(e){return e?["1","true","yes","on","enabled"].includes(e.trim().toLowerCase()):!1}function Mn(e=process.env){return Ld(e.TOOLNET_REMOTE_ENCRYPTION)}function hs(e){let t=e.trim();if(!t)throw new A("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let n;if(t.startsWith("hex:")){let r=t.slice(4);if(!/^[0-9a-f]{64}$/iu.test(r))throw new A("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");n=Buffer.from(r,"hex")}else if(/^[0-9a-f]{64}$/iu.test(t))n=Buffer.from(t,"hex");else{let r=t.startsWith("base64:")?t.slice(7):t;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(r))throw new A("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");n=Buffer.from(r,r.includes("-")||r.includes("_")?"base64url":"base64")}if(n.length!==jn)throw new A("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${jn} bytes.`);return n}function ws(e=process.env){let t=e.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),n=e.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(t&&n)throw new A("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(t)return hs(t);if(n){let r;try{r=_d(n,"utf8")}catch(o){throw new A("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${n}.`,o instanceof Error?o.message:String(o)].join(" "))}return hs(r)}}function bs(e){return Od("sha256").update(e).digest().subarray(0,De)}function xs(e){return Buffer.from(`${Kd}${e}`,"utf8")}function Pn(e){return e.byteLength<ae.length?!1:Buffer.from(e).subarray(0,ae.length).equals(ae)}function Is(e,t,n){if(n.byteLength!==jn)throw new A("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let r=typeof t=="string"?Buffer.from(t,"utf8"):Buffer.from(t),o=Nd(We),s=Pd(vs,n,o);s.setAAD(xs(e));let i=Buffer.concat([s.update(r),s.final()]),a=s.getAuthTag(),c=Buffer.alloc(ks),u=0;return ae.copy(c,u),u+=ae.length,c.writeUInt8(Ss,u),u+=1,bs(n).copy(c,u),u+=De,o.copy(c,u),u+=We,a.copy(c,u),Buffer.concat([c,i])}function Cs(e,t,n){let r=Buffer.from(t);if(!Pn(r))throw new A("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(r.length<ks)throw new A("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=ae.length,s=r.readUInt8(o);if(o+=1,s!==Ss)throw new A("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let i=r.subarray(o,o+De);o+=De;let a=bs(n);if(!Rd(i,a))throw new A("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let c=r.subarray(o,o+We);o+=We;let u=r.subarray(o,o+En);o+=En;let d=r.subarray(o),l=Td(vs,n,c);l.setAAD(xs(e)),l.setAuthTag(u);try{return Buffer.concat([l.update(d),l.final()])}catch{throw new A("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var Tn=class{constructor(t,n){this.inner=t;this.options=n;if(this.name=t.name,n.enabled&&!n.key)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(t,n,r){if(!this.options.enabled){await this.inner.put(t,n,r);return}let o=this.options.key;if(!o)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=Is(t,n,o);await this.inner.put(t,s,"application/octet-stream")}async get(t){let n=await this.inner.get(t);if(!n)return null;if(!Pn(n))return n;if(!this.options.enabled)throw new A("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let r=this.options.key;if(!r)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return Cs(t,n,r)}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){return this.inner.exists(t)}async delete(t){await this.inner.delete(t)}async list(t=""){return this.inner.list(t)}};function As(e,t=process.env){if(e.name==="local")return Mn(t)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),e;let n=Mn(t),r=n?ws(t):void 0;return new Tn(e,{enabled:n,key:r})}function ze(e){return As(e)}function On(e,t){return console.warn(t),ze(new $e(e))}function Es(e){let t=e.localRoot??Fd($d(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?ze(new Fe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):On(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?ze(new Fe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):On(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?ze(new Ot({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):On(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return ze(new $e(t))}function Dd(e){return new Promise(t=>setTimeout(t,e))}async function js(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,o=t.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(s=a,i>=n)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Dd(c+u)}throw s}var Wd=new Set(["put","get","getText","delete","list"]);function Ms(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:Wd.has(r)?(...s)=>js(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function Ps(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 Ts(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 o=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:t))}var Nt=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Ps(o??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,o=await this.provider.getText(t);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${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 s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(s,null,2)+`
114
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=Ts(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))}};function X(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function Nn(e){let t=nt(),n=Ms(Es({provider:t.storage.provider,huggingface:t.storage.huggingface,localRoot:t.storage.localRoot}),{attempts:3});return new Nt(n,e.id,e.name,e.remote??e.name)}function zd(){let e=At({cwd:process.cwd()});console.log("ToolNet CLI Integration"),console.log("======================="),console.log(""),console.log(`State : ${e.state}`),console.log(`MCP : ${e.mcp.configured?"ready":"missing"} \u2014 ${e.mcp.configFile}`),console.log(`Memory: ${e.capabilities.level}`),console.log(`Capture: ${e.capabilities.nativeCapture?"native":"not available"}`),console.log(`Native source: ${e.nativeSource.available?"available":"missing"} \u2014 ${e.nativeSource.sessionsDir}`);for(let t of e.errors)console.log(`Error : ${t}`);return console.log(""),e.installed}async function qd(){let e=process.argv.slice(2),t=e[0],n=e.includes("--json");if(t==="watch-bound"){let a=X(e,"--project")??process.cwd(),c=new ye().detect(a),u=Nn(c),d=X(e,"--interval-ms"),l=d!==void 0?Number(d):void 0,p=Number.isFinite(l)&&l!==void 0?l:void 0,f=rs({project:c,storage:u,sessionsDir:X(e,"--sessions-dir"),localOnly:e.includes("--local-only"),intervalMs:p,onSync(g){g.importedMessages===0&&g.recordedEvents===0&&g.failed===0||console.log(JSON.stringify({event:"toolnet-cli-bound-sync",...g},null,2))},onError(g){console.error(`ToolNet CLI watcher error: ${g.message}`)}}),m=await f.runOnce();console.log(JSON.stringify({event:"toolnet-cli-watcher-started",first:m,watcher:f.status()},null,2));let h=()=>{f.stop(),console.log(JSON.stringify({event:"toolnet-cli-watcher-stopped",watcher:f.status()},null,2))};process.once("SIGINT",h),process.once("SIGTERM",h);return}if(t==="sync-bound"){let a=X(e,"--project")??process.cwd(),c=new ye().detect(a),u=Nn(c),d=await Et({project:c,storage:u,sessionsDir:X(e,"--sessions-dir"),localOnly:e.includes("--local-only"),idle:e.includes("--idle")});console.log(JSON.stringify(d,null,2)),d.failed>0&&(process.exitCode=1);return}if(t==="sync"){let a=e[1];if(!a)throw new Error("Usage: toolnet-memory integrate:toolnet-cli sync <session-id> --bind [--project PATH]");let c=X(e,"--project")??process.cwd(),u=new ye().detect(c),d=Nn(u),l=await Ct({project:u,storage:d,nativeSessionId:a,sessionsDir:X(e,"--sessions-dir"),localOnly:e.includes("--local-only"),idle:e.includes("--idle"),bind:e.includes("--bind"),bindingFile:X(e,"--binding-file")});console.log(JSON.stringify(l,null,2));return}if(e.includes("--status")||e[0]==="status"){let a=At({cwd:process.cwd()});n?console.log(JSON.stringify(a,null,2)):zd(),a.installed||(process.exitCode=1);return}let o=e.includes("--force"),s=Ln({force:o,cwd:process.cwd()}),i=At({cwd:process.cwd()});if(!i.installed)throw new Error(`ToolNet CLI integration installation did not verify successfully (state=${i.state}).`);if(n){console.log(JSON.stringify({installed:!0,changed:s.changed,files:s.files,status:i},null,2));return}console.log(`ToolNet CLI MCP: ${s.mcp.configured?"configured":"not configured"}`),console.log(`Memory: ${i.capabilities.level}`),console.log(`Native source: ${i.nativeSource.available?"available":"missing"}`),s.changed?console.log(`Config updated: ${s.mcp.configFile}`):console.log("Config unchanged (already configured)"),console.log(""),console.log("ToolNet CLI integration ready.")}qd().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});