toolnet-memory 0.3.15 → 0.3.16
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.
- package/.release-target +1 -1
- package/README.md +158 -6
- package/bundle/agy-hook.js +66 -66
- package/bundle/agy.js +59 -59
- package/bundle/api.js +15 -15
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +49 -49
- package/bundle/codex-context.js +29 -29
- package/bundle/codex.js +71 -71
- package/bundle/context-runtime.js +44 -44
- package/bundle/context.js +14 -14
- package/bundle/copilot-hook.js +77 -77
- package/bundle/cursor-hook.js +78 -78
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +19 -19
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +55 -55
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +3 -3
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -5
- package/bundle/init.js +36 -35
- package/bundle/kiro-hook.js +86 -86
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +6 -6
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +73 -73
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +9 -9
- package/bundle/runtime.js +13 -13
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +48 -48
- package/bundle/work-continuity.js +7 -7
- package/package.json +14 -2
- package/release-manifest.json +51 -1
package/bundle/toolnet-cli.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`,{encoding:"utf8",mode:384}),
|
|
3
|
-
`,{encoding:"utf8",mode:384}),
|
|
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)+`
|
|
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
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(`
|
|
6
6
|
`)+`
|
|
7
|
-
`,T=w(x).slice(0,16),M=[t.remotePrefix,"events",`${
|
|
8
|
-
`,null,"utf8"),
|
|
9
|
-
`,null,"utf8"),
|
|
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(`
|
|
10
10
|
`)}
|
|
11
|
-
`;s&&
|
|
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(`
|
|
12
12
|
`)}
|
|
13
|
-
`,a=
|
|
14
|
-
`),
|
|
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(`
|
|
15
15
|
`)+`
|
|
16
|
-
`,a=
|
|
17
|
-
`)}function
|
|
18
|
-
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}import{existsSync as
|
|
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
|
|
20
|
-
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let
|
|
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(`
|
|
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=>
|
|
24
|
-
`);return
|
|
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(`
|
|
25
25
|
|
|
26
|
-
`).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o
|
|
27
|
-
`)}function
|
|
28
|
-
`;aa(Ye(Qi(e),`${c}.json`),d)?o+=1:s+=1,i.push(c),n=ca(n,{id:c,kind:a.type,bytes:Buffer.byteLength(d,"utf8"),createdAt:a.timestamp,sourceRefs:[ia(a)],files:sa(a)})}return r>0&&ra(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as ya}from"node:crypto";import{existsSync as ha,readdirSync as Sa,readFileSync as ka}from"node:fs";import{basename as va,join as Pr}from"node:path";import{randomUUID as gr}from"node:crypto";var I=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function we(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 I("Invalid Wiki slug",400);return t}function fr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(te(r))}return we(t)}function ua(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function mr(e){return{id:`revision-${gr()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function ee(e){return structuredClone(e)}var Xe=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let 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:we(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 I(`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 I("Wiki title is required",400);let s=te(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new I(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${gr()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:we(t.tags??[]),links:fr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(mr(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 I(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new I("Wiki title is required",400);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=fr(s.content)),n.tags!==void 0&&(s.tags=we(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(mr(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=we(ua(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:ee(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var yr="wiki/state.v1.json";function la(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function da(e,t){let n=JSON.parse(e);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==t.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var Ze=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(yr);if(!t){let n=la(this.project);return await this.save(n),n}return da(t,this.project)}async save(t){await this.storage.put(yr,JSON.stringify(t,null,2),"application/json")}};import{createHash as pa,randomUUID as hr}from"node:crypto";var Sr="wiki/governance.v1.json",br="toolnet.knowledge-governance.v1",kr=500,be={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function fa(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Ht(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function vr(e){return pa("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ma(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 ga(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),fa(t)}function wr(e){let t=new Date().toISOString();return{schema:br,version:1,projectId:e,policy:{...be},reviews:[],audit:[],createdAt:t,updatedAt:t}}function xr(e){let t=e.autoApproveThreshold??be.autoApproveThreshold,n=e.criticalApproveThreshold??be.criticalApproveThreshold,r=e.staleAfterDays??be.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new I("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new I("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new I("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var Qe=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Sr);if(!t){let n=wr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==br||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:xr(n.policy??be)}}catch{let n=wr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Sr,JSON.stringify(t,null,2),"application/json")}},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}audit(t,n,r,o={}){t.audit.push({id:hr(),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>kr&&(t.audit=t.audit.slice(-kr))}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=xr({...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=ga(t),s=Ht(t.title),i=n.filter(d=>d.slug!==t.slug&&Ht(d.title)===s&&vr(d.content)!==vr(t.content)).map(d=>d.slug),a=ma(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:hr(),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 I(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new I("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 I("targetReviewId is required for merge",400);let u=o.reviews.find(d=>d.id===n.targetReviewId);if(!u)throw new I("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 I(`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=Ht(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 Tr="wiki/automation.v1.json",Er="toolnet.wiki-automation.v1",Yt=8e3,Cr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Ce(e){return ya("sha256").update(JSON.stringify(e)).digest("hex")}function xe(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Ir(e){return Array.isArray(e)?e:[]}function Or(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Gt(e){return Array.isArray(e)?e.map(Or).filter(t=>!!t):[]}function L(e,t){for(let n of t){let r=Or(e[n]);if(r)return r}}function Ie(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 tt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Cr.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=>tt(i,t+1,n));let o=xe(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Cr.has(c)||s.push(...tt(a,t+1,i))}return s}function jr(e){let n=Ie(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>tt(e[o],0,o)));return(n.length>0?n:Ie(tt(e))).join(`
|
|
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(`
|
|
29
29
|
|
|
30
|
-
`).slice(0,
|
|
31
|
-
${u}`),
|
|
32
|
-
${
|
|
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
|
|
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,
|
|
41
|
-
`).slice(0,
|
|
42
|
-
`,{encoding:"utf8",mode:384}),
|
|
43
|
-
`,c=w(r.map(
|
|
44
|
-
`,"application/json"),u}};function
|
|
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(`
|
|
45
45
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
46
|
-
`).filter(Boolean).flatMap(
|
|
47
|
-
`))))}function
|
|
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
|
|
49
|
-
`,a=w(n.map(
|
|
50
|
-
`)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${
|
|
51
|
-
`,"application/json"),
|
|
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(`
|
|
52
52
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
53
|
-
`).filter(Boolean).flatMap(
|
|
54
|
-
`,"application/json"),c}};import{mkdirSync as
|
|
55
|
-
`,"application/json"),f}function
|
|
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(`
|
|
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
|
|
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
|
|
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
|
|
101
|
-
`,{encoding:"utf8"}),
|
|
102
|
-
`,{encoding:"utf8"}),
|
|
103
|
-
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function
|
|
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)+`
|
|
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
|
|
106
|
-
`)}function
|
|
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(`
|
|
107
107
|
|
|
108
108
|
`):a=r.trim()?`${r.trim()}
|
|
109
109
|
|
|
110
|
-
${o}`:o,
|
|
111
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as
|
|
112
|
-
`,{encoding:"utf8",mode:384}),qu(n,e)}function ft(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 Eo(e,t){let n=ft(t.observations,"file"),r=ft(t.observations,"next_action"),o=ft(t.observations,"blocker"),s=ft(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 Gu(Hu(e),i),i}import{existsSync as Oo,mkdirSync as Uu,readFileSync as Yu}from"node:fs";import{join as on}from"node:path";function No(e){return on(e.rootPath,".toolnet","memory","checkpoints")}function Ro(e){return on(No(e),"latest.json")}function Xu(e){let t=Ro(e);if(!Oo(t))return null;try{let n=JSON.parse(Yu(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Zu(e){return["rule","architecture","decision","fix"].includes(e)}function Qu(e,t){return t.length===0?[]:Ue(e,t).candidates.filter(r=>Zu(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 el(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 tl(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 _o(e,t,n,r){let o=Xu(e),s=el(o?.durableFacts??[],Qu(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:tl(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=No(e);Uu(m,{recursive:!0,mode:448});let h=on(m,`${p}.json`);return Oo(h)||O(h,f),O(Ro(e),f),f}function Ko(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=it(t,n);if(r.length===0)return{updated:!1,observations:0};let o=bo(e,r);To(e,o),Eo(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{_o(e,t,n,o)}catch{}try{Ao({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var mt=class{identity;wal;remote;sanitizer=new J;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=In(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new Be(this.identity,t.eventContext),this.remote=new We(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new ot({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new ct({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new lt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new pt({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{Ko(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 Lo,resolve as gt}from"node:path";function sn(){let e=process.env.XDG_CONFIG_HOME??Lo(nl(),".config");return Lo(e,"toolnet-memory","toolnet-cli-bindings.json")}function $o(e){return e.endsWith(".json")?e.slice(0,-5):e}function rl(){return{version:1,sessions:{}}}function an(e){let t=Fe(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 cn(e){return gt(e.rootPath)}function un(e,t,n={}){let r=$o(t);if(!r)throw new Error("ToolNet CLI native session ID is required.");let o=n.bindingFile??sn(),s=an(o),i=s.sessions[r],a=cn(e);if(i){if(i.projectId!==e.id||gt(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 ln(e,t,n={}){let r=$o(t),o=n.bindingFile??sn(),i=an(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=cn(e);if(i.projectId!==e.id||gt(i.projectRoot)!==a)throw new Error(`ToolNet CLI session ${r} belongs to another project: ${i.projectRoot}`);return i}function Fo(e,t={}){let n=t.bindingFile??sn(),r=an(n),o=cn(e);return Object.values(r.sessions).filter(s=>s.projectId===e.id&>(s.projectRoot)===o).sort((s,i)=>s.nativeSessionId.localeCompare(i.nativeSessionId))}function pn(){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?dn(process.env.DATA_DIR,"sessions"):dn(il(),".toolnetcli","sessions")}function Wo(e){return e.endsWith(".json")?e.slice(0,-5):e}function fn(e,t=pn()){return dn(t,`${Wo(e)}.json`)}function al(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function cl(e){return Array.isArray(e)?e.filter(t=>!!t&&typeof t=="object"&&!Array.isArray(t)):[]}function yt(e){return typeof e=="string"?e:void 0}function ul(e){if(typeof e!="string")return;let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}function ll(e,t,n){let r=w($e({nativeSessionId:e,index:t,message:n})).slice(0,20);return`toolnet-cli:message:${t}:${r}`}function dl(e,t,n,r,o){let s=yt(o.role),i="message";s==="user"&&(i="user_prompt"),s==="assistant"&&(i="assistant_message");let a={index:r,content:yt(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:ll(e,r,o),sourceSequence:r,data:a,provenance:{source:"toolnet-cli",sourcePath:t,sourceOffset:r,metadata:{nativeSessionId:e}}}}function pl(e){if(!ol(e))throw new Error(`ToolNet CLI session not found: ${e}`);let t;try{t=JSON.parse(sl(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 ht(e){let t=Wo(e.nativeSessionId);if(!t)throw new Error("ToolNet CLI native session ID is required.");e.bind?un(e.project,t,{bindingFile:e.bindingFile}):ln(e.project,t,{bindingFile:e.bindingFile}),e.bind?un(e.project,e.nativeSessionId,{bindingFile:e.bindingFile}):ln(e.project,e.nativeSessionId,{bindingFile:e.bindingFile});let n=fn(t,e.sessionsDir),r=pl(n),o=yt(r.sessionId);if(o&&o!==t)throw new Error(`ToolNet CLI session ID mismatch: requested=${t}, file=${o}`);let s=cl(r.messages),i=al(r.metadata),a=ul(r.updatedAt),c=new mt({project:e.project,storage:e.storage,agent:"toolnet-cli",nativeSessionId:t,title:yt(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)=>dl(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 ml(){return fl("sh",["-lc","command -v toolnet >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function St(e={}){let t=kn(),n=Ke({cwd:e.cwd}),r=pn(),o=mn(t),s=ml(),i=mn(n),a=mn(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:{...Mt},errors:c}}import{existsSync as gl}from"node:fs";async function kt(e){let t=Fo(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=fn(u,e.sessionsDir);if(!gl(d)){o+=1,n.push({nativeSessionId:u,status:"missing"});continue}try{let l=await ht({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 Do(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 kt({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 yl}from"node:crypto";import{existsSync as vt,mkdirSync as hl,readFileSync as Sl,renameSync as kl,writeFileSync as vl}from"node:fs";import{basename as wl,dirname as wt,join as Oe,parse as Bo,resolve as le}from"node:path";var Ho=".toolnet",bl="project.json";function xl(e){return yl("sha256").update(e).digest("hex").slice(0,16)}function bt(e){return Oe(e,Ho,bl)}function Cl(e){return vt(bt(e))}function zo(e,t){let n=le(e),r=Bo(n).root;for(;;){if(Cl(n))return n;if(n===r||t&&n===le(t))break;let o=wt(n);if(o===n)break;n=o}return null}function qo(e){let t=le(e),n=Bo(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>vt(Oe(t,s))))return t;if(t===n)break;let o=wt(t);if(o===t)break;t=o}return le(e)}function Vo(e){let t;try{t=JSON.parse(Sl(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:wt(wt(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 Jo(e,t){let n=Oe(e,Ho);hl(n,{recursive:!0});let r=bt(e),o=`${r}.tmp-${process.pid}`;vl(o,JSON.stringify(t,null,2)+`
|
|
113
|
-
`,{encoding:"utf8",mode:384}),kl(o,r)}function gn(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}var de=class{findExisting(t=process.cwd()){let n=le(t),r=qo(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>vt(Oe(r,c))),i=zo(n,s?r:void 0);if(!i)return null;let a=Vo(bt(i));return gn(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=le(t),r=qo(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>vt(Oe(r,d))),i=zo(n,s?r:void 0);if(i){let d=bt(i),l=Vo(d);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Jo(i,l)),gn(l,i)}let a=new Date().toISOString(),c=wl(r),u={version:1,id:xl(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Jo(r,u),gn(u,r)}};import{homedir as Hl}from"node:os";import{join as Gl}from"node:path";import{DeleteObjectCommand as Il,GetObjectCommand as jl,HeadObjectCommand as Al,ListObjectsV2Command as Ml,PutObjectCommand as Pl,S3Client as Tl}from"@aws-sdk/client-s3";import{getSignedUrl as El}from"@aws-sdk/s3-request-presigner";var xt=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Tl({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 Pl({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await El(this.client,new jl({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 Al({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 Il({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Ml({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 Go,mkdir as Ol,readFile as Nl,readdir as Rl,rm as _l,stat as Uo,writeFile as Kl}from"node:fs/promises";import{dirname as Ll,join as $l,relative as Yo,resolve as Fl}from"node:path";var Ne=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Fl(this.root,n)}async put(t,n){let r=this.path(t);await Ol(Ll(r),{recursive:!0}),await Kl(r,n)}async get(t){try{return await Nl(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 Go(this.path(t)),!0}catch{return!1}}async delete(t){await _l(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await Go(n)}catch{return r}let o=async i=>{let a=await Rl(i,{withFileTypes:!0});for(let c of a){let u=$l(i,c.name);if(c.isDirectory()){await o(u);continue}let d=await Uo(u);r.push({key:Yo(this.root,u),size:d.size,updatedAt:d.mtime.toISOString()})}},s=await Uo(n);return s.isDirectory()?await o(n):r.push({key:Yo(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as Wl,GetObjectCommand as Dl,HeadObjectCommand as zl,ListObjectsV2Command as ql,PutObjectCommand as Vl,S3Client as Jl}from"@aws-sdk/client-s3";import{getSignedUrl as Bl}from"@aws-sdk/s3-request-presigner";var Re=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Jl({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 Vl({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Bl(this.client,new Dl({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 zl({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 Wl({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new ql({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 yn(e,t){return console.warn(t),new Ne(e)}function Xo(e){let t=e.localRoot??Gl(Hl(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Re({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yn(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 Re({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yn(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 xt({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yn(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new Ne(t)}function Ul(e){return new Promise(t=>setTimeout(t,e))}async function Zo(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 Ul(c+u)}throw s}var Yl=new Set(["put","get","getText","delete","list"]);function Qo(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:Yl.has(r)?(...s)=>Zo(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function es(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 Ct=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=es(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=
|
|
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});
|