toolnet-memory 0.3.7 → 0.3.8

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.
@@ -0,0 +1,199 @@
1
+ import*as K from"fs";import*as O from"path";function ut(t){return t?Math.ceil(t.length/3.5):0}function lt(t,e){if(!t)return"";if(ut(t)<=e)return t;let r=Math.floor(e*3.5),s=t.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(t,e){if(!t)return"";let n=t.split(`
3
+ `).filter(o=>o.trim());if(n.length<=e)return t;let r=n.slice(0,e),s=n.length-e;return[...r,`... (${s} more items omitted)`].join(`
4
+ `)}function Is(t,e){let{maxTokens:n,trimMarker:r="[Context trimmed by ToolNet Memory token budget]"}=e;if(t.length===0)return"";let s=[...t].sort((c,u)=>u.priority-c.priority),o=[],i=0,a=!1;for(let c of s){let u=`# ${c.title}
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(`
7
+ ${r}
8
+ `),o.join(`
9
+
10
+ ---
11
+
12
+ `)}function Ut(t,e){let n=[{title:"Profile",content:Gt(t,10),priority:100},{title:"Current Work",content:Gt(e,15),priority:90}];return Is(n,{maxTokens:800})}import{createHash as Ms}from"node:crypto";import{chmodSync as Xt,existsSync as Es,mkdirSync as Ts,readFileSync as Os,renameSync as Rs,writeFileSync as Qt}from"node:fs";import{dirname as Zt,join as Ae}from"node:path";var mt="toolnet.context-offload.v1",Ns="toolnet.context-offload-asset.v1",_s=256,Ks=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function en(t){return Ae(t,".toolnet","offload")}function $s(t){return Ae(en(t),"assets")}function tn(t){return Ae(en(t),"graph.json")}function nn(t){Ts(t,{recursive:!0,mode:448});try{Xt(t,448)}catch{}}function Fs(t,e){nn(Zt(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;Qt(n,e,{encoding:"utf8",mode:384}),Rs(n,t);try{Xt(t,384)}catch{}}function pt(t){return Array.isArray(t)?t.map(pt):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,pt(n)])):t}function Ws(t){return Ms("sha256").update(JSON.stringify(pt(t)),"utf8").digest("hex")}function dt(){return{schema:mt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function rn(t){let e=tn(t);if(!Es(e))return dt();try{let n=JSON.parse(Os(e,"utf8"));return n.schema!==mt||n.version!==1||!Array.isArray(n.nodes)?dt():n}catch{return dt()}}function Ls(t,e){Fs(tn(t),JSON.stringify(e,null,2)+`
13
+ `)}function Ds(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function zs(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let s=Ds(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function qs(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Vs(t,e){nn(Zt(t));try{return Qt(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Bs(t,e){let n=t.nodes.find(s=>s.id===e.id),r=n?{...n,kind:e.kind,bytes:e.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...e.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...e.files])).slice(0,6)}:e;return{schema:mt,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(s=>s.id!==e.id),r].slice(-_s)}}function sn(t,e){let n=rn(t),r=0,s=0,o=0,i=[];for(let a of e){if(!Ks.has(a.type))continue;r+=1;let c=Ws({type:a.type,data:a.data}),u={schema:Ns,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
+ `;Vs(Ae($s(t),`${c}.json`),m)?s+=1:o+=1,i.push(c),n=Bs(n,{id:c,kind:a.type,bytes:Buffer.byteLength(m,"utf8"),createdAt:a.timestamp,sourceRefs:[qs(a)],files:zs(a)})}return r>0&&Ls(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function Yt(t,e){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,e-1).trimEnd()+"\u2026"}function on(t,e={}){let n=rn(t);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,e.maxAssets??6)),s=Math.max(320,Math.min(2400,e.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let a=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(`
15
+ `).length>s)break;o.push(u)}return o.join(`
16
+ `)}import{existsSync as cn,mkdirSync as Qs,readFileSync as un,renameSync as Zs,writeFileSync as eo}from"node:fs";import{dirname as to,join as ln}from"node:path";import{createHash as Js}from"node:crypto";import{dirname as Hs}from"node:path";import{mkdirSync as Gs,readFileSync as Us,renameSync as Ys,writeFileSync as Xs}from"node:fs";function w(t){return Js("sha256").update(t).digest("hex")}function ft(t){if(Array.isArray(t))return t.map(ft);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=ft(e[r]);return n}return t}function Ce(t){return JSON.stringify(ft(t))}function an(t){try{return JSON.parse(Us(t,"utf8"))}catch{return null}}function T(t,e){Gs(Hs(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;Xs(n,JSON.stringify(e,null,2)+`
17
+ `,{encoding:"utf8",mode:384}),Ys(n,t)}function dn(t){return ln(t.rootPath,".toolnet","context","handoff.md")}function pn(t){return ln(t.rootPath,".toolnet","context","handoff.json")}function mn(t,e){Qs(to(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;eo(n,e.endsWith(`
18
+ `)?e:`${e}
19
+ `,{encoding:"utf8",mode:384}),Zs(n,t)}function no(t,e){mn(t,`${JSON.stringify(e,null,2)}
20
+ `)}function fn(t,e){let n=e.replace(/\r\n/g,`
21
+ `).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return mn(dn(t),n),no(pn(t),r),r}function gt(t){let e=dn(t);if(!cn(e))return null;try{let n=un(e,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=pn(t);if(cn(s))try{let o=JSON.parse(un(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function gn(t,e=1800){let n=gt(t);if(!n?.text)return null;let r=n.text;return r.length>e&&(r=`${r.slice(0,e)}
22
+
23
+ [Fast handoff truncated]`),["[TOOLNET FAST HANDOFF]","",`Project: ${t.name}`,`Updated: ${n.generatedAt}`,"",r].join(`
24
+ `)}var yt="memory_agent_ask";function yn(){return`
25
+ [TOOLNET MEMORY AGENT]
26
+
27
+ Tool:
28
+ - ${yt}
29
+
30
+ For resume/continue requests:
31
+
32
+ 1. Use the injected ToolNet continuity handoff FIRST.
33
+ 2. If the handoff is missing or ambiguous, invoke
34
+ ${yt} directly BEFORE repository/history exploration.
35
+ 3. NEVER reconstruct prior work from:
36
+ - .toolnet/sessions/**
37
+ - state.json
38
+ - events.jsonl
39
+ - raw transcripts
40
+ 4. NEVER search for the implementation/schema of
41
+ ${yt}; invoke the MCP tool directly.
42
+ 5. Inspect git/source only AFTER continuity context is known.
43
+
44
+ Use:
45
+ - mode="local" for current task, last file, blocker or next action.
46
+ - mode="ai" for ambiguous or combined continuity questions.
47
+
48
+ Current repository evidence overrides stale memory.
49
+ `.trim()}function ht(t){let e=O.resolve(t),n=O.parse(e).root;for(;e!==n;){let r=O.join(e,".toolnet");if(K.existsSync(r)&&K.statSync(r).isDirectory())return e;e=O.dirname(e)}return null}function hn(t){try{return K.existsSync(t)?K.readFileSync(t,"utf-8").trim():null}catch{return null}}function Sn(t){return t.split(`
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(t={}){let e=t.projectPath||process.cwd(),n=ht(e);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]
52
+
53
+ Project: ${s}
54
+ Root: ${n}
55
+
56
+ `,m=Ut(a,c),p=gn({id:"",name:s,rootPath:n},1600),d=p?`
57
+
58
+ ${p}
59
+ `:"",l=on(n,{maxAssets:6,maxChars:900}),g=l?`
60
+
61
+ ${l}
62
+ `:"",h=`
63
+
64
+ ${yn()}
65
+
66
+ Forbidden At Startup:
67
+ - Do not run session:agy-recover, handoff:latest, or brief automatically.
68
+ - Do not perform deep recovery merely because an agent starts.
69
+ - If the user asks to resume previous work and fast context is insufficient,
70
+ use memory_agent_ask before guessing.
71
+ `;return u+m+d+g+h}var wn=6500,ro=[/\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,/\btiếp\s+tục\b/iu,/\blàm\s+tiếp\b/iu,/\blàm\s+nốt\b/iu,/\btiếp\s+phần\b/iu,/\bphần\s+đang\s+dở\b/iu,/\bđang\s+làm\s+(?:gì|đến\s+đâu)\b/iu,/\bdừng\s+(?:ở|tại)\s+đâu\b/iu,/\btask\s+(?:lúc\s+nãy|trước|đang\s+dở)\b/iu],so=[".toolnet/sessions/",".toolnet\\sessions\\","/.toolnet/sessions","\\.toolnet\\sessions",".gemini/antigravity-cli/brain/",".gemini\\antigravity-cli\\brain\\","/transcript.jsonl","\\transcript.jsonl"];function St(t){return typeof t=="string"&&t.trim()?t.trim():void 0}function vn(t){return t.replace(/\\/g,"/").toLowerCase()}function bn(t){return t.length<=wn?t:`${t.slice(0,wn)}
72
+
73
+ [ToolNet Kiro context truncated]`}function kt(t,e,n=0){if(!(n>6||e.length>=200)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t)if(kt(r,e,n+1),e.length>=200)break;return}if(t&&typeof t=="object"){for(let r of Object.values(t))if(kt(r,e,n+1),e.length>=200)break}}}function oo(t){let e=vn(t);return e.includes(".toolnet/sessions/")||e.endsWith(".toolnet/sessions")||e.includes(".gemini/antigravity-cli/brain/")||e.includes("/transcript.jsonl")||e.endsWith("transcript.jsonl")?!0:so.some(n=>e.includes(vn(n)))}function io(t){let e=t.trim();return e?ro.some(n=>n.test(e)):!1}function wt(t){if(!t.trim())return"";try{let e=kn({projectPath:t});return e?.trim()?bn(e.trim()):""}catch{return""}}function xn(t){let e=St(t.prompt)??St(process.env.USER_PROMPT)??"";if(!e||!io(e))return"";let n=St(t.cwd)??"",r=wt(n),s=`
74
+ [TOOLNET RESUME REQUEST]
75
+
76
+ The user is asking to continue previous project work.
77
+
78
+ Required order:
79
+ 1. Use the injected ToolNet fast continuity handoff first.
80
+ 2. If that handoff is missing, stale, or ambiguous, invoke the MCP tool
81
+ memory_agent_ask BEFORE repository/history exploration.
82
+ 3. Prefer mode="local" for current task, last file, blocker, completed work,
83
+ TODOs, and next action.
84
+ 4. Use mode="ai" only when continuity requires synthesis.
85
+ 5. Do NOT reconstruct prior work from .toolnet/sessions/**, state.json,
86
+ events.jsonl, raw transcripts, or another agent's internal history.
87
+ 6. After continuity is known, verify current git/source truth and continue
88
+ the work. Do not ask the user to repeat context ToolNet already provides.
89
+
90
+ Current repository evidence overrides stale memory.
91
+ `.trim();return r?bn(`${r}
92
+
93
+ ${s}`):s}function jn(t){let e=t.tool_input&&typeof t.tool_input=="object"?t.tool_input:{},n=[];return kt(e,n),n.find(oo)?{blocked:!0,reason:"ToolNet continuity guard: do not read or reconstruct previous work from raw ToolNet/agent session history. Use the injected continuity handoff first; if it is insufficient, invoke the MCP tool memory_agent_ask directly. Then inspect normal repository source/git evidence."}:{blocked:!1}}function An(t){return t==="PreToolUse"||t==="preToolUse"}function Cn(t){return t==="SessionStart"||t==="agentSpawn"}function Pn(t){return t==="UserPromptSubmit"||t==="userPromptSubmit"}import{existsSync as Cu}from"node:fs";import{join as Pu}from"node:path";import{existsSync as ao,readFileSync as co}from"node:fs";import{homedir as uo}from"node:os";import{join as lo}from"node:path";function po(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
94
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function mo(){let t=process.env.TOOLNET_GLOBAL_ENV??lo(uo(),".config","toolnet-memory",".env");if(!ao(t))return;let e=co(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=po(r.slice(s+1)))}}mo();function ce(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function ue(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}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 fo}from"node:crypto";import{existsSync as vt,mkdirSync as go,readFileSync as yo,renameSync as ho,writeFileSync as So}from"node:fs";import{basename as ko,dirname as Ie,join as Ee,parse as En,resolve as le}from"node:path";var Tn=".toolnet",wo="project.json";function vo(t){return fo("sha256").update(t).digest("hex").slice(0,16)}function bt(t){return Ee(t,Tn,wo)}function bo(t){return vt(bt(t))}function xo(t,e){let n=le(t),r=En(n).root;for(;;){if(bo(n))return n;if(n===r||e&&n===le(e))break;let s=Ie(n);if(s===n)break;n=s}return null}function jo(t){let e=le(t),n=En(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>vt(Ee(e,o))))return e;if(e===n)break;let s=Ie(e);if(s===e)break;e=s}return le(t)}function Ao(t){let e;try{e=JSON.parse(yo(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Ie(Ie(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function In(t,e){let n=Ee(t,Tn);go(n,{recursive:!0});let r=bt(t),s=`${r}.tmp-${process.pid}`;So(s,JSON.stringify(e,null,2)+`
95
+ `,{encoding:"utf8",mode:384}),ho(s,r)}function Mn(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var Me=class{detect(e=process.cwd()){let n=le(e),r=jo(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>vt(Ee(r,m))),i=xo(n,o?r:void 0);if(i){let m=bt(i),p=Ao(m);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),In(i,p)),Mn(p,i)}let a=new Date().toISOString(),c=ko(r),u={version:1,id:vo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return In(r,u),Mn(u,r)}};var Co=[{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}],Te=class{scan(e){let n=[];for(let r of Co){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var U=class{scanner=new Te;sanitize(e){let n=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.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 e}};import{homedir as Uo}from"node:os";import{join as Yo}from"node:path";import{DeleteObjectCommand as Po,GetObjectCommand as Io,HeadObjectCommand as Mo,ListObjectsV2Command as Eo,PutObjectCommand as To,S3Client as Oo}from"@aws-sdk/client-s3";import{getSignedUrl as Ro}from"@aws-sdk/s3-request-presigner";var Oe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Oo({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new To({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Ro(this.client,new Io({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Mo({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Po({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Eo({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as On,mkdir as No,readFile as _o,readdir as Ko,rm as $o,stat as Rn,writeFile as Fo}from"node:fs/promises";import{dirname as Wo,join as Lo,relative as Nn,resolve as Do}from"node:path";var de=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Do(this.root,n)}async put(e,n){let r=this.path(e);await No(Wo(r),{recursive:!0}),await Fo(r,n)}async get(e){try{return await _o(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await On(this.path(e)),!0}catch{return!1}}async delete(e){await $o(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await On(n)}catch{return r}let s=async i=>{let a=await Ko(i,{withFileTypes:!0});for(let c of a){let u=Lo(i,c.name);if(c.isDirectory()){await s(u);continue}let m=await Rn(u);r.push({key:Nn(this.root,u),size:m.size,updatedAt:m.mtime.toISOString()})}},o=await Rn(n);return o.isDirectory()?await s(n):r.push({key:Nn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as zo,GetObjectCommand as qo,HeadObjectCommand as Vo,ListObjectsV2Command as Bo,PutObjectCommand as Jo,S3Client as Ho}from"@aws-sdk/client-s3";import{getSignedUrl as Go}from"@aws-sdk/s3-request-presigner";var pe=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ho({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Jo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Go(this.client,new qo({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Vo({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new zo({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Bo({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function xt(t,e){return console.warn(e),new de(t)}function _n(t){let e=t.localRoot??Yo(Uo(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.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}):xt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new 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}):xt(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Oe({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):xt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(e)}function Xo(t){return new Promise(e=>setTimeout(e,t))}async function Kn(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Xo(c+u)}throw o}var Qo=new Set(["put","get","getText","delete","list"]);function $n(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Qo.has(r)?(...o)=>Kn(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Fn(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function Wn(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var Re=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Fn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
96
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Wn(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{existsSync as ci,readFileSync as ui}from"node:fs";import{join as li}from"node:path";import{existsSync as Zo,mkdirSync as ei,readFileSync as ti,renameSync as ni,writeFileSync as ri}from"node:fs";import{dirname as si,join as oi}from"node:path";function Ln(t){return oi(t.rootPath,".toolnet","context","session-origin.json")}function ii(t,e){ei(si(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;ri(n,`${JSON.stringify(e,null,2)}
97
+ `,{encoding:"utf8",mode:384}),ni(n,t)}function Ne(t,e){return[...t].filter(n=>n.kind===e).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function Dn(t,e){let n=Ne(e.observations,"file"),r=Ne(e.observations,"next_action"),s=Ne(e.observations,"blocker"),o=Ne(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentRequest:e.workState.currentRequest,currentActivity:e.workState.currentActivity,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??e.workState.activeFiles?.at(-1)??e.workState.filesTouched.at(-1),latestNextAction:r?.text??e.workState.nextActions.at(-1),latestBlocker:s?.text??e.workState.blockers.at(-1),latestDecision:o?.text??e.workState.decisions.at(-1)};return ii(Ln(t),i),i}function ai(t){let e=Ln(t);if(!Zo(e))return null;try{let n=JSON.parse(ti(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function zn(t){let e=ai(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentRequest&&n.push(`- Current request: ${e.currentRequest}`),e.currentActivity&&n.push(`- Current activity: ${e.currentActivity}`),e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
98
+ `)}function di(t){let e=li(t.rootPath,".toolnet","current.md");if(!ci(e))return null;try{return ui(e,"utf8").trim()}catch{return null}}function pi(t,e){let n=e.replace(/\r\n/g,`
99
+ `).trim(),r=2400,s=n.length>r?`${n.slice(0,r)}
100
+
101
+ [Current work truncated for fast handoff]`:n,o=zn(t);return["# ToolNet Fast Handoff","",`Project: ${t.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
102
+ `)}function qn(t){let e=di(t);if(e===null)return{updated:!1,reason:"missing-current",chars:0};if(!e.trim())return{updated:!1,reason:"empty-current",chars:0};let n=pi(t,e);return gt(t)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(fn(t,n),{updated:!0,reason:"updated",chars:n.length})}import{join as mi}from"node:path";function Vn(t,e){let n=t.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`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function _e(t,e,n){let r=e.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=Vn(r.toLowerCase(),"agent"),i=Vn(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:mi(t.rootPath,".toolnet","sessions",o,i)}}function Bn(t){return String(t).padStart(12,"0")}var Ke=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
103
+ `,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
104
+ `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let S=y[0],k=y[y.length-1],P=y.map(E=>JSON.stringify(E)).join(`
105
+ `)+`
106
+ `,M=w(P).slice(0,16),C=[e.remotePrefix,"events",`${Bn(S.sequence)}-${Bn(k.sequence)}-${M}.jsonl`].join("/");await this.storage.exists(C)||await this.storage.put(C,P,"application/x-ndjson"),c+=y.length}let u=await this.scan(e),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:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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 h={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:d};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:p}}};import{closeSync as At,existsSync as ki,fsyncSync as wi,mkdirSync as vi,openSync as Ct,readSync as bi,rmSync as Hn,statSync as Gn,writeSync as xi}from"node:fs";import{join as Pt}from"node:path";var fi=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),gi=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function yi(t){return t.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function hi(t){for(let e of["type","kind"]){let n=t[e];if(typeof n=="string"){let r=n.toLowerCase();if(gi.has(r))return n}}return null}function jt(t,e=0){if(e>12)return"[ToolNet nested value omitted]";if(Array.isArray(t))return t.map(o=>jt(o,e+1));if(!t||typeof t!="object")return t;let n=t,r=hi(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))fi.has(yi(o))||(s[o]=jt(i,e+1));return s}function Si(t){if(!t)return new Date().toISOString();let e=new Date(t);return Number.isNaN(e.getTime())?new Date().toISOString():e.toISOString()}function Y(t){return t?.trim()||void 0}function Jn(t,e={}){let n={...t.provenance??{}},r=Y(t.source)??Y(e.source)??Y(n.source);return{...t,timestamp:Si(t.timestamp),source:r,turnId:Y(t.turnId)??Y(e.turnId),cwd:Y(t.cwd)??Y(e.cwd),data:jt(t.data??{}),provenance:n}}var ji=12e4,Ai=80,Ci=2e3;function Pi(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var ne=class{constructor(e,n={}){this.identity=e;this.eventContext=n;vi(e.localDirectory,{recursive:!0}),this.eventsFile=Pt(e.localDirectory,"events.jsonl"),this.stateFile=Pt(e.localDirectory,"state.json"),this.lockFile=Pt(e.localDirectory,"journal.lock")}identity;eventContext;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return an(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){T(this.stateFile,e)}acquireLock(){for(let e=0;e<Ai;e+=1)try{return Ct(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Gn(this.lockFile).mtimeMs>ji){Hn(this.lockFile,{force:!0});continue}}catch{}Pi(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{At(n),Hn(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let p of e){let d=Jn(p,this.eventContext),l=d.timestamp??new Date().toISOString(),g=d.data??{},h=d.provenance?.rawDigest??w(Ce(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,h].join("|"),S=w(y).slice(0,32);if(r.has(S))continue;s+=1;let k={version:1,id:S,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:h}};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(S)}if(o.length===0)return[];let i=o.map(p=>JSON.stringify(p)).join(`
107
+ `)+`
108
+ `,a=Ct(this.eventsFile,"a",384);try{xi(a,i,null,"utf8"),wi(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(-Ci);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:m}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!ki(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=Gn(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=Ct(this.eventsFile,"r");try{bi(i,o,0,s,r)}finally{At(i)}return{events:o.toString("utf8").split(`
109
+ `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as Qa,existsSync as Za,openSync as ec,readSync as tc,statSync as nc}from"node:fs";function Un(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var Zn=[/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],Ii=[/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],Mi=[/\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],Ei=[/\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],Ti=[/đã 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],Yn=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],Oi=[/\bdùng\b/iu,/\btách\b/iu,/\bthay\b/iu,/\bchuyển\b/iu,/\blưu\b/iu,/\bmap\b/iu,/\buse\b/iu,/\bsplit\b/iu,/\bstore\b/iu,/\breplace\b/iu,/\bmove\b/iu],Ri=[/đườ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],Ni=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],Xn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),_i=new Set(["payload","data","content","message","messages","parts","summary"]);function R(t,e){return e.some(n=>n.test(t))}function er(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ki(t){return er(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function $i(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function It(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||Xn.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))It(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(Xn.has(s)||_i.has(s))&&It(o,s,n,r+1)}}function Fi(t){let e=[];It(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=er(o);if($i(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Qn(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Wi(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&R(t,Zn)?{kind:"rule",confidence:.98}:r&&R(t,Ii)?{kind:"rule",confidence:.92}:R(t,Mi)?{kind:R(t,Yn)?"architecture":"decision",confidence:r?.93:.86}:r&&R(t,Ei)?{kind:"todo",confidence:.87}:R(t,Yn)&&R(t,Oi)?{kind:"architecture",confidence:r?.88:.82}:s&&R(t,Ti)?{kind:"fix",confidence:.8}:r&&R(t,Ri)&&R(t,Ni)?{kind:"context",confidence:.79}:null}function Li(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Di(t,e,n){return t==="rule"&&R(n,Zn)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Un(e,n)}function tr(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=Qn(o);i&&a&&s.set(i,a)}for(let o of e){let i=Qn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Fi(o)){let u=Wi(c,i,o);if(!u||u.confidence<.75)continue;let m=Li(u.kind),p=Ki(c),d=w([t.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:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:m,content:c,confidence:u.confidence,importance:Di(u.kind,m,c),tags:[m],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as zi}from"node:crypto";var qi=["project-knowledge","implementation","continuation","session-context"],Vi={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Mt(t){return zi("sha256").update(t).digest("hex")}function $e(t,e){return`${t}:${Mt(e).slice(0,24)}`}function Bi(t){try{return Mt(JSON.stringify(t))}catch{return Mt(String(t))}}function X(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function rr(t,e=420){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:`${n.slice(0,Math.max(0,e-1)).trimEnd()}\u2026`}function Ji(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function nr(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function Hi(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,5).map(e=>rr(e.content)).join(" | ")}function Gi(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,6).map(e=>rr(e.content)).join(`
110
+ `)}function sr(t,e){let n=t.slice().sort((d,l)=>d.sequence-l.sequence||d.timestamp.localeCompare(l.timestamp)||d.id.localeCompare(l.id)),r=n.map(d=>({id:$e("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:Bi(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=e.map(d=>{let l=X([...d.provenance.eventIds.map(g=>s.get(g)),...d.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:$e("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=Ji(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,S)=>S.importanceScore-y.importanceScore||S.confidence-y.confidence||y.id.localeCompare(S.id)),h=g.map(y=>y.id);c.push({id:$e("scene",`${d}|${h.join("|")}`),level:"scene",kind:d,title:Vi[d],summary:Hi(g),factIds:h,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:nr(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(S=>u.get(S)).filter(S=>!!S).filter(S=>(S.knowledgeClass==="permanent"||S.knowledgeClass==="task")&&S.importanceScore>=.55);if(g.length===0)continue;let h=g.some(S=>S.knowledgeClass==="permanent")?"permanent":"task",y=Gi(g);m.push({id:$e("knowledge",`${d.id}|${h}|${g.map(S=>S.id).join("|")}`),level:"knowledge",knowledgeClass:h,title:d.title,content:y,sceneIds:[d.id],factIds:g.map(S=>S.id),importanceScore:Math.max(...g.map(S=>S.importanceScore)),confidence:nr(g.map(S=>S.confidence)),tags:X(["level:knowledge",`class:${h}`,`scene:${d.kind}`,...g.flatMap(S=>S.tags)]),sourcePaths:X(g.flatMap(S=>S.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 t=Pe(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function or(t){return(t||me()).durableMemoryMaxItemsPerSession}function ir(t){return(t||me()).sessionSummaryMaxTokens}var ar=new U;function cr(t){let e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))try{let r=JSON.parse(e);return JSON.stringify(ar.sanitizeValue(r))}catch{}let n=ar.sanitize(t).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 Ui(t,e){let n=t.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Yi(t,e){let n=[],r=new Set;for(let i of t){let a=i.split(`
111
+ `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let 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=Ui(u,p);if(d<.3)continue;let l=cr(u);n.push({category:p,text:l,importance:d,sourceSessionId:e})}}let s=me(),o=or(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function Xi(t){let e=me(),n=ir(e),o=t.join(`
112
+
113
+ `).split(`
114
+ `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>cr(i)).join(`
115
+ `);return lt(o,n)}function ur(t,e){let r=(Array.isArray(t)?t:t.split(`
116
+
117
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Yi(r,e),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:Xi(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:p,blockers:u,nextActions:m,durableFacts:s}}function B(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function Qi(t){let e=new Map;for(let n of t){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=e.get(r);(!s||n.sequence>s.sequence)&&e.set(r,n)}return[...e.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Zi(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function ea(t){let e=Zi(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function ta(t){return t.importance==="temporary"||t.confidence<.78?"transient":t.kind==="rule"||t.kind==="architecture"?"permanent":t.kind==="decision"||t.kind==="todo"||t.kind==="fix"?"task":"session"}function na(t){let e=t.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of e)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function ra(t){let e=ta(t),n=ea(t),r=na(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:B([...t.tags,"level:fact",`class:${e}`,`kind:${t.kind}`])}}function sa(t){return t.map(e=>{try{return JSON.stringify({type:e.type,role:e.role,data:e.data,provenance:{sourcePath:e.provenance.sourcePath,files:e.provenance.files}})}catch{return""}}).filter(Boolean)}function oa(t,e,n){let r=ur(sa(e),t.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=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 Fe(t,e){let n=Qi(e),r=tr(t,n).map(ra),s=r.filter(m=>m.knowledgeClass!=="transient").sort((m,p)=>p.importanceScore-m.importanceScore),{summary:o,state:i}=oa(t,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=sr(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:e.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as ma}from"node:crypto";import{existsSync as fa,readdirSync as ga,readFileSync as ya}from"node:fs";import{basename as ha,join as Cr}from"node:path";import{randomUUID as pr}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function fe(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function Z(t){let e=t.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new j("Invalid Wiki slug",400);return e}function lr(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(Z(r))}return fe(e)}function ia(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function dr(t){return{id:`revision-${pr()}`,pageId:t.id,slug:t.slug,revision:t.revision,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...t.tags],links:[...t.links],createdAt:t.updatedAt}}function Q(t){return structuredClone(t)}var We=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let e=await this.ensureState(),n=new Set(e.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:fe(e.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:e.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:e.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:e.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return Q([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=Z(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new j(`Wiki page not found: ${e}`,404);return Q(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new j("Wiki title is required",400);let o=Z(e.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-${pr()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:fe(e.tags??[]),links:lr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(dr(a)),Q(a)})}async updatePage(e,n){return this.mutate(r=>{let s=Z(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new j(`Wiki page not found: ${e}`,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=lr(o.content)),n.tags!==void 0&&(o.tags=fe(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(dr(o)),Q(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return Q(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(e){let n=await this.getPage(e),r=await this.ensureState();return Q(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(e,n=10){let r=await this.ensureState(),s=fe(ia(e));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),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(h=>h===g)?l+=5:d.some(h=>h.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 mr="wiki/state.v1.json";function aa(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function ca(t,e){let n=JSON.parse(t);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==e.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var Le=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(mr);if(!e){let n=aa(this.project);return await this.save(n),n}return ca(e,this.project)}async save(e){await this.storage.put(mr,JSON.stringify(e,null,2),"application/json")}};import{createHash as ua,randomUUID as fr}from"node:crypto";var gr="wiki/governance.v1.json",kr="toolnet.knowledge-governance.v1",yr=500,ge={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function la(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function Et(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function hr(t){return ua("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function da(t){let e=[t.title,t.summary??"",t.content.slice(0,2e3),...t.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function pa(t){let e=t.sourceType==="skill"?.96:t.sourceType==="memory"?.94:.88,n=t.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(e+=.03),t.content.length>=200&&(e+=.02),t.content.length<80&&(e-=.05),t.title.length<4&&(e-=.05),la(e)}function Sr(t){let e=new Date().toISOString();return{schema:kr,version:1,projectId:t,policy:{...ge},reviews:[],audit:[],createdAt:e,updatedAt:e}}function wr(t){let e=t.autoApproveThreshold??ge.autoApproveThreshold,n=t.criticalApproveThreshold??ge.criticalApproveThreshold,r=t.staleAfterDays??ge.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>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:e,criticalApproveThreshold:n,staleAfterDays:r}}var De=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(gr);if(!e){let n=Sr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==kr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:wr(n.policy??ge)}}catch{let n=Sr(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(gr,JSON.stringify(e,null,2),"application/json")}},ze=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,n,r,s={}){e.audit.push({id:fr(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),e.audit.length>yr&&(e.audit=e.audit.slice(-yr))}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,n){return this.mutate(r=>(r.policy=wr({...r.policy,...e}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let e=await this.ensureState(),n=r=>e.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!e||r.status===e).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(e=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(n.audit.slice(-r).reverse())}async assess(e,n){let r=await this.ensureState(),s=pa(e),o=Et(e.title),i=n.filter(m=>m.slug!==e.slug&&Et(m.title)===o&&hr(m.content)!==hr(e.content)).map(m=>m.slug),a=da(e),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,n){let r=await this.assess(e,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:fr(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(e,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===e&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:e}))})}async decide(e,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===e);if(!o)throw new j(`Governance review not found: ${e}`,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:e,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new 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:e,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new 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:e,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(e){let n=await this.ensureState(),r=await e.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(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=Et(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 Pr="wiki/automation.v1.json",Ir="toolnet.wiki-automation.v1",Rt=8e3,vr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function he(t){return ma("sha256").update(JSON.stringify(t)).digest("hex")}function ye(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function br(t){return Array.isArray(t)?t:[]}function Mr(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function Tt(t){return Array.isArray(t)?t.map(Mr).filter(e=>!!e):[]}function $(t,e){for(let n of e){let r=Mr(t[n]);if(r)return r}}function Se(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function qe(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(vr.has(r))return[];if(typeof t=="string"){let i=t.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(t))return t.flatMap(i=>qe(i,e+1,n));let s=ye(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();vr.has(c)||o.push(...qe(a,e+1,i))}return o}function xr(t){let n=Se(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>qe(t[s],0,s)));return(n.length>0?n:Se(qe(t))).join(`
118
+
119
+ `).slice(0,Rt)}function jr(t,e){return $(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function Ar(t,e){return $(t,["title","name","topic","label","task","kind","type"])??e}function Sa(t){return($(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function ka(t){return($(t,["kind","sceneKind","type"])??"").toLowerCase()}function wa(t){let e=ye(t);if(!e)return[];let n=[],r=br(e.knowledge);for(let[o,i]of r.entries()){let a=ye(i);if(!a)continue;let c=Sa(a);if(c==="session"||c==="transient")continue;let u=xr(a);if(u.length<20)continue;let m=jr(a,he(a).slice(0,16)),p=Ar(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${m}`,sourceType:"memory",title:p,summary:$(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","memory",...c?[c]:[]])})}let s=br(e.scenes);for(let[o,i]of s.entries()){let a=ye(i);if(!a)continue;let c=ka(a);if(c==="session-context")continue;let u=xr(a);if(u.length<20)continue;let m=jr(a,he(a).slice(0,16)),p=Ar(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${m}`,sourceType:"scene",title:p,summary:$(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","scene",...c?[c]:[]])})}return n}function va(t){return Cr(t,".toolnet","memory","skills")}function ba(t){let e=va(t);if(!fa(e))return{candidates:[],failed:0};let n=[],r=0,s=ga(e).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(ya(Cr(e,o),"utf8")),a=ye(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??ha(o,".json"),u=$(a,["task"])??"",m=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,p=$(a,["summary"])??void 0,d=Tt(a.steps),l=Tt(a.verification),g=Tt(a.files),h=[];u&&h.push(`## Task
120
+ ${u}`),p&&h.push(`## Summary
121
+ ${p}`),d.length>0&&h.push(`## Procedure
122
+ ${d.map((S,k)=>`${k+1}. ${S}`).join(`
123
+ `)}`),l.length>0&&h.push(`## Verification
124
+ ${l.map(S=>`- ${S}`).join(`
125
+ `)}`),g.length>0&&h.push(`## Relevant Files
126
+ ${g.map(S=>`- \`${S}\``).join(`
127
+ `)}`);let y=h.join(`
128
+
129
+ `).slice(0,Rt);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 Ot(t){let e=new Date().toISOString();return{schema:Ir,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function xa(t,e){let n=await t.getText(Pr);if(!n)return Ot(e);try{let r=JSON.parse(n);return r.schema!==Ir||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?Ot(e):r}catch{return Ot(e)}}async function ja(t,e){await t.put(Pr,JSON.stringify(e,null,2),"application/json")}function Aa(t){return`toolnet-auto-${he(t).slice(0,12)}`}function Ca(t){let e=Z(t.title).slice(0,72),n=he(t.sourceKey).slice(0,10);return Z(`auto-${t.sourceType}-${e}-${n}`)}function Pa(t){return[`> Auto-generated by ToolNet Knowledge Automation from ${t.sourceType==="skill"?"reusable Skill Memory":t.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",t.content].join(`
130
+ `).slice(0,Rt)}function Ia(t){return he({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function Ma(t,e){return t.tags.includes(e)}async function Er(t){let e=wa(t.hierarchy),n=ba(t.project.rootPath),r=new Map;for(let l of[...e,...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:e.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new We(new Le(t.storage,t.project));await i.initialize();let a=new ze(new De(t.storage,t.project));await a.initialize();let c=await xa(t.storage,t.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=Aa(l.sourceKey),h=Ia(l),y=p.get(l.sourceKey),S=y?.slug??Ca(l),k=m.get(S);if(k&&!Ma(k,g)){o.skipped+=1;continue}let P=Se([...l.tags,g]),M=Pa(l),C=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S,marker:g,digest:h,title:l.title,...l.summary?{summary:l.summary}:{},content:M,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!==h?(k=await i.updatePage(S,{title:l.title,summary:l.summary??"",content:M,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:S,action:"unchanged"})):(k=await i.createPage({slug:S,title:l.title,summary:l.summary,content:M,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 E=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S,digest:h,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,h)}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 ja(t.storage,c),o}import{createHash as Ea}from"node:crypto";import{chmodSync as Or,existsSync as Ta,mkdirSync as Oa,readFileSync as Up,readdirSync as Yp,renameSync as Ra,statSync as Xp,writeFileSync as Na}from"node:fs";import{join as Rr}from"node:path";var _a="toolnet.skill-memory.v1",Tr=5,Ka=16,$a=24,Fa=32;function Wa(t){return Ea("sha256").update(t).digest("hex")}function we(t,e=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function Nt(t,e=360){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function La(t){return t.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function q(t,e=360){return t&&Nt(La(t),e)||void 0}function ve(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function Nr(t,e){for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function _r(t,e){for(let n of e){let r=t[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function Kr(t){let e=t.data??{};if(_r(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Nr(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=ve(e,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ke(t){let e=t.data??{};if(Kr(t))return!1;if(_r(e,["passed","pass","success","succeeded","ok"])===!0||Nr(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=ve(e,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:t.type==="commit"||t.type==="deploy"}function $r(t){let e=t.data??{},n=ve(e,["path","file","filePath","filename","target"]);if(n)return q(n,260);let r=t.provenance?.files;return q(r?.[0],260)}function _t(t){return q(ve(t.data??{},["command","cmd","script"]),420)}function re(t){return q(ve(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Da(t){let e=[];for(let n of[...t].sort((r,s)=>r.sequence-s.sequence))if(ke(n)){if(n.type==="test"){let r=re(n)??_t(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=re(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=re(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return we(e,10)}function za(t,e){let n=[];for(let r of[...t].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=$r(r);s&&n.push(`Update ${s}`);break}case"command":{if(Kr(r))break;let s=_t(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ke(r))break;let s=re(r)??_t(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 e.files.slice(0,8)){let s=q(r,260);s&&n.push(`Update ${s}`)}return we(n,Ka)}function qa(t,e){let n=[...e.files];for(let r of t){let s=$r(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=q(o,260);i&&n.push(i)}}return we(n,$a)}function Va(t){return we(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),Fa)}function Ba(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Fr(t,e,n){if(e.length===0)return[];let r=Da(e),s=we(n.completed.map(g=>q(g,280)??""),Tr);if(!(s.length>0||e.some(g=>["test","commit","deploy"].includes(g.type)&&ke(g))))return[];let i=q(n.task,280)??q(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=za(e,n);if(c.length===0)return[];let u=qa(e,n),m=Va(e),p=Math.min(...e.map(g=>g.sequence)),d=Math.max(...e.map(g=>g.sequence)),l=Ba(e);return a.slice(0,Tr).map(g=>{let h=[`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:t.projectId,task:g,steps:c,verification:r,files:u}),S=Wa(y);return{schema:_a,version:1,id:`skill-${S.slice(0,24)}`,fingerprint:S,projectId:t.projectId,title:Nt(`SOP: ${g}`,180),task:g,summary:Nt(h.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:p,lastSequence:d,eventIds:m},createdAt:l}})}function Ja(t){return Rr(t.rootPath,".toolnet","memory","skills")}function Ha(t){let e=Ja(t);return Oa(e,{recursive:!0,mode:448}),Or(e,448),e}function Wr(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=Ha(t),r=0,s=0,o=[];for(let i of e){if(i.projectId!==t.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${t.id}`);let a=Rr(n,`${i.id}.json`);if(o.push(a),Ta(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Na(c,JSON.stringify(i,null,2)+`
131
+ `,{encoding:"utf8",mode:384}),Ra(c,a),Or(a,384),r+=1}return{written:r,deduped:s,files:o}}function Lr(t){return String(t).padStart(12,"0")}function Ga(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Ve=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(m=>m.sequence)),o=Math.max(...n.map(m=>m.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
132
+ `,c=w(r.map(m=>m.fingerprint).sort().join("|")).slice(0,16),u=[Ga(e),"batches",`${Lr(s)}-${Lr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as Ua}from"node:crypto";function Dr(t){return String(t).padStart(12,"0")}function Ya(t){return Ua("sha256").update(t).digest("hex")}function Xa(t){return t.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Be=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=Ya([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[Xa(e),"batches",`${Dr(s)}-${Dr(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
133
+ `,"application/json"),c}};function rc(t,e){if(!Za(t))return{events:[],nextOffset:e};let n=nc(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=ec(t,"r");try{tc(i,o,0,s,r)}finally{Qa(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
134
+ `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
135
+ `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Je=class{constructor(e){this.options=e;this.journal=new Ve(e.storage),this.hierarchyJournal=new Be(e.storage)}options;journal;hierarchyJournal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=rc(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=Fr(this.options.identity,s.events,o.state),m=Wr(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 Er({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 vc,existsSync as bc,openSync as xc,readSync as jc,statSync as Ac}from"node:fs";function zr(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function xe(t){return t.toLowerCase().replace(/[^a-z0-9]/gu,"")}function be(t,e,n=0){if(n>8)return;if(Array.isArray(t)){for(let s of t.slice(0,50))be(s,e,n+1);return}let r=zr(t);if(r)for(let[s,o]of Object.entries(r))e(s,o,r),be(o,e,n+1)}function se(t,e){let n=[];return be(t,(r,s)=>{e.has(xe(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function sc(t){let e=t.trim();if(!e.startsWith("{"))return null;try{return zr(JSON.parse(e))}catch{return null}}function oc(t){let e=t.data;for(let r of["tool","toolName","tool_name"]){let s=e[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return be(e,(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 ic(t){let e=se(t.data,new Set(["command","cmd","script"])),n=se(t.data,new Set(["arguments","args"]));for(let r of n){let s=sc(r);if(s)for(let o of se(s,new Set(["command","cmd","script"])))e.push(o)}return Array.from(new Set(e.map(r=>r.trim()).filter(Boolean)))}function ac(t){let e=se(t.data,new Set(["filepath","file_path","filename","file","path","target"].map(xe)));return Array.from(new Set(e.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
136
+ `))))}function cc(t,e){return t.type==="file_edit"||t.type==="file_write"?"modified":/\b(delete|remove|unlink)\b/iu.test(e)?"deleted":/\b(create|add[_-]?file|new[_-]?file)\b/iu.test(e)?"created":/\b(edit|write|patch|apply[_-]?patch|replace|update[_-]?file)\b/iu.test(e)?"modified":null}function uc(t){let e=se(t.data,new Set(["patch","diff","arguments","input"].map(xe))),n=[];for(let r of e){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 lc(t){let e=t.toLowerCase();return/\b(typecheck|type-check)\b/u.test(e)||/\btsc\b[\s\S]*--noemit\b/u.test(e)?"typecheck":/\b(eslint|lint)\b/u.test(e)?"lint":/\b(vitest|jest|pytest)\b/u.test(e)||/\bgo\s+test\b/u.test(e)||/\bcargo\s+test\b/u.test(e)||/\b(npm|pnpm|yarn)\s+(run\s+)?test\b/u.test(e)?"test":/\b(npm|pnpm|yarn)\s+(run\s+)?build\b/u.test(e)||/\bcargo\s+build\b/u.test(e)||/\bgo\s+build\b/u.test(e)||/\btsc\b/u.test(e)?"build":null}function dc(t){let e=null;return be(t,(n,r)=>{if(e===null&&["exitcode","code"].includes(xe(n))){if(typeof r=="number"&&Number.isFinite(r)){e=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(e=s)}}}),e}function pc(t){return se(t,new Set(["status","state","result","output","outputsummary","message","text"]))}function mc(t){let e=dc(t.data);if(e!==null)return e===0?"passed":"failed";let n=pc(t.data).join(`
137
+ `).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 fc(t){let e=[],n=new Set;for(let r of t){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),e.push(r))}return e}function qr(t){let e=[],n=oc(t),r=cc(t,n);if(r)for(let s of ac(t))e.push({kind:"file",text:s,fileAction:r,confidence:t.type==="file_edit"||t.type==="file_write"?1:.96});e.push(...uc(t));for(let s of ic(t)){e.push({kind:"command",text:s,confidence:.98});let o=lc(s);o&&e.push({kind:"test",text:s,checkKind:o,checkStatus:mc(t),confidence:.98})}return fc(e)}var gc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function te(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Br(t){return te(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function ee(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))ee(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(gc.has(r)||["data","payload","parts","messages"].includes(r))&&ee(s,e,n+1)}}function He(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function Vr(t){let e=te(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function A(t,e,n,r,s={}){let o=te(r),i=s.key??Br(o);return{version:1,id:w([t.projectId,n,i,e.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:t.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:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function yc(t,e,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(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(A(t,e,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let d=Number(u[1]),l=te(u[2]??""),g=l&&!Vr(l)?`Phase ${d} - ${l}`:`Phase ${d}`;s.push(A(t,e,"phase",g,{key:`phase:${d}`,order:d,status:He(r),confidence:.93}))}let m=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);m?.[2]&&s.push(A(t,e,"task",m[2],{status:m[1].trim()?"completed":He(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=Vr(l);s.push(A(t,e,"task",g&&d!==void 0?`TODO ${d}`:l,{key:d!==void 0?`task:${d}`:Br(l),order:d,status:He(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(t,e,"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(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(A(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(A(t,e,"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(t,e,"activity",r,{confidence:.86})),s}function Ge(t,e){if(e.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of e){if(i.type==="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(t,i,"request",u,{confidence:.96}))}for(let c of qr(i))s(A(t,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(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];ee(i.data,c);for(let u of c)s(A(t,i,"task",u,{status:He(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(t,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];ee(i.data,c);for(let u of c)s(A(t,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 yc(t,i,u))s(m)}let o=e[e.length-1];return s(A(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Jr(t){return String(t).padStart(12,"0")}var Ue=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
138
+ `,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Jr(r)}-${Jr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Hr}from"node:path";import{mkdirSync as hc}from"node:fs";function Ur(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function F(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=Ur(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function Sc(t,e=20){let n=new Map;for(let r of t){let s=`${r.kind}|${Ur(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-e)}function kc(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Gr(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&kc(e)?t.title:e.text;return{id:t?.id??w(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function wc(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Ye(t,e){let r=(await wc(t,e)).flatMap(f=>f.observations).sort((f,b)=>{let V=f.occurredAt.localeCompare(b.occurredAt);if(V!==0)return V;let Ht=f.sequence-b.sequence;return Ht!==0?Ht:f.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,m,p=[],d=[],l=[],g=[],h=[],y=new Map,S=[],k=[],P=[],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,Gr(s.get(f.key),f));break;case"task":o.set(f.key,Gr(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":{h.push(f.text);let b=f.fileAction??"active";y.delete(f.text),y.set(f.text,b),b==="modified"?S.push(f.text):b==="created"?k.push(f.text):b==="deleted"&&P.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"),z=v.find(f=>f.status==="in_progress")??v.find(f=>f.status==="blocked")??v.find(f=>f.status==="pending"),at=F([...g,...z?[z.title]:[],...!z&&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:t.id,projectName:t.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(h,30),activeFiles:Array.from(y.entries()).filter(([,f])=>f!=="deleted").map(([f])=>f).slice(-5),modifiedFiles:F(S,30),createdFiles:F(k,30),deletedFiles:F(P,30),commands:F(M,20),tests:F(C,20),checks:Sc(E,20),currentPhase:D,currentTask:z,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=Hr(t.rootPath,".toolnet","work");return hc(ae,{recursive:!0}),T(Hr(ae,"current.json"),ie),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(ie,null,2)+`
139
+ `,"application/json"),ie}async function Yr(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Cc(t,e){if(!bc(t))return{events:[],nextOffset:e};let n=Ac(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=xc(t,"r");try{jc(i,o,0,s,r)}finally{vc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
140
+ `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
141
+ `).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Xe=class{constructor(e){this.options=e;this.journal=new Ue(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=Cc(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=Ge(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ye(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 _c,existsSync as Kc,openSync as $c,readSync as Fc,statSync as Wc}from"node:fs";var Pc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function oe(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Kt(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))Kt(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Pc.has(r)||["data","payload","parts","messages"].includes(r))&&Kt(s,e,n+1)}}function N(t,e,n,r,s,o=.95){let i=oe(r);return{version:1,id:w([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function W(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return oe(t.slice(r.length+1))}return null}function Ic(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Mc(t){return oe(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Xr(t,e){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of e){let i=[];Kt(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=W(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(t,o,"mission",g,{type:"project"},.99)),u=null;continue}let h=W(p,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(N(t,o,c.type==="phase"?"phase_objective":"objective",h,c,.98)),u=null;continue}let y=W(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(t,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let S=W(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(S){s(N(t,o,"desired_outcome",S,{type:"project"},.98)),u=null;continue}let k=W(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(t,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let P=W(p,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(P){s(N(t,o,"phase_deliverable",P,c,.97)),u=null;continue}let M=W(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(t,o,"acceptance_criterion",M,c,.98)),u="acceptance_criterion";continue}let C=W(p,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(C){s(N(t,o,"dependency",C,c,.97)),u="dependency";continue}let E=W(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(t,o,"open_question",E,c,.95)),u="open_question";continue}let x=W(p,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(N(t,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&&Ic(m)){s(N(t,o,u,Mc(m),c,.96));continue}u=null}}}return n}function Qr(t){return String(t).padStart(12,"0")}var Qe=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${Qr(r)}-${Qr(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
142
+ `,"application/json"),a}};import{mkdirSync as Ec}from"node:fs";import{join as Zr}from"node:path";function Tc(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Oc(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function J(t,e){return Oc(e,t)?e:t}function H(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function Rc(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await e.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function Nc(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function es(t,e){let r=(await Rc(t,e)).flatMap(h=>h.observations).sort((h,y)=>{let S=h.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===y.evidence.sessionKey?h.evidence.sequence-y.evidence.sequence:h.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,m=[],p=[],d=[];for(let h of r){let y=Tc(h);if(h.scope==="phase"&&h.scopeKey){let S=u.get(h.scopeKey)??Nc(h);switch(h.kind){case"phase_objective":S.objective=J(S.objective,y);break;case"phase_why":S.why=J(S.why,y);break;case"phase_deliverable":S.deliverable=J(S.deliverable,y);break;case"acceptance_criterion":S.acceptanceCriteria.push(y);break;case"dependency":S.dependencies.push(y);break;case"open_question":S.openQuestions.push(y);break;case"constraint":S.constraints.push(y);break;case"note":S.notes.push(y);break}u.set(S.key,S);continue}switch(h.kind){case"mission":s=J(s,y);break;case"objective":o=J(o,y);break;case"why":i=J(i,y);break;case"desired_outcome":a=J(a,y);break;case"plan_rationale":c=J(c,y);break;case"open_question":m.push(y);break;case"constraint":p.push(y);break;case"note":d.push(y);break}}for(let h of u.values())h.acceptanceCriteria=H(h.acceptanceCriteria,20),h.dependencies=H(h.dependencies,15),h.openQuestions=H(h.openQuestions,15),h.constraints=H(h.constraints,15),h.notes=H(h.notes,20);let l={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((h,y)=>h.order-y.order),openQuestions:H(m,20),constraints:H(p,20),notes:H(d,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=Zr(t.rootPath,".toolnet","work");return Ec(g,{recursive:!0}),T(Zr(g,"semantic-current.json"),l),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
143
+ `,"application/json"),l}function Lc(t,e){if(!Kc(t))return{events:[],nextOffset:e};let n=Wc(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=$c(t,"r");try{Fc(o,s,0,s.length,r)}finally{_c(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
144
+ `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
145
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Ze=class{constructor(e){this.options=e;this.journal=new Qe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Lc(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=Xr(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await es(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 cu,mkdirSync as uu}from"node:fs";import{join as Ft}from"node:path";import{existsSync as rs,mkdirSync as Dc,readFileSync as zc,statSync as ts,writeFileSync as qc}from"node:fs";import{dirname as Vc,join as Bc}from"node:path";var ns=64*1024,Jc=`# ToolNet Project Operating Manual
146
+
147
+ This file contains persistent instructions for AI agents working on this project.
148
+
149
+ ## Critical Rules
150
+
151
+ <!--
152
+ Examples:
153
+
154
+ - [enforce] Never edit production files directly.
155
+ - [enforce] Edit source only in /path/to/source.
156
+ - [enforce] Deploy only with ./deploy.sh --apply
157
+ -->
158
+
159
+ ## Workflow
160
+
161
+ <!--
162
+ Describe the correct working process.
163
+ -->
164
+
165
+ ## Architecture
166
+
167
+ <!--
168
+ Important architecture conventions.
169
+ -->
170
+
171
+ ## Verification
172
+
173
+ <!--
174
+ Tests / QA required after changes.
175
+ -->
176
+
177
+ ## Known Gotchas
178
+
179
+ <!--
180
+ Things an AI agent should always remember.
181
+ -->
182
+
183
+ ## Preferences
184
+
185
+ <!--
186
+ - [advisory] Prefer small focused files.
187
+ -->
188
+ `;function ss(t){return Bc(t.rootPath,".toolnet","PROJECT.md")}function Hc(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Gc(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=Hc(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Uc(t){let e=ss(t);return rs(e)||(Dc(Vc(e),{recursive:!0}),qc(e,Jc,{encoding:"utf8",mode:384})),e}function os(t,e=!1){let n=e?Uc(t):ss(t);if(!rs(n))return null;if(ts(n).size>ns)throw new Error(`PROJECT.md exceeds ${ns} bytes`);let s=zc(n,"utf8");return{path:n,content:s,digest:w(s),rules:Gc(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(ts(n).mtimeMs).toISOString()}}import{existsSync as Yc,mkdirSync as Xc,readFileSync as Qc,renameSync as Zc,writeFileSync as eu}from"node:fs";import{dirname as tu,join as nu}from"node:path";function ru(t,e){Xc(tu(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;eu(n,`${JSON.stringify(e,null,2)}
189
+ `,{encoding:"utf8",mode:384}),Zc(n,t)}function ds(t){return nu(t.rootPath,".toolnet","work","current.json")}function $t(t){let e=ds(t);if(!Yc(e))return null;try{let n=JSON.parse(Qc(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function et(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(t,e,n){let r=[],s=new Set;for(let o of[...t,...e].reverse()){let i=et(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function su(t,e,n=20){let r=new Map;for(let s of[...t,...e]){let o=`${s.kind}|${et(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function ou(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function is(t,e){let n=e.status??t?.status??"pending",r=n;t?.status==="completed"&&n!=="completed"&&(r="completed"),t&&n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status);let s=t&&ou(e)?t.title:e.text;return{id:t?.id??e.id,title:s,status:r,order:e.order??t?.order,confidence:Math.max(t?.confidence??0,e.confidence),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}function as(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:et(n.title);e.set(r,n)}return e}function cs(t){return t.order!==void 0?`order:${t.order}`:et(t.key||t.text)}function us(t){return Array.from(t).sort((e,n)=>{let r=e.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:e.updatedAt.localeCompare(n.updatedAt)})}function ls(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function ps(t,e){let n=$t(t),r=as(n?.phases??[]),s=as(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,m=[],p=[],d=[],l=[],g=[],h=[...n?.activeFiles??[]],y=[],S=[],k=[],P=[],M=[],C=[],E=[...e].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=cs(f);r.set(b,is(r.get(b),f));break}case"task":{let b=cs(f);s.set(b,is(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=h.indexOf(f.text);V>=0&&h.splice(V,1),b!=="deleted"&&h.push(f.text),b==="modified"?y.push(f.text):b==="created"?S.push(f.text):b==="deleted"&&k.push(f.text);break}case"command":P.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=us(r.values()),v=us(s.values()),D=ls(x),z=ls(v),at=_(n?.nextActions??[],[...l,...z?[z.title]:[],...!z&&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:t.id,projectName:t.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:_([],h,5),modifiedFiles:_(n?.modifiedFiles??[],y,30),createdFiles:_(n?.createdFiles??[],S,30),deletedFiles:_(n?.deletedFiles??[],k,30),commands:_(n?.commands??[],P,20),tests:_(n?.tests??[],M,20),checks:su(n?.checks??[],C,20),currentPhase:D,currentTask:z,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 ru(ds(t),ae),ae}function I(t,e){let n=new Set,r=[];for(let s of t){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=e))break}return r}function ms(t){if(t)return{id:t.id,title:t.title,status:t.status}}function iu(t,e=[]){let n=e.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=t.slice(-10).join(`
190
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function au(t){return w(JSON.stringify(t))}function fs(t){let{project:e,identity:n,state:r}=t,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=I(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),p=I([...c,...m],15),d=I(r.tests.slice().reverse(),10),l=I([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={schema:"toolnet.handoff.v2",version:2,project:{id:e.id,name:e.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:t.sequence,reason:t.reason},capturedAt:t.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:ms(r.currentPhase),task:ms(r.currentTask),file:s},completed:{phases:I(o,20),tasks:I(i,30)},remaining:{phases:I(a,20),tasks:I(c,30),todos:p},nextAction:m[0],blockers:I(r.blockers.slice().reverse(),10),decisions:I(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:I(r.activeFiles??[],10),modified:I(r.modifiedFiles??[],20),created:I(r.createdFiles??[],20),deleted:I(r.deletedFiles??[],20)},tests:{status:iu(r.tests,r.checks),recent:d,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},attention:I(t.attention??[],20),progress:r.progress},{capturedAt:h,source:y,...S}=g;return{...g,stateDigest:au(S)}}function lu(t){return!!(t.currentRequest||t.currentActivity||t.goal||t.plan||t.phases.length>0||t.tasks.length>0||t.nextActions.length>0||t.blockers.length>0||t.decisions.length>0||t.filesTouched.length>0)}function gs(t,e,n,r,s){if(!lu(n))return null;let o=os(t,!1),a=[...o?o.rules.filter(p=>p.mode==="enforce").map(p=>p.text):[],...n.warnings].slice(0,20),c=fs({project:t,identity:e,state:n,reason:r,sequence:s,attention:a}),u=c.stateDigest;return{version:1,id:w([t.id,e.sessionKey,u].join("|")).slice(0,24),projectId:t.id,projectName:t.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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 ys(t,e){let n=Ft(t.rootPath,".toolnet","work","handoffs");uu(n,{recursive:!0});let r=Ft(n,`${e.id}.json`);cu(r)||T(r,e),T(Ft(t.rootPath,".toolnet","work","handoff-latest.json"),e)}function hs(t){let e=gs(t.project,t.identity,t.state,t.reason,t.sequence);return e?(ys(t.project,e),e):null}var tt=class{constructor(e){this.options=e}options;async capture(e,n){let r=$t(this.options.project);r||(r=await Yr(this.options.project,this.options.storage)),r||(r=await Ye(this.options.project,this.options.storage));let s=gs(this.options.project,this.options.identity,r,e,n);if(!s)return null;ys(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)+`
191
+ `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
192
+ `,"application/json"),s}};import{existsSync as du,readFileSync as pu,writeFileSync as mu}from"node:fs";import{join as fu}from"node:path";var ks="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Wt="<!-- TOOLNET:STABLE-WORK:END -->";function Lt(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function L(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function Ss(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${Lt(n)} ${n.title}`)]:[]}function gu(t){let e=[ks,"# ToolNet Stable Work State","",`Updated: ${t.updatedAt}`];return t.lastSession&&e.push(`Last agent: ${t.lastSession.agent}`,`Last session: ${t.lastSession.nativeSessionId}`),t.currentRequest&&e.push("","Current request:",t.currentRequest),t.currentActivity&&e.push("","Current activity:",t.currentActivity),t.goal&&e.push("","Goal:",t.goal),t.plan&&e.push("","Plan:",t.plan),t.currentPhase&&e.push("","Current phase:",`${Lt(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${Lt(t.currentTask)} ${t.currentTask.title}`),e.push(...Ss("Phases",t.phases)),e.push(...Ss("TODO / Tasks",t.tasks)),e.push(...L("Next actions",t.nextActions)),e.push(...L("Blockers",t.blockers)),e.push(...L("Important decisions",t.decisions)),e.push(...L("Active files",t.activeFiles??[])),e.push(...L("Modified files",t.modifiedFiles??[])),e.push(...L("Created files",t.createdFiles??[])),e.push(...L("Deleted files",t.deletedFiles??[])),e.push(...L("Files touched",t.filesTouched)),e.push(...L("Recent commands",t.commands??[])),e.push(...L("Checks",(t.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),e.push("","Progress:",`- Phases: ${t.progress.phasesCompleted}/${t.progress.phasesTotal}`,`- Tasks: ${t.progress.tasksCompleted}/${t.progress.tasksTotal}`,`- Blocked: ${t.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),e.join(`
193
+ `)}function ws(t,e){let n=fu(t.rootPath,".toolnet","current.md"),r="";if(du(n))try{r=pu(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=gu(e),o=r.indexOf(ks),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(`
194
+
195
+ `):a=r.trim()?`${r.trim()}
196
+
197
+ ${s}`:s,mu(n,`${a.trim()}
198
+ `,{encoding:"utf8",mode:384})}import{existsSync as vs,mkdirSync as yu,readFileSync as hu}from"node:fs";import{join as Dt}from"node:path";function bs(t){return Dt(t.rootPath,".toolnet","memory","checkpoints")}function xs(t){return Dt(bs(t),"latest.json")}function Su(t){let e=xs(t);if(!vs(e))return null;try{let n=JSON.parse(hu(e,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==t.id?null:n}catch{return null}}function ku(t){return["rule","architecture","decision","fix"].includes(t)}function wu(t,e){return e.length===0?[]:Fe(t,e).candidates.filter(r=>ku(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:t.agent,nativeSessionId:t.nativeSessionId}))}function vu(t,e){let n=new Map;for(let r of[...t,...e]){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 bu(t){return{request:t.currentRequest,activity:t.currentActivity,goal:t.goal,phase:t.currentPhase?{title:t.currentPhase.title,status:t.currentPhase.status}:void 0,task:t.currentTask?{title:t.currentTask.title,status:t.currentTask.status}:void 0,phases:t.phases.map(e=>({title:e.title,status:e.status})),tasks:t.tasks.map(e=>({title:e.title,status:e.status})),activeFiles:t.activeFiles??[],modifiedFiles:t.modifiedFiles??[],createdFiles:t.createdFiles??[],deletedFiles:t.deletedFiles??[],checks:t.checks??[],blockers:t.blockers,decisions:t.decisions,nextActions:t.nextActions}}function js(t,e,n,r){let s=Su(t),o=vu(s?.durableFacts??[],wu(e,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:bu(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:t.id,name:t.name},source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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=bs(t);yu(g,{recursive:!0,mode:448});let h=Dt(g,`${d}.json`);return vs(h)||T(h,l),T(xs(t),l),l}function nt(t,e,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ge(e,n);if(r.length===0)return{updated:!1,observations:0};let s=ps(t,r);ws(t,s),Dn(t,{agent:e.agent,nativeSessionId:e.nativeSessionId,observations:r,workState:s});try{js(t,e,n,s)}catch{}try{hs({project:t,identity:e,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var rt=class{identity;wal;remote;sanitizer=new U;learner;continuity;semantic;handoff;project;title;metadata;constructor(e){this.project=e.project,this.identity=_e(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new ne(this.identity,e.eventContext),this.remote=new Ke(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new Je({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new Xe({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Ze({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new tt({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}checkpointLocal(e){if(e.length!==0)try{nt(this.project,this.identity,e)}catch{}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){let n=this.wal.append([this.sanitizeEvent(e)]);return this.checkpointLocal(n),n[0]}recordMany(e){let n=this.wal.append(e.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};var st=4e3,zt=20,qt=30,As=4,Vt=20;function je(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function G(t){return typeof t=="string"&&t.trim()?t.trim():void 0}function ot(t,e=0){if(e>=As)return typeof t=="string"?t.length>st?`${t.slice(0,st)}\u2026`:t:Array.isArray(t)?`[array:${t.length}]`:je(t)?`[object:${Object.keys(t).length}]`:t;if(typeof t=="string")return t.length>st?`${t.slice(0,st)}\u2026`:t;if(Array.isArray(t)){let n=t.slice(0,zt).map(r=>ot(r,e+1));return t.length>zt&&n.push(`[+${t.length-zt} items]`),n}if(je(t)){let n={},r=Object.entries(t);for(let[s,o]of r.slice(0,qt))n[s]=ot(o,e+1);return r.length>qt&&(n.__truncatedKeys=r.length-qt),n}return t}function Jt(t,e,n=0){if(!(n>As||e.size>=Vt)){if(Array.isArray(t)){for(let r of t)if(Jt(r,e,n+1),e.size>=Vt)break;return}if(je(t))for(let[r,s]of Object.entries(t)){let o=r.toLowerCase().replace(/[^a-z]/g,"");if((o==="path"||o==="filepath"||o==="filename")&&typeof s=="string"&&s.trim()&&e.add(s.trim()),Jt(s,e,n+1),e.size>=Vt)break}}}function xu(t){let e=G(t);if(e)switch(e){case"agentSpawn":case"SessionStart":return"SessionStart";case"userPromptSubmit":case"UserPromptSubmit":return"UserPromptSubmit";case"postToolUse":case"PostToolUse":return"PostToolUse";case"preToolUse":case"PreToolUse":return"PreToolUse";case"stop":case"Stop":return"Stop";default:return e}}function Bt(t){try{return w(Ce(t)).slice(0,20)}catch{return w(String(t)).slice(0,20)}}function ju(t){let e=G(t.timestamp);if(e){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Au(t,e){let n=(t??"").toLowerCase();return n==="read"||n==="fs_read"||n.includes("read_file")||n.includes("list_dir")||n.includes("grep")||n.includes("search")?null:e.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":e.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function Cs(t,e){let n=xu(t.hook_event_name);if(!n)return[];let r=G(t.session_id)??"kiro",s=G(t.cwd)??e.rootPath,i={timestamp:ju(t),cwd:s,source:"kiro",provenance:{source:"kiro-hook"}};if(n==="SessionStart")return[{...i,type:"session_start",sourceEventId:`kiro:${r}:start`,data:{sessionId:r,cwd:s}}];if(n==="UserPromptSubmit"){let a=G(t.prompt)??G(process.env.USER_PROMPT)??"";return a?[{...i,type:"user_prompt",role:"user",sourceEventId:`kiro:${r}:prompt:${Bt(a)}`,data:{content:a}}]:[]}if(n==="PostToolUse"){let a=G(t.tool_name),c=je(t.tool_input)?t.tool_input:{},u=je(t.tool_response)?t.tool_response:{},m=new Set;Jt(c,m);let p=[...m],d=Au(a,p);if(!d)return[];let l=ot(c),g=ot(u),h=["kiro",r,"tool",Bt({toolName:a,input:l,response:g})].join(":");return[{...i,type:d,sourceEventId:h,data:{tool:a,input:l,response:g,files:p},provenance:{source:"kiro-hook",files:p.length>0?p:void 0}}]}if(n==="Stop"){let a=G(t.assistant_response),c=Bt({assistantResponse:a??"",sessionId:r}),u=[];return a&&u.push({...i,type:"assistant_message",role:"assistant",sourceEventId:`kiro:${r}:assistant:${c}`,data:{content:a}}),u.push({...i,type:"session_idle",sourceEventId:`kiro:${r}:idle:${c}`,data:{sessionId:r}}),u}return[]}function it(t){return typeof t=="string"&&t.trim()?t.trim():void 0}function Iu(t){switch(it(t)){case"agentSpawn":return"SessionStart";case"userPromptSubmit":return"UserPromptSubmit";case"postToolUse":return"PostToolUse";case"stop":return"Stop";default:return it(t)??""}}function Mu(t){let e=ht(t);if(!e||!Cu(Pu(e,".toolnet","project.json")))return null;try{return new Me().detect(e)}catch{return null}}function Eu(t,e,n,r){let s=Cs(r,t);if(s.length===0)return 0;let o=_e(t,"kiro",e),a=new ne(o,{source:"kiro",cwd:n}).append(s);return nt(t,o,a),a.length}async function Tu(t,e,n){let r=Pe(),s=$n(_n({provider:r.storage.provider,huggingface:r.storage.huggingface,localRoot:r.storage.localRoot}),{attempts:2}),o=new Re(s,t.id,t.name,t.remote??t.name);await new rt({project:t,storage:o,agent:"kiro",nativeSessionId:e,metadata:{source:"kiro-hook"},eventContext:{source:"kiro",cwd:n}}).flush()}async function Ps(t,e={}){let n=it(t.cwd),r=it(t.session_id);if(!n||!r)return{active:!1,captured:0,flushed:!1};let s=Mu(n);if(!s)return{active:!1,captured:0,flushed:!1};let o=0;try{o=Eu(s,r,n,t)}catch(c){return{active:!0,projectRoot:s.rootPath,sessionId:r,captured:0,flushed:!1,error:c instanceof Error?c.message:String(c)}}let i=Iu(t.hook_event_name);if(i==="PostToolUse"||i==="Stop")try{qn(s)}catch{}if(i!=="Stop")return{active:!0,projectRoot:s.rootPath,sessionId:r,captured:o,flushed:!1};let a=e.flushSession??Tu;try{return await a(s,r,n),{active:!0,projectRoot:s.rootPath,sessionId:r,captured:o,flushed:!0}}catch(c){return{active:!0,projectRoot:s.rootPath,sessionId:r,captured:o,flushed:!1,error:c instanceof Error?c.message:String(c)}}}async function Ou(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}async function Ru(){let t=await Ou(),e=t.hook_event_name;if(An(e)){let n=jn(t);if(n.blocked){process.stderr.write(`${n.reason??"ToolNet continuity guard blocked this tool."}
199
+ `),process.exitCode=2;return}return}if(await Ps(t),Cn(e)){let n=typeof t.cwd=="string"?t.cwd:"",r=wt(n);r&&process.stdout.write(r);return}if(Pn(e)){let n=xn(t);n&&process.stdout.write(n)}}Ru().catch(()=>{process.exitCode=0});
package/bundle/kiro.js ADDED
@@ -0,0 +1,3 @@
1
+ import{existsSync as P,mkdirSync as A,readFileSync as H,renameSync as R,rmSync as T,writeFileSync as _}from"node:fs";import{dirname as D}from"node:path";import{homedir as $}from"node:os";import{join as m}from"node:path";function S(o={}){return o.kiroHome??process.env.KIRO_HOME??m(o.home??$(),".kiro")}function N(o={}){return m(S(o),"settings")}function h(o={}){return m(N(o),"mcp.json")}function M(o={}){return m(S(o),"hooks")}function y(o={}){return m(M(o),"toolnet-memory.json")}var u="ToolNet Memory - ";function v(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function G(o){return/^[A-Za-z0-9_./:-]+$/u.test(o)?o:`'${o.replace(/'/gu,"'\\''")}'`}function O(o){if(!P(o))return{};let r=H(o,"utf8").trim();if(!r)return{};let n;try{n=JSON.parse(r)}catch(t){throw new Error(`Invalid existing Kiro hooks file: ${t instanceof Error?t.message:String(t)}`)}if(!v(n))throw new Error("Invalid existing Kiro hooks file: root must be a JSON object.");return n}function w(o){return v(o)?typeof o.name=="string"&&o.name.startsWith(u):!1}function d(o){return{type:"command",command:o}}function U(o){return[{name:`${u}Session Start`,description:"Inject compact local ToolNet continuity and capture Kiro session activation.",trigger:"SessionStart",action:d(o),timeout:10,enabled:!0},{name:`${u}Prompt Continuity`,description:"Capture prompts and refresh ToolNet guidance only for resume/continue requests.",trigger:"UserPromptSubmit",action:d(o),timeout:10,enabled:!0},{name:`${u}Raw History Guard`,description:"Prevent Kiro from reconstructing continuity from raw ToolNet/agent session history.",trigger:"PreToolUse",matcher:"*",action:d(o),timeout:10,enabled:!0},{name:`${u}Tool Capture`,description:"Capture durable tool activity while filtering noisy read-only events.",trigger:"PostToolUse",matcher:"*",action:d(o),timeout:15,enabled:!0},{name:`${u}Final Flush`,description:"Flush pending Kiro WAL events when the assistant finishes a turn.",trigger:"Stop",action:d(o),timeout:30,enabled:!0}]}function L(o,r){A(D(o),{recursive:!0,mode:448});let n=`${o}.toolnet-${process.pid}-${Date.now()}.tmp`;try{_(n,JSON.stringify(r,null,2)+`
2
+ `,{encoding:"utf8",mode:384}),R(n,o)}finally{T(n,{force:!0})}}function K(o={}){let r=o.hooksFile??y(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=O(r);if(t.version!==void 0&&t.version!=="v1")throw new Error(`Unsupported existing Kiro hooks version: ${String(t.version)}`);let e=t.hooks;if(e!==void 0&&!Array.isArray(e))throw new Error("Invalid existing Kiro hooks file: hooks must be an array.");let i=Array.isArray(e)?e.filter(g=>!w(g)):[],a=`${G(n)} session:kiro-hook`,s=U(a),c={...t,version:"v1",hooks:[...i,...s]};if(JSON.stringify(t)===JSON.stringify(c))return{hooksFile:r,changed:!1,hookCount:s.length};L(r,c);let l=O(r);if(l.version!=="v1"||!Array.isArray(l.hooks)||l.hooks.filter(w).length!==s.length)throw new Error("Kiro hooks were written but verification failed.");return{hooksFile:r,changed:!0,hookCount:s.length}}import{existsSync as W,mkdirSync as B,readFileSync as Y,renameSync as Q,rmSync as X,writeFileSync as q}from"node:fs";import{dirname as z}from"node:path";function p(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function F(o){if(!W(o))return{};let r=Y(o,"utf8").trim();if(!r)return{};let n;try{n=JSON.parse(r)}catch(t){throw new Error(`Invalid existing Kiro MCP config: ${t instanceof Error?t.message:String(t)}`)}if(!p(n))throw new Error("Invalid existing Kiro MCP config: root must be a JSON object.");return n}function I(o,r){return p(o)?o.command===r&&Array.isArray(o.args)&&o.args.length===1&&o.args[0]==="mcp"&&o.disabled===!1:!1}function Z(o,r){B(z(o),{recursive:!0,mode:448});let n=`${o}.tmp-${process.pid}-${Date.now()}`;try{q(n,`${JSON.stringify(r,null,2)}
3
+ `,{encoding:"utf8",mode:384}),Q(n,o)}finally{X(n,{force:!0})}}function C(o={}){let r=o.configFile??h(),n=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",t=o.serverName??"toolnet-memory",e=F(r),i=e.mcpServers;if(i!==void 0&&!p(i))throw new Error("Invalid existing Kiro MCP config: mcpServers must be an object.");let a=p(i)?{...i}:{},s=a[t];if(I(s,n))return{installed:!0,changed:!1,configFile:r,serverName:t,command:n,args:["mcp"]};a[t]={command:n,args:["mcp"],disabled:!1};let c={...e,mcpServers:a};Z(r,c);let g=F(r).mcpServers;if(!p(g)||!I(g[t],n))throw new Error("Kiro MCP configuration was written but verification failed.");return{installed:!0,changed:!0,configFile:r,serverName:t,command:n,args:["mcp"]}}function x(o={}){let r=o.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=C({binary:r,configFile:o.configFile}),t=K({binary:r,hooksFile:o.hooksFile});return{installed:n.installed,changed:n.changed||t.changed,mcp:n,hooks:t,files:[n.configFile,t.hooksFile]}}import{existsSync as b,readFileSync as V}from"node:fs";var oo="ToolNet Memory - ",ro=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function f(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function j(o){if(!b(o))return{};let r;try{r=JSON.parse(V(o,"utf8"))}catch(n){return{error:n instanceof Error?n.message:String(n)}}return f(r)?{value:r}:{error:"root must be a JSON object"}}function no(o){if(!o||!f(o.mcpServers))return!1;let r=o.mcpServers["toolnet-memory"];return f(r)?typeof r.command=="string"&&r.command.trim().length>0&&Array.isArray(r.args)&&r.args.length===1&&r.args[0]==="mcp"&&r.disabled!==!0:!1}function to(o){if(!(!f(o)||!f(o.action)))return typeof o.action.command=="string"?o.action.command:void 0}function eo(o){if(!o||o.version!=="v1"||!Array.isArray(o.hooks))return[];let r=new Set;for(let n of o.hooks){if(!f(n)||typeof n.name!="string"||!n.name.startsWith(oo))continue;let t=to(n);!t||!t.includes("session:kiro-hook")||n.enabled!==!1&&typeof n.trigger=="string"&&r.add(n.trigger)}return[...r]}function k(o={}){let r=o.configFile??h(),n=o.hooksFile??y(),t=j(r),e=j(n),i=!t.error&&no(t.value),a=e.error?[]:eo(e.value),s=ro.every(J=>a.includes(J)),c=[];t.error&&c.push(`MCP config: ${t.error}`),e.error&&c.push(`Hooks config: ${e.error}`);let l=i&&s,g=b(r)||b(n),E=c.length>0?"invalid":l?"ready":g?"partial":"not-installed";return{installed:l,state:E,mcp:{configured:i,configFile:r,error:t.error},hooks:{configured:s,hooksFile:n,triggers:a,error:e.error},errors:c}}function io(){let o=k();console.log("Kiro CLI Integration"),console.log("===================="),console.log(""),console.log(`State : ${o.state}`),console.log(`MCP : ${o.mcp.configured?"ready":"missing"} \u2014 ${o.mcp.configFile}`),console.log(`Hooks : ${o.hooks.configured?"ready":"missing"} \u2014 ${o.hooks.hooksFile}`),o.hooks.triggers.length>0&&console.log(`Events: ${o.hooks.triggers.join(", ")}`);for(let r of o.errors)console.log(`Error : ${r}`);return console.log(""),o.installed}function so(){let o=process.argv.slice(2),r=o.includes("--json");if(o.includes("--status")||o[0]==="status"){let i=k();r?console.log(JSON.stringify(i,null,2)):io(),i.installed||(process.exitCode=1);return}let t=x(),e=k();if(!e.installed)throw new Error(`Kiro integration installation did not verify successfully (state=${e.state}).`);if(r){console.log(JSON.stringify({installed:!0,changed:t.changed,files:t.files,status:e},null,2));return}console.log("\u2705 Kiro CLI integration installed"),console.log(`MCP: ${t.mcp.configFile}`),console.log(`Hooks: ${t.hooks.hooksFile}`),console.log("Server: toolnet-memory")}try{so()}catch(o){console.error(o instanceof Error?o.message:String(o)),process.exitCode=1}
@@ -1,5 +1,5 @@
1
- import{spawnSync as _}from"node:child_process";import{chmodSync as T,cpSync as v,existsSync as p,lstatSync as N,mkdirSync as A,mkdtempSync as F,readFileSync as C,rmSync as L,symlinkSync as w}from"node:fs";import{tmpdir as M}from"node:os";import{basename as P,dirname as b,join as r,resolve as B}from"node:path";import{fileURLToPath as J}from"node:url";var U=["package.json","bin/toolnet-memory","bundle/init.js","bundle/auto-integrate.js","bundle/mcp.js","bundle/continuity-certify.js","bundle/recovery-certify.js","bundle/production-certify.js"],D=["init.js","auto-integrate.js","mcp.js","continuity-certify.js","recovery-certify.js","production-certify.js"];function K(){if(process.env.TOOLNET_PACKAGE_ROOT?.trim())return B(process.env.TOOLNET_PACKAGE_ROOT);let t=b(J(import.meta.url));return P(t)==="bundle"?b(t):P(t)==="production"&&P(b(t))==="src"?b(b(t)):process.cwd()}function h(t,e,n,o=process.env){let i=_(t,e,{cwd:n,env:o,encoding:"utf8",timeout:3e4,maxBuffer:10485760});return{status:i.status,stdout:i.stdout??"",stderr:i.stderr??""}}function f(t){let e=`${t.stdout}
2
- ${t.stderr}`.trim();return e?e.slice(-1200):`exit=${String(t.status)}`}function u(t,e,n,o){return{id:t,label:e,passed:n,detail:n?void 0:o}}function G(t){let e=t.map(s=>s.replace(/\\/gu,"/")),n=new Set(e),o=U.filter(s=>!n.has(s)),i=e.filter(s=>s==="src"||s.startsWith("src/"));return{passed:o.length===0&&i.length===0,missing:[...o],sourceFiles:i}}function V(t){let e=h("npm",["pack","--dry-run","--json"],t);if(e.status!==0)return{files:[],error:f(e)};try{let n=JSON.parse(e.stdout);return{files:(Array.isArray(n)?n[0]:n)?.files?.map(s=>s.path).filter(s=>typeof s=="string")??[]}}catch(n){return{files:[],error:n instanceof Error?`Cannot parse npm pack JSON: ${n.message}`:String(n)}}}function x(t){try{let e=JSON.parse(C(t,"utf8"));return typeof e.id=="string"&&e.id.trim()?e.id:void 0}catch{return}}function Q(t){let e=F(r(M(),"toolnet-x3-runtime-")),n=r(e,"package"),o=r(e,"project");try{A(r(n,"bin"),{recursive:!0}),A(o,{recursive:!0}),v(r(t,"bin","toolnet-memory"),r(n,"bin","toolnet-memory")),T(r(n,"bin","toolnet-memory"),493),v(r(t,"bundle"),r(n,"bundle"),{recursive:!0}),v(r(t,"package.json"),r(n,"package.json"));let i=r(t,"node_modules");if(!p(i))return{firstStatus:null,secondStatus:null,sourceAbsent:!0,detail:"node_modules is missing; run npm ci first."};w(i,r(n,"node_modules"),"dir");let s=r(n,"bin","toolnet-memory"),j=["init","--project",o,"--json","--no-integrate"],m={...process.env,TOOLNET_MEMORY_BIN:s,TOOLNET_PACKAGE_ROOT:n},l=h(s,j,o,m),a=r(o,".toolnet","project.json"),g=x(a),d=h(s,j,o,m),y=x(a);return{firstStatus:l.status,secondStatus:d.status,firstId:g,secondId:y,sourceAbsent:!p(r(n,"src")),detail:l.status===0&&d.status===0?void 0:["First init:",f(l),"","Second init:",f(d)].join(`
3
- `)}}finally{L(e,{recursive:!0,force:!0})}}function E(t,e){return h(process.execPath,[r(t,"bundle",e)],t,{...process.env,TOOLNET_PACKAGE_ROOT:t})}async function $(t=K()){let e=[],n=r(t,"package.json"),o=r(t,"bin","toolnet-memory"),i=r(t,"bundle"),s={};try{s=JSON.parse(C(n,"utf8"))}catch{}let j=s.bin&&typeof s.bin=="object"?s.bin["toolnet-memory"]:void 0,m=Array.isArray(s.files)?s.files:[];e.push(u("package-manifest","package manifest valid",s.name==="toolnet-memory"&&typeof s.version=="string"&&s.version.length>0&&j==="bin/toolnet-memory"&&m.includes("bundle")&&m.includes("bin/toolnet-memory"),"package.json does not expose the expected production package."));let l=V(t),a=G(l.files);e.push(u("npm-package","npm package contains production runtime only",!l.error&&a.passed,l.error??[a.missing.length>0?`Missing: ${a.missing.join(", ")}`:"",a.sourceFiles.length>0?`Unexpected src files: ${a.sourceFiles.join(", ")}`:""].filter(Boolean).join(`
4
- `)));let g=!1;if(p(o))try{g=(N(o).mode&73)!==0}catch{g=!1}let d=p(o)?h(o,["--version"],t):{status:null,stdout:"",stderr:"CLI file does not exist."};e.push(u("cli","CLI executable and version command works",g&&d.status===0&&typeof s.version=="string"&&`${d.stdout}${d.stderr}`.includes(s.version),f(d)));let y=D.filter(k=>!p(r(i,k)));e.push(u("bundle-complete","production bundle complete",y.length===0,y.length>0?`Missing bundles: ${y.join(", ")}`:void 0));let c=Q(t);e.push(u("init-outside-source","init works outside source tree",c.firstStatus===0&&c.sourceAbsent&&!!c.firstId,c.detail??`firstStatus=${String(c.firstStatus)}, sourceAbsent=${String(c.sourceAbsent)}, projectId=${String(c.firstId)}`)),e.push(u("stable-project-id","project identity remains stable after re-init",c.firstStatus===0&&c.secondStatus===0&&!!c.firstId&&c.firstId===c.secondId,`first=${String(c.firstId)}, second=${String(c.secondId)}`));let S="";try{S=C(o,"utf8")}catch{S=""}e.push(u("auto-integration","automatic integration production entry available",p(r(i,"auto-integrate.js"))&&S.includes("bundle/auto-integrate.js"),"auto-integrate production bundle or CLI routing is missing.")),e.push(u("mcp-bootstrap","MCP production bootstrap available",p(r(i,"mcp.js"))&&S.includes("run bundle/mcp.js src/mcp/bootstrap.ts"),"MCP production bundle or CLI routing is missing."));let R=E(t,"continuity-certify.js");e.push(u("x1","X1 cross-agent certification passes",R.status===0,f(R)));let O=E(t,"recovery-certify.js");e.push(u("x2","X2 recovery certification passes",O.status===0,f(O)));let I=e.filter(k=>k.passed).length;return{passed:I===e.length,total:e.length,passedCount:I,checks:e}}async function X(){let t=await $();console.log(""),console.log("\u25C7 ToolNet Production Readiness Certification"),console.log("\u2502");for(let e of t.checks)if(console.log(`\u2502 ${e.passed?"\u2713":"\u2717"} ${e.label}`),!e.passed&&e.detail)for(let n of e.detail.split(`
5
- `))console.log(`\u2502 \u21B3 ${n}`);if(console.log("\u2502"),t.passed){console.log(`\u25C6 PASS ${t.passedCount}/${t.total} production checks`);return}console.log(`\u25C6 FAIL ${t.passedCount}/${t.total} production checks`),process.exitCode=1}await X();
1
+ import{spawnSync as _}from"node:child_process";import{chmodSync as T,cpSync as v,existsSync as a,lstatSync as L,mkdirSync as A,mkdtempSync as N,readFileSync as P,rmSync as F,symlinkSync as w}from"node:fs";import{tmpdir as M}from"node:os";import{basename as C,dirname as h,join as r,resolve as B}from"node:path";import{fileURLToPath as J}from"node:url";var K=["package.json","bin/toolnet-memory","bundle/init.js","bundle/auto-integrate.js","bundle/kiro.js","bundle/kiro-hook.js","bundle/mcp.js","bundle/continuity-certify.js","bundle/recovery-certify.js","bundle/production-certify.js"],U=["init.js","auto-integrate.js","kiro.js","kiro-hook.js","mcp.js","continuity-certify.js","recovery-certify.js","production-certify.js"];function D(){if(process.env.TOOLNET_PACKAGE_ROOT?.trim())return B(process.env.TOOLNET_PACKAGE_ROOT);let e=h(J(import.meta.url));return C(e)==="bundle"?h(e):C(e)==="production"&&C(h(e))==="src"?h(h(e)):process.cwd()}function k(e,t,n,o=process.env){let i=_(e,t,{cwd:n,env:o,encoding:"utf8",timeout:3e4,maxBuffer:10485760});return{status:i.status,stdout:i.stdout??"",stderr:i.stderr??""}}function f(e){let t=`${e.stdout}
2
+ ${e.stderr}`.trim();return t?t.slice(-1200):`exit=${String(e.status)}`}function u(e,t,n,o){return{id:e,label:t,passed:n,detail:n?void 0:o}}function G(e){let t=e.map(s=>s.replace(/\\/gu,"/")),n=new Set(t),o=K.filter(s=>!n.has(s)),i=t.filter(s=>s==="src"||s.startsWith("src/"));return{passed:o.length===0&&i.length===0,missing:[...o],sourceFiles:i}}function V(e){let t=k("npm",["pack","--dry-run","--json"],e);if(t.status!==0)return{files:[],error:f(t)};try{let n=JSON.parse(t.stdout);return{files:(Array.isArray(n)?n[0]:n)?.files?.map(s=>s.path).filter(s=>typeof s=="string")??[]}}catch(n){return{files:[],error:n instanceof Error?`Cannot parse npm pack JSON: ${n.message}`:String(n)}}}function x(e){try{let t=JSON.parse(P(e,"utf8"));return typeof t.id=="string"&&t.id.trim()?t.id:void 0}catch{return}}function Q(e){let t=N(r(M(),"toolnet-x3-runtime-")),n=r(t,"package"),o=r(t,"project");try{A(r(n,"bin"),{recursive:!0}),A(o,{recursive:!0}),v(r(e,"bin","toolnet-memory"),r(n,"bin","toolnet-memory")),T(r(n,"bin","toolnet-memory"),493),v(r(e,"bundle"),r(n,"bundle"),{recursive:!0}),v(r(e,"package.json"),r(n,"package.json"));let i=r(e,"node_modules");if(!a(i))return{firstStatus:null,secondStatus:null,sourceAbsent:!0,detail:"node_modules is missing; run npm ci first."};w(i,r(n,"node_modules"),"dir");let s=r(n,"bin","toolnet-memory"),j=["init","--project",o,"--json","--no-integrate"],g={...process.env,TOOLNET_MEMORY_BIN:s,TOOLNET_PACKAGE_ROOT:n},m=k(s,j,o,g),d=r(o,".toolnet","project.json"),b=x(d),l=k(s,j,o,g),y=x(d);return{firstStatus:m.status,secondStatus:l.status,firstId:b,secondId:y,sourceAbsent:!a(r(n,"src")),detail:m.status===0&&l.status===0?void 0:["First init:",f(m),"","Second init:",f(l)].join(`
3
+ `)}}finally{F(t,{recursive:!0,force:!0})}}function E(e,t){return k(process.execPath,[r(e,"bundle",t)],e,{...process.env,TOOLNET_PACKAGE_ROOT:e})}async function $(e=D()){let t=[],n=r(e,"package.json"),o=r(e,"bin","toolnet-memory"),i=r(e,"bundle"),s={};try{s=JSON.parse(P(n,"utf8"))}catch{}let j=s.bin&&typeof s.bin=="object"?s.bin["toolnet-memory"]:void 0,g=Array.isArray(s.files)?s.files:[];t.push(u("package-manifest","package manifest valid",s.name==="toolnet-memory"&&typeof s.version=="string"&&s.version.length>0&&j==="bin/toolnet-memory"&&g.includes("bundle")&&g.includes("bin/toolnet-memory"),"package.json does not expose the expected production package."));let m=V(e),d=G(m.files);t.push(u("npm-package","npm package contains production runtime only",!m.error&&d.passed,m.error??[d.missing.length>0?`Missing: ${d.missing.join(", ")}`:"",d.sourceFiles.length>0?`Unexpected src files: ${d.sourceFiles.join(", ")}`:""].filter(Boolean).join(`
4
+ `)));let b=!1;if(a(o))try{b=(L(o).mode&73)!==0}catch{b=!1}let l=a(o)?k(o,["--version"],e):{status:null,stdout:"",stderr:"CLI file does not exist."};t.push(u("cli","CLI executable and version command works",b&&l.status===0&&typeof s.version=="string"&&`${l.stdout}${l.stderr}`.includes(s.version),f(l)));let y=U.filter(S=>!a(r(i,S)));t.push(u("bundle-complete","production bundle complete",y.length===0,y.length>0?`Missing bundles: ${y.join(", ")}`:void 0));let c=Q(e);t.push(u("init-outside-source","init works outside source tree",c.firstStatus===0&&c.sourceAbsent&&!!c.firstId,c.detail??`firstStatus=${String(c.firstStatus)}, sourceAbsent=${String(c.sourceAbsent)}, projectId=${String(c.firstId)}`)),t.push(u("stable-project-id","project identity remains stable after re-init",c.firstStatus===0&&c.secondStatus===0&&!!c.firstId&&c.firstId===c.secondId,`first=${String(c.firstId)}, second=${String(c.secondId)}`));let p="";try{p=P(o,"utf8")}catch{p=""}t.push(u("auto-integration","automatic integration production entry available",a(r(i,"auto-integrate.js"))&&p.includes("bundle/auto-integrate.js"),"auto-integrate production bundle or CLI routing is missing.")),t.push(u("kiro-integration","Kiro CLI production integration available",a(r(i,"kiro.js"))&&a(r(i,"kiro-hook.js"))&&p.includes("integrate:kiro)")&&p.includes("session:kiro-hook)")&&p.includes("bundle/kiro.js")&&p.includes("bundle/kiro-hook.js"),"Kiro production bundle or CLI routing is missing.")),t.push(u("mcp-bootstrap","MCP production bootstrap available",a(r(i,"mcp.js"))&&p.includes("run bundle/mcp.js src/mcp/bootstrap.ts"),"MCP production bundle or CLI routing is missing."));let R=E(e,"continuity-certify.js");t.push(u("x1","X1 cross-agent certification passes",R.status===0,f(R)));let I=E(e,"recovery-certify.js");t.push(u("x2","X2 recovery certification passes",I.status===0,f(I)));let O=t.filter(S=>S.passed).length;return{passed:O===t.length,total:t.length,passedCount:O,checks:t}}async function X(){let e=await $();console.log(""),console.log("\u25C7 ToolNet Production Readiness Certification"),console.log("\u2502");for(let t of e.checks)if(console.log(`\u2502 ${t.passed?"\u2713":"\u2717"} ${t.label}`),!t.passed&&t.detail)for(let n of t.detail.split(`
5
+ `))console.log(`\u2502 \u21B3 ${n}`);if(console.log("\u2502"),e.passed){console.log(`\u25C6 PASS ${e.passedCount}/${e.total} production checks`);return}console.log(`\u25C6 FAIL ${e.passedCount}/${e.total} production checks`),process.exitCode=1}await X();