toolnet-memory 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,44 +1,44 @@
1
- import*as K from"fs";import*as O from"path";function ut(e){return e?Math.ceil(e.length/3.5):0}function lt(e,t){if(!e)return"";if(ut(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
2
- `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function Gt(e,t){if(!e)return"";let n=e.split(`
1
+ import*as $ from"fs";import*as R from"path";function dt(e){return e?Math.ceil(e.length/3.5):0}function pt(e,t){if(!e)return"";if(dt(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
2
+ `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function Xt(e,t){if(!e)return"";let n=e.split(`
3
3
  `).filter(o=>o.trim());if(n.length<=t)return e;let r=n.slice(0,t),s=n.length-t;return[...r,`... (${s} more items omitted)`].join(`
4
- `)}function Os(e,t){let{maxTokens:n,trimMarker:r="[Context trimmed by ToolNet Memory token budget]"}=t;if(e.length===0)return"";let s=[...e].sort((c,u)=>u.priority-c.priority),o=[],i=0,a=!1;for(let c of s){let u=`# ${c.title}
4
+ `)}function Fs(e,t){let{maxTokens:n,trimMarker:r="[Context trimmed by ToolNet Memory token budget]"}=t;if(e.length===0)return"";let s=[...e].sort((c,u)=>u.priority-c.priority),o=[],i=0,a=!1;for(let c of s){let u=`# ${c.title}
5
5
 
6
- `,m=ut(u),p=ut(c.content),d=m+p;if(i+d<=n)o.push(u+c.content),i+=d;else{let l=n-i-m;if(l>50){let g=lt(c.content,l);o.push(u+g),i=n,a=!0}else a=!0;break}}return a&&o.push(`
6
+ `,m=dt(u),p=dt(c.content),d=m+p;if(i+d<=n)o.push(u+c.content),i+=d;else{let l=n-i-m;if(l>50){let g=pt(c.content,l);o.push(u+g),i=n,a=!0}else a=!0;break}}return a&&o.push(`
7
7
  ${r}
8
8
  `),o.join(`
9
9
 
10
10
  ---
11
11
 
12
- `)}function Ut(e,t){let n=[{title:"Profile",content:Gt(e,10),priority:100},{title:"Current Work",content:Gt(t,15),priority:90}];return Os(n,{maxTokens:800})}import{createHash as Rs}from"node:crypto";import{chmodSync as Xt,existsSync as Ns,mkdirSync as _s,readFileSync as Ks,renameSync as $s,writeFileSync as Qt}from"node:fs";import{dirname as Zt,join as Ce}from"node:path";var mt="toolnet.context-offload.v1",Ws="toolnet.context-offload-asset.v1",Fs=256,Ls=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function en(e){return Ce(e,".toolnet","offload")}function zs(e){return Ce(en(e),"assets")}function tn(e){return Ce(en(e),"graph.json")}function nn(e){_s(e,{recursive:!0,mode:448});try{Xt(e,448)}catch{}}function Ds(e,t){nn(Zt(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;Qt(n,t,{encoding:"utf8",mode:384}),$s(n,e);try{Xt(e,384)}catch{}}function pt(e){return Array.isArray(e)?e.map(pt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,pt(n)])):e}function qs(e){return Rs("sha256").update(JSON.stringify(pt(e)),"utf8").digest("hex")}function dt(){return{schema:mt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function rn(e){let t=tn(e);if(!Ns(t))return dt();try{let n=JSON.parse(Ks(t,"utf8"));return n.schema!==mt||n.version!==1||!Array.isArray(n.nodes)?dt():n}catch{return dt()}}function Hs(e,t){Ds(tn(e),JSON.stringify(t,null,2)+`
13
- `)}function Vs(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Js(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=Vs(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Bs(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Gs(e,t){nn(Zt(e));try{return Qt(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Us(e,t){let n=e.nodes.find(s=>s.id===t.id),r=n?{...n,kind:t.kind,bytes:t.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...t.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...t.files])).slice(0,6)}:t;return{schema:mt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-Fs)}}function sn(e,t){let n=rn(e),r=0,s=0,o=0,i=[];for(let a of t){if(!Ls.has(a.type))continue;r+=1;let c=qs({type:a.type,data:a.data}),u={schema:Ws,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}},m=JSON.stringify(u,null,2)+`
14
- `;Gs(Ce(zs(e),`${c}.json`),m)?s+=1:o+=1,i.push(c),n=Us(n,{id:c,kind:a.type,bytes:Buffer.byteLength(m,"utf8"),createdAt:a.timestamp,sourceRefs:[Bs(a)],files:Js(a)})}return r>0&&Hs(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function Yt(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function on(e,t={}){let n=rn(e);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,t.maxAssets??6)),s=Math.max(320,Math.min(2400,t.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let a=Yt(i.sourceRefs.at(-1)??"unknown",72),c=i.files.length>0?` files=${Yt(i.files.join(","),120)}`:"",u=`event:${a} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${c}`;if([...o,u].join(`
12
+ `)}function Qt(e,t){let n=[{title:"Profile",content:Xt(e,10),priority:100},{title:"Current Work",content:Xt(t,15),priority:90}];return Fs(n,{maxTokens:800})}import{createHash as Ws}from"node:crypto";import{chmodSync as en,existsSync as Ls,mkdirSync as Ds,readFileSync as zs,renameSync as qs,writeFileSync as tn}from"node:fs";import{dirname as nn,join as Ce}from"node:path";var gt="toolnet.context-offload.v1",Hs="toolnet.context-offload-asset.v1",Js=256,Vs=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function rn(e){return Ce(e,".toolnet","offload")}function Bs(e){return Ce(rn(e),"assets")}function sn(e){return Ce(rn(e),"graph.json")}function on(e){Ds(e,{recursive:!0,mode:448});try{en(e,448)}catch{}}function Gs(e,t){on(nn(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;tn(n,t,{encoding:"utf8",mode:384}),qs(n,e);try{en(e,384)}catch{}}function ft(e){return Array.isArray(e)?e.map(ft):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,ft(n)])):e}function Us(e){return Ws("sha256").update(JSON.stringify(ft(e)),"utf8").digest("hex")}function mt(){return{schema:gt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function an(e){let t=sn(e);if(!Ls(t))return mt();try{let n=JSON.parse(zs(t,"utf8"));return n.schema!==gt||n.version!==1||!Array.isArray(n.nodes)?mt():n}catch{return mt()}}function Ys(e,t){Gs(sn(e),JSON.stringify(t,null,2)+`
13
+ `)}function Xs(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Qs(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=Xs(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Zs(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function eo(e,t){on(nn(e));try{return tn(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function to(e,t){let n=e.nodes.find(s=>s.id===t.id),r=n?{...n,kind:t.kind,bytes:t.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...t.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...t.files])).slice(0,6)}:t;return{schema:gt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-Js)}}function cn(e,t){let n=an(e),r=0,s=0,o=0,i=[];for(let a of t){if(!Vs.has(a.type))continue;r+=1;let c=Us({type:a.type,data:a.data}),u={schema:Hs,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}},m=JSON.stringify(u,null,2)+`
14
+ `;eo(Ce(Bs(e),`${c}.json`),m)?s+=1:o+=1,i.push(c),n=to(n,{id:c,kind:a.type,bytes:Buffer.byteLength(m,"utf8"),createdAt:a.timestamp,sourceRefs:[Zs(a)],files:Qs(a)})}return r>0&&Ys(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function Zt(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function un(e,t={}){let n=an(e);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,t.maxAssets??6)),s=Math.max(320,Math.min(2400,t.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let a=Zt(i.sourceRefs.at(-1)??"unknown",72),c=i.files.length>0?` files=${Zt(i.files.join(","),120)}`:"",u=`event:${a} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${c}`;if([...o,u].join(`
15
15
  `).length>s)break;o.push(u)}return o.join(`
16
- `)}import{existsSync as cn,mkdirSync as no,readFileSync as un,renameSync as ro,writeFileSync as so}from"node:fs";import{dirname as oo,join as ln}from"node:path";import{createHash as Ys}from"node:crypto";import{dirname as Xs}from"node:path";import{mkdirSync as Qs,readFileSync as Zs,renameSync as eo,writeFileSync as to}from"node:fs";function w(e){return Ys("sha256").update(e).digest("hex")}function ft(e){if(Array.isArray(e))return e.map(ft);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=ft(t[r]);return n}return e}function Ie(e){return JSON.stringify(ft(e))}function an(e){try{return JSON.parse(Zs(e,"utf8"))}catch{return null}}function T(e,t){Qs(Xs(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;to(n,JSON.stringify(t,null,2)+`
17
- `,{encoding:"utf8",mode:384}),eo(n,e)}function dn(e){return ln(e.rootPath,".toolnet","context","handoff.md")}function pn(e){return ln(e.rootPath,".toolnet","context","handoff.json")}function mn(e,t){no(oo(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;so(n,t.endsWith(`
16
+ `)}import{existsSync as dn,mkdirSync as co,readFileSync as pn,renameSync as uo,writeFileSync as lo}from"node:fs";import{dirname as po,join as mn}from"node:path";import{createHash as no}from"node:crypto";import{dirname as ro}from"node:path";import{mkdirSync as so,readFileSync as oo,renameSync as io,writeFileSync as ao}from"node:fs";function w(e){return no("sha256").update(e).digest("hex")}function yt(e){if(Array.isArray(e))return e.map(yt);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=yt(t[r]);return n}return e}function Pe(e){return JSON.stringify(yt(e))}function ln(e){try{return JSON.parse(oo(e,"utf8"))}catch{return null}}function O(e,t){so(ro(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;ao(n,JSON.stringify(t,null,2)+`
17
+ `,{encoding:"utf8",mode:384}),io(n,e)}function fn(e){return mn(e.rootPath,".toolnet","context","handoff.md")}function gn(e){return mn(e.rootPath,".toolnet","context","handoff.json")}function yn(e,t){co(po(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;lo(n,t.endsWith(`
18
18
  `)?t:`${t}
19
- `,{encoding:"utf8",mode:384}),ro(n,e)}function io(e,t){mn(e,`${JSON.stringify(t,null,2)}
20
- `)}function fn(e,t){let n=t.replace(/\r\n/g,`
21
- `).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return mn(dn(e),n),io(pn(e),r),r}function gt(e){let t=dn(e);if(!cn(t))return null;try{let n=un(t,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=pn(e);if(cn(s))try{let o=JSON.parse(un(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function gn(e,t=1800){let n=gt(e);if(!n?.text)return null;let r=n.text;return r.length>t&&(r=`${r.slice(0,t)}
19
+ `,{encoding:"utf8",mode:384}),uo(n,e)}function mo(e,t){yn(e,`${JSON.stringify(t,null,2)}
20
+ `)}function hn(e,t){let n=t.replace(/\r\n/g,`
21
+ `).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return yn(fn(e),n),mo(gn(e),r),r}function ht(e){let t=fn(e);if(!dn(t))return null;try{let n=pn(t,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=gn(e);if(dn(s))try{let o=JSON.parse(pn(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function Sn(e,t=1800){let n=ht(e);if(!n?.text)return null;let r=n.text;return r.length>t&&(r=`${r.slice(0,t)}
22
22
 
23
23
  [Fast handoff truncated]`),["[TOOLNET FAST HANDOFF]","",`Project: ${e.name}`,`Updated: ${n.generatedAt}`,"",r].join(`
24
- `)}var yt="memory_agent_ask";function yn(){return`
24
+ `)}var St="memory_agent_ask";function kn(){return`
25
25
  [TOOLNET MEMORY AGENT]
26
26
 
27
27
  Tool:
28
- - ${yt}
28
+ - ${St}
29
29
 
30
30
  For resume/continue requests:
31
31
 
32
32
  1. Use the injected ToolNet continuity handoff FIRST.
33
33
  2. If the handoff is missing or ambiguous, invoke
34
- ${yt} directly BEFORE repository/history exploration.
34
+ ${St} directly BEFORE repository/history exploration.
35
35
  3. NEVER reconstruct prior work from:
36
36
  - .toolnet/sessions/**
37
37
  - state.json
38
38
  - events.jsonl
39
39
  - raw transcripts
40
40
  4. NEVER search for the implementation/schema of
41
- ${yt}; invoke the MCP tool directly.
41
+ ${St}; invoke the MCP tool directly.
42
42
  5. Inspect git/source only AFTER continuity context is known.
43
43
 
44
44
  Use:
@@ -46,31 +46,31 @@ Use:
46
46
  - mode="ai" for ambiguous or combined continuity questions.
47
47
 
48
48
  Current repository evidence overrides stale memory.
49
- `.trim()}function ht(e){let t=O.resolve(e),n=O.parse(t).root;for(;t!==n;){let r=O.join(t,".toolnet");if(K.existsSync(r)&&K.statSync(r).isDirectory())return t;t=O.dirname(t)}return null}function hn(e){try{return K.existsSync(e)?K.readFileSync(e,"utf-8").trim():null}catch{return null}}function Sn(e){return e.split(`
49
+ `.trim()}function kt(e){let t=R.resolve(e),n=R.parse(t).root;for(;t!==n;){let r=R.join(t,".toolnet");if($.existsSync(r)&&$.statSync(r).isDirectory())return t;t=R.dirname(t)}return null}function wn(e){try{return $.existsSync(e)?$.readFileSync(e,"utf-8").trim():null}catch{return null}}function vn(e){return e.split(`
50
50
  `).filter(r=>{let s=r.toUpperCase();return!(s.includes("SECRET")||s.includes("TOKEN")||s.includes("API_KEY")||s.includes("APIKEY")||s.includes("PASSWORD")||s.includes("PASS="))}).join(`
51
- `)}function kn(e={}){let t=e.projectPath||process.cwd(),n=ht(t);if(!n)return null;let r=O.join(n,".toolnet","project.json"),s="Unknown";try{if(K.existsSync(r)){let y=JSON.parse(K.readFileSync(r,"utf-8"));s=y.name||y.projectName||"Unknown"}}catch{}let o=O.join(n,".toolnet","profile.md"),i=O.join(n,".toolnet","current.md"),a=hn(o)||"",c=hn(i)||"";a=Sn(a),c=Sn(c);let u=`[TOOLNET PROJECT CONTEXT]
51
+ `)}function bn(e={}){let t=e.projectPath||process.cwd(),n=kt(t);if(!n)return null;let r=R.join(n,".toolnet","project.json"),s="Unknown";try{if($.existsSync(r)){let y=JSON.parse($.readFileSync(r,"utf-8"));s=y.name||y.projectName||"Unknown"}}catch{}let o=R.join(n,".toolnet","profile.md"),i=R.join(n,".toolnet","current.md"),a=wn(o)||"",c=wn(i)||"";a=vn(a),c=vn(c);let u=`[TOOLNET PROJECT CONTEXT]
52
52
 
53
53
  Project: ${s}
54
54
  Root: ${n}
55
55
 
56
- `,m=Ut(a,c),p=gn({id:"",name:s,rootPath:n},1600),d=p?`
56
+ `,m=Qt(a,c),p=Sn({id:"",name:s,rootPath:n},1600),d=p?`
57
57
 
58
58
  ${p}
59
- `:"",l=on(n,{maxAssets:6,maxChars:900}),g=l?`
59
+ `:"",l=un(n,{maxAssets:6,maxChars:900}),g=l?`
60
60
 
61
61
  ${l}
62
62
  `:"",S=`
63
63
 
64
- ${yn()}
64
+ ${kn()}
65
65
 
66
66
  Forbidden At Startup:
67
67
  - Do not run session:agy-recover, handoff:latest, or brief automatically.
68
68
  - Do not perform deep recovery merely because an agent starts.
69
69
  - If the user asks to resume previous work and fast context is insufficient,
70
70
  use memory_agent_ask before guessing.
71
- `;return u+m+d+g+S}var wn=6500,ao=[/\bcontinue\b/i,/\bresume\b/i,/\bpick\s+up\b/i,/\bcarry\s+on\b/i,/\bfinish\s+(?:the\s+)?(?:previous|last|unfinished|remaining)\b/i,/\bwhere\s+(?:did\s+we|were\s+we)\b/i,/\bwhat\s+was\s+(?:the\s+)?(?:last|previous)\b/i,/(?:^|[\s,.;:!?])tiếp\s+tục(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])làm\s+tiếp(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])làm\s+nốt(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])tiếp\s+phần(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])phần\s+đang\s+dở(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])đang\s+làm\s+(?:gì|đến\s+đâu)(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])dừng\s+(?:ở|tại)\s+đâu(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])task\s+(?:lúc\s+nãy|trước|đang\s+dở)(?:$|[\s,.;:!?])/iu];function bn(e,t){return e.length<=wn?e:`${e.slice(0,wn)}
71
+ `;return u+m+d+g+S}var xn=6500,fo=[/\bcontinue\b/i,/\bresume\b/i,/\bpick\s+up\b/i,/\bcarry\s+on\b/i,/\bfinish\s+(?:the\s+)?(?:previous|last|unfinished|remaining)\b/i,/\bwhere\s+(?:did\s+we|were\s+we)\b/i,/\bwhat\s+was\s+(?:the\s+)?(?:last|previous)\b/i,/(?:^|[\s,.;:!?])tiếp\s+tục(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])làm\s+tiếp(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])làm\s+nốt(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])tiếp\s+phần(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])phần\s+đang\s+dở(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])đang\s+làm\s+(?:gì|đến\s+đâu)(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])dừng\s+(?:ở|tại)\s+đâu(?:$|[\s,.;:!?])/iu,/(?:^|[\s,.;:!?])task\s+(?:lúc\s+nãy|trước|đang\s+dở)(?:$|[\s,.;:!?])/iu];function In(e,t){return e.length<=xn?e:`${e.slice(0,xn)}
72
72
 
73
- [ToolNet ${t} context truncated]`}function vn(e){return e.replace(/\\/g,"/").toLowerCase()}function St(e,t,n=0){if(!(n>6||t.length>=250)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e)if(St(r,t,n+1),t.length>=250)break;return}if(e&&typeof e=="object"){for(let r of Object.values(e))if(St(r,t,n+1),t.length>=250)break}}}function co(e){let t=vn(e);if(t.includes(".toolnet/sessions/")||t.endsWith(".toolnet/sessions")||t.includes(".gemini/antigravity-cli/brain/")||t.endsWith(".gemini/antigravity-cli/brain")||t.includes("/transcript.jsonl")||t.endsWith("transcript.jsonl")||t.includes(".toolnet/")&&(t.endsWith("/events.jsonl")||t.endsWith("/state.json")||t.includes("/sessions/")))return!0;let n=process.env.CURSOR_TRANSCRIPT_PATH;return!!(n&&vn(n)===t)}function uo(e){let t=e.trim();return t?ao.some(n=>n.test(t)):!1}function kt(e,t){if(!e.trim())return"";let n="";try{n=kn({projectPath:e})?.trim()??""}catch{n=""}let r=`
73
+ [ToolNet ${t} context truncated]`}function jn(e){return e.replace(/\\/g,"/").toLowerCase()}function wt(e,t,n=0){if(!(n>6||t.length>=250)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e)if(wt(r,t,n+1),t.length>=250)break;return}if(e&&typeof e=="object"){for(let r of Object.values(e))if(wt(r,t,n+1),t.length>=250)break}}}function go(e){let t=jn(e);if(t.includes(".toolnet/sessions/")||t.endsWith(".toolnet/sessions")||t.includes(".gemini/antigravity-cli/brain/")||t.endsWith(".gemini/antigravity-cli/brain")||t.includes("/transcript.jsonl")||t.endsWith("transcript.jsonl")||t.includes(".toolnet/")&&(t.endsWith("/events.jsonl")||t.endsWith("/state.json")||t.includes("/sessions/")))return!0;let n=process.env.CURSOR_TRANSCRIPT_PATH;return!!(n&&jn(n)===t)}function yo(e){let t=e.trim();return t?fo.some(n=>n.test(t)):!1}function vt(e,t){if(!e.trim())return"";let n="";try{n=bn({projectPath:e})?.trim()??""}catch{n=""}let r=`
74
74
  [TOOLNET CONTINUITY]
75
75
 
76
76
  ToolNet Memory is the continuity source for this repository.
@@ -88,45 +88,45 @@ When the user asks to continue, resume, pick up, or finish previous work:
88
88
  7. Do not ask the user to repeat context ToolNet already provides.
89
89
 
90
90
  Current repository evidence overrides stale memory.
91
- `.trim();return bn(n?`${n}
91
+ `.trim();return In(n?`${n}
92
92
 
93
- ${r}`:r,t)}function xn(e,t,n){if(!uo(e))return"";let r=kt(t,n),s=`
93
+ ${r}`:r,t)}function An(e,t,n){if(!yo(e))return"";let r=vt(t,n),s=`
94
94
  [TOOLNET RESUME REQUEST]
95
95
 
96
96
  The current user message explicitly asks to continue previous work.
97
97
  Use memory_agent_ask now if the fast handoff does not contain a clear,
98
98
  current next action. Do not reconstruct continuity from raw session files.
99
- `.trim();return bn(r?`${r}
99
+ `.trim();return In(r?`${r}
100
100
 
101
- ${s}`:s,n)}function jn(e){let t=[];return St(e,t),t.find(co)?{blocked:!0,reason:"ToolNet continuity guard: do not read or reconstruct previous work from raw ToolNet/agent session history. Use the injected ToolNet handoff first; if it is insufficient, invoke the MCP tool memory_agent_ask directly. Then verify normal repository/git source truth."}:{blocked:!1}}function $(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function An(e,t=process.env){return $(t.TOOLNET_HOOK_EVENT)??$(e.hook_event_name)??$(e.hookEventName)??""}function Cn(e){let t=$(e.cwd)??$(e.workspaceRoot)??"",n=kt(t,"Copilot");return n?{additionalContext:n}:{}}function In(e){let t=$(e.prompt)??"",n=$(e.transformedPrompt)??$(e.transformed_prompt)??t,r=$(e.cwd)??$(e.workspaceRoot)??"",s=xn(t,r,"Copilot");return s?{modifiedTransformedPrompt:`${n}
101
+ ${s}`:s,n)}function Cn(e){let t=[];return wt(e,t),t.find(go)?{blocked:!0,reason:"ToolNet continuity guard: do not read or reconstruct previous work from raw ToolNet/agent session history. Use the injected ToolNet handoff first; if it is insufficient, invoke the MCP tool memory_agent_ask directly. Then verify normal repository/git source truth."}:{blocked:!1}}function F(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Pn(e,t=process.env){return F(t.TOOLNET_HOOK_EVENT)??F(e.hook_event_name)??F(e.hookEventName)??""}function Mn(e){let t=F(e.cwd)??F(e.workspaceRoot)??"",n=vt(t,"Copilot");return n?{additionalContext:n}:{}}function En(e){let t=F(e.prompt)??"",n=F(e.transformedPrompt)??F(e.transformed_prompt)??t,r=F(e.cwd)??F(e.workspaceRoot)??"",s=An(t,r,"Copilot");return s?{modifiedTransformedPrompt:`${n}
102
102
 
103
- ${s}`}:{}}function Pn(e){return jn(e.toolArgs??e.tool_input??e.toolInput??e)}function Mn(e){return{permissionDecision:"deny",permissionDecisionReason:e}}import{existsSync as Pu}from"node:fs";import{join as Mu}from"node:path";import{existsSync as lo,readFileSync as po}from"node:fs";import{homedir as mo}from"node:os";import{join as fo}from"node:path";function go(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
104
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function yo(){let e=process.env.TOOLNET_GLOBAL_ENV??fo(mo(),".config","toolnet-memory",".env");if(!lo(e))return;let t=po(e,"utf8");for(let n of t.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=go(r.slice(s+1)))}}yo();function ce(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function ue(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Pe(){return{memory:{autoCapture:ce(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ce(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ce(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ce(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ue(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ue(process.env.MEMORY_RERANK_TOP,10),finalContext:ue(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ue(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:ce(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:ue(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ho}from"node:crypto";import{existsSync as wt,mkdirSync as So,readFileSync as ko,renameSync as wo,writeFileSync as vo}from"node:fs";import{basename as bo,dirname as Me,join as Te,parse as On,resolve as le}from"node:path";var Rn=".toolnet",xo="project.json";function jo(e){return ho("sha256").update(e).digest("hex").slice(0,16)}function vt(e){return Te(e,Rn,xo)}function Ao(e){return wt(vt(e))}function Co(e,t){let n=le(e),r=On(n).root;for(;;){if(Ao(n))return n;if(n===r||t&&n===le(t))break;let s=Me(n);if(s===n)break;n=s}return null}function Io(e){let t=le(e),n=On(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>wt(Te(t,o))))return t;if(t===n)break;let s=Me(t);if(s===t)break;t=s}return le(e)}function Po(e){let t;try{t=JSON.parse(ko(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let n=t;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Me(Me(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 En(e,t){let n=Te(e,Rn);So(n,{recursive:!0});let r=vt(e),s=`${r}.tmp-${process.pid}`;vo(s,JSON.stringify(t,null,2)+`
105
- `,{encoding:"utf8",mode:384}),wo(s,r)}function Tn(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 Ee=class{detect(t=process.cwd()){let n=le(t),r=Io(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>wt(Te(r,m))),i=Co(n,o?r:void 0);if(i){let m=vt(i),p=Po(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),En(i,p)),Tn(p,i)}let a=new Date().toISOString(),c=bo(r),u={version:1,id:jo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return En(r,u),Tn(u,r)}};var Mo=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Oe=class{scan(t){let n=[];for(let r of Mo){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of t.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(t){return this.scan(t).length>0}};var U=class{scanner=new Oe;sanitize(t){let n=t,r=this.scanner.scan(t),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,s]of Object.entries(t)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return t}};import{homedir as Qo}from"node:os";import{join as Zo}from"node:path";import{DeleteObjectCommand as Eo,GetObjectCommand as To,HeadObjectCommand as Oo,ListObjectsV2Command as Ro,PutObjectCommand as No,S3Client as _o}from"@aws-sdk/client-s3";import{getSignedUrl as Ko}from"@aws-sdk/s3-request-presigner";var Re=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new _o({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new No({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ko(this.client,new To({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 Oo({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 Eo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Ro({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as Nn,mkdir as $o,readFile as Wo,readdir as Fo,rm as Lo,stat as _n,writeFile as zo}from"node:fs/promises";import{dirname as Do,join as qo,relative as Kn,resolve as Ho}from"node:path";var de=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Ho(this.root,n)}async put(t,n){let r=this.path(t);await $o(Do(r),{recursive:!0}),await zo(r,n)}async get(t){try{return await Wo(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 Nn(this.path(t)),!0}catch{return!1}}async delete(t){await Lo(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await Nn(n)}catch{return r}let s=async i=>{let a=await Fo(i,{withFileTypes:!0});for(let c of a){let u=qo(i,c.name);if(c.isDirectory()){await s(u);continue}let m=await _n(u);r.push({key:Kn(this.root,u),size:m.size,updatedAt:m.mtime.toISOString()})}},o=await _n(n);return o.isDirectory()?await s(n):r.push({key:Kn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Vo,GetObjectCommand as Jo,HeadObjectCommand as Bo,ListObjectsV2Command as Go,PutObjectCommand as Uo,S3Client as Yo}from"@aws-sdk/client-s3";import{getSignedUrl as Xo}from"@aws-sdk/s3-request-presigner";var pe=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Yo({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Uo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Xo(this.client,new Jo({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 Bo({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 Vo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Go({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function bt(e,t){return console.warn(t),new de(e)}function $n(e){let t=e.localRoot??Zo(Qo(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new pe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bt(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new pe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bt(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 Re({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):bt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(t)}function ei(e){return new Promise(t=>setTimeout(t,e))}async function Wn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await ei(c+u)}throw o}var ti=new Set(["put","get","getText","delete","list"]);function Fn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:ti.has(r)?(...o)=>Wn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function Ln(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 zn(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:t))}var Ne=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Ln(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(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 o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
106
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=zn(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,n,r){return await this.ensureRegistered(),this.provider.put(this.key(t),n,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{existsSync as di,readFileSync as pi}from"node:fs";import{join as mi}from"node:path";import{existsSync as ni,mkdirSync as ri,readFileSync as si,renameSync as oi,writeFileSync as ii}from"node:fs";import{dirname as ai,join as ci}from"node:path";function Dn(e){return ci(e.rootPath,".toolnet","context","session-origin.json")}function ui(e,t){ri(ai(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;ii(n,`${JSON.stringify(t,null,2)}
107
- `,{encoding:"utf8",mode:384}),oi(n,e)}function _e(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function qn(e,t){let n=_e(t.observations,"file"),r=_e(t.observations,"next_action"),s=_e(t.observations,"blocker"),o=_e(t.observations,"decision"),i={version:1,projectId:e.id,agent:t.agent,nativeSessionId:t.nativeSessionId,updatedAt:t.workState.updatedAt,currentRequest:t.workState.currentRequest,currentActivity:t.workState.currentActivity,currentTask:t.workState.currentTask?.title,currentPhase:t.workState.currentPhase?.title,lastTouchedFile:n?.text??t.workState.activeFiles?.at(-1)??t.workState.filesTouched.at(-1),latestNextAction:r?.text??t.workState.nextActions.at(-1),latestBlocker:s?.text??t.workState.blockers.at(-1),latestDecision:o?.text??t.workState.decisions.at(-1)};return ui(Dn(e),i),i}function li(e){let t=Dn(e);if(!ni(t))return null;try{let n=JSON.parse(si(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function Hn(e){let t=li(e);if(!t)return null;let n=["Previous session:",`- Agent: ${t.agent}`,`- Session: ${t.nativeSessionId}`];return t.currentRequest&&n.push(`- Current request: ${t.currentRequest}`),t.currentActivity&&n.push(`- Current activity: ${t.currentActivity}`),t.currentPhase&&n.push(`- Current phase: ${t.currentPhase}`),t.currentTask&&n.push(`- Current task: ${t.currentTask}`),t.lastTouchedFile&&n.push(`- Last touched file: ${t.lastTouchedFile}`),t.latestBlocker&&n.push(`- Blocker: ${t.latestBlocker}`),t.latestNextAction&&n.push(`- Next action: ${t.latestNextAction}`),t.latestDecision&&n.push(`- Important decision: ${t.latestDecision}`),n.join(`
108
- `)}function fi(e){let t=mi(e.rootPath,".toolnet","current.md");if(!di(t))return null;try{return pi(t,"utf8").trim()}catch{return null}}function gi(e,t){let n=t.replace(/\r\n/g,`
103
+ ${s}`}:{}}function Tn(e){return Cn(e.toolArgs??e.tool_input??e.toolInput??e)}function On(e){return{permissionDecision:"deny",permissionDecisionReason:e}}import{existsSync as Nu}from"node:fs";import{join as _u}from"node:path";import{existsSync as ho,readFileSync as So}from"node:fs";import{homedir as ko}from"node:os";import{join as wo}from"node:path";function vo(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
104
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function bo(){let e=process.env.TOOLNET_GLOBAL_ENV??wo(ko(),".config","toolnet-memory",".env");if(!ho(e))return;let t=So(e,"utf8");for(let n of t.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=vo(r.slice(s+1)))}}bo();function ue(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function le(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Me(){return{memory:{autoCapture:ue(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ue(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ue(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ue(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:le(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:le(process.env.MEMORY_RERANK_TOP,10),finalContext:le(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:le(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:ue(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:le(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as xo}from"node:crypto";import{existsSync as bt,mkdirSync as jo,readFileSync as Io,renameSync as Ao,writeFileSync as Co}from"node:fs";import{basename as Po,dirname as Ee,join as Oe,parse as _n,resolve as de}from"node:path";var Kn=".toolnet",Mo="project.json";function Eo(e){return xo("sha256").update(e).digest("hex").slice(0,16)}function xt(e){return Oe(e,Kn,Mo)}function To(e){return bt(xt(e))}function Oo(e,t){let n=de(e),r=_n(n).root;for(;;){if(To(n))return n;if(n===r||t&&n===de(t))break;let s=Ee(n);if(s===n)break;n=s}return null}function Ro(e){let t=de(e),n=_n(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>bt(Oe(t,o))))return t;if(t===n)break;let s=Ee(t);if(s===t)break;t=s}return de(e)}function No(e){let t;try{t=JSON.parse(Io(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let n=t;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Ee(Ee(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 Rn(e,t){let n=Oe(e,Kn);jo(n,{recursive:!0});let r=xt(e),s=`${r}.tmp-${process.pid}`;Co(s,JSON.stringify(t,null,2)+`
105
+ `,{encoding:"utf8",mode:384}),Ao(s,r)}function Nn(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 Te=class{detect(t=process.cwd()){let n=de(t),r=Ro(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>bt(Oe(r,m))),i=Oo(n,o?r:void 0);if(i){let m=xt(i),p=No(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Rn(i,p)),Nn(p,i)}let a=new Date().toISOString(),c=Po(r),u={version:1,id:Eo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return Rn(r,u),Nn(u,r)}};var _o=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Re=class{scan(t){let n=[];for(let r of _o){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of t.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(t){return this.scan(t).length>0}};var Y=class{scanner=new Re;sanitize(t){let n=t,r=this.scanner.scan(t),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,s]of Object.entries(t)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return t}};import{homedir as si}from"node:os";import{join as oi}from"node:path";import{DeleteObjectCommand as Ko,GetObjectCommand as $o,HeadObjectCommand as Fo,ListObjectsV2Command as Wo,PutObjectCommand as Lo,S3Client as Do}from"@aws-sdk/client-s3";import{getSignedUrl as zo}from"@aws-sdk/s3-request-presigner";var Ne=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Do({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Lo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await zo(this.client,new $o({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 Fo({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 Ko({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Wo({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as $n,mkdir as qo,readFile as Ho,readdir as Jo,rm as Vo,stat as Fn,writeFile as Bo}from"node:fs/promises";import{dirname as Go,join as Uo,relative as Wn,resolve as Yo}from"node:path";var pe=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Yo(this.root,n)}async put(t,n){let r=this.path(t);await qo(Go(r),{recursive:!0}),await Bo(r,n)}async get(t){try{return await Ho(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 $n(this.path(t)),!0}catch{return!1}}async delete(t){await Vo(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await $n(n)}catch{return r}let s=async i=>{let a=await Jo(i,{withFileTypes:!0});for(let c of a){let u=Uo(i,c.name);if(c.isDirectory()){await s(u);continue}let m=await Fn(u);r.push({key:Wn(this.root,u),size:m.size,updatedAt:m.mtime.toISOString()})}},o=await Fn(n);return o.isDirectory()?await s(n):r.push({key:Wn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Xo,GetObjectCommand as Qo,HeadObjectCommand as Zo,ListObjectsV2Command as ei,PutObjectCommand as ti,S3Client as ni}from"@aws-sdk/client-s3";import{getSignedUrl as ri}from"@aws-sdk/s3-request-presigner";var me=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new ni({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ti({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await ri(this.client,new Qo({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 Zo({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 Xo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new ei({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function jt(e,t){return console.warn(t),new pe(e)}function Ln(e){let t=e.localRoot??oi(si(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new me({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):jt(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 me({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):jt(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 Ne({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):jt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new pe(t)}function ii(e){return new Promise(t=>setTimeout(t,e))}async function Dn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await ii(c+u)}throw o}var ai=new Set(["put","get","getText","delete","list"]);function zn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:ai.has(r)?(...o)=>Dn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function qn(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 Hn(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:t))}var _e=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=qn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(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 o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
106
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=Hn(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,n,r){return await this.ensureRegistered(),this.provider.put(this.key(t),n,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{existsSync as hi,readFileSync as Si}from"node:fs";import{join as ki}from"node:path";import{existsSync as ci,mkdirSync as ui,readFileSync as li,renameSync as di,writeFileSync as pi}from"node:fs";import{dirname as mi,join as fi}from"node:path";function Jn(e){return fi(e.rootPath,".toolnet","context","session-origin.json")}function gi(e,t){ui(mi(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;pi(n,`${JSON.stringify(t,null,2)}
107
+ `,{encoding:"utf8",mode:384}),di(n,e)}function Ke(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function Vn(e,t){let n=Ke(t.observations,"file"),r=Ke(t.observations,"next_action"),s=Ke(t.observations,"blocker"),o=Ke(t.observations,"decision"),i={version:1,projectId:e.id,agent:t.agent,nativeSessionId:t.nativeSessionId,updatedAt:t.workState.updatedAt,currentRequest:t.workState.currentRequest,currentActivity:t.workState.currentActivity,currentTask:t.workState.currentTask?.title,currentPhase:t.workState.currentPhase?.title,lastTouchedFile:n?.text??t.workState.activeFiles?.at(-1)??t.workState.filesTouched.at(-1),latestNextAction:r?.text??t.workState.nextActions.at(-1),latestBlocker:s?.text??t.workState.blockers.at(-1),latestDecision:o?.text??t.workState.decisions.at(-1)};return gi(Jn(e),i),i}function yi(e){let t=Jn(e);if(!ci(t))return null;try{let n=JSON.parse(li(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function Bn(e){let t=yi(e);if(!t)return null;let n=["Previous session:",`- Agent: ${t.agent}`,`- Session: ${t.nativeSessionId}`];return t.currentRequest&&n.push(`- Current request: ${t.currentRequest}`),t.currentActivity&&n.push(`- Current activity: ${t.currentActivity}`),t.currentPhase&&n.push(`- Current phase: ${t.currentPhase}`),t.currentTask&&n.push(`- Current task: ${t.currentTask}`),t.lastTouchedFile&&n.push(`- Last touched file: ${t.lastTouchedFile}`),t.latestBlocker&&n.push(`- Blocker: ${t.latestBlocker}`),t.latestNextAction&&n.push(`- Next action: ${t.latestNextAction}`),t.latestDecision&&n.push(`- Important decision: ${t.latestDecision}`),n.join(`
108
+ `)}function wi(e){let t=ki(e.rootPath,".toolnet","current.md");if(!hi(t))return null;try{return Si(t,"utf8").trim()}catch{return null}}function vi(e,t){let n=t.replace(/\r\n/g,`
109
109
  `).trim(),r=2400,s=n.length>r?`${n.slice(0,r)}
110
110
 
111
- [Current work truncated for fast handoff]`:n,o=Hn(e);return["# ToolNet Fast Handoff","",`Project: ${e.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
112
- `)}function Vn(e){let t=fi(e);if(t===null)return{updated:!1,reason:"missing-current",chars:0};if(!t.trim())return{updated:!1,reason:"empty-current",chars:0};let n=gi(e,t);return gt(e)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(fn(e,n),{updated:!0,reason:"updated",chars:n.length})}import{join as yi}from"node:path";function Jn(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function Ke(e,t,n){let r=t.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=Jn(r.toLowerCase(),"agent"),i=Jn(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"sessions",o,i].join("/"),localDirectory:yi(e.rootPath,".toolnet","sessions",o,i)}}function Bn(e){return String(e).padStart(12,"0")}var $e=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)+`
111
+ [Current work truncated for fast handoff]`:n,o=Bn(e);return["# ToolNet Fast Handoff","",`Project: ${e.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
112
+ `)}function Gn(e){let t=wi(e);if(t===null)return{updated:!1,reason:"missing-current",chars:0};if(!t.trim())return{updated:!1,reason:"empty-current",chars:0};let n=vi(e,t);return ht(e)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(hn(e,n),{updated:!0,reason:"updated",chars:n.length})}import{join as bi}from"node:path";function Un(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function $e(e,t,n){let r=t.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=Un(r.toLowerCase(),"agent"),i=Un(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"sessions",o,i].join("/"),localDirectory:bi(e.rootPath,".toolnet","sessions",o,i)}}function Yn(e){return String(e).padStart(12,"0")}var Fe=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)+`
113
113
  `,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(t){let n=[],r=[],s=0;for(let o of t){let i=Buffer.byteLength(JSON.stringify(o)+`
114
- `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,s={}){let o=await this.loadManifest(t),i=await this.scan(t),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],I=y.map(E=>JSON.stringify(E)).join(`
114
+ `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,s={}){let o=await this.loadManifest(t),i=await this.scan(t),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],P=y.map(T=>JSON.stringify(T)).join(`
115
115
  `)+`
116
- `,M=w(I).slice(0,16),C=[t.remotePrefix,"events",`${Bn(h.sequence)}-${Bn(k.sequence)}-${M}.jsonl`].join("/");await this.storage.exists(C)||await this.storage.put(C,I,"application/x-ndjson"),c+=y.length}let u=await this.scan(t),m=n[n.length-1],p=o?.status??"active";m?.type==="session_end"||m?.type==="session_idle"?p="idle":m?.type==="error"?p="error":n.length>0&&(p="active");let d=new Date().toISOString(),l=n[0],g={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:p,createdAt:o?.createdAt??l?.timestamp??d,updatedAt:m?.timestamp??d,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:m?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(g.title=s.title??o?.title);let S={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:d};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:p}}};import{closeSync as jt,existsSync as bi,fsyncSync as xi,mkdirSync as ji,openSync as At,readSync as Ai,rmSync as Un,statSync as Yn,writeSync as Ci}from"node:fs";import{join as Ct}from"node:path";var hi=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),Si=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function ki(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function wi(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(Si.has(r))return n}}return null}function xt(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>xt(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=wi(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))hi.has(ki(o))||(s[o]=xt(i,t+1));return s}function vi(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function Y(e){return e?.trim()||void 0}function Gn(e,t={}){let n={...e.provenance??{}},r=Y(e.source)??Y(t.source)??Y(n.source);return{...e,timestamp:vi(e.timestamp),source:r,turnId:Y(e.turnId)??Y(t.turnId),cwd:Y(e.cwd)??Y(t.cwd),data:xt(e.data??{}),provenance:n}}var Ii=12e4,Pi=80,Mi=2e3;function Ei(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}var ne=class{constructor(t,n={}){this.identity=t;this.eventContext=n;ji(t.localDirectory,{recursive:!0}),this.eventsFile=Ct(t.localDirectory,"events.jsonl"),this.stateFile=Ct(t.localDirectory,"state.json"),this.lockFile=Ct(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 an(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(t){T(this.stateFile,t)}acquireLock(){for(let t=0;t<Pi;t+=1)try{return At(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Yn(this.lockFile).mtimeMs>Ii){Un(this.lockFile,{force:!0});continue}}catch{}Ei(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{jt(n),Un(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let p of t){let d=Gn(p,this.eventContext),l=d.timestamp??new Date().toISOString(),g=d.data??{},S=d.provenance?.rawDigest??w(Ie(g)),y=d.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,d.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,d.type,l,S].join("|"),h=w(y).slice(0,32);if(r.has(h))continue;s+=1;let k={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:d.type,timestamp:l,source:d.source??d.provenance?.source??this.identity.agent,data:g,provenance:{...d.provenance,rawDigest:S}};d.role!==void 0&&(k.role=d.role),d.turnId!==void 0&&(k.turnId=d.turnId),d.cwd!==void 0&&(k.cwd=d.cwd),d.sourceEventId!==void 0&&(k.sourceEventId=d.sourceEventId),d.sourceSequence!==void 0&&(k.sourceSequence=d.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(p=>JSON.stringify(p)).join(`
116
+ `,E=w(P).slice(0,16),C=[t.remotePrefix,"events",`${Yn(h.sequence)}-${Yn(k.sequence)}-${E}.jsonl`].join("/");await this.storage.exists(C)||await this.storage.put(C,P,"application/x-ndjson"),c+=y.length}let u=await this.scan(t),m=n[n.length-1],p=o?.status??"active";m?.type==="session_end"||m?.type==="session_idle"?p="idle":m?.type==="error"?p="error":n.length>0&&(p="active");let d=new Date().toISOString(),l=n[0],g={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:p,createdAt:o?.createdAt??l?.timestamp??d,updatedAt:m?.timestamp??d,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:m?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(g.title=s.title??o?.title);let S={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:d};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:p}}};import{closeSync as At,existsSync as Pi,fsyncSync as Mi,mkdirSync as Ei,openSync as Ct,readSync as Ti,rmSync as Qn,statSync as Zn,writeSync as Oi}from"node:fs";import{join as Pt}from"node:path";var xi=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),ji=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Ii(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Ai(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(ji.has(r))return n}}return null}function It(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>It(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=Ai(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))xi.has(Ii(o))||(s[o]=It(i,t+1));return s}function Ci(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function X(e){return e?.trim()||void 0}function Xn(e,t={}){let n={...e.provenance??{}},r=X(e.source)??X(t.source)??X(n.source);return{...e,timestamp:Ci(e.timestamp),source:r,turnId:X(e.turnId)??X(t.turnId),cwd:X(e.cwd)??X(t.cwd),data:It(e.data??{}),provenance:n}}var Ri=12e4,Ni=80,_i=2e3;function Ki(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}var re=class{constructor(t,n={}){this.identity=t;this.eventContext=n;Ei(t.localDirectory,{recursive:!0}),this.eventsFile=Pt(t.localDirectory,"events.jsonl"),this.stateFile=Pt(t.localDirectory,"state.json"),this.lockFile=Pt(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 ln(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(t){O(this.stateFile,t)}acquireLock(){for(let t=0;t<Ni;t+=1)try{return Ct(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Zn(this.lockFile).mtimeMs>Ri){Qn(this.lockFile,{force:!0});continue}}catch{}Ki(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{At(n),Qn(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let p of t){let d=Xn(p,this.eventContext),l=d.timestamp??new Date().toISOString(),g=d.data??{},S=d.provenance?.rawDigest??w(Pe(g)),y=d.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,d.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,d.type,l,S].join("|"),h=w(y).slice(0,32);if(r.has(h))continue;s+=1;let k={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:d.type,timestamp:l,source:d.source??d.provenance?.source??this.identity.agent,data:g,provenance:{...d.provenance,rawDigest:S}};d.role!==void 0&&(k.role=d.role),d.turnId!==void 0&&(k.turnId=d.turnId),d.cwd!==void 0&&(k.cwd=d.cwd),d.sourceEventId!==void 0&&(k.sourceEventId=d.sourceEventId),d.sourceSequence!==void 0&&(k.sourceSequence=d.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(p=>JSON.stringify(p)).join(`
117
117
  `)+`
118
- `,a=At(this.eventsFile,"a",384);try{Ci(a,i,null,"utf8"),xi(a)}finally{jt(a)}let c=o[o.length-1],u="active";c.type==="session_end"||c.type==="session_idle"?u="idle":c.type==="error"&&(u="error");let m=Array.from(r).slice(-Mi);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:m}),o})}readPending(){return this.withLock(()=>{let t=this.loadStateUnsafe();if(!bi(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Yn(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=At(this.eventsFile,"r");try{Ai(i,o,0,s,r)}finally{jt(i)}return{events:o.toString("utf8").split(`
119
- `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.loadStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as tc,existsSync as nc,openSync as rc,readSync as sc,statSync as oc}from"node:fs";function Xn(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 tr=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],Ti=[/từ giờ/iu,/về sau/iu,/mỗi lần/iu,/luôn luôn/iu,/\bluôn\b/iu,/quy tắc/iu,/workflow/iu,/\balways\b/iu,/\brequired\b/iu,/\bmust\b/iu,/from now on/iu],Oi=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],Ri=[/\btodo\b/iu,/cần làm/iu,/cần thêm/iu,/cần sửa/iu,/cần kiểm tra/iu,/tiếp theo/iu,/bước tiếp theo/iu,/còn phải/iu,/còn cần/iu,/next step/iu,/\bneed to\b/iu,/\bremaining\b/iu,/follow[- ]?up/iu],Ni=[/đã 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],Qn=[/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],_i=[/\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],Ki=[/đườ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],$i=[/\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"]),Wi=new Set(["payload","data","content","message","messages","parts","summary"]);function R(e,t){return t.some(n=>n.test(e))}function nr(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Fi(e){return nr(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Li(e){return!(e.length<12||e.length>1e3||(e.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(e))}function It(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||Zn.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))It(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(Zn.has(s)||Wi.has(s))&&It(o,s,n,r+1)}}function zi(e){let t=[];It(e.data,void 0,t);let n=[],r=new Set;for(let s of t)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=nr(o);if(Li(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function er(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Di(e,t,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=t==="user"||n.type==="user_prompt",s=t==="assistant"||n.type==="assistant_message";return r&&R(e,tr)?{kind:"rule",confidence:.98}:r&&R(e,Ti)?{kind:"rule",confidence:.92}:R(e,Oi)?{kind:R(e,Qn)?"architecture":"decision",confidence:r?.93:.86}:r&&R(e,Ri)?{kind:"todo",confidence:.87}:R(e,Qn)&&R(e,_i)?{kind:"architecture",confidence:r?.88:.82}:s&&R(e,Ni)?{kind:"fix",confidence:.8}:r&&R(e,Ki)&&R(e,$i)?{kind:"context",confidence:.79}:null}function qi(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Hi(e,t,n){return e==="rule"&&R(n,tr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Xn(t,n)}function rr(e,t){let n=[],r=new Set,s=new Map;for(let o of t){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=er(o);i&&a&&s.set(i,a)}for(let o of t){let i=er(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of zi(o)){let u=Di(c,i,o);if(!u||u.confidence<.75)continue;let m=qi(u.kind),p=Fi(c),d=w([e.projectId,u.kind,p].join("|"));if(r.has(d))continue;r.add(d);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:d,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:m,content:c,confidence:u.confidence,importance:Hi(u.kind,m,c),tags:[m],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as Vi}from"node:crypto";var Ji=["project-knowledge","implementation","continuation","session-context"],Bi={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Pt(e){return Vi("sha256").update(e).digest("hex")}function We(e,t){return`${e}:${Pt(t).slice(0,24)}`}function Gi(e){try{return Pt(JSON.stringify(e))}catch{return Pt(String(e))}}function X(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function 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 Ui(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function sr(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Yi(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 Xi(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(`
120
- `)}function ir(e,t){let n=e.slice().sort((d,l)=>d.sequence-l.sequence||d.timestamp.localeCompare(l.timestamp)||d.id.localeCompare(l.id)),r=n.map(d=>({id:We("raw",[d.projectId,d.agent,d.nativeSessionId,d.id,String(d.sequence)].join("|")),level:"raw",eventId:d.id,sourceEventId:d.sourceEventId,sequence:d.sequence,type:d.type,role:d.role,timestamp:d.timestamp,sourcePath:d.provenance.sourcePath,payloadDigest:Gi(d.data)})),s=new Map,o=new Map;n.forEach((d,l)=>{let g=r[l];g&&(s.set(d.id,g.id),d.sourceEventId&&o.set(d.sourceEventId,g.id))});let i=t.map(d=>{let l=X([...d.provenance.eventIds.map(g=>s.get(g)),...d.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:We("fact",d.fingerprint),level:"fact",fingerprint:d.fingerprint,kind:d.kind,type:d.type,content:d.content,knowledgeClass:d.knowledgeClass,importanceScore:d.importanceScore,confidence:d.confidence,tags:X([...d.tags,"level:fact",`class:${d.knowledgeClass}`,`kind:${d.kind}`]),rawIds:l,sourcePaths:X(d.provenance.sourcePaths)}}),a=new Map;for(let d of i){let l=Ui(d.kind),g=a.get(l)??[];g.push(d),a.set(l,g)}let c=[];for(let d of Ji){let l=a.get(d);if(!l?.length)continue;let g=l.slice().sort((y,h)=>h.importanceScore-y.importanceScore||h.confidence-y.confidence||y.id.localeCompare(h.id)),S=g.map(y=>y.id);c.push({id:We("scene",`${d}|${S.join("|")}`),level:"scene",kind:d,title:Bi[d],summary:Yi(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:sr(g.map(y=>y.confidence)),tags:X(["level:scene",`scene:${d}`,...g.flatMap(y=>y.tags)]),sourcePaths:X(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(d=>[d.id,d])),m=[];for(let d of c){let g=d.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(g.length===0)continue;let S=g.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",y=Xi(g);m.push({id:We("knowledge",`${d.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:d.title,content:y,sceneIds:[d.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:sr(g.map(h=>h.confidence)),tags:X(["level:knowledge",`class:${S}`,`scene:${d.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:X(g.flatMap(h=>h.sourcePaths))})}let p=[];for(let d of i)for(let l of d.rawIds)p.push({from:l,to:d.id,type:"supports"});for(let d of c)for(let l of d.factIds)p.push({from:l,to:d.id,type:"belongs_to"});for(let d of m)for(let l of d.sceneIds)p.push({from:l,to:d.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:m,links:p,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:m.length,links:p.length}}}function me(){let e=Pe(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function ar(e){return(e||me()).durableMemoryMaxItemsPerSession}function cr(e){return(e||me()).sessionSummaryMaxTokens}var ur=new U;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 Qi(e,t){let n=e.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);t==="rule"||t==="architecture"||t==="blocker"?r+=.2:t==="decision"||t==="deploy"?r+=.15:(t==="fix"||t==="next_action")&&(r+=.1),e.length<20?r-=.3:e.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Zi(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
121
- `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let m=u.toLowerCase().replace(/\s+/g," ");if(r.has(m))continue;r.add(m);let p="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)?p="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?p="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?p="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?p="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?p="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?p="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(p="file");let d=Qi(u,p);if(d<.3)continue;let l=lr(u);n.push({category:p,text:l,importance:d,sourceSessionId:t})}}let s=me(),o=ar(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function ea(e){let t=me(),n=cr(t),o=e.join(`
118
+ `,a=Ct(this.eventsFile,"a",384);try{Oi(a,i,null,"utf8"),Mi(a)}finally{At(a)}let c=o[o.length-1],u="active";c.type==="session_end"||c.type==="session_idle"?u="idle":c.type==="error"&&(u="error");let m=Array.from(r).slice(-_i);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:m}),o})}readPending(){return this.withLock(()=>{let t=this.loadStateUnsafe();if(!Pi(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Zn(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=Ct(this.eventsFile,"r");try{Ti(i,o,0,s,r)}finally{At(i)}return{events:o.toString("utf8").split(`
119
+ `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.loadStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ac,existsSync as cc,openSync as uc,readSync as lc,statSync as dc}from"node:fs";function er(e,t){let n=t.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":e==="rule"||e==="decision"?"high":e==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var sr=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],$i=[/từ giờ/iu,/về sau/iu,/mỗi lần/iu,/luôn luôn/iu,/\bluôn\b/iu,/quy tắc/iu,/workflow/iu,/\balways\b/iu,/\brequired\b/iu,/\bmust\b/iu,/from now on/iu],Fi=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],Wi=[/\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],Li=[/đã sửa/iu,/đã fix/iu,/đã khắc phục/iu,/đã xử lý/iu,/hoàn tất/iu,/hoàn thành/iu,/\bfixed\b/iu,/\bresolved\b/iu,/\bimplemented\b/iu,/\bcompleted\b/iu,/\bpasses?\b/iu],tr=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],Di=[/\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],zi=[/đườ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],qi=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],nr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Hi=new Set(["payload","data","content","message","messages","parts","summary"]);function N(e,t){return t.some(n=>n.test(e))}function or(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ji(e){return or(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Vi(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 Mt(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||nr.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))Mt(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(nr.has(s)||Hi.has(s))&&Mt(o,s,n,r+1)}}function Bi(e){let t=[];Mt(e.data,void 0,t);let n=[],r=new Set;for(let s of t)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=or(o);if(Vi(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function rr(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Gi(e,t,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=t==="user"||n.type==="user_prompt",s=t==="assistant"||n.type==="assistant_message";return r&&N(e,sr)?{kind:"rule",confidence:.98}:r&&N(e,$i)?{kind:"rule",confidence:.92}:N(e,Fi)?{kind:N(e,tr)?"architecture":"decision",confidence:r?.93:.86}:r&&N(e,Wi)?{kind:"todo",confidence:.87}:N(e,tr)&&N(e,Di)?{kind:"architecture",confidence:r?.88:.82}:s&&N(e,Li)?{kind:"fix",confidence:.8}:r&&N(e,zi)&&N(e,qi)?{kind:"context",confidence:.79}:null}function Ui(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Yi(e,t,n){return e==="rule"&&N(n,sr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":er(t,n)}function ir(e,t){let n=[],r=new Set,s=new Map;for(let o of t){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=rr(o);i&&a&&s.set(i,a)}for(let o of t){let i=rr(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Bi(o)){let u=Gi(c,i,o);if(!u||u.confidence<.75)continue;let m=Ui(u.kind),p=Ji(c),d=w([e.projectId,u.kind,p].join("|"));if(r.has(d))continue;r.add(d);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:d,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:m,content:c,confidence:u.confidence,importance:Yi(u.kind,m,c),tags:[m],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as Xi}from"node:crypto";var Qi=["project-knowledge","implementation","continuation","session-context"],Zi={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Et(e){return Xi("sha256").update(e).digest("hex")}function We(e,t){return`${e}:${Et(t).slice(0,24)}`}function ea(e){try{return Et(JSON.stringify(e))}catch{return Et(String(e))}}function Q(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function cr(e,t=420){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-1)).trimEnd()}\u2026`}function ta(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function ar(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function na(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,5).map(t=>cr(t.content)).join(" | ")}function ra(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,6).map(t=>cr(t.content)).join(`
120
+ `)}function ur(e,t){let n=e.slice().sort((d,l)=>d.sequence-l.sequence||d.timestamp.localeCompare(l.timestamp)||d.id.localeCompare(l.id)),r=n.map(d=>({id:We("raw",[d.projectId,d.agent,d.nativeSessionId,d.id,String(d.sequence)].join("|")),level:"raw",eventId:d.id,sourceEventId:d.sourceEventId,sequence:d.sequence,type:d.type,role:d.role,timestamp:d.timestamp,sourcePath:d.provenance.sourcePath,payloadDigest:ea(d.data)})),s=new Map,o=new Map;n.forEach((d,l)=>{let g=r[l];g&&(s.set(d.id,g.id),d.sourceEventId&&o.set(d.sourceEventId,g.id))});let i=t.map(d=>{let l=Q([...d.provenance.eventIds.map(g=>s.get(g)),...d.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:We("fact",d.fingerprint),level:"fact",fingerprint:d.fingerprint,kind:d.kind,type:d.type,content:d.content,knowledgeClass:d.knowledgeClass,importanceScore:d.importanceScore,confidence:d.confidence,tags:Q([...d.tags,"level:fact",`class:${d.knowledgeClass}`,`kind:${d.kind}`]),rawIds:l,sourcePaths:Q(d.provenance.sourcePaths)}}),a=new Map;for(let d of i){let l=ta(d.kind),g=a.get(l)??[];g.push(d),a.set(l,g)}let c=[];for(let d of Qi){let l=a.get(d);if(!l?.length)continue;let g=l.slice().sort((y,h)=>h.importanceScore-y.importanceScore||h.confidence-y.confidence||y.id.localeCompare(h.id)),S=g.map(y=>y.id);c.push({id:We("scene",`${d}|${S.join("|")}`),level:"scene",kind:d,title:Zi[d],summary:na(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:ar(g.map(y=>y.confidence)),tags:Q(["level:scene",`scene:${d}`,...g.flatMap(y=>y.tags)]),sourcePaths:Q(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(d=>[d.id,d])),m=[];for(let d of c){let g=d.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(g.length===0)continue;let S=g.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",y=ra(g);m.push({id:We("knowledge",`${d.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:d.title,content:y,sceneIds:[d.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:ar(g.map(h=>h.confidence)),tags:Q(["level:knowledge",`class:${S}`,`scene:${d.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:Q(g.flatMap(h=>h.sourcePaths))})}let p=[];for(let d of i)for(let l of d.rawIds)p.push({from:l,to:d.id,type:"supports"});for(let d of c)for(let l of d.factIds)p.push({from:l,to:d.id,type:"belongs_to"});for(let d of m)for(let l of d.sceneIds)p.push({from:l,to:d.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:m,links:p,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:m.length,links:p.length}}}function fe(){let e=Me(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function lr(e){return(e||fe()).durableMemoryMaxItemsPerSession}function dr(e){return(e||fe()).sessionSummaryMaxTokens}var pr=new Y;function mr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(pr.sanitizeValue(r))}catch{}let n=pr.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 sa(e,t){let n=e.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);t==="rule"||t==="architecture"||t==="blocker"?r+=.2:t==="decision"||t==="deploy"?r+=.15:(t==="fix"||t==="next_action")&&(r+=.1),e.length<20?r-=.3:e.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function oa(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
121
+ `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let m=u.toLowerCase().replace(/\s+/g," ");if(r.has(m))continue;r.add(m);let p="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)?p="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?p="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?p="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?p="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?p="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?p="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(p="file");let d=sa(u,p);if(d<.3)continue;let l=mr(u);n.push({category:p,text:l,importance:d,sourceSessionId:t})}}let s=fe(),o=lr(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function ia(e){let t=fe(),n=dr(t),o=e.join(`
122
122
 
123
123
  `).split(`
124
- `).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(`
125
- `);return lt(o,n)}function dr(e,t){let r=(Array.isArray(e)?e:e.split(`
124
+ `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>mr(i)).join(`
125
+ `);return pt(o,n)}function fr(e,t){let r=(Array.isArray(e)?e:e.split(`
126
126
 
127
- `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Zi(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),a=s.filter(l=>l.category==="file").map(l=>l.text),c=s.filter(l=>l.category==="fix").map(l=>l.text),u=s.filter(l=>l.category==="blocker").map(l=>l.text),m=s.filter(l=>l.category==="next_action").map(l=>l.text),p=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:ea(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:p,blockers:u,nextActions:m,durableFacts:s}}function J(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function ta(e){let t=new Map;for(let n of e){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=t.get(r);(!s||n.sequence>s.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function na(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function ra(e){let t=na(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function sa(e){return e.importance==="temporary"||e.confidence<.78?"transient":e.kind==="rule"||e.kind==="architecture"?"permanent":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function oa(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 ia(e){let t=sa(e),n=ra(e),r=oa(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:J([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function aa(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 ca(e,t,n){let r=dr(aa(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=J([...s,...r.nextActions]),c=J([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:J(r.decisions),files:J([...r.filesChanged,...o]),todos:a,completed:J(r.bugsFixed),blockers:J(r.blockers),nextActions:c,architecture:J(i)}}}function Fe(e,t){let n=ta(t),r=rr(e,n).map(ia),s=r.filter(m=>m.knowledgeClass!=="transient").sort((m,p)=>p.importanceScore-m.importanceScore),{summary:o,state:i}=ca(e,n,s),a=s.map(m=>({fingerprint:m.fingerprint,kind:m.kind,knowledgeClass:m.knowledgeClass,importanceScore:m.importanceScore,content:m.content,terms:m.retrievalTerms})),c=ir(n,s),u=m=>r.filter(p=>p.knowledgeClass===m).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as ya}from"node:crypto";import{existsSync as ha,readdirSync as Sa,readFileSync as ka}from"node:fs";import{basename as wa,join as Pr}from"node:path";import{randomUUID as fr}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function fe(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Z(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 j("Invalid Wiki slug",400);return t}function pr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(Z(r))}return fe(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-${fr()}`,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 Q(e){return structuredClone(e)}var Le=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:fe(t.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:t.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return Q([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=Z(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);return Q(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new j("Wiki title is required",400);let o=Z(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new j(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${fr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:fe(t.tags??[]),links:pr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(mr(a)),Q(a)})}async updatePage(t,n){return this.mutate(r=>{let s=Z(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=pr(o.content)),n.tags!==void 0&&(o.tags=fe(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(mr(o)),Q(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return Q(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return Q(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(t,n=10){let r=await this.ensureState(),s=fe(ua(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),m=a.summary?.toLowerCase()??"",p=a.content.toLowerCase(),d=a.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),c===g&&(l+=10),c.includes(g)&&(l+=6),u.includes(g)&&(l+=5),d.some(S=>S===g)?l+=5:d.some(S=>S.includes(g))&&(l+=3),m.includes(g)&&(l+=2),p.includes(g)&&(l+=1);l>0&&i.push({page:Q(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var gr="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(gr);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(gr,JSON.stringify(t,null,2),"application/json")}};import{createHash as pa,randomUUID as yr}from"node:crypto";var hr="wiki/governance.v1.json",vr="toolnet.knowledge-governance.v1",Sr=500,ge={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function ma(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Mt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function kr(e){return pa("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function fa(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),ma(t)}function wr(e){let t=new Date().toISOString();return{schema:vr,version:1,projectId:e,policy:{...ge},reviews:[],audit:[],createdAt:t,updatedAt:t}}function br(e){let t=e.autoApproveThreshold??ge.autoApproveThreshold,n=e.criticalApproveThreshold??ge.criticalApproveThreshold,r=e.staleAfterDays??ge.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var De=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(hr);if(!t){let n=wr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==vr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:br(n.policy??ge)}}catch{let n=wr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(hr,JSON.stringify(t,null,2),"application/json")}},qe=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,s={}){t.audit.push({id:yr(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),t.audit.length>Sr&&(t.audit=t.audit.slice(-Sr))}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=br({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),s=ga(t),o=Mt(t.title),i=n.filter(m=>m.slug!==t.slug&&Mt(m.title)===o&&kr(m.content)!==kr(t.content)).map(m=>m.slug),a=fa(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:yr(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new j(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new j("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new j("targetReviewId is required for merge",400);let u=s.reviews.find(m=>m.id===n.targetReviewId);if(!u)throw new j("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new j(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(m=>{let p=s-Date.parse(m.updatedAt);return{slug:m.slug,title:m.title,updatedAt:m.updatedAt,ageDays:Math.max(0,Math.floor(p/864e5)),stale:Number.isFinite(p)&&p>o}}).filter(m=>m.stale).map(({stale:m,...p})=>p),a=new Map;for(let m of r){let p=Mt(m.title),d=a.get(p)??[];d.push(m),a.set(p,d)}let c=[...a.entries()].filter(([,m])=>m.length>1).map(([m,p])=>({title:m,pages:p.map(d=>d.slug)})),u=n.reviews.filter(m=>m.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(m=>m.tags.some(p=>p.startsWith("toolnet-auto-"))).length,manualPages:r.filter(m=>!m.tags.some(p=>p.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(m=>m.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(m=>m.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Mr="wiki/automation.v1.json",Er="toolnet.wiki-automation.v1",Ot=8e3,xr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function he(e){return ya("sha256").update(JSON.stringify(e)).digest("hex")}function ye(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function jr(e){return Array.isArray(e)?e:[]}function Tr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Et(e){return Array.isArray(e)?e.map(Tr).filter(t=>!!t):[]}function W(e,t){for(let n of t){let r=Tr(e[n]);if(r)return r}}function Se(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function He(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(xr.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=>He(i,t+1,n));let s=ye(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();xr.has(c)||o.push(...He(a,t+1,i))}return o}function Ar(e){let n=Se(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>He(e[s],0,s)));return(n.length>0?n:Se(He(e))).join(`
127
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=oa(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),a=s.filter(l=>l.category==="file").map(l=>l.text),c=s.filter(l=>l.category==="fix").map(l=>l.text),u=s.filter(l=>l.category==="blocker").map(l=>l.text),m=s.filter(l=>l.category==="next_action").map(l=>l.text),p=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:ia(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:p,blockers:u,nextActions:m,durableFacts:s}}function B(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function aa(e){let t=new Map;for(let n of e){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=t.get(r);(!s||n.sequence>s.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function ca(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function ua(e){let t=ca(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function la(e){return e.importance==="temporary"||e.confidence<.78?"transient":e.kind==="rule"||e.kind==="architecture"?"permanent":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function da(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 pa(e){let t=la(e),n=ua(e),r=da(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:B([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function ma(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 fa(e,t,n){let r=fr(ma(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=B([...s,...r.nextActions]),c=B([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:B(r.decisions),files:B([...r.filesChanged,...o]),todos:a,completed:B(r.bugsFixed),blockers:B(r.blockers),nextActions:c,architecture:B(i)}}}function Le(e,t){let n=aa(t),r=ir(e,n).map(pa),s=r.filter(m=>m.knowledgeClass!=="transient").sort((m,p)=>p.importanceScore-m.importanceScore),{summary:o,state:i}=fa(e,n,s),a=s.map(m=>({fingerprint:m.fingerprint,kind:m.kind,knowledgeClass:m.knowledgeClass,importanceScore:m.importanceScore,content:m.content,terms:m.retrievalTerms})),c=ur(n,s),u=m=>r.filter(p=>p.knowledgeClass===m).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as ba}from"node:crypto";import{existsSync as xa,readdirSync as ja,readFileSync as Ia}from"node:fs";import{basename as Aa,join as Tr}from"node:path";import{randomUUID as hr}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function ge(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function ee(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 j("Invalid Wiki slug",400);return t}function gr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(ee(r))}return ge(t)}function ga(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function yr(e){return{id:`revision-${hr()}`,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 Z(e){return structuredClone(e)}var De=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:ge(t.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:t.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return Z([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=ee(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);return Z(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new j("Wiki title is required",400);let o=ee(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new j(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${hr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:ge(t.tags??[]),links:gr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(yr(a)),Z(a)})}async updatePage(t,n){return this.mutate(r=>{let s=ee(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=gr(o.content)),n.tags!==void 0&&(o.tags=ge(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(yr(o)),Z(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return Z(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return Z(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(t,n=10){let r=await this.ensureState(),s=ge(ga(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),m=a.summary?.toLowerCase()??"",p=a.content.toLowerCase(),d=a.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),c===g&&(l+=10),c.includes(g)&&(l+=6),u.includes(g)&&(l+=5),d.some(S=>S===g)?l+=5:d.some(S=>S.includes(g))&&(l+=3),m.includes(g)&&(l+=2),p.includes(g)&&(l+=1);l>0&&i.push({page:Z(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Sr="wiki/state.v1.json";function ya(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function ha(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(Sr);if(!t){let n=ya(this.project);return await this.save(n),n}return ha(t,this.project)}async save(t){await this.storage.put(Sr,JSON.stringify(t,null,2),"application/json")}};import{createHash as Sa,randomUUID as kr}from"node:crypto";var wr="wiki/governance.v1.json",jr="toolnet.knowledge-governance.v1",vr=500,ye={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function ka(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Tt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function br(e){return Sa("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function wa(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 va(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),ka(t)}function xr(e){let t=new Date().toISOString();return{schema:jr,version:1,projectId:e,policy:{...ye},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Ir(e){let t=e.autoApproveThreshold??ye.autoApproveThreshold,n=e.criticalApproveThreshold??ye.criticalApproveThreshold,r=e.staleAfterDays??ye.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("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(wr);if(!t){let n=xr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==jr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Ir(n.policy??ye)}}catch{let n=xr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(wr,JSON.stringify(t,null,2),"application/json")}},He=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,s={}){t.audit.push({id:kr(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),t.audit.length>vr&&(t.audit=t.audit.slice(-vr))}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=Ir({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),s=va(t),o=Tt(t.title),i=n.filter(m=>m.slug!==t.slug&&Tt(m.title)===o&&br(m.content)!==br(t.content)).map(m=>m.slug),a=wa(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:kr(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new j(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new j("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new j("targetReviewId is required for merge",400);let u=s.reviews.find(m=>m.id===n.targetReviewId);if(!u)throw new j("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new j(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(m=>{let p=s-Date.parse(m.updatedAt);return{slug:m.slug,title:m.title,updatedAt:m.updatedAt,ageDays:Math.max(0,Math.floor(p/864e5)),stale:Number.isFinite(p)&&p>o}}).filter(m=>m.stale).map(({stale:m,...p})=>p),a=new Map;for(let m of r){let p=Tt(m.title),d=a.get(p)??[];d.push(m),a.set(p,d)}let c=[...a.entries()].filter(([,m])=>m.length>1).map(([m,p])=>({title:m,pages:p.map(d=>d.slug)})),u=n.reviews.filter(m=>m.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(m=>m.tags.some(p=>p.startsWith("toolnet-auto-"))).length,manualPages:r.filter(m=>!m.tags.some(p=>p.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(m=>m.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(m=>m.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Or="wiki/automation.v1.json",Rr="toolnet.wiki-automation.v1",Nt=8e3,Ar=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Se(e){return ba("sha256").update(JSON.stringify(e)).digest("hex")}function he(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Cr(e){return Array.isArray(e)?e:[]}function Nr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Ot(e){return Array.isArray(e)?e.map(Nr).filter(t=>!!t):[]}function W(e,t){for(let n of t){let r=Nr(e[n]);if(r)return r}}function ke(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Je(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Ar.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=>Je(i,t+1,n));let s=he(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Ar.has(c)||o.push(...Je(a,t+1,i))}return o}function Pr(e){let n=ke(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>Je(e[s],0,s)));return(n.length>0?n:ke(Je(e))).join(`
128
128
 
129
- `).slice(0,Ot)}function Cr(e,t){return W(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Ir(e,t){return W(e,["title","name","topic","label","task","kind","type"])??t}function va(e){return(W(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function ba(e){return(W(e,["kind","sceneKind","type"])??"").toLowerCase()}function xa(e){let t=ye(e);if(!t)return[];let n=[],r=jr(t.knowledge);for(let[o,i]of r.entries()){let a=ye(i);if(!a)continue;let c=va(a);if(c==="session"||c==="transient")continue;let u=Ar(a);if(u.length<20)continue;let m=Cr(a,he(a).slice(0,16)),p=Ir(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${m}`,sourceType:"memory",title:p,summary:W(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","memory",...c?[c]:[]])})}let s=jr(t.scenes);for(let[o,i]of s.entries()){let a=ye(i);if(!a)continue;let c=ba(a);if(c==="session-context")continue;let u=Ar(a);if(u.length<20)continue;let m=Cr(a,he(a).slice(0,16)),p=Ir(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${m}`,sourceType:"scene",title:p,summary:W(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","scene",...c?[c]:[]])})}return n}function ja(e){return Pr(e,".toolnet","memory","skills")}function Aa(e){let t=ja(e);if(!ha(t))return{candidates:[],failed:0};let n=[],r=0,s=Sa(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(ka(Pr(t,o),"utf8")),a=ye(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=W(a,["id","fingerprint"])??wa(o,".json"),u=W(a,["task"])??"",m=W(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,p=W(a,["summary"])??void 0,d=Et(a.steps),l=Et(a.verification),g=Et(a.files),S=[];u&&S.push(`## Task
129
+ `).slice(0,Nt)}function Mr(e,t){return W(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Er(e,t){return W(e,["title","name","topic","label","task","kind","type"])??t}function Ca(e){return(W(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Pa(e){return(W(e,["kind","sceneKind","type"])??"").toLowerCase()}function Ma(e){let t=he(e);if(!t)return[];let n=[],r=Cr(t.knowledge);for(let[o,i]of r.entries()){let a=he(i);if(!a)continue;let c=Ca(a);if(c==="session"||c==="transient")continue;let u=Pr(a);if(u.length<20)continue;let m=Mr(a,Se(a).slice(0,16)),p=Er(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${m}`,sourceType:"memory",title:p,summary:W(a,["summary","description"]),content:u,tags:ke(["toolnet","auto","memory",...c?[c]:[]])})}let s=Cr(t.scenes);for(let[o,i]of s.entries()){let a=he(i);if(!a)continue;let c=Pa(a);if(c==="session-context")continue;let u=Pr(a);if(u.length<20)continue;let m=Mr(a,Se(a).slice(0,16)),p=Er(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${m}`,sourceType:"scene",title:p,summary:W(a,["summary","description"]),content:u,tags:ke(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Ea(e){return Tr(e,".toolnet","memory","skills")}function Ta(e){let t=Ea(e);if(!xa(t))return{candidates:[],failed:0};let n=[],r=0,s=ja(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Ia(Tr(t,o),"utf8")),a=he(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=W(a,["id","fingerprint"])??Aa(o,".json"),u=W(a,["task"])??"",m=W(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,p=W(a,["summary"])??void 0,d=Ot(a.steps),l=Ot(a.verification),g=Ot(a.files),S=[];u&&S.push(`## Task
130
130
  ${u}`),p&&S.push(`## Summary
131
131
  ${p}`),d.length>0&&S.push(`## Procedure
132
132
  ${d.map((h,k)=>`${k+1}. ${h}`).join(`
@@ -136,23 +136,23 @@ ${l.map(h=>`- ${h}`).join(`
136
136
  ${g.map(h=>`- \`${h}\``).join(`
137
137
  `)}`);let y=S.join(`
138
138
 
139
- `).slice(0,Ot);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:m,summary:p,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Tt(e){let t=new Date().toISOString();return{schema:Er,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Ca(e,t){let n=await e.getText(Mr);if(!n)return Tt(t);try{let r=JSON.parse(n);return r.schema!==Er||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Tt(t):r}catch{return Tt(t)}}async function Ia(e,t){await e.put(Mr,JSON.stringify(t,null,2),"application/json")}function Pa(e){return`toolnet-auto-${he(e).slice(0,12)}`}function Ma(e){let t=Z(e.title).slice(0,72),n=he(e.sourceKey).slice(0,10);return Z(`auto-${e.sourceType}-${t}-${n}`)}function Ea(e){return[`> Auto-generated by ToolNet Knowledge Automation from ${e.sourceType==="skill"?"reusable Skill Memory":e.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",e.content].join(`
140
- `).slice(0,Ot)}function Ta(e){return he({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Oa(e,t){return e.tags.includes(t)}async function Or(e){let t=xa(e.hierarchy),n=Aa(e.project.rootPath),r=new Map;for(let l of[...t,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new Le(new ze(e.storage,e.project));await i.initialize();let a=new qe(new De(e.storage,e.project));await a.initialize();let c=await Ca(e.storage,e.project.id),u=await i.listPages(),m=new Map(u.map(l=>[l.slug,l])),p=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=Pa(l.sourceKey),S=Ta(l),y=p.get(l.sourceKey),h=y?.slug??Ma(l),k=m.get(h);if(k&&!Oa(k,g)){o.skipped+=1;continue}let I=Se([...l.tags,g]),M=Ea(l),C=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,marker:g,digest:S,title:l.title,...l.summary?{summary:l.summary}:{},content:M,tags:I},[...m.values()]);if(!C.allowed){C.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}C.mode==="auto-approved"?o.autoApproved+=1:C.mode==="review-approved"&&(o.reviewApproved+=1),k?y?.digest!==S?(k=await i.updatePage(h,{title:l.title,summary:l.summary??"",content:M,tags:I}),m.set(k.slug,k),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,action:"unchanged"})):(k=await i.createPage({slug:h,title:l.title,summary:l.summary,content:M,tags:I}),m.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let E=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,digest:S,marker:g,updatedAt:E},v=c.entries.findIndex(D=>D.sourceKey===l.sourceKey);v>=0?c.entries[v]=x:c.entries.push(x),p.set(l.sourceKey,x),await a.markApplied(l.sourceKey,S)}catch(g){if(g instanceof j&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let d=new Date().toISOString();return c.updatedAt=d,c.lastRunAt=d,c.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Ia(e.storage,c),o}import{createHash as Ra}from"node:crypto";import{chmodSync as Nr,existsSync as Na,mkdirSync as _a,readFileSync as Zp,readdirSync as em,renameSync as Ka,statSync as tm,writeFileSync as $a}from"node:fs";import{join as _r}from"node:path";var Wa="toolnet.skill-memory.v1",Rr=5,Fa=16,La=24,za=32;function Da(e){return Ra("sha256").update(e).digest("hex")}function we(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function Rt(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 qa(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 H(e,t=360){return e&&Rt(qa(e),t)||void 0}function ve(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Kr(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 $r(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function Wr(e){let t=e.data??{};if($r(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Kr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=ve(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ke(e){let t=e.data??{};if(Wr(e))return!1;if($r(t,["passed","pass","success","succeeded","ok"])===!0||Kr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=ve(t,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:e.type==="commit"||e.type==="deploy"}function Fr(e){let t=e.data??{},n=ve(t,["path","file","filePath","filename","target"]);if(n)return H(n,260);let r=e.provenance?.files;return H(r?.[0],260)}function Nt(e){return H(ve(e.data??{},["command","cmd","script"]),420)}function re(e){return H(ve(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Ha(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(ke(n)){if(n.type==="test"){let r=re(n)??Nt(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=re(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=re(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return we(t,10)}function Va(e,t){let n=[];for(let r of[...e].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=Fr(r);s&&n.push(`Update ${s}`);break}case"command":{if(Wr(r))break;let s=Nt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ke(r))break;let s=re(r)??Nt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!ke(r))break;let s=re(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!ke(r))break;let s=re(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let s=H(r,260);s&&n.push(`Update ${s}`)}return we(n,Fa)}function Ja(e,t){let n=[...t.files];for(let r of e){let s=Fr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=H(o,260);i&&n.push(i)}}return we(n,La)}function Ba(e){return we(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),za)}function Ga(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Lr(e,t,n){if(t.length===0)return[];let r=Ha(t),s=we(n.completed.map(g=>H(g,280)??""),Rr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&ke(g))))return[];let i=H(n.task,280)??H(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=Va(t,n);if(c.length===0)return[];let u=Ja(t,n),m=Ba(t),p=Math.min(...t.map(g=>g.sequence)),d=Math.max(...t.map(g=>g.sequence)),l=Ga(t);return a.slice(0,Rr).map(g=>{let S=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),y=JSON.stringify({projectId:e.projectId,task:g,steps:c,verification:r,files:u}),h=Da(y);return{schema:Wa,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:Rt(`SOP: ${g}`,180),task:g,summary:Rt(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:p,lastSequence:d,eventIds:m},createdAt:l}})}function Ua(e){return _r(e.rootPath,".toolnet","memory","skills")}function Ya(e){let t=Ua(e);return _a(t,{recursive:!0,mode:448}),Nr(t,448),t}function zr(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=Ya(e),r=0,s=0,o=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=_r(n,`${i.id}.json`);if(o.push(a),Na(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;$a(c,JSON.stringify(i,null,2)+`
141
- `,{encoding:"utf8",mode:384}),Ka(c,a),Nr(a,384),r+=1}return{written:r,deduped:s,files:o}}function Dr(e){return String(e).padStart(12,"0")}function Xa(e){return e.remotePrefix.replace("/sessions/","/memory/learned/")}var Ve=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(m=>m.sequence)),o=Math.max(...n.map(m=>m.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
142
- `,c=w(r.map(m=>m.fingerprint).sort().join("|")).slice(0,16),u=[Xa(t),"batches",`${Dr(s)}-${Dr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as Qa}from"node:crypto";function qr(e){return String(e).padStart(12,"0")}function Za(e){return Qa("sha256").update(e).digest("hex")}function ec(e){return e.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Je=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=Za([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[ec(t),"batches",`${qr(s)}-${qr(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
143
- `,"application/json"),c}};function ic(e,t){if(!nc(e))return{events:[],nextOffset:t};let n=oc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=rc(e,"r");try{sc(i,o,0,s,r)}finally{tc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
139
+ `).slice(0,Nt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:m,summary:p,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Rt(e){let t=new Date().toISOString();return{schema:Rr,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Oa(e,t){let n=await e.getText(Or);if(!n)return Rt(t);try{let r=JSON.parse(n);return r.schema!==Rr||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Rt(t):r}catch{return Rt(t)}}async function Ra(e,t){await e.put(Or,JSON.stringify(t,null,2),"application/json")}function Na(e){return`toolnet-auto-${Se(e).slice(0,12)}`}function _a(e){let t=ee(e.title).slice(0,72),n=Se(e.sourceKey).slice(0,10);return ee(`auto-${e.sourceType}-${t}-${n}`)}function Ka(e){return[`> Auto-generated by ToolNet Knowledge Automation from ${e.sourceType==="skill"?"reusable Skill Memory":e.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",e.content].join(`
140
+ `).slice(0,Nt)}function $a(e){return Se({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Fa(e,t){return e.tags.includes(t)}async function _r(e){let t=Ma(e.hierarchy),n=Ta(e.project.rootPath),r=new Map;for(let l of[...t,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new De(new ze(e.storage,e.project));await i.initialize();let a=new He(new qe(e.storage,e.project));await a.initialize();let c=await Oa(e.storage,e.project.id),u=await i.listPages(),m=new Map(u.map(l=>[l.slug,l])),p=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=Na(l.sourceKey),S=$a(l),y=p.get(l.sourceKey),h=y?.slug??_a(l),k=m.get(h);if(k&&!Fa(k,g)){o.skipped+=1;continue}let P=ke([...l.tags,g]),E=Ka(l),C=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,marker:g,digest:S,title:l.title,...l.summary?{summary:l.summary}:{},content:E,tags:P},[...m.values()]);if(!C.allowed){C.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}C.mode==="auto-approved"?o.autoApproved+=1:C.mode==="review-approved"&&(o.reviewApproved+=1),k?y?.digest!==S?(k=await i.updatePage(h,{title:l.title,summary:l.summary??"",content:E,tags:P}),m.set(k.slug,k),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,action:"unchanged"})):(k=await i.createPage({slug:h,title:l.title,summary:l.summary,content:E,tags:P}),m.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let T=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,digest:S,marker:g,updatedAt:T},v=c.entries.findIndex(q=>q.sourceKey===l.sourceKey);v>=0?c.entries[v]=x:c.entries.push(x),p.set(l.sourceKey,x),await a.markApplied(l.sourceKey,S)}catch(g){if(g instanceof j&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let d=new Date().toISOString();return c.updatedAt=d,c.lastRunAt=d,c.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Ra(e.storage,c),o}import{createHash as Wa}from"node:crypto";import{chmodSync as $r,existsSync as La,mkdirSync as Da,readFileSync as vm,readdirSync as bm,renameSync as za,statSync as xm,writeFileSync as qa}from"node:fs";import{join as Fr}from"node:path";var Ha="toolnet.skill-memory.v1",Kr=5,Ja=16,Va=24,Ba=32;function Ga(e){return Wa("sha256").update(e).digest("hex")}function ve(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function _t(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 Ua(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 J(e,t=360){return e&&_t(Ua(e),t)||void 0}function be(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Wr(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 Lr(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function Dr(e){let t=e.data??{};if(Lr(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Wr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=be(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function we(e){let t=e.data??{};if(Dr(e))return!1;if(Lr(t,["passed","pass","success","succeeded","ok"])===!0||Wr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=be(t,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:e.type==="commit"||e.type==="deploy"}function zr(e){let t=e.data??{},n=be(t,["path","file","filePath","filename","target"]);if(n)return J(n,260);let r=e.provenance?.files;return J(r?.[0],260)}function Kt(e){return J(be(e.data??{},["command","cmd","script"]),420)}function se(e){return J(be(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Ya(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(we(n)){if(n.type==="test"){let r=se(n)??Kt(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=se(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=se(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return ve(t,10)}function Xa(e,t){let n=[];for(let r of[...e].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=zr(r);s&&n.push(`Update ${s}`);break}case"command":{if(Dr(r))break;let s=Kt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!we(r))break;let s=se(r)??Kt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!we(r))break;let s=se(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!we(r))break;let s=se(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let s=J(r,260);s&&n.push(`Update ${s}`)}return ve(n,Ja)}function Qa(e,t){let n=[...t.files];for(let r of e){let s=zr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=J(o,260);i&&n.push(i)}}return ve(n,Va)}function Za(e){return ve(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Ba)}function ec(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function qr(e,t,n){if(t.length===0)return[];let r=Ya(t),s=ve(n.completed.map(g=>J(g,280)??""),Kr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&we(g))))return[];let i=J(n.task,280)??J(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=Xa(t,n);if(c.length===0)return[];let u=Qa(t,n),m=Za(t),p=Math.min(...t.map(g=>g.sequence)),d=Math.max(...t.map(g=>g.sequence)),l=ec(t);return a.slice(0,Kr).map(g=>{let S=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),y=JSON.stringify({projectId:e.projectId,task:g,steps:c,verification:r,files:u}),h=Ga(y);return{schema:Ha,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:_t(`SOP: ${g}`,180),task:g,summary:_t(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:p,lastSequence:d,eventIds:m},createdAt:l}})}function tc(e){return Fr(e.rootPath,".toolnet","memory","skills")}function nc(e){let t=tc(e);return Da(t,{recursive:!0,mode:448}),$r(t,448),t}function Hr(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=nc(e),r=0,s=0,o=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=Fr(n,`${i.id}.json`);if(o.push(a),La(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;qa(c,JSON.stringify(i,null,2)+`
141
+ `,{encoding:"utf8",mode:384}),za(c,a),$r(a,384),r+=1}return{written:r,deduped:s,files:o}}function Jr(e){return String(e).padStart(12,"0")}function rc(e){return e.remotePrefix.replace("/sessions/","/memory/learned/")}var Ve=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(m=>m.sequence)),o=Math.max(...n.map(m=>m.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
142
+ `,c=w(r.map(m=>m.fingerprint).sort().join("|")).slice(0,16),u=[rc(t),"batches",`${Jr(s)}-${Jr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as sc}from"node:crypto";function Vr(e){return String(e).padStart(12,"0")}function oc(e){return sc("sha256").update(e).digest("hex")}function ic(e){return e.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Be=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=oc([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[ic(t),"batches",`${Vr(s)}-${Vr(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
143
+ `,"application/json"),c}};function pc(e,t){if(!cc(e))return{events:[],nextOffset:t};let n=dc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=uc(e,"r");try{lc(i,o,0,s,r)}finally{ac(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
144
144
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
145
- `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Be=class{constructor(t){this.options=t;this.journal=new Ve(t.storage),this.hierarchyJournal=new Je(t.storage)}options;journal;hierarchyJournal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=ic(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Fe(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=Lr(this.options.identity,s.events,o.state),m=zr(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",m.written),this.options.wal.setSourceCursor("memory.skill.deduped",m.deduped);try{let p=sn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",p.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",p.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",p.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",p.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let p=await Or({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",p.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",p.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",p.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",p.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",p.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",p.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",p.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",p.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",p.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",p.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:a,nextOffset:s.nextOffset}}};import{closeSync as jc,existsSync as Ac,openSync as Cc,readSync as Ic,statSync as Pc}from"node:fs";function Hr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function xe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function be(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))be(s,t,n+1);return}let r=Hr(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),be(o,t,n+1)}function se(e,t){let n=[];return be(e,(r,s)=>{t.has(xe(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function ac(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Hr(JSON.parse(t))}catch{return null}}function cc(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let s=t[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return be(t,(r,s,o)=>{if(n)return;let i=xe(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function uc(e){let t=se(e.data,new Set(["command","cmd","script"])),n=se(e.data,new Set(["arguments","args"]));for(let r of n){let s=ac(r);if(s)for(let o of se(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function lc(e){let t=se(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(xe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
146
- `))))}function dc(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 pc(e){let t=se(e.data,new Set(["patch","diff","arguments","input"].map(xe))),n=[];for(let r of t){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function mc(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 fc(e){let t=null;return be(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(xe(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(t=s)}}}),t}function gc(e){return se(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function yc(e){let t=fc(e.data);if(t!==null)return t===0?"passed":"failed";let n=gc(e.data).join(`
147
- `).toLowerCase();return/\b(error|failed|failure|failing)\b/u.test(n)&&!/\b0\s+failed\b/u.test(n)?"failed":/\b(success|successful|completed|passed|green)\b/u.test(n)||/\b\d+\s+passed\b/u.test(n)?"passed":/\b(running|started|in[_ -]?progress)\b/u.test(n)?"running":"unknown"}function hc(e){let t=[],n=new Set;for(let r of e){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),t.push(r))}return t}function Vr(e){let t=[],n=cc(e),r=dc(e,n);if(r)for(let s of lc(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...pc(e));for(let s of uc(e)){t.push({kind:"command",text:s,confidence:.98});let o=mc(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:yc(e),confidence:.98})}return hc(t)}var Sc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function te(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Br(e){return te(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function ee(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))ee(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Sc.has(r)||["data","payload","parts","messages"].includes(r))&&ee(s,t,n+1)}}function Ge(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 Jr(e){let t=te(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 A(e,t,n,r,s={}){let o=te(r),i=s.key??Br(o);return{version:1,id:w([e.projectId,n,i,t.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function kc(e,t,n){let r=te(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(A(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(A(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(;!o&&(u=c.exec(r));){let d=Number(u[1]),l=te(u[2]??""),g=l&&!Jr(l)?`Phase ${d} - ${l}`:`Phase ${d}`;s.push(A(e,t,"phase",g,{key:`phase:${d}`,order:d,status:Ge(r),confidence:.93}))}let m=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);m?.[2]&&s.push(A(e,t,"task",m[2],{status:m[1].trim()?"completed":Ge(m[2]),confidence:.96}));let p=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(p?.[2]){let d=p[1]?Number(p[1]):void 0,l=te(p[2]),g=Jr(l);s.push(A(e,t,"task",g&&d!==void 0?`TODO ${d}`:l,{key:d!==void 0?`task:${d}`:Br(l),order:d,status:Ge(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 d=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");d&&s.push(A(e,t,"next_action",d,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(A(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(A(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(A(e,t,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&s.push(A(e,t,"activity",r,{confidence:.86})),s}function Ue(e,t){if(t.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let c=[];ee(i.data,c);let u=c.map(m=>te(m)).find(m=>m.length>=8&&m.length<=1200&&!/^\[?toolnet\b/iu.test(m));u&&s(A(e,i,"request",u,{confidence:.96}))}for(let c of Vr(i))s(A(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=[];ee(i.data,c);for(let u of c)s(A(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];ee(i.data,c);for(let u of c)s(A(e,i,"task",u,{status:Ge(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(A(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];ee(i.data,c);for(let u of c)s(A(e,i,"test",u,{confidence:1}))}let a=[];ee(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let m of kc(e,i,u))s(m)}let o=t[t.length-1];return s(A(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function Gr(e){return String(e).padStart(12,"0")}var Ye=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
148
- `,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${Gr(r)}-${Gr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Ur}from"node:path";import{mkdirSync as wc}from"node:fs";function Xr(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function F(e,t=20){let n=[],r=new Set;for(let s of e.slice().reverse()){let o=Xr(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function vc(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${Xr(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function bc(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 Yr(e,t){let n=t.status??e?.status??"pending",r=n;e&&(e.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status));let s=e&&bc(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:s,status:r,order:t.order??e?.order,confidence:Math.max(t.confidence,e?.confidence??0),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}async function xc(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Xe(e,t){let r=(await xc(e,t)).flatMap(f=>f.observations).sort((f,b)=>{let V=f.occurredAt.localeCompare(b.occurredAt);if(V!==0)return V;let Bt=f.sequence-b.sequence;return Bt!==0?Bt:f.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,m,p=[],d=[],l=[],g=[],S=[],y=new Map,h=[],k=[],I=[],M=[],C=[],E=[];for(let f of r)switch(f.kind){case"request":i=f.text;break;case"activity":a=f.text;break;case"goal":c=f.text;break;case"plan":u=f.text;break;case"phase":s.set(f.key,Yr(s.get(f.key),f));break;case"task":o.set(f.key,Yr(o.get(f.key),f));break;case"decision":p.push(f.text);break;case"blocker":d.push(f.text);break;case"warning":l.push(f.text);break;case"next_action":g.push(f.text);break;case"file":{S.push(f.text);let b=f.fileAction??"active";y.delete(f.text),y.set(f.text,b),b==="modified"?h.push(f.text):b==="created"?k.push(f.text):b==="deleted"&&I.push(f.text);break}case"command":M.push(f.text);break;case"test":C.push(f.text),f.checkKind&&E.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":m={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=Array.from(s.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),v=Array.from(o.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),D=x.find(f=>f.status==="in_progress")??x.find(f=>f.status==="blocked")??x.find(f=>f.status==="pending"),q=v.find(f=>f.status==="in_progress")??v.find(f=>f.status==="blocked")??v.find(f=>f.status==="pending"),at=F([...g,...q?[q.title]:[],...!q&&D?[D.title]:[],...v.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),ct=F([...d,...x.filter(f=>f.status==="blocked").map(f=>f.title),...v.filter(f=>f.status==="blocked").map(f=>f.title)],20),ie={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:v,decisions:F(p,20),blockers:ct,warnings:F(l,20),nextActions:at,filesTouched:F(S,30),activeFiles:Array.from(y.entries()).filter(([,f])=>f!=="deleted").map(([f])=>f).slice(-5),modifiedFiles:F(h,30),createdFiles:F(k,30),deletedFiles:F(I,30),commands:F(M,20),tests:F(C,20),checks:vc(E,20),currentPhase:D,currentTask:q,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+v.filter(f=>f.status==="blocked").length},lastSession:m,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ae=Ur(e.rootPath,".toolnet","work");return wc(ae,{recursive:!0}),T(Ur(ae,"current.json"),ie),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ie,null,2)+`
149
- `,"application/json"),ie}async function Qr(e,t){let n=await t.getText(`projects/${e.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Mc(e,t){if(!Ac(e))return{events:[],nextOffset:t};let n=Pc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Cc(e,"r");try{Ic(i,o,0,s,r)}finally{jc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
145
+ `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Ge=class{constructor(t){this.options=t;this.journal=new Ve(t.storage),this.hierarchyJournal=new Be(t.storage)}options;journal;hierarchyJournal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=pc(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Le(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=qr(this.options.identity,s.events,o.state),m=Hr(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",m.written),this.options.wal.setSourceCursor("memory.skill.deduped",m.deduped);try{let p=cn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",p.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",p.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",p.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",p.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let p=await _r({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",p.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",p.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",p.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",p.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",p.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",p.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",p.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",p.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",p.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",p.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:a,nextOffset:s.nextOffset}}};import{closeSync as Ec,existsSync as Tc,openSync as Oc,readSync as Rc,statSync as Nc}from"node:fs";function Br(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function je(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function xe(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))xe(s,t,n+1);return}let r=Br(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),xe(o,t,n+1)}function oe(e,t){let n=[];return xe(e,(r,s)=>{t.has(je(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function mc(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Br(JSON.parse(t))}catch{return null}}function fc(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let s=t[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return xe(t,(r,s,o)=>{if(n)return;let i=je(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function gc(e){let t=oe(e.data,new Set(["command","cmd","script"])),n=oe(e.data,new Set(["arguments","args"]));for(let r of n){let s=mc(r);if(s)for(let o of oe(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function yc(e){let t=oe(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(je)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
146
+ `))))}function hc(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 Sc(e){let t=oe(e.data,new Set(["patch","diff","arguments","input"].map(je))),n=[];for(let r of t){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function kc(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 wc(e){let t=null;return xe(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(je(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(t=s)}}}),t}function vc(e){return oe(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function bc(e){let t=wc(e.data);if(t!==null)return t===0?"passed":"failed";let n=vc(e.data).join(`
147
+ `).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 xc(e){let t=[],n=new Set;for(let r of e){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),t.push(r))}return t}function Gr(e){let t=[],n=fc(e),r=hc(e,n);if(r)for(let s of yc(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...Sc(e));for(let s of gc(e)){t.push({kind:"command",text:s,confidence:.98});let o=kc(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:bc(e),confidence:.98})}return xc(t)}var jc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ne(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Yr(e){return ne(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function te(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))te(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(jc.has(r)||["data","payload","parts","messages"].includes(r))&&te(s,t,n+1)}}function Ue(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 Ur(e){let t=ne(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 I(e,t,n,r,s={}){let o=ne(r),i=s.key??Yr(o);return{version:1,id:w([e.projectId,n,i,t.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function Ic(e,t,n){let r=ne(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(I(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(I(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(;!o&&(u=c.exec(r));){let d=Number(u[1]),l=ne(u[2]??""),g=l&&!Ur(l)?`Phase ${d} - ${l}`:`Phase ${d}`;s.push(I(e,t,"phase",g,{key:`phase:${d}`,order:d,status:Ue(r),confidence:.93}))}let m=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);m?.[2]&&s.push(I(e,t,"task",m[2],{status:m[1].trim()?"completed":Ue(m[2]),confidence:.96}));let p=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(p?.[2]){let d=p[1]?Number(p[1]):void 0,l=ne(p[2]),g=Ur(l);s.push(I(e,t,"task",g&&d!==void 0?`TODO ${d}`:l,{key:d!==void 0?`task:${d}`:Yr(l),order:d,status:Ue(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 d=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");d&&s.push(I(e,t,"next_action",d,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(I(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(I(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(I(e,t,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&s.push(I(e,t,"activity",r,{confidence:.86})),s}function Ye(e,t){if(t.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let c=[];te(i.data,c);let u=c.map(m=>ne(m)).find(m=>m.length>=8&&m.length<=1200&&!/^\[?toolnet\b/iu.test(m));u&&s(I(e,i,"request",u,{confidence:.96}))}for(let c of Gr(i))s(I(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=[];te(i.data,c);for(let u of c)s(I(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];te(i.data,c);for(let u of c)s(I(e,i,"task",u,{status:Ue(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(I(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];te(i.data,c);for(let u of c)s(I(e,i,"test",u,{confidence:1}))}let a=[];te(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let m of Ic(e,i,u))s(m)}let o=t[t.length-1];return s(I(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function Xr(e){return String(e).padStart(12,"0")}var Xe=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
148
+ `,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${Xr(r)}-${Xr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Qr}from"node:path";import{mkdirSync as Ac}from"node:fs";function es(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(e,t=20){let n=[],r=new Set;for(let s of e.slice().reverse()){let o=es(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function Cc(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${es(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function Pc(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 Zr(e,t){let n=t.status??e?.status??"pending",r=n;e&&(e.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status));let s=e&&Pc(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:s,status:r,order:t.order??e?.order,confidence:Math.max(t.confidence,e?.confidence??0),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}async function Mc(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Qe(e,t){let r=(await Mc(e,t)).flatMap(f=>f.observations).sort((f,b)=>{let V=f.occurredAt.localeCompare(b.occurredAt);if(V!==0)return V;let Yt=f.sequence-b.sequence;return Yt!==0?Yt:f.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,m,p=[],d=[],l=[],g=[],S=[],y=new Map,h=[],k=[],P=[],E=[],C=[],T=[];for(let f of r)switch(f.kind){case"request":i=f.text;break;case"activity":a=f.text;break;case"goal":c=f.text;break;case"plan":u=f.text;break;case"phase":s.set(f.key,Zr(s.get(f.key),f));break;case"task":o.set(f.key,Zr(o.get(f.key),f));break;case"decision":p.push(f.text);break;case"blocker":d.push(f.text);break;case"warning":l.push(f.text);break;case"next_action":g.push(f.text);break;case"file":{S.push(f.text);let b=f.fileAction??"active";y.delete(f.text),y.set(f.text,b),b==="modified"?h.push(f.text):b==="created"?k.push(f.text):b==="deleted"&&P.push(f.text);break}case"command":E.push(f.text);break;case"test":C.push(f.text),f.checkKind&&T.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":m={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=Array.from(s.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),v=Array.from(o.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),q=x.find(f=>f.status==="in_progress")??x.find(f=>f.status==="blocked")??x.find(f=>f.status==="pending"),H=v.find(f=>f.status==="in_progress")??v.find(f=>f.status==="blocked")??v.find(f=>f.status==="pending"),ut=L([...g,...H?[H.title]:[],...!H&&q?[q.title]:[],...v.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),lt=L([...d,...x.filter(f=>f.status==="blocked").map(f=>f.title),...v.filter(f=>f.status==="blocked").map(f=>f.title)],20),ae={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:v,decisions:L(p,20),blockers:lt,warnings:L(l,20),nextActions:ut,filesTouched:L(S,30),activeFiles:Array.from(y.entries()).filter(([,f])=>f!=="deleted").map(([f])=>f).slice(-5),modifiedFiles:L(h,30),createdFiles:L(k,30),deletedFiles:L(P,30),commands:L(E,20),tests:L(C,20),checks:Cc(T,20),currentPhase:q,currentTask:H,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+v.filter(f=>f.status==="blocked").length},lastSession:m,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ce=Qr(e.rootPath,".toolnet","work");return Ac(ce,{recursive:!0}),O(Qr(ce,"current.json"),ae),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ae,null,2)+`
149
+ `,"application/json"),ae}async function ts(e,t){let n=await t.getText(`projects/${e.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function _c(e,t){if(!Tc(e))return{events:[],nextOffset:t};let n=Nc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Oc(e,"r");try{Rc(i,o,0,s,r)}finally{Ec(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
150
150
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
151
- `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Qe=class{constructor(t){this.options=t;this.journal=new Ye(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=Mc(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Ue(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Xe(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Wc,existsSync as Fc,openSync as Lc,readSync as zc,statSync as Dc}from"node:fs";var Ec=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function oe(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function _t(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))_t(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Ec.has(r)||["data","payload","parts","messages"].includes(r))&&_t(s,t,n+1)}}function N(e,t,n,r,s,o=.95){let i=oe(r);return{version:1,id:w([e.projectId,n,s.type,s.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function L(e,t){let n=e.toLowerCase();for(let r of t){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return oe(e.slice(r.length+1))}return null}function Tc(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Oc(e){return oe(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Zr(e,t){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of t){let i=[];_t(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let m of a.split(/\r?\n/u)){let p=oe(m);if(!p){u=null;continue}let d=p.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let v=Number(d[1]);c={type:"phase",key:`phase:${v}`,order:v,title:oe(d[2]??"")},u=null;continue}let l=p.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let v=Number(l[1]);c={type:"task",key:`task:${v}`,order:v,title:oe(l[2]??"")},u=null;continue}let g=L(p,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(N(e,o,"mission",g,{type:"project"},.99)),u=null;continue}let S=L(p,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(N(e,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=L(p,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(N(e,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=L(p,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(N(e,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=L(p,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(N(e,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let I=L(p,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(I){s(N(e,o,"phase_deliverable",I,c,.97)),u=null;continue}let M=L(p,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(M){s(N(e,o,"acceptance_criterion",M,c,.98)),u="acceptance_criterion";continue}let C=L(p,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(C){s(N(e,o,"dependency",C,c,.97)),u="dependency";continue}let E=L(p,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(E){s(N(e,o,"open_question",E,c,.95)),u="open_question";continue}let x=L(p,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(N(e,o,"constraint",x,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(p)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(p)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(p)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(p)){u="constraint";continue}if(u&&Tc(m)){s(N(e,o,u,Oc(m),c,.96));continue}u=null}}}return n}function es(e){return String(e).padStart(12,"0")}var Ze=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${t.projectId}`,"work","semantic","observations",t.agent,t.nativeSessionId,`${es(r)}-${es(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
152
- `,"application/json"),a}};import{mkdirSync as Rc}from"node:fs";import{join as ts}from"node:path";function Nc(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function _c(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 B(e,t){return _c(t,e)?t:e}function G(e,t=30){let n=new Set,r=[];for(let s of e){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-t)}async function Kc(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function $c(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function ns(e,t){let r=(await Kc(e,t)).flatMap(S=>S.observations).sort((S,y)=>{let h=S.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===y.evidence.sessionKey?S.evidence.sequence-y.evidence.sequence:S.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,m=[],p=[],d=[];for(let S of r){let y=Nc(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??$c(S);switch(S.kind){case"phase_objective":h.objective=B(h.objective,y);break;case"phase_why":h.why=B(h.why,y);break;case"phase_deliverable":h.deliverable=B(h.deliverable,y);break;case"acceptance_criterion":h.acceptanceCriteria.push(y);break;case"dependency":h.dependencies.push(y);break;case"open_question":h.openQuestions.push(y);break;case"constraint":h.constraints.push(y);break;case"note":h.notes.push(y);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=B(s,y);break;case"objective":o=B(o,y);break;case"why":i=B(i,y);break;case"desired_outcome":a=B(a,y);break;case"plan_rationale":c=B(c,y);break;case"open_question":m.push(y);break;case"constraint":p.push(y);break;case"note":d.push(y);break}}for(let S of u.values())S.acceptanceCriteria=G(S.acceptanceCriteria,20),S.dependencies=G(S.dependencies,15),S.openQuestions=G(S.openQuestions,15),S.constraints=G(S.constraints,15),S.notes=G(S.notes,20);let l={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,y)=>S.order-y.order),openQuestions:G(m,20),constraints:G(p,20),notes:G(d,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=ts(e.rootPath,".toolnet","work");return Rc(g,{recursive:!0}),T(ts(g,"semantic-current.json"),l),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
153
- `,"application/json"),l}function qc(e,t){if(!Fc(e))return{events:[],nextOffset:t};let n=Dc(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=Lc(e,"r");try{zc(o,s,0,s.length,r)}finally{Wc(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
151
+ `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Ze=class{constructor(t){this.options=t;this.journal=new Xe(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 s=Ye(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Qe(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Hc,existsSync as Jc,openSync as Vc,readSync as Bc,statSync as Gc}from"node:fs";var Kc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ie(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function $t(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))$t(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Kc.has(r)||["data","payload","parts","messages"].includes(r))&&$t(s,t,n+1)}}function _(e,t,n,r,s,o=.95){let i=ie(r);return{version:1,id:w([e.projectId,n,s.type,s.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function D(e,t){let n=e.toLowerCase();for(let r of t){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return ie(e.slice(r.length+1))}return null}function $c(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Fc(e){return ie(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function ns(e,t){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of t){let i=[];$t(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let m of a.split(/\r?\n/u)){let p=ie(m);if(!p){u=null;continue}let d=p.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let v=Number(d[1]);c={type:"phase",key:`phase:${v}`,order:v,title:ie(d[2]??"")},u=null;continue}let l=p.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let v=Number(l[1]);c={type:"task",key:`task:${v}`,order:v,title:ie(l[2]??"")},u=null;continue}let g=D(p,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(_(e,o,"mission",g,{type:"project"},.99)),u=null;continue}let S=D(p,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(_(e,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=D(p,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(_(e,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=D(p,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(_(e,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=D(p,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(_(e,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let P=D(p,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(P){s(_(e,o,"phase_deliverable",P,c,.97)),u=null;continue}let E=D(p,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(E){s(_(e,o,"acceptance_criterion",E,c,.98)),u="acceptance_criterion";continue}let C=D(p,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(C){s(_(e,o,"dependency",C,c,.97)),u="dependency";continue}let T=D(p,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){s(_(e,o,"open_question",T,c,.95)),u="open_question";continue}let x=D(p,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(_(e,o,"constraint",x,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(p)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(p)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(p)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(p)){u="constraint";continue}if(u&&$c(m)){s(_(e,o,u,Fc(m),c,.96));continue}u=null}}}return n}function rs(e){return String(e).padStart(12,"0")}var et=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${t.projectId}`,"work","semantic","observations",t.agent,t.nativeSessionId,`${rs(r)}-${rs(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
152
+ `,"application/json"),a}};import{mkdirSync as Wc}from"node:fs";import{join as ss}from"node:path";function Lc(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function Dc(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 Dc(t,e)?t:e}function U(e,t=30){let n=new Set,r=[];for(let s of e){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-t)}async function zc(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function qc(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function os(e,t){let r=(await zc(e,t)).flatMap(S=>S.observations).sort((S,y)=>{let h=S.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===y.evidence.sessionKey?S.evidence.sequence-y.evidence.sequence:S.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,m=[],p=[],d=[];for(let S of r){let y=Lc(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??qc(S);switch(S.kind){case"phase_objective":h.objective=G(h.objective,y);break;case"phase_why":h.why=G(h.why,y);break;case"phase_deliverable":h.deliverable=G(h.deliverable,y);break;case"acceptance_criterion":h.acceptanceCriteria.push(y);break;case"dependency":h.dependencies.push(y);break;case"open_question":h.openQuestions.push(y);break;case"constraint":h.constraints.push(y);break;case"note":h.notes.push(y);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=G(s,y);break;case"objective":o=G(o,y);break;case"why":i=G(i,y);break;case"desired_outcome":a=G(a,y);break;case"plan_rationale":c=G(c,y);break;case"open_question":m.push(y);break;case"constraint":p.push(y);break;case"note":d.push(y);break}}for(let S of u.values())S.acceptanceCriteria=U(S.acceptanceCriteria,20),S.dependencies=U(S.dependencies,15),S.openQuestions=U(S.openQuestions,15),S.constraints=U(S.constraints,15),S.notes=U(S.notes,20);let l={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,y)=>S.order-y.order),openQuestions:U(m,20),constraints:U(p,20),notes:U(d,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=ss(e.rootPath,".toolnet","work");return Wc(g,{recursive:!0}),O(ss(g,"semantic-current.json"),l),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
153
+ `,"application/json"),l}function Uc(e,t){if(!Jc(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 s=Buffer.alloc(n-r),o=Vc(e,"r");try{Bc(o,s,0,s.length,r)}finally{Hc(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
154
154
  `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
155
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var et=class{constructor(t){this.options=t;this.journal=new Ze(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=qc(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Zr(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await ns(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as du,mkdirSync as pu}from"node:fs";import{join as $t}from"node:path";import{existsSync as os,mkdirSync as Hc,readFileSync as Vc,statSync as rs,writeFileSync as Jc}from"node:fs";import{dirname as Bc,join as Gc}from"node:path";var ss=64*1024,Uc=`# ToolNet Project Operating Manual
155
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var tt=class{constructor(t){this.options=t;this.journal=new et(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=Uc(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=ns(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await os(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as hu,mkdirSync as Su}from"node:fs";import{join as Wt}from"node:path";import{existsSync as cs,mkdirSync as Yc,readFileSync as Xc,statSync as is,writeFileSync as Qc}from"node:fs";import{dirname as Zc,join as eu}from"node:path";var as=64*1024,tu=`# ToolNet Project Operating Manual
156
156
 
157
157
  This file contains persistent instructions for AI agents working on this project.
158
158
 
@@ -195,14 +195,14 @@ Things an AI agent should always remember.
195
195
  <!--
196
196
  - [advisory] Prefer small focused files.
197
197
  -->
198
- `;function is(e){return Gc(e.rootPath,".toolnet","PROJECT.md")}function Yc(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Xc(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(e);){let o=s[1].toLowerCase(),i=Yc(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function Qc(e){let t=is(e);return os(t)||(Hc(Bc(t),{recursive:!0}),Jc(t,Uc,{encoding:"utf8",mode:384})),t}function as(e,t=!1){let n=t?Qc(e):is(e);if(!os(n))return null;if(rs(n).size>ss)throw new Error(`PROJECT.md exceeds ${ss} bytes`);let s=Vc(n,"utf8");return{path:n,content:s,digest:w(s),rules:Xc(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(rs(n).mtimeMs).toISOString()}}import{existsSync as Zc,mkdirSync as eu,readFileSync as tu,renameSync as nu,writeFileSync as ru}from"node:fs";import{dirname as su,join as ou}from"node:path";function iu(e,t){eu(su(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;ru(n,`${JSON.stringify(t,null,2)}
199
- `,{encoding:"utf8",mode:384}),nu(n,e)}function ms(e){return ou(e.rootPath,".toolnet","work","current.json")}function Kt(e){let t=ms(e);if(!Zc(t))return null;try{let n=JSON.parse(tu(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function tt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=tt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function au(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${tt(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function cu(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 cs(e,t){let n=t.status??e?.status??"pending",r=n;e?.status==="completed"&&n!=="completed"&&(r="completed"),e&&n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status);let s=e&&cu(t)?e.title:t.text;return{id:e?.id??t.id,title:s,status:r,order:t.order??e?.order,confidence:Math.max(e?.confidence??0,t.confidence),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}function us(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:tt(n.title);t.set(r,n)}return t}function ls(e){return e.order!==void 0?`order:${e.order}`:tt(e.key||e.text)}function ds(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:t.updatedAt.localeCompare(n.updatedAt)})}function ps(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function fs(e,t){let n=Kt(e),r=us(n?.phases??[]),s=us(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,m=[],p=[],d=[],l=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],I=[],M=[],C=[],E=[...t].sort((f,b)=>{let V=f.occurredAt.localeCompare(b.occurredAt);return V!==0?V:f.sequence-b.sequence});for(let f of E)switch(f.kind){case"request":o=f.text;break;case"activity":i=f.text;break;case"goal":a=f.text;break;case"plan":c=f.text;break;case"phase":{let b=ls(f);r.set(b,cs(r.get(b),f));break}case"task":{let b=ls(f);s.set(b,cs(s.get(b),f));break}case"decision":m.push(f.text);break;case"blocker":p.push(f.text);break;case"warning":d.push(f.text);break;case"next_action":l.push(f.text);break;case"file":{g.push(f.text);let b=f.fileAction??"active",V=S.indexOf(f.text);V>=0&&S.splice(V,1),b!=="deleted"&&S.push(f.text),b==="modified"?y.push(f.text):b==="created"?h.push(f.text):b==="deleted"&&k.push(f.text);break}case"command":I.push(f.text);break;case"test":M.push(f.text),f.checkKind&&C.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":u={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=ds(r.values()),v=ds(s.values()),D=ps(x),q=ps(v),at=_(n?.nextActions??[],[...l,...q?[q.title]:[],...!q&&D?[D.title]:[],...v.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),ct=_(n?.blockers??[],[...p,...x.filter(f=>f.status==="blocked").map(f=>f.title),...v.filter(f=>f.status==="blocked").map(f=>f.title)],20),ie=E.length>0?E[E.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ae={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:v,decisions:_(n?.decisions??[],m,20),blockers:ct,warnings:_(n?.warnings??[],d,20),nextActions:at,filesTouched:_(n?.filesTouched??[],g,30),activeFiles:_([],S,5),modifiedFiles:_(n?.modifiedFiles??[],y,30),createdFiles:_(n?.createdFiles??[],h,30),deletedFiles:_(n?.deletedFiles??[],k,30),commands:_(n?.commands??[],I,20),tests:_(n?.tests??[],M,20),checks:au(n?.checks??[],C,20),currentPhase:D,currentTask:q,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+v.filter(f=>f.status==="blocked").length},lastSession:u,updatedAt:ie};return iu(ms(e),ae),ae}function P(e,t){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function gs(e){if(e)return{id:e.id,title:e.title,status:e.status}}function uu(e,t=[]){let n=t.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=e.slice(-10).join(`
200
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function lu(e){return w(JSON.stringify(e))}function ys(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(k=>k.status==="completed").map(k=>k.title),i=r.tasks.filter(k=>k.status==="completed").map(k=>k.title),a=r.phases.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),c=r.tasks.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),u=new Set(r.tasks.filter(k=>k.status==="completed").map(k=>k.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),m=P(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),p=P([...c,...m],15),d=P(r.tests.slice().reverse(),10),l=P([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={schema:"toolnet.handoff.v2",version:2,project:{id:t.id,name:t.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:e.sequence,reason:e.reason},capturedAt:e.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:gs(r.currentPhase),task:gs(r.currentTask),file:s},completed:{phases:P(o,20),tasks:P(i,30)},remaining:{phases:P(a,20),tasks:P(c,30),todos:p},nextAction:m[0],blockers:P(r.blockers.slice().reverse(),10),decisions:P(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:P(r.activeFiles??[],10),modified:P(r.modifiedFiles??[],20),created:P(r.createdFiles??[],20),deleted:P(r.deletedFiles??[],20)},tests:{status:uu(r.tests,r.checks),recent:d,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},attention:P(e.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:lu(h)}}function mu(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 hs(e,t,n,r,s){if(!mu(n))return null;let o=as(e,!1),a=[...o?o.rules.filter(p=>p.mode==="enforce").map(p=>p.text):[],...n.warnings].slice(0,20),c=ys({project:e,identity:t,state:n,reason:r,sequence:s,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:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(p=>p.status!=="completed"&&p.status!=="cancelled"),incompleteTasks:n.tasks.filter(p=>p.status!=="completed"&&p.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 Ss(e,t){let n=$t(e.rootPath,".toolnet","work","handoffs");pu(n,{recursive:!0});let r=$t(n,`${t.id}.json`);du(r)||T(r,t),T($t(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function ks(e){let t=hs(e.project,e.identity,e.state,e.reason,e.sequence);return t?(Ss(e.project,t),t):null}var nt=class{constructor(t){this.options=t}options;async capture(t,n){let r=Kt(this.options.project);r||(r=await Qr(this.options.project,this.options.storage)),r||(r=await Xe(this.options.project,this.options.storage));let s=hs(this.options.project,this.options.identity,r,t,n);if(!s)return null;Ss(this.options.project,s);let o=`projects/${this.options.project.id}/work/handoffs/${s.id}.json`;return await this.options.storage.exists(o)||await this.options.storage.put(o,JSON.stringify(s,null,2)+`
198
+ `;function us(e){return eu(e.rootPath,".toolnet","PROJECT.md")}function nu(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function ru(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(e);){let o=s[1].toLowerCase(),i=nu(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function su(e){let t=us(e);return cs(t)||(Yc(Zc(t),{recursive:!0}),Qc(t,tu,{encoding:"utf8",mode:384})),t}function ls(e,t=!1){let n=t?su(e):us(e);if(!cs(n))return null;if(is(n).size>as)throw new Error(`PROJECT.md exceeds ${as} bytes`);let s=Xc(n,"utf8");return{path:n,content:s,digest:w(s),rules:ru(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(is(n).mtimeMs).toISOString()}}import{existsSync as ou,mkdirSync as iu,readFileSync as au,renameSync as cu,writeFileSync as uu}from"node:fs";import{dirname as lu,join as du}from"node:path";function pu(e,t){iu(lu(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;uu(n,`${JSON.stringify(t,null,2)}
199
+ `,{encoding:"utf8",mode:384}),cu(n,e)}function ys(e){return du(e.rootPath,".toolnet","work","current.json")}function Ft(e){let t=ys(e);if(!ou(t))return null;try{let n=JSON.parse(au(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function nt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function K(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=nt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function mu(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${nt(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function fu(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 ds(e,t){let n=t.status??e?.status??"pending",r=n;e?.status==="completed"&&n!=="completed"&&(r="completed"),e&&n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status);let s=e&&fu(t)?e.title:t.text;return{id:e?.id??t.id,title:s,status:r,order:t.order??e?.order,confidence:Math.max(e?.confidence??0,t.confidence),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}function ps(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:nt(n.title);t.set(r,n)}return t}function ms(e){return e.order!==void 0?`order:${e.order}`:nt(e.key||e.text)}function fs(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:t.updatedAt.localeCompare(n.updatedAt)})}function gs(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function hs(e,t){let n=Ft(e),r=ps(n?.phases??[]),s=ps(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,m=[],p=[],d=[],l=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],P=[],E=[],C=[],T=[...t].sort((f,b)=>{let V=f.occurredAt.localeCompare(b.occurredAt);return V!==0?V:f.sequence-b.sequence});for(let f of T)switch(f.kind){case"request":o=f.text;break;case"activity":i=f.text;break;case"goal":a=f.text;break;case"plan":c=f.text;break;case"phase":{let b=ms(f);r.set(b,ds(r.get(b),f));break}case"task":{let b=ms(f);s.set(b,ds(s.get(b),f));break}case"decision":m.push(f.text);break;case"blocker":p.push(f.text);break;case"warning":d.push(f.text);break;case"next_action":l.push(f.text);break;case"file":{g.push(f.text);let b=f.fileAction??"active",V=S.indexOf(f.text);V>=0&&S.splice(V,1),b!=="deleted"&&S.push(f.text),b==="modified"?y.push(f.text):b==="created"?h.push(f.text):b==="deleted"&&k.push(f.text);break}case"command":P.push(f.text);break;case"test":E.push(f.text),f.checkKind&&C.push({kind:f.checkKind,command:f.text,status:f.checkStatus??"unknown",updatedAt:f.occurredAt,agent:f.agent,nativeSessionId:f.nativeSessionId});break;case"session":u={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let x=fs(r.values()),v=fs(s.values()),q=gs(x),H=gs(v),ut=K(n?.nextActions??[],[...l,...H?[H.title]:[],...!H&&q?[q.title]:[],...v.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),lt=K(n?.blockers??[],[...p,...x.filter(f=>f.status==="blocked").map(f=>f.title),...v.filter(f=>f.status==="blocked").map(f=>f.title)],20),ae=T.length>0?T[T.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ce={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:v,decisions:K(n?.decisions??[],m,20),blockers:lt,warnings:K(n?.warnings??[],d,20),nextActions:ut,filesTouched:K(n?.filesTouched??[],g,30),activeFiles:K([],S,5),modifiedFiles:K(n?.modifiedFiles??[],y,30),createdFiles:K(n?.createdFiles??[],h,30),deletedFiles:K(n?.deletedFiles??[],k,30),commands:K(n?.commands??[],P,20),tests:K(n?.tests??[],E,20),checks:mu(n?.checks??[],C,20),currentPhase:q,currentTask:H,progress:{phasesTotal:x.length,phasesCompleted:x.filter(f=>f.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(f=>f.status==="completed").length,blocked:x.filter(f=>f.status==="blocked").length+v.filter(f=>f.status==="blocked").length},lastSession:u,updatedAt:ae};return pu(ys(e),ce),ce}function M(e,t){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function Ss(e){if(e)return{id:e.id,title:e.title,status:e.status}}function gu(e,t=[]){let n=t.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=e.slice(-10).join(`
200
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function yu(e){return w(JSON.stringify(e))}function ks(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(k=>k.status==="completed").map(k=>k.title),i=r.tasks.filter(k=>k.status==="completed").map(k=>k.title),a=r.phases.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),c=r.tasks.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),u=new Set(r.tasks.filter(k=>k.status==="completed").map(k=>k.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),m=M(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),p=M([...c,...m],15),d=M(r.tests.slice().reverse(),10),l=M([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={schema:"toolnet.handoff.v2",version:2,project:{id:t.id,name:t.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:e.sequence,reason:e.reason},capturedAt:e.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:Ss(r.currentPhase),task:Ss(r.currentTask),file:s},completed:{phases:M(o,20),tasks:M(i,30)},remaining:{phases:M(a,20),tasks:M(c,30),todos:p},nextAction:m[0],blockers:M(r.blockers.slice().reverse(),10),decisions:M(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:M(r.activeFiles??[],10),modified:M(r.modifiedFiles??[],20),created:M(r.createdFiles??[],20),deleted:M(r.deletedFiles??[],20)},tests:{status:gu(r.tests,r.checks),recent:d,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},attention:M(e.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:yu(h)}}function ku(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 ws(e,t,n,r,s){if(!ku(n))return null;let o=ls(e,!1),a=[...o?o.rules.filter(p=>p.mode==="enforce").map(p=>p.text):[],...n.warnings].slice(0,20),c=ks({project:e,identity:t,state:n,reason:r,sequence:s,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:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(p=>p.status!=="completed"&&p.status!=="cancelled"),incompleteTasks:n.tasks.filter(p=>p.status!=="completed"&&p.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 vs(e,t){let n=Wt(e.rootPath,".toolnet","work","handoffs");Su(n,{recursive:!0});let r=Wt(n,`${t.id}.json`);hu(r)||O(r,t),O(Wt(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function bs(e){let t=ws(e.project,e.identity,e.state,e.reason,e.sequence);return t?(vs(e.project,t),t):null}var rt=class{constructor(t){this.options=t}options;async capture(t,n){let r=Ft(this.options.project);r||(r=await ts(this.options.project,this.options.storage)),r||(r=await Qe(this.options.project,this.options.storage));let s=ws(this.options.project,this.options.identity,r,t,n);if(!s)return null;vs(this.options.project,s);let o=`projects/${this.options.project.id}/work/handoffs/${s.id}.json`;return await this.options.storage.exists(o)||await this.options.storage.put(o,JSON.stringify(s,null,2)+`
201
201
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
202
- `,"application/json"),s}};import{existsSync as fu,readFileSync as gu,writeFileSync as yu}from"node:fs";import{join as hu}from"node:path";var vs="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Wt="<!-- TOOLNET:STABLE-WORK:END -->";function Ft(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function z(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function ws(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${Ft(n)} ${n.title}`)]:[]}function Su(e){let t=[vs,"# 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:",`${Ft(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${Ft(e.currentTask)} ${e.currentTask.title}`),t.push(...ws("Phases",e.phases)),t.push(...ws("TODO / Tasks",e.tasks)),t.push(...z("Next actions",e.nextActions)),t.push(...z("Blockers",e.blockers)),t.push(...z("Important decisions",e.decisions)),t.push(...z("Active files",e.activeFiles??[])),t.push(...z("Modified files",e.modifiedFiles??[])),t.push(...z("Created files",e.createdFiles??[])),t.push(...z("Deleted files",e.deletedFiles??[])),t.push(...z("Files touched",e.filesTouched)),t.push(...z("Recent commands",e.commands??[])),t.push(...z("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.",Wt),t.join(`
203
- `)}function bs(e,t){let n=hu(e.rootPath,".toolnet","current.md"),r="";if(fu(n))try{r=gu(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=Su(t),o=r.indexOf(vs),i=r.indexOf(Wt),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+Wt.length).trimStart()].filter(Boolean).join(`
202
+ `,"application/json"),s}};import{existsSync as wu,readFileSync as vu,writeFileSync as bu}from"node:fs";import{join as xu}from"node:path";var js="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Lt="<!-- TOOLNET:STABLE-WORK:END -->";function Dt(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function z(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function xs(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${Dt(n)} ${n.title}`)]:[]}function ju(e){let t=[js,"# 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:",`${Dt(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${Dt(e.currentTask)} ${e.currentTask.title}`),t.push(...xs("Phases",e.phases)),t.push(...xs("TODO / Tasks",e.tasks)),t.push(...z("Next actions",e.nextActions)),t.push(...z("Blockers",e.blockers)),t.push(...z("Important decisions",e.decisions)),t.push(...z("Active files",e.activeFiles??[])),t.push(...z("Modified files",e.modifiedFiles??[])),t.push(...z("Created files",e.createdFiles??[])),t.push(...z("Deleted files",e.deletedFiles??[])),t.push(...z("Files touched",e.filesTouched)),t.push(...z("Recent commands",e.commands??[])),t.push(...z("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.",Lt),t.join(`
203
+ `)}function Is(e,t){let n=xu(e.rootPath,".toolnet","current.md"),r="";if(wu(n))try{r=vu(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=ju(t),o=r.indexOf(js),i=r.indexOf(Lt),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+Lt.length).trimStart()].filter(Boolean).join(`
204
204
 
205
205
  `):a=r.trim()?`${r.trim()}
206
206
 
207
- ${s}`:s,yu(n,`${a.trim()}
208
- `,{encoding:"utf8",mode:384})}import{existsSync as xs,mkdirSync as ku,readFileSync as wu}from"node:fs";import{join as Lt}from"node:path";function js(e){return Lt(e.rootPath,".toolnet","memory","checkpoints")}function As(e){return Lt(js(e),"latest.json")}function vu(e){let t=As(e);if(!xs(t))return null;try{let n=JSON.parse(wu(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function bu(e){return["rule","architecture","decision","fix"].includes(e)}function xu(e,t){return t.length===0?[]:Fe(e,t).candidates.filter(r=>bu(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 ju(e,t){let n=new Map;for(let r of[...e,...t]){let s=n.get(r.fingerprint);(!s||r.importanceScore>s.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,s)=>s.importanceScore-r.importanceScore||s.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Au(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 Cs(e,t,n,r){let s=vu(e),o=ju(s?.durableFacts??[],xu(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),m=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),p={work:Au(r),durableFacts:o.map(y=>y.fingerprint).sort()},d=w(JSON.stringify(p)).slice(0,32),l={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:m},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:d},g=js(e);ku(g,{recursive:!0,mode:448});let S=Lt(g,`${d}.json`);return xs(S)||T(S,l),T(As(e),l),l}function rt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ue(t,n);if(r.length===0)return{updated:!1,observations:0};let s=fs(e,r);bs(e,s),qn(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Cs(e,t,n,s)}catch{}try{ks({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var st=class{identity;wal;remote;sanitizer=new U;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=Ke(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new ne(this.identity,t.eventContext),this.remote=new $e(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new Be({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Qe({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new et({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new nt({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{rt(this.project,this.identity,t)}catch{}}start(t={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:t,provenance:{source:this.identity.agent}})}record(t){let n=this.wal.append([this.sanitizeEvent(t)]);return this.checkpointLocal(n),n[0]}recordMany(t){let n=this.wal.append(t.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(t,n){this.wal.setSourceCursor(t,n)}async flush(){let t=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,t.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(t.events.length>0){let s=t.events[t.events.length-1];this.wal.markRemote(s.sequence,t.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&t.events.length>0)try{let s=t.events[t.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(t={}){return this.record({type:"session_idle",data:t,provenance:{source:this.identity.agent}}),this.flush()}async end(t={}){return this.record({type:"session_end",data:t,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};var ot=4e3,zt=20,Dt=30,Is=4,qt=20;function Ht(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function it(e,t=0){if(t>=Is)return typeof e=="string"?e.length>ot?`${e.slice(0,ot)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:Ht(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>ot?`${e.slice(0,ot)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,zt).map(r=>it(r,t+1));return e.length>zt&&n.push(`[+${e.length-zt} items]`),n}if(Ht(e)){let n={},r=Object.entries(e);for(let[s,o]of r.slice(0,Dt))n[s]=it(o,t+1);return r.length>Dt&&(n.__truncatedKeys=r.length-Dt),n}return e}function Vt(e,t,n=0){if(!(n>Is||t.size>=qt)){if(Array.isArray(e)){for(let r of e)if(Vt(r,t,n+1),t.size>=qt)break;return}if(Ht(e))for(let[r,s]of Object.entries(e)){let o=r.toLowerCase().replace(/[^a-z]/g,"");if((o==="path"||o==="filepath"||o==="filename")&&typeof s=="string"&&s.trim()&&t.add(s.trim()),Vt(s,t,n+1),t.size>=qt)break}}}function je(e){try{return w(Ie(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function Cu(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function Iu(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function Jt(e,t){let r={timestamp:Cu(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let s=e.prompt?.trim();return s?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+je(s),data:{content:s}}]:[]}if(e.event==="PostToolUse"){let s=new Set;Vt(e.toolInput,s);let o=[...s],i=Iu(e.toolName,o);if(!i)return[];let a=it(e.toolInput),c=it(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",je({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:o},provenance:{source:`${e.agent}-hook`,files:o.length>0?o:void 0}}]}if(e.event==="AssistantMessage"){let s=e.assistantResponse?.trim();return s?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+je(s),data:{content:s}}]:[]}if(e.event==="Stop"){let s=[],o=e.assistantResponse?.trim();return o&&s.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+je(o),data:{content:o}}),s.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+je({sessionId:e.sessionId,response:o??""}),data:{sessionId:e.sessionId}}),s}return[]}function Eu(e){let t=ht(e);if(!t||!Pu(Mu(t,".toolnet","project.json")))return null;try{return new Ee().detect(t)}catch{return null}}function Tu(e,t){let n=Jt(t,e);if(n.length===0)return 0;let r=Ke(e,t.agent,t.sessionId),o=new ne(r,{source:t.agent,cwd:t.cwd}).append(n);return rt(e,r,o),o.length}async function Ou(e,t,n,r){let s=Pe(),o=Fn($n({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:2}),i=new Ne(o,e.id,e.name,e.remote??e.name);await new st({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function Ps(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=Eu(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=Tu(n,e)}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:o instanceof Error?o.message:String(o)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{Vn(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let s=t.flushSession??Ou;try{return await s(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:o instanceof Error?o.message:String(o)}}}function Ms(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ae(...e){for(let t of e){let n=Ms(t);if(n)return n}}function Ru(e){switch(Ms(e)){case"sessionStart":case"SessionStart":return"SessionStart";case"userPromptSubmitted":case"UserPromptSubmit":return"UserPromptSubmit";case"postToolUse":case"PostToolUse":return"PostToolUse";case"agentStop":case"Stop":return"Stop";default:return null}}function Es(e,t=process.env){let n=Ru(t.TOOLNET_HOOK_EVENT??e.hook_event_name??e.hookEventName);if(!n)return null;let r=Ae(e.session_id,e.sessionId),s=Ae(e.cwd,e.workspaceRoot);return!r||!s?null:{agent:"copilot",event:n,sessionId:r,cwd:s,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:Ae(e.prompt),toolName:Ae(e.tool_name,e.toolName),toolInput:e.tool_input??e.toolInput??e.toolArgs,toolResponse:e.tool_result??e.toolResult??e.tool_response,assistantResponse:Ae(e.response,e.last_assistant_message,e.assistant_response)}}async function Ts(e,t={},n=process.env){let r=Es(e,n);return r?Ps(r,t):{active:!1,captured:0,flushed:!1}}async function Nu(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function _u(){let e=await Nu(),t=An(e);if(t==="preToolUse"||t==="PreToolUse"){let n=Pn(e);n.blocked&&process.stdout.write(JSON.stringify(Mn(n.reason??"ToolNet continuity guard blocked this tool.")));return}if(t==="userPromptTransformed"||t==="UserPromptTransformed"){process.stdout.write(JSON.stringify(In(e)));return}await Ts(e),(t==="sessionStart"||t==="SessionStart")&&process.stdout.write(JSON.stringify(Cn(e)))}_u().catch(()=>{process.exitCode=0});
207
+ ${s}`:s,bu(n,`${a.trim()}
208
+ `,{encoding:"utf8",mode:384})}import{existsSync as As,mkdirSync as Iu,readFileSync as Au}from"node:fs";import{join as zt}from"node:path";function Cs(e){return zt(e.rootPath,".toolnet","memory","checkpoints")}function Ps(e){return zt(Cs(e),"latest.json")}function Cu(e){let t=Ps(e);if(!As(t))return null;try{let n=JSON.parse(Au(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Pu(e){return["rule","architecture","decision","fix"].includes(e)}function Mu(e,t){return t.length===0?[]:Le(e,t).candidates.filter(r=>Pu(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 Eu(e,t){let n=new Map;for(let r of[...e,...t]){let s=n.get(r.fingerprint);(!s||r.importanceScore>s.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,s)=>s.importanceScore-r.importanceScore||s.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Tu(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 Ms(e,t,n,r){let s=Cu(e),o=Eu(s?.durableFacts??[],Mu(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),m=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),p={work:Tu(r),durableFacts:o.map(y=>y.fingerprint).sort()},d=w(JSON.stringify(p)).slice(0,32),l={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:m},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:d},g=Cs(e);Iu(g,{recursive:!0,mode:448});let S=zt(g,`${d}.json`);return As(S)||O(S,l),O(Ps(e),l),l}function st(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ye(t,n);if(r.length===0)return{updated:!1,observations:0};let s=hs(e,r);Is(e,s),Vn(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Ms(e,t,n,s)}catch{}try{bs({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var ot=class{identity;wal;remote;sanitizer=new Y;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=$e(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new re(this.identity,t.eventContext),this.remote=new Fe(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new Ge({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Ze({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new tt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new rt({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{st(this.project,this.identity,t)}catch{}}start(t={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:t,provenance:{source:this.identity.agent}})}record(t){let n=this.wal.append([this.sanitizeEvent(t)]);return this.checkpointLocal(n),n[0]}recordMany(t){let n=this.wal.append(t.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(t,n){this.wal.setSourceCursor(t,n)}async flush(){let t=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,t.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(t.events.length>0){let s=t.events[t.events.length-1];this.wal.markRemote(s.sequence,t.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&t.events.length>0)try{let s=t.events[t.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(t={}){return this.record({type:"session_idle",data:t,provenance:{source:this.identity.agent}}),this.flush()}async end(t={}){return this.record({type:"session_end",data:t,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};var it=4e3,qt=20,Ht=30,Es=4,Jt=20;function Vt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function at(e,t=0){if(t>=Es)return typeof e=="string"?e.length>it?`${e.slice(0,it)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:Vt(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>it?`${e.slice(0,it)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,qt).map(r=>at(r,t+1));return e.length>qt&&n.push(`[+${e.length-qt} items]`),n}if(Vt(e)){let n={},r=Object.entries(e);for(let[s,o]of r.slice(0,Ht))n[s]=at(o,t+1);return r.length>Ht&&(n.__truncatedKeys=r.length-Ht),n}return e}function Bt(e,t,n=0){if(!(n>Es||t.size>=Jt)){if(Array.isArray(e)){for(let r of e)if(Bt(r,t,n+1),t.size>=Jt)break;return}if(Vt(e))for(let[r,s]of Object.entries(e)){let o=r.toLowerCase().replace(/[^a-z]/g,"");if((o==="path"||o==="filepath"||o==="filename")&&typeof s=="string"&&s.trim()&&t.add(s.trim()),Bt(s,t,n+1),t.size>=Jt)break}}}function Ie(e){try{return w(Pe(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function Ou(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function Ru(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function Gt(e,t){let r={timestamp:Ou(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let s=e.prompt?.trim();return s?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+Ie(s),data:{content:s}}]:[]}if(e.event==="PostToolUse"){let s=new Set;Bt(e.toolInput,s);let o=[...s],i=Ru(e.toolName,o);if(!i)return[];let a=at(e.toolInput),c=at(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",Ie({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:o},provenance:{source:`${e.agent}-hook`,files:o.length>0?o:void 0}}]}if(e.event==="AssistantMessage"){let s=e.assistantResponse?.trim();return s?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+Ie(s),data:{content:s}}]:[]}if(e.event==="Stop"){let s=[],o=e.assistantResponse?.trim();return o&&s.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+Ie(o),data:{content:o}}),s.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+Ie({sessionId:e.sessionId,response:o??""}),data:{sessionId:e.sessionId}}),s}return[]}function Ku(e){let t=kt(e);if(!t||!Nu(_u(t,".toolnet","project.json")))return null;try{return new Te().detect(t)}catch{return null}}function $u(e,t){let n=Gt(t,e);if(n.length===0)return 0;let r=$e(e,t.agent,t.sessionId),o=new re(r,{source:t.agent,cwd:t.cwd}).append(n);return st(e,r,o),o.length}async function Fu(e,t,n,r){let s=Me(),o=zn(Ln({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:2}),i=new _e(o,e.id,e.name,e.remote??e.name);await new ot({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function Ts(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=Ku(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=$u(n,e)}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:o instanceof Error?o.message:String(o)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{Gn(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let s=t.flushSession??Fu;try{return await s(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:o instanceof Error?o.message:String(o)}}}function Os(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ae(...e){for(let t of e){let n=Os(t);if(n)return n}}function Wu(e){switch(Os(e)){case"sessionStart":case"SessionStart":return"SessionStart";case"userPromptSubmitted":case"UserPromptSubmit":return"UserPromptSubmit";case"postToolUse":case"PostToolUse":return"PostToolUse";case"agentStop":case"Stop":return"Stop";default:return null}}function Rs(e,t=process.env){let n=Wu(t.TOOLNET_HOOK_EVENT??e.hook_event_name??e.hookEventName);if(!n)return null;let r=Ae(e.session_id,e.sessionId),s=Ae(e.cwd,e.workspaceRoot);return!r||!s?null:{agent:"copilot",event:n,sessionId:r,cwd:s,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:Ae(e.prompt),toolName:Ae(e.tool_name,e.toolName),toolInput:e.tool_input??e.toolInput??e.toolArgs,toolResponse:e.tool_result??e.toolResult??e.tool_response,assistantResponse:Ae(e.response,e.last_assistant_message,e.assistant_response)}}async function Ns(e,t={},n=process.env){let r=Rs(e,n);return r?Ts(r,t):{active:!1,captured:0,flushed:!1}}import{createHash as Lu}from"node:crypto";import{closeSync as Du,existsSync as zu,mkdirSync as qu,openSync as Hu,readFileSync as Ju,rmSync as Vu,statSync as _s,writeFileSync as Bu}from"node:fs";import{tmpdir as Gu}from"node:os";import{join as Ks}from"node:path";function A(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ut(e){if(Array.isArray(e))return e.map(Ut);if(e&&typeof e=="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map(n=>[n,Ut(t[n])]))}return e}function ct(e){return A(e.sessionId)??A(e.session_id)??A(e.conversation_id)??A(e.conversationId)??"unknown-session"}function Uu(e){return A(e.toolUseId)??A(e.tool_use_id)??A(e.toolCallId)??A(e.tool_call_id)??A(e.callId)??A(e.call_id)??A(e.generation_id)??A(e.generationId)}function Yu(e){return A(e.prompt)??A(e.userPrompt)??A(e.user_prompt)??A(e.originalPrompt)??A(e.original_prompt)}function Xu(e){let t=e.timestamp;return typeof t=="string"||typeof t=="number"?String(t):void 0}function Qu(e){let t=Uu(e.input),n=Yu(e.input),r=Xu(e.input),s=t?{agent:e.agent,event:e.event,session:ct(e.input),nativeId:t}:n?{agent:e.agent,event:e.event,session:ct(e.input),prompt:n,timestamp:r}:{agent:e.agent,event:e.event,session:ct(e.input),input:Ut(e.input)};return Lu("sha256").update(JSON.stringify(s)).digest("hex")}function Zu(e){return e.directory??Ks(Gu(),"toolnet-memory-hook-dedupe")}function el(e){try{let t=JSON.parse(Ju(e,"utf8"));return typeof t.createdAt=="number"?t.createdAt:_s(e).mtimeMs}catch{try{return _s(e).mtimeMs}catch{return}}}function tl(e,t,n){let r=el(e);return r===void 0||t-r>n}function $s(e){let t=e.ttlMs??1e4,n=e.nowMs??Date.now(),r=Zu(e),s=Qu(e),o=Ks(r,`${s}.json`);qu(r,{recursive:!0,mode:448});for(let i=0;i<2;i+=1)try{let a=Hu(o,"wx",384);try{Bu(a,JSON.stringify({createdAt:n,agent:e.agent,event:e.event,sessionId:ct(e.input)}),"utf8")}finally{Du(a)}return{duplicate:!1,key:s,file:o}}catch(a){if((a&&typeof a=="object"&&"code"in a?String(a.code):"")!=="EEXIST")throw a;if(i===0&&zu(o)&&tl(o,n,t)){Vu(o,{force:!0});continue}return{duplicate:!0,key:s,file:o}}return{duplicate:!0,key:s,file:o}}async function nl(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function rl(){let e=await nl(),t=Pn(e);if(t==="preToolUse"||t==="PreToolUse"){let n=Tn(e);n.blocked&&process.stdout.write(JSON.stringify(On(n.reason??"ToolNet continuity guard blocked this tool.")));return}if(!(t&&$s({agent:"copilot",event:t,input:e,directory:process.env.TOOLNET_HOOK_DEDUPE_DIR}).duplicate)){if(t==="userPromptTransformed"||t==="UserPromptTransformed"){process.stdout.write(JSON.stringify(En(e)));return}await Ns(e),(t==="sessionStart"||t==="SessionStart")&&process.stdout.write(JSON.stringify(Mn(e)))}}rl().catch(()=>{process.exitCode=0});