toolnet-memory 0.3.16 → 0.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +74 -0
- package/.release-target +1 -1
- package/README.md +157 -7
- package/bin/toolnet-memory +12 -0
- package/bundle/agy-hook.js +59 -59
- package/bundle/agy.js +58 -58
- package/bundle/api.js +15 -15
- package/bundle/audit.js +2 -0
- package/bundle/background-refresh.js +7 -7
- package/bundle/code-capabilities.js +2 -0
- package/bundle/codex.js +63 -63
- package/bundle/context-runtime.js +41 -41
- package/bundle/context.js +15 -15
- package/bundle/copilot-hook.js +73 -73
- package/bundle/cursor-hook.js +73 -73
- package/bundle/docker-healthcheck.js +3 -0
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +20 -19
- package/bundle/gc.js +5 -3
- package/bundle/graph-cli.js +1 -1
- package/bundle/graph-index.js +5 -4
- package/bundle/graph-ui.js +4 -3
- package/bundle/grok-hook.js +52 -52
- package/bundle/handoff-refresh.js +2 -2
- package/bundle/help-cli.js +4 -4
- package/bundle/impact.js +5 -4
- package/bundle/incremental.js +5 -5
- package/bundle/init.js +35 -35
- package/bundle/kiro-hook.js +74 -74
- package/bundle/learner.js +8 -6
- package/bundle/mcp.js +19 -17
- package/bundle/memory-agent.js +4 -4
- package/bundle/memory-query.js +3 -3
- package/bundle/opencode.js +73 -73
- package/bundle/project-manual.js +7 -7
- package/bundle/public/index.html +1089 -2306
- package/bundle/runtime.js +16 -13
- package/bundle/semantic.js +6 -5
- package/bundle/service.js +11 -6
- package/bundle/snapshot.js +6 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +49 -49
- package/bundle/work-continuity.js +7 -7
- package/package.json +26 -2
- package/release-manifest.json +57 -1
package/bundle/grok-hook.js
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}import{createHash as
|
|
3
|
-
`)}function
|
|
4
|
-
`;
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
1
|
+
import*as ae from"fs";import*as V from"path";function ni(e){return e?Math.ceil(e.length/3.5):0}function Kn(e,t){if(!e)return"";if(ni(e)<=t)return e;let r=Math.floor(t*3.5),o=e.slice(0,r),s=o.lastIndexOf("."),i=o.lastIndexOf(`
|
|
2
|
+
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}import{createHash as ri}from"node:crypto";import{chmodSync as Ln,existsSync as oi,mkdirSync as si,readFileSync as ii,renameSync as ai,writeFileSync as $n}from"node:fs";import{dirname as Dn,join as Ue}from"node:path";var zt="toolnet.context-offload.v1",ci="toolnet.context-offload-asset.v1",ui=256,li=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Fn(e){return Ue(e,".toolnet","offload")}function di(e){return Ue(Fn(e),"assets")}function Wn(e){return Ue(Fn(e),"graph.json")}function zn(e){si(e,{recursive:!0,mode:448});try{Ln(e,448)}catch{}}function pi(e,t){zn(Dn(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;$n(n,t,{encoding:"utf8",mode:384}),ai(n,e);try{Ln(e,384)}catch{}}function Wt(e){return Array.isArray(e)?e.map(Wt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Wt(n)])):e}function fi(e){return ri("sha256").update(JSON.stringify(Wt(e)),"utf8").digest("hex")}function Ft(){return{schema:zt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function mi(e){let t=Wn(e);if(!oi(t))return Ft();try{let n=JSON.parse(ii(t,"utf8"));return n.schema!==zt||n.version!==1||!Array.isArray(n.nodes)?Ft():n}catch{return Ft()}}function gi(e,t){pi(Wn(e),JSON.stringify(t,null,2)+`
|
|
3
|
+
`)}function yi(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function hi(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let o=yi(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function Si(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function ki(e,t){zn(Dn(e));try{return $n(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function vi(e,t){let n=e.nodes.find(o=>o.id===t.id),r=n?{...n,kind:t.kind,bytes:t.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...t.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...t.files])).slice(0,6)}:t;return{schema:zt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(o=>o.id!==t.id),r].slice(-ui)}}function Hn(e,t){let n=mi(e),r=0,o=0,s=0,i=[];for(let a of t){if(!li.has(a.type))continue;r+=1;let c=fi({type:a.type,data:a.data}),u={schema:ci,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},l=JSON.stringify(u,null,2)+`
|
|
4
|
+
`;ki(Ue(di(e),`${c}.json`),l)?o+=1:s+=1,i.push(c),n=vi(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[Si(a)],files:hi(a)})}return r>0&&gi(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{existsSync as Jn,mkdirSync as Ei,readFileSync as Vn,renameSync as Pi,writeFileSync as Mi}from"node:fs";import{dirname as Ci,join as Bn}from"node:path";import{createHash as wi}from"node:crypto";import{dirname as bi}from"node:path";import{mkdirSync as xi,readFileSync as Ii,renameSync as ji,writeFileSync as Ai}from"node:fs";function w(e){return wi("sha256").update(e).digest("hex")}function Ht(e){if(Array.isArray(e))return e.map(Ht);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=Ht(t[r]);return n}return e}function Ye(e){return JSON.stringify(Ht(e))}function qn(e){try{return JSON.parse(Ii(e,"utf8"))}catch{return null}}function N(e,t){xi(bi(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;Ai(n,JSON.stringify(t,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),ji(n,e)}function Gn(e){return Bn(e.rootPath,".toolnet","context","handoff.md")}function Un(e){return Bn(e.rootPath,".toolnet","context","handoff.json")}function Yn(e,t){Ei(Ci(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Mi(n,t.endsWith(`
|
|
6
6
|
`)?t:`${t}
|
|
7
|
-
`,{encoding:"utf8",mode:384}),
|
|
8
|
-
`)}function
|
|
9
|
-
`).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return
|
|
10
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function
|
|
11
|
-
`,{encoding:"utf8",mode:384}),Mi(o,r)}function X(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}function zt(e){return{version:1,scheme:he,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function Ri(e){let t=e.metadata?.toolnetIdentity;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return typeof n.fingerprint=="string"?n.fingerprint:null}var Ze=class{adopt(t,n){let r=Wt(Z(t));if(!n.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!n.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!n.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(or(r)){let a=Ge(ie(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return X(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=zt(n.gitIdentity));let i={version:1,id:n.id.trim(),name:n.name.trim(),remote:n.remote.trim(),rootPath:r,createdAt:n.createdAt??o,updatedAt:o,graphVersion:n.graphVersion??0,memoryVersion:n.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return Ue(r,i),X(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=ie(o.rootPath),i=Ge(s),a=Ri(i);if(a&&a!==n.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${n.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===n.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:zt(n)},i.updatedAt=new Date().toISOString(),Ue(o.rootPath,i)),X(i,o.rootPath)}findExisting(t=process.cwd()){let n=Z(t),r=Wt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Ye(Se(r,c))),i=tr(n,s?r:void 0);if(!i)return null;let a=Ge(ie(i));return X(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=Z(t),r=Wt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>Ye(Se(r,d))),i=tr(n,s?r:void 0);if(i){let d=ie(i),p=Ge(d);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Ue(i,p)),X(p,i)}let a=new Date().toISOString(),c=Ei(r),u=er(r),l={version:1,id:u?Qn(u.canonicalRemote):Ti(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:zt(u)}:void 0};return Ue(r,l),X(l,r)}};var Ni=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],_i=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function sr(e){return e.normalize("NFKC").trim().toLowerCase()}function Ki(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let o=r/e.length;n-=o*Math.log2(o)}return n}function $i(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function Li(e,t,n){let r=e.slice(Math.max(0,t-48),t),o=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function Fi(e,t){return e.start<t.end&&t.start<e.end}function ir(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var Qe=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=sr(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of Ni){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=ir(n),o=[];for(let s of r)o.some(i=>Fi(i,s))||o.push(s);return ir(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=sr(t);return _i.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of t.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||$i(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Li(t,o.index,o.index+s.length)&&(Ki(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var V=class{scanner;constructor(t={}){this.scanner=new Qe(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,o=[...n].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...s].sort()}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,o]of Object.entries(t)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(o)}return n}return t}};var Di=new V;function ke(e){return Di.sanitizeValue(e)}import{homedir as ua}from"node:os";import{join as la}from"node:path";import{DeleteObjectCommand as Wi,GetObjectCommand as zi,HeadObjectCommand as qi,ListObjectsV2Command as Hi,PutObjectCommand as Ji,S3Client as Vi}from"@aws-sdk/client-s3";import{getSignedUrl as Bi}from"@aws-sdk/s3-request-presigner";var et=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Vi({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Ji({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Bi(this.client,new zi({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new qi({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new Wi({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Hi({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{access as ar,mkdir as Gi,readFile as Ui,readdir as Yi,rm as Xi,stat as cr,writeFile as Zi}from"node:fs/promises";import{dirname as Qi,join as ea,relative as ur,resolve as ta}from"node:path";var ve=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return ta(this.root,n)}async put(t,n){let r=this.path(t);await Gi(Qi(r),{recursive:!0}),await Zi(r,n)}async get(t){try{return await Ui(this.path(t))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await ar(this.path(t)),!0}catch{return!1}}async delete(t){await Xi(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await ar(n)}catch{return r}let o=async i=>{let a=await Yi(i,{withFileTypes:!0});for(let c of a){let u=ea(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await cr(u);r.push({key:ur(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await cr(n);return s.isDirectory()?await o(n):r.push({key:ur(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as na,GetObjectCommand as ra,HeadObjectCommand as oa,ListObjectsV2Command as sa,PutObjectCommand as ia,S3Client as aa}from"@aws-sdk/client-s3";import{getSignedUrl as ca}from"@aws-sdk/s3-request-presigner";var we=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new aa({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ia({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await ca(this.client,new ra({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new oa({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new na({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new sa({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};function qt(e,t){return console.warn(t),new ve(e)}function lr(e){let t=e.localRoot??la(ua(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new we({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):qt(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new we({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):qt(t,"[storage] S3 credentials missing. Using local fallback.")}if(e.provider==="huggingface"){let n=e.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new et({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):qt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ve(t)}function da(e){return new Promise(t=>setTimeout(t,e))}async function dr(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,o=t.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(s=a,i>=n)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await da(c+u)}throw s}var pa=new Set(["put","get","getText","delete","list"]);function pr(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:pa.has(r)?(...s)=>dr(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function fr(e){let t=e.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function mr(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let o=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:t))}var tt=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=fr(o??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,o=await this.provider.getText(t);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(s,null,2)+`
|
|
12
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=
|
|
13
|
-
`,{encoding:"utf8",mode:384}),
|
|
14
|
-
`)}function
|
|
7
|
+
`,{encoding:"utf8",mode:384}),Pi(n,e)}function Ti(e,t){Yn(e,`${JSON.stringify(t,null,2)}
|
|
8
|
+
`)}function Xn(e,t){let n=t.replace(/\r\n/g,`
|
|
9
|
+
`).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return Yn(Gn(e),n),Ti(Un(e),r),r}function Qn(e){let t=Gn(e);if(!Jn(t))return null;try{let n=Vn(t,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),o=Un(e);if(Jn(o))try{let s=JSON.parse(Vn(o,"utf8"));typeof s.generatedAt=="string"&&(r=s.generatedAt)}catch{}return{version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function Zn(e){let t=V.resolve(e),n=V.parse(t).root;for(;t!==n;){let r=V.join(t,".toolnet");if(ae.existsSync(r)&&ae.statSync(r).isDirectory())return t;t=V.dirname(t)}return null}function er(e){return e.replace(/\\/g,"/").toLowerCase()}function qt(e,t,n=0){if(!(n>6||t.length>=250)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e)if(qt(r,t,n+1),t.length>=250)break;return}if(e&&typeof e=="object"){for(let r of Object.values(e))if(qt(r,t,n+1),t.length>=250)break}}}function Oi(e){let t=er(e);if(t.includes(".toolnet/journal/")||t.includes(".toolnet/runtime/sources/")||t.endsWith(".toolnet/journal")||t.endsWith(".toolnet/runtime/sources")||t.includes(".toolnet/sessions/")||t.endsWith(".toolnet/sessions")||t.includes(".gemini/antigravity-cli/brain/")||t.endsWith(".gemini/antigravity-cli/brain")||t.includes("/transcript.jsonl")||t.endsWith("transcript.jsonl")||t.includes(".toolnet/")&&(t.endsWith("/events.jsonl")||t.endsWith("/state.json")||t.includes("/sessions/")))return!0;let n=process.env.CURSOR_TRANSCRIPT_PATH;return!!(n&&er(n)===t)}function tr(e){let t=[];return qt(e,t),t.find(Oi)?{blocked:!0,reason:"ToolNet continuity guard: do not read or reconstruct previous work from raw ToolNet/agent session history. Use the injected ToolNet handoff first; if it is insufficient, invoke the MCP tool memory_agent_ask directly. Then verify normal repository/git source truth."}:{blocked:!1}}function Xe(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function nr(e,t=process.env){return Xe(t.TOOLNET_HOOK_EVENT)??Xe(e.hookEventName)??Xe(e.hook_event_name)??Xe(t.GROK_HOOK_EVENT)??""}function rr(e){return tr(e.toolInput??e.tool_input??e)}function or(e){return{decision:"deny",reason:e}}import{existsSync as tp}from"node:fs";import{join as np}from"node:path";import{existsSync as Ri,readFileSync as Ni}from"node:fs";import{homedir as _i}from"node:os";import{join as Ki}from"node:path";function Li(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
|
|
10
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function $i(){let e=process.env.TOOLNET_GLOBAL_ENV??Ki(_i(),".config","toolnet-memory",".env");if(!Ri(e))return;let t=Ni(e,"utf8");for(let n of t.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let s=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Li(r.slice(o+1)))}}$i();function Se(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function ke(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Qe(){return{memory:{autoCapture:Se(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:Se(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:Se(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:Se(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ke(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ke(process.env.MEMORY_RERANK_TOP,10),finalContext:ke(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ke(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:Se(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:ke(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Ji}from"node:crypto";import{existsSync as tt,mkdirSync as Vi,readFileSync as Bi,renameSync as Gi,writeFileSync as Ui}from"node:fs";import{basename as Yi,dirname as nt,join as we,parse as pr,resolve as Z}from"node:path";import{createHash as ar}from"node:crypto";import{spawnSync as Di}from"node:child_process";var ve="git-remote-v1",Fi=new Set(["github.com","gitlab.com","bitbucket.org"]);function cr(e,t){let n=t.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!n||n==="."||n===".."||n.split("/").some(r=>!r||r==="."||r==="..")?null:(Fi.has(e)&&(n=n.toLowerCase()),n)}function Wi(e){let t;try{t=new URL(e)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(t.protocol))return null;let n=t.hostname.trim().toLowerCase();if(!n)return null;let r=t.protocol==="https:"&&t.port==="443"||t.protocol==="http:"&&t.port==="80"||t.protocol==="ssh:"&&t.port==="22",o=t.port&&!r?`${n}:${t.port}`:n,s=cr(n,t.pathname);return s?`${o}/${s}`:null}function zi(e){let t=e.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!t)return null;let n=t[1]?.trim().toLowerCase();if(!n||n.length===1)return null;let r=cr(n,t[2]??"");return r?`${n}/${r}`:null}function sr(e){let t=e.trim();return t?t.includes("://")?Wi(t):zi(t):null}function Hi(e){return ar("sha256").update(`${ve}:${e}`).digest("hex")}function ur(e){return ar("sha256").update(`toolnet-project:${ve}:${e}`).digest("hex").slice(0,16)}function qi(e){return e.split("/").filter(Boolean).at(-1)?.trim()||null}function Jt(e,t){let n=Di("git",["-C",e,...t],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function ir(e,t){let n=qi(e);return n?{scheme:ve,canonicalRemote:e,fingerprint:Hi(e),repositoryName:n,source:t}:null}function lr(e){let t=Jt(e,["remote","get-url","origin"]);if(t){let o=sr(t);if(o)return ir(o,"origin")}let n=Jt(e,["remote"]);if(!n)return null;let r=new Set;for(let o of n.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=Jt(e,["remote","get-url",o]);if(!s)continue;let i=sr(s);i&&r.add(i)}return r.size!==1?null:ir([...r][0],"unique-remote")}var fr=".toolnet",Xi="project.json";function Qi(e){return Ji("sha256").update(e).digest("hex").slice(0,16)}function ce(e){return we(e,fr,Xi)}function mr(e){return tt(ce(e))}function dr(e,t){let n=Z(e),r=pr(n).root;for(;;){if(mr(n))return n;if(n===r||t&&n===Z(t))break;let o=nt(n);if(o===n)break;n=o}return null}function Vt(e){let t=Z(e),n=pr(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>tt(we(t,s))))return t;if(t===n)break;let o=nt(t);if(o===t)break;t=o}return Z(e)}function Ze(e){let t;try{t=JSON.parse(Bi(e,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${e}: ${o instanceof Error?o.message:String(o)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let n=t;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:nt(nt(e)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function et(e,t){let n=we(e,fr);Vi(n,{recursive:!0});let r=ce(e),o=`${r}.tmp-${process.pid}`;Ui(o,JSON.stringify(t,null,2)+`
|
|
11
|
+
`,{encoding:"utf8",mode:384}),Gi(o,r)}function Q(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}function Bt(e){return{version:1,scheme:ve,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function Zi(e){let t=e.metadata?.toolnetIdentity;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return typeof n.fingerprint=="string"?n.fingerprint:null}var rt=class{adopt(t,n){let r=Vt(Z(t));if(!n.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!n.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!n.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(mr(r)){let a=Ze(ce(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return Q(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=Bt(n.gitIdentity));let i={version:1,id:n.id.trim(),name:n.name.trim(),remote:n.remote.trim(),rootPath:r,createdAt:n.createdAt??o,updatedAt:o,graphVersion:n.graphVersion??0,memoryVersion:n.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return et(r,i),Q(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=ce(o.rootPath),i=Ze(s),a=Zi(i);if(a&&a!==n.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${n.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===n.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:Bt(n)},i.updatedAt=new Date().toISOString(),et(o.rootPath,i)),Q(i,o.rootPath)}findExisting(t=process.cwd()){let n=Z(t),r=Vt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>tt(we(r,c))),i=dr(n,s?r:void 0);if(!i)return null;let a=Ze(ce(i));return Q(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=Z(t),r=Vt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>tt(we(r,d))),i=dr(n,s?r:void 0);if(i){let d=ce(i),p=Ze(d);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),et(i,p)),Q(p,i)}let a=new Date().toISOString(),c=Yi(r),u=lr(r),l={version:1,id:u?ur(u.canonicalRemote):Qi(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:Bt(u)}:void 0};return et(r,l),Q(l,r)}};var ea=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],ta=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function gr(e){return e.normalize("NFKC").trim().toLowerCase()}function na(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let o=r/e.length;n-=o*Math.log2(o)}return n}function ra(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function oa(e,t,n){let r=e.slice(Math.max(0,t-48),t),o=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function sa(e,t){return e.start<t.end&&t.start<e.end}function yr(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var ot=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=gr(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of ea){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=yr(n),o=[];for(let s of r)o.some(i=>sa(i,s))||o.push(s);return yr(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=gr(t);return ta.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of t.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||ra(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||oa(t,o.index,o.index+s.length)&&(na(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var B=class{scanner;constructor(t={}){this.scanner=new ot(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,o=[...n].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...s].sort()}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,o]of Object.entries(t)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(o)}return n}return t}};var ia=new B;function ue(e){return ia.sanitizeValue(e)}import{homedir as La}from"node:os";import{join as $a}from"node:path";import{DeleteObjectCommand as aa,GetObjectCommand as ca,HeadObjectCommand as ua,ListObjectsV2Command as la,PutObjectCommand as da,S3Client as pa}from"@aws-sdk/client-s3";import{getSignedUrl as fa}from"@aws-sdk/s3-request-presigner";var st=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new pa({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new da({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await fa(this.client,new ca({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new ua({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new aa({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new la({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{access as hr,mkdir as ma,readFile as ga,readdir as ya,rm as ha,stat as Sr,writeFile as Sa}from"node:fs/promises";import{dirname as ka,join as va,relative as kr,resolve as wa}from"node:path";var be=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return wa(this.root,n)}async put(t,n){let r=this.path(t);await ma(ka(r),{recursive:!0}),await Sa(r,n)}async get(t){try{return await ga(this.path(t))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await hr(this.path(t)),!0}catch{return!1}}async delete(t){await ha(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await hr(n)}catch{return r}let o=async i=>{let a=await ya(i,{withFileTypes:!0});for(let c of a){let u=va(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Sr(u);r.push({key:kr(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Sr(n);return s.isDirectory()?await o(n):r.push({key:kr(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as ba,GetObjectCommand as xa,HeadObjectCommand as Ia,ListObjectsV2Command as ja,PutObjectCommand as Aa,S3Client as Ea}from"@aws-sdk/client-s3";import{getSignedUrl as Pa}from"@aws-sdk/s3-request-presigner";var xe=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Ea({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Aa({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Pa(this.client,new xa({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new Ia({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new ba({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new ja({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{createCipheriv as Ma,createDecipheriv as Ca,createHash as Ta,randomBytes as Oa,timingSafeEqual as Ra}from"node:crypto";import{readFileSync as Na}from"node:fs";var ee=Buffer.from("TNMEME01","ascii"),wr=1,Ie=8,je=12,Gt=16,br=ee.length+1+Ie+je+Gt,_a="toolnet-memory:remote-encryption:v1:",xr="aes-256-gcm",Ut=32,A=class extends Error{constructor(n,r){super(r);this.code=n;this.name="RemoteEncryptionError"}code};function Ka(e){return e?["1","true","yes","on","enabled"].includes(e.trim().toLowerCase()):!1}function Yt(e=process.env){return Ka(e.TOOLNET_REMOTE_ENCRYPTION)}function vr(e){let t=e.trim();if(!t)throw new A("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let n;if(t.startsWith("hex:")){let r=t.slice(4);if(!/^[0-9a-f]{64}$/iu.test(r))throw new A("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");n=Buffer.from(r,"hex")}else if(/^[0-9a-f]{64}$/iu.test(t))n=Buffer.from(t,"hex");else{let r=t.startsWith("base64:")?t.slice(7):t;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(r))throw new A("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");n=Buffer.from(r,r.includes("-")||r.includes("_")?"base64url":"base64")}if(n.length!==Ut)throw new A("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${Ut} bytes.`);return n}function Ir(e=process.env){let t=e.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),n=e.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(t&&n)throw new A("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(t)return vr(t);if(n){let r;try{r=Na(n,"utf8")}catch(o){throw new A("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${n}.`,o instanceof Error?o.message:String(o)].join(" "))}return vr(r)}}function jr(e){return Ta("sha256").update(e).digest().subarray(0,Ie)}function Ar(e){return Buffer.from(`${_a}${e}`,"utf8")}function Xt(e){return e.byteLength<ee.length?!1:Buffer.from(e).subarray(0,ee.length).equals(ee)}function Er(e,t,n){if(n.byteLength!==Ut)throw new A("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let r=typeof t=="string"?Buffer.from(t,"utf8"):Buffer.from(t),o=Oa(je),s=Ma(xr,n,o);s.setAAD(Ar(e));let i=Buffer.concat([s.update(r),s.final()]),a=s.getAuthTag(),c=Buffer.alloc(br),u=0;return ee.copy(c,u),u+=ee.length,c.writeUInt8(wr,u),u+=1,jr(n).copy(c,u),u+=Ie,o.copy(c,u),u+=je,a.copy(c,u),Buffer.concat([c,i])}function Pr(e,t,n){let r=Buffer.from(t);if(!Xt(r))throw new A("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(r.length<br)throw new A("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=ee.length,s=r.readUInt8(o);if(o+=1,s!==wr)throw new A("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let i=r.subarray(o,o+Ie);o+=Ie;let a=jr(n);if(!Ra(i,a))throw new A("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let c=r.subarray(o,o+je);o+=je;let u=r.subarray(o,o+Gt);o+=Gt;let l=r.subarray(o),d=Ca(xr,n,c);d.setAAD(Ar(e)),d.setAuthTag(u);try{return Buffer.concat([d.update(l),d.final()])}catch{throw new A("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var Qt=class{constructor(t,n){this.inner=t;this.options=n;if(this.name=t.name,n.enabled&&!n.key)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(t,n,r){if(!this.options.enabled){await this.inner.put(t,n,r);return}let o=this.options.key;if(!o)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=Er(t,n,o);await this.inner.put(t,s,"application/octet-stream")}async get(t){let n=await this.inner.get(t);if(!n)return null;if(!Xt(n))return n;if(!this.options.enabled)throw new A("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let r=this.options.key;if(!r)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return Pr(t,n,r)}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){return this.inner.exists(t)}async delete(t){await this.inner.delete(t)}async list(t=""){return this.inner.list(t)}};function Mr(e,t=process.env){if(e.name==="local")return Yt(t)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),e;let n=Yt(t),r=n?Ir(t):void 0;return new Qt(e,{enabled:n,key:r})}function Ae(e){return Mr(e)}function Zt(e,t){return console.warn(t),Ae(new be(e))}function Cr(e){let t=e.localRoot??$a(La(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?Ae(new xe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Zt(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?Ae(new xe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Zt(t,"[storage] S3 credentials missing. Using local fallback.")}if(e.provider==="huggingface"){let n=e.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?Ae(new st({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Zt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return Ae(new be(t))}function Da(e){return new Promise(t=>setTimeout(t,e))}async function Tr(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,o=t.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(s=a,i>=n)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Da(c+u)}throw s}var Fa=new Set(["put","get","getText","delete","list"]);function Or(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:Fa.has(r)?(...s)=>Tr(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function Rr(e){let t=e.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function Nr(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let o=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:t))}var it=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Rr(o??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,o=await this.provider.getText(t);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(s,null,2)+`
|
|
12
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=Nr(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,n,r){return await this.ensureRegistered(),this.provider.put(this.key(t),n,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{existsSync as Ya,readFileSync as Xa}from"node:fs";import{join as Qa}from"node:path";import{existsSync as Wa,mkdirSync as za,readFileSync as Ha,renameSync as qa,writeFileSync as Ja}from"node:fs";import{dirname as Va,join as Ba}from"node:path";function _r(e){return Ba(e.rootPath,".toolnet","context","session-origin.json")}function Ga(e,t){za(Va(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Ja(n,`${JSON.stringify(t,null,2)}
|
|
13
|
+
`,{encoding:"utf8",mode:384}),qa(n,e)}function at(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let o=n.occurredAt.localeCompare(r.occurredAt);return o!==0?o:n.sequence-r.sequence}).at(-1)}function Kr(e,t){let n=at(t.observations,"file"),r=at(t.observations,"next_action"),o=at(t.observations,"blocker"),s=at(t.observations,"decision"),i={version:1,projectId:e.id,agent:t.agent,nativeSessionId:t.nativeSessionId,updatedAt:t.workState.updatedAt,currentRequest:t.workState.currentRequest,currentActivity:t.workState.currentActivity,currentTask:t.workState.currentTask?.title,currentPhase:t.workState.currentPhase?.title,lastTouchedFile:n?.text??t.workState.activeFiles?.at(-1)??t.workState.filesTouched.at(-1),latestNextAction:r?.text??t.workState.nextActions.at(-1),latestBlocker:o?.text??t.workState.blockers.at(-1),latestDecision:s?.text??t.workState.decisions.at(-1)};return Ga(_r(e),i),i}function Ua(e){let t=_r(e);if(!Wa(t))return null;try{let n=JSON.parse(Ha(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function Lr(e){let t=Ua(e);if(!t)return null;let n=["Previous session:",`- Agent: ${t.agent}`,`- Session: ${t.nativeSessionId}`];return t.currentRequest&&n.push(`- Current request: ${t.currentRequest}`),t.currentActivity&&n.push(`- Current activity: ${t.currentActivity}`),t.currentPhase&&n.push(`- Current phase: ${t.currentPhase}`),t.currentTask&&n.push(`- Current task: ${t.currentTask}`),t.lastTouchedFile&&n.push(`- Last touched file: ${t.lastTouchedFile}`),t.latestBlocker&&n.push(`- Blocker: ${t.latestBlocker}`),t.latestNextAction&&n.push(`- Next action: ${t.latestNextAction}`),t.latestDecision&&n.push(`- Important decision: ${t.latestDecision}`),n.join(`
|
|
14
|
+
`)}function Za(e){let t=Qa(e.rootPath,".toolnet","current.md");if(!Ya(t))return null;try{return Xa(t,"utf8").trim()}catch{return null}}function ec(e,t){let n=t.replace(/\r\n/g,`
|
|
15
15
|
`).trim(),r=2400,o=n.length>r?`${n.slice(0,r)}
|
|
16
16
|
|
|
17
|
-
[Current work truncated for fast handoff]`:n,s=
|
|
18
|
-
`)}function
|
|
17
|
+
[Current work truncated for fast handoff]`:n,s=Lr(e);return["# ToolNet Fast Handoff","",`Project: ${e.name}`,"",...s?[s,""]:[],o,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
|
|
18
|
+
`)}function $r(e){let t=Za(e);if(t===null)return{updated:!1,reason:"missing-current",chars:0};if(!t.trim())return{updated:!1,reason:"empty-current",chars:0};let n=ec(e,t);return Qn(e)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(Xn(e,n),{updated:!0,reason:"updated",chars:n.length})}import{join as tc}from"node:path";function Dr(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),o=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${o}`;let s=r.slice(0,100);return s===n&&n.length<=100?s:`${s.slice(0,85)}--${o}`}function ct(e,t,n){let r=t.trim(),o=n.trim();if(!r)throw new Error("Session agent is required");if(!o)throw new Error("Native session ID is required");let s=Dr(r.toLowerCase(),"agent"),i=Dr(o,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:o,sessionKey:`${r}:${o}`,remotePrefix:["projects",e.id,"runtime","sources",s,i].join("/"),localDirectory:tc(e.rootPath,".toolnet","runtime","sources",s,i)}}function Fr(e){return String(e).padStart(12,"0")}var ut=class{constructor(t,n=100,r=512*1024){this.storage=t;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(t){let n=await this.storage.getText(t);return n?JSON.parse(n):null}async putJson(t,n){await this.storage.put(t,JSON.stringify(n,null,2)+`
|
|
19
19
|
`,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),o=[],s=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(o.push({key:i.key,start:c,end:u}),s=Math.max(s,u))}return o.sort((i,a)=>i.start-a.start),{chunks:o,maxSequence:s}}split(t){let n=[],r=[],o=0;for(let s of t){let i=Buffer.byteLength(JSON.stringify(s)+`
|
|
20
|
-
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||o+i>this.maxChunkBytes)&&(n.push(r),r=[],o=0),r.push(s),o+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,o={}){let s=await this.loadManifest(t),i=await this.scan(t),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let h=g[0],v=g[g.length-1],
|
|
20
|
+
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||o+i>this.maxChunkBytes)&&(n.push(r),r=[],o=0),r.push(s),o+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,o={}){let s=await this.loadManifest(t),i=await this.scan(t),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let h=g[0],v=g[g.length-1],I=g.map(R=>JSON.stringify(R)).join(`
|
|
21
21
|
`)+`
|
|
22
|
-
`,O=w(
|
|
23
|
-
`,null,"utf8"),
|
|
24
|
-
`,null,"utf8"),
|
|
22
|
+
`,O=w(I).slice(0,16),C=[t.remotePrefix,"events",`${Fr(h.sequence)}-${Fr(v.sequence)}-${O}.jsonl`].join("/");await this.storage.exists(C)||await this.storage.put(C,I,"application/x-ndjson"),c+=g.length}let u=await this.scan(t),l=n[n.length-1],d=s?.status??"active";l?.type==="session_end"||l?.type==="session_idle"?d="idle":l?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),f=n[0],m={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:s?.createdAt??f?.timestamp??p,updatedAt:l?.timestamp??p,firstEventAt:s?.firstEventAt??f?.timestamp,lastEventAt:l?.timestamp??s?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...s?.metadata,...o.metadata}};(o.title??s?.title)&&(m.title=o.title??s?.title);let S={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:p};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:d}}};import{closeSync as Me,existsSync as mt,fsyncSync as cn,mkdirSync as Sc,openSync as Ce,readFileSync as to,readSync as kc,rmSync as Qr,statSync as sn,truncateSync as vc,writeSync as wc}from"node:fs";import{join as an}from"node:path";var nc=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),rc=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function oc(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function sc(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(rc.has(r))return n}}return null}function en(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(s=>en(s,t+1));if(!e||typeof e!="object")return e;let n=e,r=sc(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))nc.has(oc(s))||(o[s]=en(i,t+1));return o}function ic(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function te(e){return e?.trim()||void 0}function Wr(e,t={}){let n={...e.provenance??{}},r=te(e.source)??te(t.source)??te(n.source);return{...e,timestamp:ic(e.timestamp),source:r,turnId:te(e.turnId)??te(t.turnId),cwd:te(e.cwd)??te(t.cwd),data:en(e.data??{}),provenance:n}}import{randomUUID as tn}from"node:crypto";import{closeSync as le,existsSync as de,fsyncSync as Ee,mkdirSync as nn,openSync as Pe,readFileSync as rn,readdirSync as ac,renameSync as cc,rmSync as lt,statSync as uc,writeSync as dt}from"node:fs";import{join as G}from"node:path";var lc=12e4,dc=80,pc="reconcile-required";function fc(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function pe(e){return G(e,".toolnet","journal")}function qr(e){return G(pe(e),"events.jsonl")}function pt(e){return G(pe(e),pc)}function mc(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Jr(e){if(!de(e))return null;try{let t=JSON.parse(rn(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function gc(e){if(!de(e))return!1;let t=0;try{t=Date.now()-uc(e).mtimeMs}catch{return!1}if(t<=lc)return!1;let n=Jr(e);return n?!mc(n.pid):!0}function yc(e){if(!gc(e))return!1;try{return lt(e,{force:!0}),!0}catch{return!1}}function Vr(e){for(let t=0;t<dc;t+=1){let n=tn();try{let r=Pe(e,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return dt(r,`${JSON.stringify(o)}
|
|
23
|
+
`,null,"utf8"),Ee(r),{fd:r,token:n}}catch(s){throw le(r),lt(e,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(yc(e))continue;fc(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function Br(e,t){le(t.fd),Jr(e)?.token===t.token&<(e,{force:!0})}function zr(e){if(!de(e))return[];let t="";try{t=rn(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=r.trim();if(o)try{let s=JSON.parse(o);if(s.version!==1||typeof s.id!="string"||s.id.length===0||typeof s.projectId!="string"||s.projectId.length===0)continue;n.push(s)}catch{}}return n}function Gr(e){if(!de(e))return[];let t=[];for(let n of ac(e,{withFileTypes:!0})){let r=G(e,n.name);if(n.isDirectory()){t.push(...Gr(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function ft(e){let t=null;try{t=Pe(e,"r"),Ee(t)}catch{}finally{if(t===null)return;le(t)}}function Hr(e){let t=pt(e);if(!de(t))return null;try{return rn(t,"utf8").trim()||null}catch{return null}}function on(e){let t=pe(e);nn(t,{recursive:!0,mode:448});let n=pt(e),r=[tn(),new Date().toISOString()].join("|"),o=Pe(n,"w",384);try{dt(o,`${r}
|
|
24
|
+
`,null,"utf8"),Ee(o)}finally{le(o)}ft(t)}function hc(e,t,n){let r=G(e,`.events.jsonl.tmp-${process.pid}-${tn()}`),o=Pe(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
|
|
25
25
|
`)}
|
|
26
|
-
`;s&&
|
|
26
|
+
`;s&&dt(o,s,null,"utf8"),Ee(o)}finally{le(o)}cc(r,t),ft(e)}function Ur(e){let t=pe(e),n=qr(e),r=G(e,".toolnet","runtime","sources"),o=Hr(e),s=Gr(r),i=[],a=new Set;for(let d of zr(n))a.has(d.id)||(a.add(d.id),i.push(d));let c=i.length,u=[];for(let d of s)for(let p of zr(d))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((d,p)=>{let f=d.timestamp.localeCompare(p.timestamp);return f!==0?f:d.id.localeCompare(p.id)}),i.push(...u),hc(t,n,i);let l=Hr(e);return o&&l===o&&(lt(pt(e),{force:!0}),ft(t)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function Yr(e){let t=pe(e);nn(t,{recursive:!0,mode:448});let n=G(t,"journal.lock"),r=Vr(n);try{return Ur(e)}finally{Br(n,r)}}function Xr(e,t){if(t.length===0)return;let n=pe(e);nn(n,{recursive:!0,mode:448});let r=qr(e),o=G(n,"journal.lock"),s=Vr(o);try{if(de(pt(e))){Ur(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
|
|
27
27
|
`)}
|
|
28
|
-
`,a=
|
|
29
|
-
`),
|
|
28
|
+
`,a=Pe(r,"a",384);try{dt(a,i,null,"utf8"),Ee(a)}finally{le(a)}ft(n)}finally{Br(o,s)}}var bc=12e4,xc=80,Zr=2e3;function Ic(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function no(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let o=wc(e,n,r,n.length-r);if(o<=0)throw new Error("Unable to write session WAL");r+=o}}function un(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function jc(e){if(!mt(e))return[];let t="";try{t=to(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=un(r);o&&n.push(o)}return n}function eo(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function Ac(e){if(!mt(e))return!1;let t;try{t=to(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,o=t.subarray(r).toString("utf8").trim();if(un(o)){let i=Ce(e,"a");try{no(i,`
|
|
29
|
+
`),cn(i)}finally{Me(i)}return!0}vc(e,r);let s=Ce(e,"a");try{cn(s)}finally{Me(s)}return!0}function Ec(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var fe=class{constructor(t,n={}){this.identity=t;this.eventContext=n;Sc(t.localDirectory,{recursive:!0}),this.eventsFile=an(t.localDirectory,"events.jsonl"),this.stateFile=an(t.localDirectory,"state.json"),this.lockFile=an(t.localDirectory,"journal.lock")}identity;eventContext;eventsFile;stateFile;lockFile;initialState(){let t=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:t,updatedAt:t,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return qn(this.stateFile)??this.initialState()}recoverStateUnsafe(){Ac(this.eventsFile);let t=this.loadStateUnsafe(),n=jc(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let d of n)d.sequence<=r.sequence||(r=d);let o=n.slice(-Zr).map(d=>d.id),s=mt(this.eventsFile)?sn(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,s),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!Ec(t.recentEventIds,o)||t.lastLocalEventAt!==r.timestamp))return t;let l={...t,status:eo(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(l),!c)return l;try{on(this.identity.projectRoot)}catch{return l}try{Yr(this.identity.projectRoot)}catch{}return l}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){N(this.stateFile,t)}acquireLock(){for(let t=0;t<xc;t+=1)try{return Ce(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-sn(this.lockFile).mtimeMs>bc){Qr(this.lockFile,{force:!0});continue}}catch{}Ic(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Me(n),Qr(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),o=n.lastSequence,s=[];for(let d of t){let p=Wr(d,this.eventContext),f=p.timestamp??new Date().toISOString(),m=p.data??{},S=p.provenance?.rawDigest??w(Ye(m)),g=ue(m),h=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,o+1,p.type,f,S].join("|"),v=w(h).slice(0,32);if(r.has(v))continue;o+=1;let I={version:1,id:v,sequence:o,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:S}};p.role!==void 0&&(I.role=p.role),p.turnId!==void 0&&(I.turnId=p.turnId),p.cwd!==void 0&&(I.cwd=p.cwd),p.sourceEventId!==void 0&&(I.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(I.sourceSequence=p.sourceSequence),s.push(I),r.add(v)}if(s.length===0)return[];let i=s.map(d=>JSON.stringify(d)).join(`
|
|
30
30
|
`)+`
|
|
31
|
-
`,a=
|
|
32
|
-
`)}function
|
|
33
|
-
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let l=u.toLowerCase().replace(/\s+/g," ");if(r.has(l))continue;r.add(l);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=
|
|
31
|
+
`,a=Ce(this.eventsFile,"a",384);try{no(a,i),cn(a)}finally{Me(a)}try{Xr(this.identity.projectRoot,s)}catch{try{on(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=eo(c),l=Array.from(r).slice(-Zr);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:l}),s})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!mt(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=sn(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let o=n-r,s=Buffer.alloc(o),i=Ce(this.eventsFile,"r");try{kc(i,s,0,o,r)}finally{Me(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=un(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),o=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:o,updatedAt:o})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ol,existsSync as sl,openSync as il,readSync as al,statSync as cl}from"node:fs";var Pc=new Set(["rule","blocker","architecture","deploy"]),Mc=new Set(["fix","todo","context","next_action"]);function ln(e){return e<0?0:e>1?1:e}function ro(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function Cc(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function dn(){return{mode:Cc(process.env.TOOLNET_MEMORY_PROMOTION),minScore:ln(ro(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:ln(ro(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Tc(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Oc(e){let t=ln(Tc(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function Rc(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Nc(e,t=dn()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=Rc(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="next_action"||e.kind==="fix"?"task":"session"}function _c(e,t=dn()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return Pc.has(e)&&(r=Math.max(.5,r-.1)),Mc.has(e)&&(r=Math.max(.5,r-.05)),r}function pn(e,t=dn()){let n=Nc(e,t),r=Oc(e),o=_c(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:{knowledgeClass:n,score:r,threshold:o,persist:r>=o}}function oo(e,t){let n=t.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":e==="rule"||e==="decision"?"high":e==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var co=[/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],Kc=[/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],Lc=[/\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],$c=[/\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],Dc=[/tiếp theo/iu,/bước tiếp theo/iu,/việc tiếp theo/iu,/sau đó cần/iu,/next step/iu,/next action/iu,/follow[- ]?up/iu],Fc=[/đã 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],so=[/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],Wc=[/\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],zc=[/đườ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],Hc=[/\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],io=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),qc=new Set(["payload","data","content","message","messages","parts","summary"]);function _(e,t){return t.some(n=>n.test(e))}function uo(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Jc(e){return uo(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Vc(e){return!(e.length<12||e.length>1e3||(e.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(e))}function fn(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!io.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let o of e.slice(0,50))fn(o,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[o,s]of Object.entries(e))(io.has(o)||qc.has(o))&&fn(s,o,n,r+1)}}function Bc(e){let t=[];fn(e.data,void 0,t);let n=[],r=new Set;for(let o of t)for(let s of o.split(/\n+|(?<=[.!?])\s+/u)){let i=uo(s);if(Vc(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function ao(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Gc(e,t,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message";return r&&_(e,co)?{kind:"rule",confidence:.98}:r&&_(e,Kc)?{kind:"rule",confidence:.92}:_(e,Lc)?{kind:_(e,so)?"architecture":"decision",confidence:r?.93:.86}:r&&_(e,Dc)?{kind:"next_action",confidence:.88}:r&&_(e,$c)?{kind:"todo",confidence:.87}:_(e,so)&&_(e,Wc)?{kind:"architecture",confidence:r?.88:.82}:o&&_(e,Fc)?{kind:"fix",confidence:.8}:r&&_(e,zc)&&_(e,Hc)?{kind:"context",confidence:.79}:null}function Uc(e,t,n){let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message",s=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:s,testVerified:i,crossSessionConfirmations:1,assistantDerived:o}}function Yc(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":case"next_action":return"todo";case"fix":case"context":return"code"}}function Xc(e,t,n){return e==="rule"&&_(n,co)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":oo(t,n)}function lo(e,t){let n=[],r=new Set,o=new Map;for(let s of t){let i=typeof s.data.messageId=="string"?s.data.messageId:void 0,a=ao(s);i&&a&&o.set(i,a)}for(let s of t){let i=ao(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of Bc(s)){let u=Gc(c,i,s);if(!u||u.confidence<.75)continue;let l=Yc(u.kind),d=Jc(c),p=w([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let f=s.provenance.sourcePath?[s.provenance.sourcePath]:[],m=s.sourceEventId?[s.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:l,content:c,confidence:u.confidence,importance:Xc(u.kind,l,c),evidence:Uc(u.kind,i,s),tags:[l],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:f,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as Qc}from"node:crypto";var Zc=["project-knowledge","implementation","continuation","session-context"],eu={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function mn(e){return Qc("sha256").update(e).digest("hex")}function gt(e,t){return`${e}:${mn(t).slice(0,24)}`}function tu(e){try{return mn(JSON.stringify(e))}catch{return mn(String(e))}}function ne(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function fo(e,t=420){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-1)).trimEnd()}\u2026`}function nu(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function po(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function ru(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,5).map(t=>fo(t.content)).join(" | ")}function ou(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,6).map(t=>fo(t.content)).join(`
|
|
32
|
+
`)}function mo(e,t){let n=e.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:gt("raw",[p.projectId,p.agent,p.nativeSessionId,p.id,String(p.sequence)].join("|")),level:"raw",eventId:p.id,sourceEventId:p.sourceEventId,sequence:p.sequence,type:p.type,role:p.role,timestamp:p.timestamp,sourcePath:p.provenance.sourcePath,payloadDigest:tu(p.data)})),o=new Map,s=new Map;n.forEach((p,f)=>{let m=r[f];m&&(o.set(p.id,m.id),p.sourceEventId&&s.set(p.sourceEventId,m.id))});let i=t.map(p=>{let f=ne([...p.provenance.eventIds.map(m=>o.get(m)),...p.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:gt("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:ne([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:f,sourcePaths:ne(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=nu(p.kind),m=a.get(f)??[];m.push(p),a.set(f,m)}let c=[];for(let p of Zc){let f=a.get(p);if(!f?.length)continue;let m=f.slice().sort((g,h)=>h.importanceScore-g.importanceScore||h.confidence-g.confidence||g.id.localeCompare(h.id)),S=m.map(g=>g.id);c.push({id:gt("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:eu[p],summary:ru(m),factIds:S,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:po(m.map(g=>g.confidence)),tags:ne(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:ne(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),l=[];for(let p of c){let m=p.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(m.length===0)continue;let S=m.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",g=ou(m);l.push({id:gt("knowledge",`${p.id}|${S}|${m.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:g,sceneIds:[p.id],factIds:m.map(h=>h.id),importanceScore:Math.max(...m.map(h=>h.importanceScore)),confidence:po(m.map(h=>h.confidence)),tags:ne(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...m.flatMap(h=>h.tags)]),sourcePaths:ne(m.flatMap(h=>h.sourcePaths))})}let d=[];for(let p of i)for(let f of p.rawIds)d.push({from:f,to:p.id,type:"supports"});for(let p of c)for(let f of p.factIds)d.push({from:f,to:p.id,type:"belongs_to"});for(let p of l)for(let f of p.sceneIds)d.push({from:f,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:l,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:l.length,links:d.length}}}function Te(){let e=Qe(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",o=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),s=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:o,sessionSummaryMaxTokens:s,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function go(e){return(e||Te()).durableMemoryMaxItemsPerSession}function yo(e){return(e||Te()).sessionSummaryMaxTokens}var ho=new B;function So(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(ho.sanitizeValue(r))}catch{}let n=ho.sanitize(e).text;return n=n.replace(/("(?:api[_-]?key|token|secret|password|cookie|authorization)"\s*:\s*)"[^"]*"/gi,'$1"[REDACTED]"').replace(/('(?:api[_-]?key|token|secret|password|cookie|authorization)'\s*:\s*)'[^']*'/gi,"$1'[REDACTED]'").replace(/\b(api[_-]?key|token|secret|password|cookie|authorization)\b\s*[:=]\s*[^\s,;]+/gi,"$1=[REDACTED]").replace(/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [REDACTED]"),n}function su(e,t){let n=e.toLowerCase(),r=.5,o=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of o)n.includes(i)&&(r+=.15);t==="rule"||t==="architecture"||t==="blocker"?r+=.2:t==="decision"||t==="deploy"?r+=.15:(t==="fix"||t==="next_action")&&(r+=.1),e.length<20?r-=.3:e.length>500&&(r-=.1);let s=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of s)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function iu(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
|
|
33
|
+
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let l=u.toLowerCase().replace(/\s+/g," ");if(r.has(l))continue;r.add(l);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=su(u,d);if(p<.3)continue;let f=So(u);n.push({category:d,text:f,importance:p,sourceSessionId:t})}}let o=Te(),s=go(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function au(e){let t=Te(),n=yo(t),s=e.join(`
|
|
34
34
|
|
|
35
35
|
`).split(`
|
|
36
|
-
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>
|
|
37
|
-
`);return
|
|
36
|
+
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>So(i)).join(`
|
|
37
|
+
`);return Kn(s,n)}function ko(e,t){let r=(Array.isArray(e)?e:e.split(`
|
|
38
38
|
|
|
39
|
-
`).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=Tc(r,t),s=o.filter(f=>f.category==="decision").map(f=>f.text),i=o.filter(f=>f.category==="rule").map(f=>f.text),a=o.filter(f=>f.category==="file").map(f=>f.text),c=o.filter(f=>f.category==="fix").map(f=>f.text),u=o.filter(f=>f.category==="blocker").map(f=>f.text),l=o.filter(f=>f.category==="next_action").map(f=>f.text),d=o.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:Rc(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:o}}function G(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function Nc(e){let t=new Map;for(let n of e){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,o=t.get(r);(!o||n.sequence>o.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function _c(e){let t=e.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of t)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function Kc(e){let t=tn(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:_c(e.content),tags:G([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function $c(e){return e.map(t=>{try{return JSON.stringify({type:t.type,role:t.role,data:t.data,provenance:{sourcePath:t.provenance.sourcePath,files:t.provenance.files}})}catch{return""}}).filter(Boolean)}function Lc(e,t,n){let r=Zr($c(t),e.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=G([...o,...r.nextActions]),c=G([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:G(r.decisions),files:G([...r.filesChanged,...s]),todos:a,completed:G(r.bugsFixed),blockers:G(r.blockers),nextActions:c,architecture:G(i)}}}function dt(e,t){let n=Nc(t),r=Hr(e,n).map(Kc),o=r.filter(l=>tn(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:s,state:i}=Lc(e,n,o),a=o.map(l=>({fingerprint:l.fingerprint,kind:l.kind,knowledgeClass:l.knowledgeClass,importanceScore:l.importanceScore,content:l.content,terms:l.retrievalTerms})),c=Br(n,o),u=l=>r.filter(d=>d.knowledgeClass===l).length;return{version:2,normalizedEvents:n,summary:s,state:i,candidates:o,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:o.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as Vc}from"node:crypto";import{existsSync as Bc,readdirSync as Gc,readFileSync as Uc}from"node:fs";import{basename as Yc,join as yo}from"node:path";import{randomUUID as to}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Pe(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function ne(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new A("Invalid Wiki slug",400);return t}function Qr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(ne(r))}return Pe(t)}function Fc(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function eo(e){return{id:`revision-${to()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function te(e){return structuredClone(e)}var pt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:Pe(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return te([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=ne(t),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new A(`Wiki page not found: ${t}`,404);return te(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new A("Wiki title is required",400);let s=ne(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new A(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${to()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:Pe(t.tags??[]),links:Qr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(eo(a)),te(a)})}async updatePage(t,n){return this.mutate(r=>{let o=ne(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new A(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new A("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=Qr(s.content)),n.tags!==void 0&&(s.tags=Pe(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(eo(s)),te(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return te(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return te(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=Pe(Fc(t));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),f=0;for(let m of o)u===m&&(f+=12),c===m&&(f+=10),c.includes(m)&&(f+=6),u.includes(m)&&(f+=5),p.some(S=>S===m)?f+=5:p.some(S=>S.includes(m))&&(f+=3),l.includes(m)&&(f+=2),d.includes(m)&&(f+=1);f>0&&i.push({page:te(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var no="wiki/state.v1.json";function Dc(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Wc(e,t){let n=JSON.parse(e);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==t.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var ft=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(no);if(!t){let n=Dc(this.project);return await this.save(n),n}return Wc(t,this.project)}async save(t){await this.storage.put(no,JSON.stringify(t,null,2),"application/json")}};import{createHash as zc,randomUUID as ro}from"node:crypto";var oo="wiki/governance.v1.json",co="toolnet.knowledge-governance.v1",so=500,Me={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function qc(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function on(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function io(e){return zc("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Hc(e){let t=[e.title,e.summary??"",e.content.slice(0,2e3),...e.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(t)}function Jc(e){let t=e.sourceType==="skill"?.96:e.sourceType==="memory"?.94:.88,n=e.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(t+=.03),e.content.length>=200&&(t+=.02),e.content.length<80&&(t-=.05),e.title.length<4&&(t-=.05),qc(t)}function ao(e){let t=new Date().toISOString();return{schema:co,version:1,projectId:e,policy:{...Me},reviews:[],audit:[],createdAt:t,updatedAt:t}}function uo(e){let t=e.autoApproveThreshold??Me.autoApproveThreshold,n=e.criticalApproveThreshold??Me.criticalApproveThreshold,r=e.staleAfterDays??Me.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new A("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new A("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new A("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var mt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(oo);if(!t){let n=ao(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==co||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:uo(n.policy??Me)}}catch{let n=ao(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(oo,JSON.stringify(t,null,2),"application/json")}},gt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,o={}){t.audit.push({id:ro(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),t.audit.length>so&&(t.audit=t.audit.slice(-so))}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=uo({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(o=>o.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),o=Jc(t),s=on(t.title),i=n.filter(l=>l.slug!==t.slug&&on(l.title)===s&&io(l.content)!==io(t.content)).map(l=>l.slug),a=Hc(t),c=[];o<r.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<r.policy.autoApproveThreshold||a&&o<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(s)};if(!r.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:ro(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===t&&s.digest===n&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(r,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===t);if(!s)throw new A(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new A("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=n.principal,s.updatedAt=i,n.note?.trim()&&(s.reviewNote=n.note.trim()),n.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s);if(n.action==="supersede")return s.status="superseded",n.targetReviewId&&(s.supersededBy=n.targetReviewId),this.audit(o,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(s);if(n.action==="merge"){if(!n.targetReviewId)throw new A("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new A("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await r.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new A(`Wiki page '${s.slug}' is manually managed`,409);return c?await r.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await r.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),o=Date.now(),s=n.policy.staleAfterDays*864e5,i=r.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of r){let d=on(l.title),p=a.get(d)??[];p.push(l),a.set(d,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(p=>p.slug)})),u=n.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var ho="wiki/automation.v1.json",So="toolnet.wiki-automation.v1",cn=8e3,lo=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Ee(e){return Vc("sha256").update(JSON.stringify(e)).digest("hex")}function Ce(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function po(e){return Array.isArray(e)?e:[]}function ko(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function sn(e){return Array.isArray(e)?e.map(ko).filter(t=>!!t):[]}function $(e,t){for(let n of t){let r=ko(e[n]);if(r)return r}}function Oe(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function yt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(lo.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>yt(i,t+1,n));let o=Ce(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();lo.has(c)||s.push(...yt(a,t+1,i))}return s}function fo(e){let n=Oe(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>yt(e[o],0,o)));return(n.length>0?n:Oe(yt(e))).join(`
|
|
39
|
+
`).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=iu(r,t),s=o.filter(f=>f.category==="decision").map(f=>f.text),i=o.filter(f=>f.category==="rule").map(f=>f.text),a=o.filter(f=>f.category==="file").map(f=>f.text),c=o.filter(f=>f.category==="fix").map(f=>f.text),u=o.filter(f=>f.category==="blocker").map(f=>f.text),l=o.filter(f=>f.category==="next_action").map(f=>f.text),d=o.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:au(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:o}}function U(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function cu(e){let t=new Map;for(let n of e){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,o=t.get(r);(!o||n.sequence>o.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function uu(e){let t=e.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of t)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function lu(e){let t=pn(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:uu(e.content),tags:U([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function du(e){return e.map(t=>{try{return JSON.stringify({type:t.type,role:t.role,data:t.data,provenance:{sourcePath:t.provenance.sourcePath,files:t.provenance.files}})}catch{return""}}).filter(Boolean)}function pu(e,t,n){let r=ko(du(t),e.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=U([...o,...r.nextActions]),c=U([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:U(r.decisions),files:U([...r.filesChanged,...s]),todos:a,completed:U(r.bugsFixed),blockers:U(r.blockers),nextActions:c,architecture:U(i)}}}function yt(e,t){let n=cu(t),r=lo(e,n).map(lu),o=r.filter(l=>pn(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:s,state:i}=pu(e,n,o),a=o.map(l=>({fingerprint:l.fingerprint,kind:l.kind,knowledgeClass:l.knowledgeClass,importanceScore:l.importanceScore,content:l.content,terms:l.retrievalTerms})),c=mo(n,o),u=l=>r.filter(d=>d.knowledgeClass===l).length;return{version:2,normalizedEvents:n,summary:s,state:i,candidates:o,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:o.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as vu}from"node:crypto";import{existsSync as wu,readdirSync as bu,readFileSync as xu}from"node:fs";import{basename as Iu,join as Ko}from"node:path";import{randomUUID as bo}from"node:crypto";var E=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Oe(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function oe(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new E("Invalid Wiki slug",400);return t}function vo(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(oe(r))}return Oe(t)}function fu(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function wo(e){return{id:`revision-${bo()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function re(e){return structuredClone(e)}var ht=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:Oe(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return re([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=oe(t),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new E(`Wiki page not found: ${t}`,404);return re(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new E("Wiki title is required",400);let s=oe(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new E(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${bo()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:Oe(t.tags??[]),links:vo(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(wo(a)),re(a)})}async updatePage(t,n){return this.mutate(r=>{let o=oe(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new E(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new E("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=vo(s.content)),n.tags!==void 0&&(s.tags=Oe(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(wo(s)),re(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return re(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return re(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=Oe(fu(t));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),f=0;for(let m of o)u===m&&(f+=12),c===m&&(f+=10),c.includes(m)&&(f+=6),u.includes(m)&&(f+=5),p.some(S=>S===m)?f+=5:p.some(S=>S.includes(m))&&(f+=3),l.includes(m)&&(f+=2),d.includes(m)&&(f+=1);f>0&&i.push({page:re(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var xo="wiki/state.v1.json";function mu(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function gu(e,t){let n=JSON.parse(e);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==t.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var St=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(xo);if(!t){let n=mu(this.project);return await this.save(n),n}return gu(t,this.project)}async save(t){await this.storage.put(xo,JSON.stringify(t,null,2),"application/json")}};import{createHash as yu,randomUUID as Io}from"node:crypto";var jo="wiki/governance.v1.json",Mo="toolnet.knowledge-governance.v1",Ao=500,Re={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function hu(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function gn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Eo(e){return yu("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Su(e){let t=[e.title,e.summary??"",e.content.slice(0,2e3),...e.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(t)}function ku(e){let t=e.sourceType==="skill"?.96:e.sourceType==="memory"?.94:.88,n=e.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(t+=.03),e.content.length>=200&&(t+=.02),e.content.length<80&&(t-=.05),e.title.length<4&&(t-=.05),hu(t)}function Po(e){let t=new Date().toISOString();return{schema:Mo,version:1,projectId:e,policy:{...Re},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Co(e){let t=e.autoApproveThreshold??Re.autoApproveThreshold,n=e.criticalApproveThreshold??Re.criticalApproveThreshold,r=e.staleAfterDays??Re.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new E("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new E("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new E("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var kt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(jo);if(!t){let n=Po(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Mo||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Co(n.policy??Re)}}catch{let n=Po(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(jo,JSON.stringify(t,null,2),"application/json")}},vt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,o={}){t.audit.push({id:Io(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),t.audit.length>Ao&&(t.audit=t.audit.slice(-Ao))}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=Co({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(o=>o.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),o=ku(t),s=gn(t.title),i=n.filter(l=>l.slug!==t.slug&&gn(l.title)===s&&Eo(l.content)!==Eo(t.content)).map(l=>l.slug),a=Su(t),c=[];o<r.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<r.policy.autoApproveThreshold||a&&o<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(s)};if(!r.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:Io(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===t&&s.digest===n&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(r,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===t);if(!s)throw new E(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new E("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=n.principal,s.updatedAt=i,n.note?.trim()&&(s.reviewNote=n.note.trim()),n.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s);if(n.action==="supersede")return s.status="superseded",n.targetReviewId&&(s.supersededBy=n.targetReviewId),this.audit(o,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(s);if(n.action==="merge"){if(!n.targetReviewId)throw new E("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new E("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await r.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new E(`Wiki page '${s.slug}' is manually managed`,409);return c?await r.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await r.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),o=Date.now(),s=n.policy.staleAfterDays*864e5,i=r.map(l=>{let d=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>s}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of r){let d=gn(l.title),p=a.get(d)??[];p.push(l),a.set(d,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(p=>p.slug)})),u=n.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Lo="wiki/automation.v1.json",$o="toolnet.wiki-automation.v1",Sn=8e3,To=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function _e(e){return vu("sha256").update(JSON.stringify(e)).digest("hex")}function Ne(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Oo(e){return Array.isArray(e)?e:[]}function Do(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function yn(e){return Array.isArray(e)?e.map(Do).filter(t=>!!t):[]}function $(e,t){for(let n of t){let r=Do(e[n]);if(r)return r}}function Ke(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function wt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(To.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>wt(i,t+1,n));let o=Ne(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();To.has(c)||s.push(...wt(a,t+1,i))}return s}function Ro(e){let n=Ke(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>wt(e[o],0,o)));return(n.length>0?n:Ke(wt(e))).join(`
|
|
40
40
|
|
|
41
|
-
`).slice(0,
|
|
41
|
+
`).slice(0,Sn)}function No(e,t){return $(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function _o(e,t){return $(e,["title","name","topic","label","task","kind","type"])??t}function ju(e){return($(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Au(e){return($(e,["kind","sceneKind","type"])??"").toLowerCase()}function Eu(e){let t=Ne(e);if(!t)return[];let n=[],r=Oo(t.knowledge);for(let[s,i]of r.entries()){let a=Ne(i);if(!a)continue;let c=ju(a);if(c==="session"||c==="transient")continue;let u=Ro(a);if(u.length<20)continue;let l=No(a,_e(a).slice(0,16)),d=_o(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${l}`,sourceType:"memory",title:d,summary:$(a,["summary","description"]),content:u,tags:Ke(["toolnet","auto","memory",...c?[c]:[]])})}let o=Oo(t.scenes);for(let[s,i]of o.entries()){let a=Ne(i);if(!a)continue;let c=Au(a);if(c==="session-context")continue;let u=Ro(a);if(u.length<20)continue;let l=No(a,_e(a).slice(0,16)),d=_o(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${l}`,sourceType:"scene",title:d,summary:$(a,["summary","description"]),content:u,tags:Ke(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Pu(e){return Ko(e,".toolnet","memory","skills")}function Mu(e){let t=Pu(e);if(!wu(t))return{candidates:[],failed:0};let n=[],r=0,o=bu(t).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(xu(Ko(t,s),"utf8")),a=Ne(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??Iu(s,".json"),u=$(a,["task"])??"",l=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=$(a,["summary"])??void 0,p=yn(a.steps),f=yn(a.verification),m=yn(a.files),S=[];u&&S.push(`## Task
|
|
42
42
|
${u}`),d&&S.push(`## Summary
|
|
43
43
|
${d}`),p.length>0&&S.push(`## Procedure
|
|
44
44
|
${p.map((h,v)=>`${v+1}. ${h}`).join(`
|
|
@@ -48,24 +48,24 @@ ${f.map(h=>`- ${h}`).join(`
|
|
|
48
48
|
${m.map(h=>`- \`${h}\``).join(`
|
|
49
49
|
`)}`);let g=S.join(`
|
|
50
50
|
|
|
51
|
-
`).slice(0,
|
|
52
|
-
`).slice(0,
|
|
53
|
-
`,{encoding:"utf8",mode:384}),
|
|
54
|
-
`,c=w(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),l=[
|
|
55
|
-
`,"application/json"),u}};function
|
|
51
|
+
`).slice(0,Sn);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:l,summary:d,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function hn(e){let t=new Date().toISOString();return{schema:$o,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Cu(e,t){let n=await e.getText(Lo);if(!n)return hn(t);try{let r=JSON.parse(n);return r.schema!==$o||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?hn(t):r}catch{return hn(t)}}async function Tu(e,t){await e.put(Lo,JSON.stringify(t,null,2),"application/json")}function Ou(e){return`toolnet-auto-${_e(e).slice(0,12)}`}function Ru(e){let t=oe(e.title).slice(0,72),n=_e(e.sourceKey).slice(0,10);return oe(`auto-${e.sourceType}-${t}-${n}`)}function Nu(e){return[`> Auto-generated by ToolNet Knowledge Automation from ${e.sourceType==="skill"?"reusable Skill Memory":e.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",e.content].join(`
|
|
52
|
+
`).slice(0,Sn)}function _u(e){return _e({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Ku(e,t){return e.tags.includes(t)}async function Fo(e){let t=Eu(e.hierarchy),n=Mu(e.project.rootPath),r=new Map;for(let f of[...t,...n.candidates])r.set(f.sourceKey,f);let o=[...r.values()].sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),s={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:o.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new ht(new St(e.storage,e.project));await i.initialize();let a=new vt(new kt(e.storage,e.project));await a.initialize();let c=await Cu(e.storage,e.project.id),u=await i.listPages(),l=new Map(u.map(f=>[f.slug,f])),d=new Map(c.entries.map(f=>[f.sourceKey,f]));for(let f of o)try{let m=Ou(f.sourceKey),S=_u(f),g=d.get(f.sourceKey),h=g?.slug??Ru(f),v=l.get(h);if(v&&!Ku(v,m)){s.skipped+=1;continue}let I=Ke([...f.tags,m]),O=Nu(f),C=await a.gate({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,marker:m,digest:S,title:f.title,...f.summary?{summary:f.summary}:{},content:O,tags:I},[...l.values()]);if(!C.allowed){C.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}C.mode==="auto-approved"?s.autoApproved+=1:C.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==S?(v=await i.updatePage(h,{title:f.title,summary:f.summary??"",content:O,tags:I}),l.set(v.slug,v),s.updated+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"updated"})):(s.unchanged+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,action:"unchanged"})):(v=await i.createPage({slug:h,title:f.title,summary:f.summary,content:O,tags:I}),l.set(v.slug,v),s.created+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"created"}));let R=new Date().toISOString(),j={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,digest:S,marker:m,updatedAt:R},b=c.entries.findIndex(z=>z.sourceKey===f.sourceKey);b>=0?c.entries[b]=j:c.entries.push(j),d.set(f.sourceKey,j),await a.markApplied(f.sourceKey,S)}catch(m){if(m instanceof E&&m.statusCode===409){s.skipped+=1;continue}s.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),await Tu(e.storage,c),s}import{createHash as Lu}from"node:crypto";import{chmodSync as zo,existsSync as $u,mkdirSync as Du,readFileSync as Ky,readdirSync as Ly,renameSync as Fu,statSync as $y,writeFileSync as Wu}from"node:fs";import{join as Ho}from"node:path";var zu="toolnet.skill-memory.v1",Wo=5,Hu=16,qu=24,Ju=32;function Vu(e){return Lu("sha256").update(e).digest("hex")}function $e(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function kn(e,t=360){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,Math.max(0,t-1)).trimEnd()+"\u2026"}function Bu(e){return e.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function q(e,t=360){return e&&kn(Bu(e),t)||void 0}function De(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function qo(e,t){for(let n of t){let r=e[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function Jo(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let o=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(o))return!0;if(["false","no","fail","failed","error"].includes(o))return!1}}}function Vo(e){let t=e.data??{};if(Jo(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=qo(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let o=De(t,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function Le(e){let t=e.data??{};if(Vo(e))return!1;if(Jo(t,["passed","pass","success","succeeded","ok"])===!0||qo(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=De(t,["status","result","outcome"]);return o&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(o)?!0:e.type==="commit"||e.type==="deploy"}function Bo(e){let t=e.data??{},n=De(t,["path","file","filePath","filename","target"]);if(n)return q(n,260);let r=e.provenance?.files;return q(r?.[0],260)}function vn(e){return q(De(e.data??{},["command","cmd","script"]),420)}function me(e){return q(De(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Gu(e){let t=[];for(let n of[...e].sort((r,o)=>r.sequence-o.sequence))if(Le(n)){if(n.type==="test"){let r=me(n)??vn(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=me(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=me(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return $e(t,10)}function Uu(e,t){let n=[];for(let r of[...e].sort((o,s)=>o.sequence-s.sequence))switch(r.type){case"file_write":case"file_edit":{let o=Bo(r);o&&n.push(`Update ${o}`);break}case"command":{if(Vo(r))break;let o=vn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!Le(r))break;let o=me(r)??vn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!Le(r))break;let o=me(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!Le(r))break;let o=me(r);n.push(o?`Deploy: ${o}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let o=q(r,260);o&&n.push(`Update ${o}`)}return $e(n,Hu)}function Yu(e,t){let n=[...t.files];for(let r of e){let o=Bo(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=q(s,260);i&&n.push(i)}}return $e(n,qu)}function Xu(e){return $e(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Ju)}function Qu(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Go(e,t,n){if(t.length===0)return[];let r=Gu(t),o=$e(n.completed.map(m=>q(m,280)??""),Wo);if(!(o.length>0||t.some(m=>["test","commit","deploy"].includes(m.type)&&Le(m))))return[];let i=q(n.task,280)??q(n.nextActions[0],280),a=o.length>0?o:i?[i]:[];if(a.length===0)return[];let c=Uu(t,n);if(c.length===0)return[];let u=Yu(t,n),l=Xu(t),d=Math.min(...t.map(m=>m.sequence)),p=Math.max(...t.map(m=>m.sequence)),f=Qu(t);return a.slice(0,Wo).map(m=>{let S=[`Reusable procedure learned from successful task: ${m}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),g=JSON.stringify({projectId:e.projectId,task:m,steps:c,verification:r,files:u}),h=Vu(g);return{schema:zu,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:kn(`SOP: ${m}`,180),task:m,summary:kn(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:l},createdAt:f}})}function Zu(e){return Ho(e.rootPath,".toolnet","memory","skills")}function el(e){let t=Zu(e);return Du(t,{recursive:!0,mode:448}),zo(t,448),t}function Uo(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=el(e),r=0,o=0,s=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=Ho(n,`${i.id}.json`);if(s.push(a),$u(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Wu(c,JSON.stringify(i,null,2)+`
|
|
53
|
+
`,{encoding:"utf8",mode:384}),Fu(c,a),zo(a,384),r+=1}return{written:r,deduped:o,files:s}}var Yy="0".repeat(64);function Yo(e){return String(e).padStart(12,"0")}function tl(e){return`projects/${e.projectId}/memory/learned`}var bt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let o=Math.min(...n.map(d=>d.sequence)),s=Math.max(...n.map(d=>d.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
|
|
54
|
+
`,c=w(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),l=[tl(t),"batches",`${Yo(o)}-${Yo(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(l)||await this.storage.put(l,a,"application/json"),l}};import{createHash as nl}from"node:crypto";function Xo(e){return String(e).padStart(12,"0")}function Qo(e){return nl("sha256").update(e).digest("hex")}function rl(e){return`projects/${e.projectId}/memory/hierarchy`}var xt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let o=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,hierarchy:r},a=Qo([...r.facts.map(l=>l.id),...r.knowledge.map(l=>l.id)].sort().join("|")).slice(0,16),c=Qo(t.sessionKey).slice(0,12),u=[rl(t),"batches",`${Xo(o)}-${Xo(s)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
|
|
55
|
+
`,"application/json"),u}};function ul(e,t){if(!sl(e))return{events:[],nextOffset:t};let n=cl(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=il(e,"r");try{al(i,s,0,o,r)}finally{ol(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
56
56
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
57
|
-
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
58
|
-
`))))}function
|
|
59
|
-
`).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
|
|
57
|
+
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var It=class{constructor(t){this.options=t;this.journal=new bt(t.storage),this.hierarchyJournal=new xt(t.storage)}options;journal;hierarchyJournal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,o=ul(this.options.wal.eventsFile,r);if(o.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:o.nextOffset};let s=yt(this.options.identity,o.events),i=s.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,o.events,i));let c=!1;s.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,o.events,s.hierarchy));let u=Go(this.options.identity,o.events,s.state),l=Uo(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",s.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",s.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",s.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",s.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",s.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",s.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",s.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",s.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",s.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",s.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",s.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",l.written),this.options.wal.setSourceCursor("memory.skill.deduped",l.deduped);try{let d=Hn(this.options.project.rootPath,o.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",d.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",d.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",d.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",d.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let d=await Fo({project:this.options.project,storage:this.options.storage,hierarchy:s.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",d.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",d.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",d.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",d.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",d.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",d.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",d.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",d.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",d.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",d.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",o.nextOffset),{scannedEvents:o.events.length,candidates:i.length,journalWritten:a,nextOffset:o.nextOffset}}};import{closeSync as Al,existsSync as El,openSync as Pl,readSync as Ml,statSync as Cl}from"node:fs";function Zo(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function We(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Fe(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let o of e.slice(0,50))Fe(o,t,n+1);return}let r=Zo(e);if(r)for(let[o,s]of Object.entries(r))t(o,s,r),Fe(s,t,n+1)}function ge(e,t){let n=[];return Fe(e,(r,o)=>{t.has(We(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function ll(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Zo(JSON.parse(t))}catch{return null}}function dl(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let o=t[r];if(typeof o=="string"&&o.trim())return o.trim().toLowerCase()}let n="";return Fe(t,(r,o,s)=>{if(n)return;let i=We(r);if(["tool","toolname"].includes(i)&&typeof o=="string"){n=o.trim().toLowerCase();return}if(i!=="name"||typeof o!="string")return;let a=typeof s.type=="string"?s.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=o.trim().toLowerCase())}),n}function pl(e){let t=ge(e.data,new Set(["command","cmd","script"])),n=ge(e.data,new Set(["arguments","args"]));for(let r of n){let o=ll(r);if(o)for(let s of ge(o,new Set(["command","cmd","script"])))t.push(s)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function fl(e){let t=ge(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(We)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
|
|
58
|
+
`))))}function ml(e,t){return e.type==="file_edit"||e.type==="file_write"?"modified":/\b(delete|remove|unlink)\b/iu.test(t)?"deleted":/\b(create|add[_-]?file|new[_-]?file)\b/iu.test(t)?"created":/\b(edit|write|patch|apply[_-]?patch|replace|update[_-]?file)\b/iu.test(t)?"modified":null}function gl(e){let t=ge(e.data,new Set(["patch","diff","arguments","input"].map(We))),n=[];for(let r of t){let o=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let s of o)for(let i of r.matchAll(s.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:s.action,confidence:.99})}}return n}function yl(e){let t=e.toLowerCase();return/\b(typecheck|type-check)\b/u.test(t)||/\btsc\b[\s\S]*--noemit\b/u.test(t)?"typecheck":/\b(eslint|lint)\b/u.test(t)?"lint":/\b(vitest|jest|pytest)\b/u.test(t)||/\bgo\s+test\b/u.test(t)||/\bcargo\s+test\b/u.test(t)||/\b(npm|pnpm|yarn)\s+(run\s+)?test\b/u.test(t)?"test":/\b(npm|pnpm|yarn)\s+(run\s+)?build\b/u.test(t)||/\bcargo\s+build\b/u.test(t)||/\bgo\s+build\b/u.test(t)||/\btsc\b/u.test(t)?"build":null}function hl(e){let t=null;return Fe(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(We(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let o=Number(r);Number.isFinite(o)&&(t=o)}}}),t}function Sl(e){return ge(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function kl(e){let t=hl(e.data);if(t!==null)return t===0?"passed":"failed";let n=Sl(e.data).join(`
|
|
59
|
+
`).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 vl(e){let t=[],n=new Set;for(let r of e){let o=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(o)||(n.add(o),t.push(r))}return t}function es(e){let t=[],n=dl(e),r=ml(e,n);if(r)for(let o of fl(e))t.push({kind:"file",text:o,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...gl(e));for(let o of pl(e)){t.push({kind:"command",text:o,confidence:.98});let s=yl(o);s&&t.push({kind:"test",text:o,checkKind:s,checkStatus:kl(e),confidence:.98})}return vl(t)}var wl=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ie(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function ns(e){return ie(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function se(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))se(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(wl.has(r)||["data","payload","parts","messages"].includes(r))&&se(o,t,n+1)}}function jt(e){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(e)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(e)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(e)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(e)?"in_progress":"pending"}function ts(e){let t=ie(e);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(t)}function P(e,t,n,r,o={}){let s=ie(r),i=o.key??ns(s);return{version:1,id:w([e.projectId,n,i,t.id,s,o.status??"",o.fileAction??"",o.checkKind??"",o.checkStatus??"",o.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:s,status:o.status,fileAction:o.fileAction,checkKind:o.checkKind,checkStatus:o.checkStatus,order:o.order,confidence:o.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function bl(e,t,n){let r=ie(n);if(r.length<5||r.length>1200)return[];let o=[],s=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&o.push(P(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(P(e,t,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!s&&(u=c.exec(r));){let p=Number(u[1]),f=ie(u[2]??""),m=f&&!ts(f)?`Phase ${p} - ${f}`:`Phase ${p}`;o.push(P(e,t,"phase",m,{key:`phase:${p}`,order:p,status:jt(r),confidence:.93}))}let l=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);l?.[2]&&o.push(P(e,t,"task",l[2],{status:l[1].trim()?"completed":jt(l[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,f=ie(d[2]),m=ts(f);o.push(P(e,t,"task",m&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:ns(f),order:p,status:jt(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let p=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");p&&o.push(P(e,t,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&o.push(P(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(P(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.push(P(e,t,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&o.push(P(e,t,"activity",r,{confidence:.86})),o}function At(e,t){if(t.length===0)return[];let n=[],r=new Set;function o(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let c=[];se(i.data,c);let u=c.map(l=>ie(l)).find(l=>l.length>=8&&l.length<=1200&&!/^\[?toolnet\b/iu.test(l));u&&o(P(e,i,"request",u,{confidence:.96}))}for(let c of es(i))o(P(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];se(i.data,c);for(let u of c)o(P(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];se(i.data,c);for(let u of c)o(P(e,i,"task",u,{status:jt(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&o(P(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];se(i.data,c);for(let u of c)o(P(e,i,"test",u,{confidence:1}))}let a=[];se(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let l of bl(e,i,u))o(l)}let s=t[t.length-1];return o(P(e,s,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function rs(e){return String(e).padStart(12,"0")}var Et=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(l=>l.sequence)),o=Math.max(...n.map(l=>l.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(l=>l.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:o,observations:n},i=JSON.stringify(s,null,2)+`
|
|
60
60
|
`,a=w(n.map(l=>JSON.stringify(l)).sort().join(`
|
|
61
|
-
`)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${
|
|
62
|
-
`,"application/json"),
|
|
61
|
+
`)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${rs(r)}-${rs(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as os}from"node:path";import{mkdirSync as xl}from"node:fs";function is(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function D(e,t=20){let n=[],r=new Set;for(let o of e.slice().reverse()){let s=is(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=t))break}return n.reverse()}function Il(e,t=20){let n=new Map;for(let r of e){let o=`${r.kind}|${is(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-t)}function jl(e){return e.kind==="phase"?/^Phase\s+\d+$/iu.test(e.text):e.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(e.text):!1}function ss(e,t){let n=t.status??e?.status??"pending",r=n;e&&(e.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status));let o=e&&jl(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:o,status:r,order:t.order??e?.order,confidence:Math.max(t.confidence,e?.confidence??0),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}async function as(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}async function ze(e,t){let r=(await as(e,t)).flatMap(y=>y.observations).sort((y,k)=>{let T=y.occurredAt.localeCompare(k.occurredAt);if(T!==0)return T;let J=y.sequence-k.sequence;return J!==0?J:y.id.localeCompare(k.id)}),o=new Map,s=new Map,i,a,c,u,l,d=[],p=[],f=[],m=[],S=[],g=new Map,h=[],v=[],I=[],O=[],C=[],R=[];for(let y of r)switch(y.kind){case"request":i=y.text;break;case"activity":a=y.text;break;case"goal":c=y.text;break;case"plan":u=y.text;break;case"phase":o.set(y.key,ss(o.get(y.key),y));break;case"task":s.set(y.key,ss(s.get(y.key),y));break;case"decision":d.push(y.text);break;case"blocker":p.push(y.text);break;case"warning":f.push(y.text);break;case"next_action":m.push(y.text);break;case"file":{S.push(y.text);let k=y.fileAction??"active";g.delete(y.text),g.set(y.text,k),k==="modified"?h.push(y.text):k==="created"?v.push(y.text):k==="deleted"&&I.push(y.text);break}case"command":O.push(y.text);break;case"test":C.push(y.text),y.checkKind&&R.push({kind:y.checkKind,command:y.text,status:y.checkStatus??"unknown",updatedAt:y.occurredAt,agent:y.agent,nativeSessionId:y.nativeSessionId});break;case"session":l={agent:y.agent,nativeSessionId:y.nativeSessionId,sessionKey:y.sessionKey,updatedAt:y.occurredAt};break}let j=Array.from(o.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),b=Array.from(s.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),z=j.find(y=>y.status==="in_progress")??j.find(y=>y.status==="blocked")??j.find(y=>y.status==="pending"),H=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),$t=D([...m,...H?[H.title]:[],...!H&&z?[z.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),Dt=D([...p,...j.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),he={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:j,tasks:b,decisions:D(d,20),blockers:Dt,warnings:D(f,20),nextActions:$t,filesTouched:D(S,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:D(h,30),createdFiles:D(v,30),deletedFiles:D(I,30),commands:D(O,20),tests:D(C,20),checks:Il(R,20),currentPhase:z,currentTask:H,progress:{phasesTotal:j.length,phasesCompleted:j.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:j.filter(y=>y.status==="blocked").length+b.filter(y=>y.status==="blocked").length},lastSession:l,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},Ge=os(e.rootPath,".toolnet","work");return xl(Ge,{recursive:!0}),N(os(Ge,"current.json"),he),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(he,null,2)+`
|
|
62
|
+
`,"application/json"),he}async function cs(e,t){if((await as(e,t)).length>0)return ze(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function Tl(e,t){if(!El(e))return{events:[],nextOffset:t};let n=Cl(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=Pl(e,"r");try{Ml(i,s,0,o,r)}finally{Al(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
63
63
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
64
|
-
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
65
|
-
`,"application/json"),c}};import{mkdirSync as
|
|
66
|
-
`,"application/json"),f}function
|
|
64
|
+
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Pt=class{constructor(t){this.options=t;this.journal=new Et(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=Tl(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let o=At(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await ze(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Fl,existsSync as Wl,openSync as zl,readSync as Hl,statSync as ql}from"node:fs";var Ol=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ye(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function wn(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))wn(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Ol.has(r)||["data","payload","parts","messages"].includes(r))&&wn(o,t,n+1)}}function K(e,t,n,r,o,s=.95){let i=ye(r);return{version:1,id:w([e.projectId,n,o.type,o.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:o.type,scopeKey:o.key,scopeOrder:o.order,confidence:s,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function F(e,t){let n=e.toLowerCase();for(let r of t){let o=r.toLowerCase();if(n.startsWith(`${o}:`)||n.startsWith(`${o} -`)||n.startsWith(`${o} \u2014`))return ye(e.slice(r.length+1))}return null}function Rl(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Nl(e){return ye(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function us(e,t){let n=[],r=new Set;function o(s){!s.value||s.value.length<3||r.has(s.id)||(r.add(s.id),n.push(s))}for(let s of t){let i=[];wn(s.data,i);for(let a of i){let c={type:"project"},u=null;for(let l of a.split(/\r?\n/u)){let d=ye(l);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let b=Number(p[1]);c={type:"phase",key:`phase:${b}`,order:b,title:ye(p[2]??"")},u=null;continue}let f=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let b=Number(f[1]);c={type:"task",key:`task:${b}`,order:b,title:ye(f[2]??"")},u=null;continue}let m=F(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o(K(e,s,"mission",m,{type:"project"},.99)),u=null;continue}let S=F(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){o(K(e,s,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let g=F(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o(K(e,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let h=F(d,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){o(K(e,s,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let v=F(d,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(v){o(K(e,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let I=F(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(I){o(K(e,s,"phase_deliverable",I,c,.97)),u=null;continue}let O=F(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(O){o(K(e,s,"acceptance_criterion",O,c,.98)),u="acceptance_criterion";continue}let C=F(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(C){o(K(e,s,"dependency",C,c,.97)),u="dependency";continue}let R=F(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){o(K(e,s,"open_question",R,c,.95)),u="open_question";continue}let j=F(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(j){o(K(e,s,"constraint",j,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&Rl(l)){o(K(e,s,u,Nl(l),c,.96));continue}u=null}}}return n}function ls(e){return String(e).padStart(12,"0")}var Mt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),o=Math.max(...n.map(u=>u.evidence.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:o,createdAt:new Date().toISOString(),observations:n},i=w(n.map(u=>u.id).sort().join("|")).slice(0,16),a=w(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${ls(r)}-${ls(o)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(s,null,2)+`
|
|
65
|
+
`,"application/json"),c}};import{mkdirSync as _l}from"node:fs";import{join as ds}from"node:path";function Kl(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function Ll(e,t){if(!t)return!0;let n=e.evidence.occurredAt.localeCompare(t.evidence.occurredAt);return n!==0?n>0:e.evidence.sessionKey===t.evidence.sessionKey?e.evidence.sequence>=t.evidence.sequence:e.confidence>=t.confidence}function Y(e,t){return Ll(t,e)?t:e}function X(e,t=30){let n=new Set,r=[];for(let o of e){let s=o.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!s||n.has(s)||(n.add(s),r.push(o))}return r.slice(-t)}async function $l(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}function Dl(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function ps(e,t){let r=(await $l(e,t)).flatMap(S=>S.observations).sort((S,g)=>{let h=S.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===g.evidence.sessionKey?S.evidence.sequence-g.evidence.sequence:S.id.localeCompare(g.id)}),o,s,i,a,c,u=new Map,l=[],d=[],p=[];for(let S of r){let g=Kl(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??Dl(S);switch(S.kind){case"phase_objective":h.objective=Y(h.objective,g);break;case"phase_why":h.why=Y(h.why,g);break;case"phase_deliverable":h.deliverable=Y(h.deliverable,g);break;case"acceptance_criterion":h.acceptanceCriteria.push(g);break;case"dependency":h.dependencies.push(g);break;case"open_question":h.openQuestions.push(g);break;case"constraint":h.constraints.push(g);break;case"note":h.notes.push(g);break}u.set(h.key,h);continue}switch(S.kind){case"mission":o=Y(o,g);break;case"objective":s=Y(s,g);break;case"why":i=Y(i,g);break;case"desired_outcome":a=Y(a,g);break;case"plan_rationale":c=Y(c,g);break;case"open_question":l.push(g);break;case"constraint":d.push(g);break;case"note":p.push(g);break}}for(let S of u.values())S.acceptanceCriteria=X(S.acceptanceCriteria,20),S.dependencies=X(S.dependencies,15),S.openQuestions=X(S.openQuestions,15),S.constraints=X(S.constraints,15),S.notes=X(S.notes,20);let f={version:1,projectId:e.id,projectName:e.name,mission:o,activeObjective:s,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,g)=>S.order-g.order),openQuestions:X(l,20),constraints:X(d,20),notes:X(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=ds(e.rootPath,".toolnet","work");return _l(m,{recursive:!0}),N(ds(m,"semantic-current.json"),f),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
|
|
66
|
+
`,"application/json"),f}function Jl(e,t){if(!Wl(e))return{events:[],nextOffset:t};let n=ql(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=Buffer.alloc(n-r),s=zl(e,"r");try{Hl(s,o,0,o.length,r)}finally{Fl(s)}let i=o.toString("utf8"),a=i.lastIndexOf(`
|
|
67
67
|
`);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
|
|
68
|
-
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var
|
|
68
|
+
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Ct=class{constructor(t){this.options=t;this.journal=new Mt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=Jl(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let o=us(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await ps(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as $d,mkdirSync as Dd}from"node:fs";import{join as xn}from"node:path";import{existsSync as gs,mkdirSync as Vl,readFileSync as Bl,statSync as fs,writeFileSync as Gl}from"node:fs";import{dirname as Ul,join as Yl}from"node:path";var ms=64*1024,Xl=`# ToolNet Project Operating Manual
|
|
69
69
|
|
|
70
70
|
This file contains persistent instructions for AI agents working on this project.
|
|
71
71
|
|
|
@@ -108,16 +108,16 @@ Things an AI agent should always remember.
|
|
|
108
108
|
<!--
|
|
109
109
|
- [advisory] Prefer small focused files.
|
|
110
110
|
-->
|
|
111
|
-
`;function
|
|
112
|
-
`,{encoding:"utf8"}),
|
|
113
|
-
`,{encoding:"utf8"}),
|
|
114
|
-
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function
|
|
111
|
+
`;function ys(e){return Yl(e.rootPath,".toolnet","PROJECT.md")}function Ql(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Zl(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,o;for(;o=r.exec(e);){let s=o[1].toLowerCase(),i=Ql(o[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:s,text:i,source:"manual"}))}return t}function ed(e){let t=ys(e);return gs(t)||(Vl(Ul(t),{recursive:!0}),Gl(t,Xl,{encoding:"utf8",mode:384})),t}function hs(e,t=!1){let n=t?ed(e):ys(e);if(!gs(n))return null;if(fs(n).size>ms)throw new Error(`PROJECT.md exceeds ${ms} bytes`);let o=Bl(n,"utf8");return{path:n,content:o,digest:w(o),rules:Zl(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(fs(n).mtimeMs).toISOString()}}import{randomUUID as td}from"node:crypto";import{closeSync as nd,existsSync as Ss,fsyncSync as rd,mkdirSync as od,openSync as sd,readFileSync as id,statSync as ad,unlinkSync as ks,writeFileSync as cd}from"node:fs";import{dirname as ud,join as ld}from"node:path";var dd=new Int32Array(new SharedArrayBuffer(4));function pd(e){e<=0||Atomics.wait(dd,0,0,e)}function fd(e){return ld(e.rootPath,".toolnet","work",".current.lock")}function md(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function vs(e){if(!Ss(e))return null;try{let t=JSON.parse(id(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function gd(e){try{return Date.now()-ad(e).mtimeMs}catch{return 0}}function yd(e,t){if(!Ss(e)||gd(e)<t)return!1;let n=vs(e);return n?!md(n.pid):!0}function hd(e,t){if(!yd(e,t))return!1;try{return ks(e),!0}catch{return!1}}function Sd(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=sd(e,"wx",384);try{cd(r,`${JSON.stringify(n,null,2)}
|
|
112
|
+
`,{encoding:"utf8"}),rd(r)}finally{nd(r)}}function kd(e,t){if(vs(e)?.token===t)try{ks(e)}catch{}}function vd(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),o=Math.max(n*2,t.staleMs??3e4),s=fd(e);od(ud(s),{recursive:!0});let i=td(),a=Date.now()+n;for(;;)try{Sd(s,i);let c=!1;return()=>{c||(c=!0,kd(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(hd(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);pd(r)}}function ws(e,t,n={}){let r=vd(e,n);try{return t()}finally{r()}}import{closeSync as wd,existsSync as bd,fsyncSync as xd,mkdirSync as Id,openSync as jd,readFileSync as Ad,renameSync as Ed,writeFileSync as Pd}from"node:fs";import{dirname as Md,join as Cd}from"node:path";function Td(e,t){Id(Md(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=jd(n,"w",384);try{Pd(r,`${JSON.stringify(t,null,2)}
|
|
113
|
+
`,{encoding:"utf8"}),xd(r)}finally{wd(r)}Ed(n,e)}function Es(e){return Cd(e.rootPath,".toolnet","work","current.json")}function bn(e){let t=Es(e);if(!bd(t))return null;try{let n=JSON.parse(Ad(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function Tt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(e,t,n){let r=[],o=new Set;for(let s of[...e,...t].reverse()){let i=Tt(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function Od(e,t,n=20){let r=new Map;for(let o of[...e,...t]){let s=`${o.kind}|${Tt(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function Rd(e){return e.kind==="phase"?/^Phase\s+\d+$/iu.test(e.text):e.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(e.text):!1}function bs(e,t){let n=t.status??e?.status??"pending",r=n;e?.status==="completed"&&n!=="completed"&&(r="completed"),e&&n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status);let o=e&&Rd(t)?e.title:t.text;return{id:e?.id??t.id,title:o,status:r,order:t.order??e?.order,confidence:Math.max(e?.confidence??0,t.confidence),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}function xs(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:Tt(n.title);t.set(r,n)}return t}function Is(e){return e.order!==void 0?`order:${e.order}`:Tt(e.key||e.text)}function js(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,o=n.order??Number.MAX_SAFE_INTEGER;return r!==o?r-o:t.updatedAt.localeCompare(n.updatedAt)})}function As(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function Nd(e,t){let n=bn(e),r=xs(n?.phases??[]),o=xs(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,l=[],d=[],p=[],f=[],m=[],S=[...n?.activeFiles??[]],g=[],h=[],v=[],I=[],O=[],C=[],R=[...t].sort((k,T)=>{let J=k.occurredAt.localeCompare(T.occurredAt);return J!==0?J:k.sequence-T.sequence});for(let k of R)switch(k.kind){case"request":s=k.text;break;case"activity":i=k.text;break;case"goal":a=k.text;break;case"plan":c=k.text;break;case"phase":{let T=Is(k);r.set(T,bs(r.get(T),k));break}case"task":{let T=Is(k);o.set(T,bs(o.get(T),k));break}case"decision":l.push(k.text);break;case"blocker":d.push(k.text);break;case"warning":p.push(k.text);break;case"next_action":f.push(k.text);break;case"file":{m.push(k.text);let T=k.fileAction??"active",J=S.indexOf(k.text);J>=0&&S.splice(J,1),T!=="deleted"&&S.push(k.text),T==="modified"?g.push(k.text):T==="created"?h.push(k.text):T==="deleted"&&v.push(k.text);break}case"command":I.push(k.text);break;case"test":O.push(k.text),k.checkKind&&C.push({kind:k.checkKind,command:k.text,status:k.checkStatus??"unknown",updatedAt:k.occurredAt,agent:k.agent,nativeSessionId:k.nativeSessionId});break;case"session":u={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let j=js(r.values()),b=js(o.values()),z=As(j),H=As(b),$t=L(n?.nextActions??[],[...f,...H?[H.title]:[],...!H&&z?[z.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),Dt=L(n?.blockers??[],[...d,...j.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),he=R.length>0?R[R.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),Ge={version:1,projectId:e.id,projectName:e.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:j,tasks:b,decisions:L(n?.decisions??[],l,20),blockers:Dt,warnings:L(n?.warnings??[],p,20),nextActions:$t,filesTouched:L(n?.filesTouched??[],m,30),activeFiles:L([],S,5),modifiedFiles:L(n?.modifiedFiles??[],g,30),createdFiles:L(n?.createdFiles??[],h,30),deletedFiles:L(n?.deletedFiles??[],v,30),commands:L(n?.commands??[],I,20),tests:L(n?.tests??[],O,20),checks:Od(n?.checks??[],C,20),currentPhase:z,currentTask:H,progress:{phasesTotal:j.length,phasesCompleted:j.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:j.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:he},y=ue(Ge);return Td(Es(e),y),y}function Ps(e,t){return ws(e,()=>Nd(e,t))}function M(e,t){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/g," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function Ms(e){if(e)return{id:e.id,title:e.title,status:e.status}}function _d(e,t=[]){let n=t.slice(-10);if(n.some(o=>o.status==="failed"))return"failing";if(n.some(o=>o.status==="passed"))return"passing";let r=e.slice(-10).join(`
|
|
114
|
+
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Kd(e){return w(JSON.stringify(e))}function Ld(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let o of r){let s=o.replace(/[.,;:!?]+$/gu,"").trim();s&&t.push(s)}}return M(t,30)}function Cs(e){let{project:t,identity:n,state:r}=e,o=r.activeFiles?.at(-1)??r.filesTouched.at(-1),s=r.phases.filter(v=>v.status==="completed").map(v=>v.title),i=r.tasks.filter(v=>v.status==="completed").map(v=>v.title),a=r.phases.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),c=r.tasks.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),u=new Set(r.tasks.filter(v=>v.status==="completed").map(v=>v.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),l=M(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=M([...c,...l],15),p=M(r.tests.slice().reverse(),10),f=M([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),m={schema:"toolnet.handoff.v2",version:2,project:{id:t.id,name:t.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:e.sequence,reason:e.reason},capturedAt:e.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:Ms(r.currentPhase),task:Ms(r.currentTask),file:o},completed:{phases:M(s,20),tasks:M(i,30)},remaining:{phases:M(a,20),tasks:M(c,30),todos:d},nextAction:l[0],blockers:M(r.blockers.slice().reverse(),10),decisions:M(r.decisions.slice().reverse(),10),files:{current:o,recent:f,active:M(r.activeFiles??[],10),modified:M(r.modifiedFiles??[],20),created:M(r.createdFiles??[],20),deleted:M(r.deletedFiles??[],20)},tests:{status:_d(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:M((r.commands??[]).slice().reverse(),20),references:Ld([r.currentRequest,r.currentActivity,r.goal,r.plan,...r.decisions,...r.blockers,...r.warnings,...r.nextActions,...r.filesTouched,...r.commands??[],...r.tests,...(r.checks??[]).map(v=>v.command)])},attention:M(e.attention??[],20),progress:r.progress},{capturedAt:S,source:g,...h}=m;return{...m,stateDigest:Kd(h)}}function Fd(e){return!!(e.currentRequest||e.currentActivity||e.goal||e.plan||e.phases.length>0||e.tasks.length>0||e.nextActions.length>0||e.blockers.length>0||e.decisions.length>0||e.filesTouched.length>0)}function Ts(e,t,n,r,o){if(!Fd(n))return null;let s=hs(e,!1),a=[...s?s.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=Cs({project:e,identity:t,state:n,reason:r,sequence:o,attention:a}),u=c.stateDigest;return{version:1,id:w([e.id,t.sessionKey,u].join("|")).slice(0,24),projectId:e.id,projectName:e.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:o},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),incompleteTasks:n.tasks.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),nextActions:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,filesTouched:n.filesTouched.slice(-20),activeFiles:n.activeFiles?.slice(-10),modifiedFiles:n.modifiedFiles?.slice(-20),createdFiles:n.createdFiles?.slice(-20),deletedFiles:n.deletedFiles?.slice(-20),tests:n.tests.slice(-15),checks:n.checks?.slice(-10),stateDigest:u,continuity:c}}function Os(e,t){let n=xn(e.rootPath,".toolnet","work","handoffs");Dd(n,{recursive:!0});let r=xn(n,`${t.id}.json`);$d(r)||N(r,t),N(xn(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function Rs(e){let t=Ts(e.project,e.identity,e.state,e.reason,e.sequence);return t?(Os(e.project,t),t):null}var Ot=class{constructor(t){this.options=t}options;async capture(t,n){let r=bn(this.options.project);r||(r=await cs(this.options.project,this.options.storage)),r||(r=await ze(this.options.project,this.options.storage));let o=Ts(this.options.project,this.options.identity,r,t,n);if(!o)return null;Os(this.options.project,o);let s=`projects/${this.options.project.id}/work/handoffs/${o.id}.json`;return await this.options.storage.exists(s)||await this.options.storage.put(s,JSON.stringify(o,null,2)+`
|
|
115
115
|
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(o,null,2)+`
|
|
116
|
-
`,"application/json"),o}};import{existsSync as
|
|
117
|
-
`)}function
|
|
116
|
+
`,"application/json"),o}};import{existsSync as Wd,readFileSync as zd,writeFileSync as Hd}from"node:fs";import{join as qd}from"node:path";var _s="<!-- TOOLNET:STABLE-WORK:BEGIN -->",In="<!-- TOOLNET:STABLE-WORK:END -->";function jn(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Ns(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${jn(n)} ${n.title}`)]:[]}function Jd(e){let t=[_s,"# ToolNet Stable Work State","",`Updated: ${e.updatedAt}`];return e.lastSession&&t.push(`Last agent: ${e.lastSession.agent}`,`Last session: ${e.lastSession.nativeSessionId}`),e.currentRequest&&t.push("","Current request:",e.currentRequest),e.currentActivity&&t.push("","Current activity:",e.currentActivity),e.goal&&t.push("","Goal:",e.goal),e.plan&&t.push("","Plan:",e.plan),e.currentPhase&&t.push("","Current phase:",`${jn(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${jn(e.currentTask)} ${e.currentTask.title}`),t.push(...Ns("Phases",e.phases)),t.push(...Ns("TODO / Tasks",e.tasks)),t.push(...W("Next actions",e.nextActions)),t.push(...W("Blockers",e.blockers)),t.push(...W("Important decisions",e.decisions)),t.push(...W("Active files",e.activeFiles??[])),t.push(...W("Modified files",e.modifiedFiles??[])),t.push(...W("Created files",e.createdFiles??[])),t.push(...W("Deleted files",e.deletedFiles??[])),t.push(...W("Files touched",e.filesTouched)),t.push(...W("Recent commands",e.commands??[])),t.push(...W("Checks",(e.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),t.push("","Progress:",`- Phases: ${e.progress.phasesCompleted}/${e.progress.phasesTotal}`,`- Tasks: ${e.progress.tasksCompleted}/${e.progress.tasksTotal}`,`- Blocked: ${e.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",In),t.join(`
|
|
117
|
+
`)}function Ks(e,t){let n=qd(e.rootPath,".toolnet","current.md"),r="";if(Wd(n))try{r=zd(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=Jd(t),s=r.indexOf(_s),i=r.indexOf(In),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+In.length).trimStart()].filter(Boolean).join(`
|
|
118
118
|
|
|
119
119
|
`):a=r.trim()?`${r.trim()}
|
|
120
120
|
|
|
121
|
-
${o}`:o,
|
|
122
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as hs,mkdirSync as Sd,readFileSync as kd}from"node:fs";import{join as yn}from"node:path";function Ss(e){return yn(e.rootPath,".toolnet","memory","checkpoints")}function ks(e){return yn(Ss(e),"latest.json")}function vd(e){let t=ks(e);if(!hs(t))return null;try{let n=JSON.parse(kd(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function wd(e){return["rule","architecture","decision","fix"].includes(e)}function bd(e,t){return t.length===0?[]:dt(e,t).candidates.filter(r=>wd(r.kind)&&r.knowledgeClass!=="transient"&&r.importanceScore>=.65).map(r=>({fingerprint:r.fingerprint,kind:r.kind,content:r.content,knowledgeClass:r.knowledgeClass,importanceScore:r.importanceScore,confidence:r.confidence,createdAt:r.createdAt,agent:e.agent,nativeSessionId:e.nativeSessionId}))}function xd(e,t){let n=new Map;for(let r of[...e,...t]){let o=n.get(r.fingerprint);(!o||r.importanceScore>o.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,o)=>o.importanceScore-r.importanceScore||o.createdAt.localeCompare(r.createdAt)).slice(0,80)}function jd(e){return{request:e.currentRequest,activity:e.currentActivity,goal:e.goal,phase:e.currentPhase?{title:e.currentPhase.title,status:e.currentPhase.status}:void 0,task:e.currentTask?{title:e.currentTask.title,status:e.currentTask.status}:void 0,phases:e.phases.map(t=>({title:t.title,status:t.status})),tasks:e.tasks.map(t=>({title:t.title,status:t.status})),activeFiles:e.activeFiles??[],modifiedFiles:e.modifiedFiles??[],createdFiles:e.createdFiles??[],deletedFiles:e.deletedFiles??[],checks:e.checks??[],blockers:e.blockers,decisions:e.decisions,nextActions:e.nextActions}}function vs(e,t,n,r){let o=vd(e),s=xd(o?.durableFacts??[],bd(t,n)),i=n.at(-1)?.sequence??o?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),d={work:jd(r),durableFacts:s.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(d)).slice(0,32),f={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:l},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:s,stateDigest:p},m=Ss(e);Sd(m,{recursive:!0,mode:448});let S=yn(m,`${p}.json`);return hs(S)||R(S,f),R(ks(e),f),f}function Mt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=wt(t,n);if(r.length===0)return{updated:!1,observations:0};let o=cs(e,r);ys(e,o),yr(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{vs(e,t,n,o)}catch{}try{fs({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var Ct=class{identity;wal;remote;sanitizer=new V;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=rt(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new le(this.identity,t.eventContext),this.remote=new ot(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new kt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new xt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new It({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new Pt({project:t.project,storage:t.storage,identity:this.identity})}sanitizeEvent(t){let n=t.provenance?{...t.provenance,metadata:this.sanitizer.sanitizeValue(t.provenance.metadata)}:void 0;return{...t,data:this.sanitizer.sanitizeValue(t.data??{}),provenance:n}}checkpointLocal(t){if(t.length!==0)try{Mt(this.project,this.identity,t)}catch{}}start(t={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:t,provenance:{source:this.identity.agent}})}record(t){let n=this.wal.append([this.sanitizeEvent(t)]);return this.checkpointLocal(n),n[0]}recordMany(t){let n=this.wal.append(t.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(t,n){this.wal.setSourceCursor(t,n)}async flush(){let t=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,t.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(t.events.length>0){let o=t.events[t.events.length-1];this.wal.markRemote(o.sequence,t.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&t.events.length>0)try{let o=t.events[t.events.length-1],s=["session_idle","session_end","session_compact"].includes(o.type)?o.type:"checkpoint";await this.handoff.capture(s,o.sequence)}catch{}return r}async idle(t={}){return this.record({type:"session_idle",data:t,provenance:{source:this.identity.agent}}),this.flush()}async end(t={}){return this.record({type:"session_end",data:t,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};var Et=4e3,hn=20,Sn=30,ws=4,kn=20;function vn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ot(e,t=0){if(t>=ws)return typeof e=="string"?e.length>Et?`${e.slice(0,Et)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:vn(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>Et?`${e.slice(0,Et)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,hn).map(r=>Ot(r,t+1));return e.length>hn&&n.push(`[+${e.length-hn} items]`),n}if(vn(e)){let n={},r=Object.entries(e);for(let[o,s]of r.slice(0,Sn))n[o]=Ot(s,t+1);return r.length>Sn&&(n.__truncatedKeys=r.length-Sn),n}return e}function wn(e,t,n=0){if(!(n>ws||t.size>=kn)){if(Array.isArray(e)){for(let r of e)if(wn(r,t,n+1),t.size>=kn)break;return}if(vn(e))for(let[r,o]of Object.entries(e)){let s=r.toLowerCase().replace(/[^a-z]/g,"");if((s==="path"||s==="filepath"||s==="filename")&&typeof o=="string"&&o.trim()&&t.add(o.trim()),wn(o,t,n+1),t.size>=kn)break}}}function Le(e){try{return w(Je(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function Id(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function Ad(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function bn(e,t){let r={timestamp:Id(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let o=e.prompt?.trim();return o?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+Le(o),data:{content:o}}]:[]}if(e.event==="PostToolUse"){let o=new Set;wn(e.toolInput,o);let s=[...o],i=Ad(e.toolName,s);if(!i)return[];let a=Ot(e.toolInput),c=Ot(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",Le({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:s},provenance:{source:`${e.agent}-hook`,files:s.length>0?s:void 0}}]}if(e.event==="AssistantMessage"){let o=e.assistantResponse?.trim();return o?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+Le(o),data:{content:o}}]:[]}if(e.event==="Stop"){let o=[],s=e.assistantResponse?.trim();return s&&o.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+Le(s),data:{content:s}}),o.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+Le({sessionId:e.sessionId,response:s??""}),data:{sessionId:e.sessionId}}),o}return[]}function Cd(e){let t=qn(e);if(!t||!Pd(Md(t,".toolnet","project.json")))return null;try{return new Ze().detect(t)}catch{return null}}function Ed(e,t){let n=bn(t,e);if(n.length===0)return 0;let r=rt(e,t.agent,t.sessionId),s=new le(r,{source:t.agent,cwd:t.cwd}).append(n);return Mt(e,r,s),s.length}async function Od(e,t,n,r){let o=Be(),s=pr(lr({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),{attempts:2}),i=new tt(s,e.id,e.name,e.remote??e.name);await new Ct({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function bs(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=Cd(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=Ed(n,e)}catch(s){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:s instanceof Error?s.message:String(s)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{Sr(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let o=t.flushSession??Od;try{return await o(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(s){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:s instanceof Error?s.message:String(s)}}}function xs(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Fe(...e){for(let t of e){let n=xs(t);if(n)return n}}function Td(e){switch(xs(e)){case"SessionStart":case"sessionStart":case"session_start":return"SessionStart";case"UserPromptSubmit":case"userPromptSubmit":case"user_prompt_submit":return"UserPromptSubmit";case"PostToolUse":case"postToolUse":case"post_tool_use":return"PostToolUse";case"Stop":case"stop":return"Stop";default:return null}}function js(e,t=process.env){let n=Td(t.TOOLNET_HOOK_EVENT??e.hookEventName??e.hook_event_name);if(!n)return null;let r=Fe(e.sessionId,e.session_id,t.GROK_SESSION_ID),o=Fe(e.cwd,e.workspaceRoot,t.GROK_WORKSPACE_ROOT,t.CLAUDE_PROJECT_DIR);return!r||!o?null:{agent:"grok",event:n,sessionId:r,cwd:o,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:Fe(e.prompt),toolName:Fe(e.toolName,e.tool_name),toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResult??e.tool_result??e.toolResponse,assistantResponse:Fe(e.response,e.assistantResponse,e.lastAssistantMessage)}}async function Is(e,t={},n=process.env){let r=js(e,n);return r?bs(r,t):{active:!1,captured:0,flushed:!1}}import{createHash as Rd,randomUUID as Nd}from"node:crypto";import{closeSync as _d,existsSync as In,fsyncSync as Kd,mkdirSync as $d,openSync as Ld,readFileSync as Ps,readdirSync as Fd,rmSync as Dd,statSync as Ms,writeFileSync as Wd}from"node:fs";import{tmpdir as zd}from"node:os";import{dirname as qd,join as De,parse as Hd,resolve as We}from"node:path";var Jd=1e4,Vd=64,xn=2;function x(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Cs(e){return Rd("sha256").update(e).digest("hex")}function ze(e){if(Array.isArray(e))return e.map(ze);if(e&&typeof e=="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map(n=>[n,ze(t[n])]))}return e}function Es(e){return x(e.sessionId)??x(e.session_id)??x(e.conversation_id)??x(e.conversationId)??"unknown-session"}function Bd(e){return x(e.toolUseId)??x(e.tool_use_id)??x(e.toolCallId)??x(e.tool_call_id)??x(e.callId)??x(e.call_id)??x(e.generation_id)??x(e.generationId)??x(e.sourceEventId)??x(e.source_event_id)}function Gd(e){return x(e.prompt)??x(e.userPrompt)??x(e.user_prompt)??x(e.originalPrompt)??x(e.original_prompt)}function Ud(e){let t=e.timestamp;return typeof t=="string"||typeof t=="number"?String(t):void 0}var Yd=new Set(["pid","processId","process_id","cwd","projectRoot","project_root","hookSource","hook_source","transformedPrompt","transformed_prompt","sessionId","session_id","conversation_id","conversationId","toolUseId","tool_use_id","toolCallId","tool_call_id","callId","call_id","generation_id","generationId","sourceEventId","source_event_id","timestamp"]);function Xd(e,t){if(!t)return e;let n=e.replaceAll("\\","/"),r=We(t).replaceAll("\\","/").replace(/\/+$/u,"");return!r||!n.includes(r)?e:n.split(r).join("<PROJECT>")}function Tt(e,t){if(typeof e=="string")return Xd(e,t);if(Array.isArray(e))return e.map(n=>Tt(n,t));if(e&&typeof e=="object"){let n=e,r={};for(let o of Object.keys(n).sort())Yd.has(o)||(r[o]=Tt(n[o],t));return r}return e}function Zd(e,t){let n=Tt(e,t);return Cs(JSON.stringify(ze(n)))}function Qd(e){return De(e,".toolnet","project.json")}function Os(e){let t=We(e),n=Qd(t);if(!In(n))return null;let r;try{r=JSON.parse(Ps(n,"utf8"))}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let o=x(r.id);return o?{root:t,id:o}:null}function ep(e){let t=We(e),n=Hd(t).root;for(;;){let r=Os(t);if(r)return r;if(t===n)return null;let o=qd(t);if(o===t)return null;t=o}}function tp(e){return x(e.cwd)??x(e.projectRoot)??x(e.project_root)}function As(e,t){if(!Number.isSafeInteger(e)||e<1)throw new Error(`${t} must be a positive integer`);return e}function np(e){if(e.directory)return{directory:We(e.directory),scope:"explicit",...e.projectRoot?{projectRoot:We(e.projectRoot)}:{},...e.projectId?{projectId:e.projectId}:{}};let t=null;if(e.projectRoot&&(t=Os(e.projectRoot)),!t){let n=tp(e.input)??process.cwd();t=ep(n)}if(t){if(e.projectId&&e.projectId!==t.id)throw new Error(["Hook dedupe project mismatch.",`Expected: ${e.projectId}.`,`Resolved: ${t.id}.`].join(" "));return{directory:De(t.root,".toolnet","runtime","dedupe","hooks"),scope:"project",projectRoot:t.root,projectId:t.id}}return{directory:De(zd(),"toolnet-memory-hook-dedupe"),scope:"temporary",...e.projectId?{projectId:e.projectId}:{}}}function rp(e,t,n){let r=Bd(e.input),o=Gd(e.input),s=Ud(e.input),i={projectId:t.projectId??e.projectId??"unscoped",agent:e.agent,event:e.event,session:Es(e.input),payloadFingerprint:n},a=r?{...i,nativeId:r}:o?{...i,prompt:o,timestamp:s}:{...i,input:ze(Tt(e.input,t.projectRoot))};return Cs(JSON.stringify(ze(a)))}function jn(e){if(!In(e))return null;let t;try{t=JSON.parse(Ps(e,"utf8"))}catch{return null}if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return n.version!==xn||typeof n.token!="string"||!n.token||typeof n.createdAt!="number"||!Number.isFinite(n.createdAt)||typeof n.agent!="string"||typeof n.event!="string"||typeof n.sessionId!="string"||typeof n.payloadFingerprint!="string"?null:{version:xn,token:n.token,createdAt:n.createdAt,...typeof n.projectId=="string"&&n.projectId?{projectId:n.projectId}:{},agent:n.agent,event:n.event,sessionId:n.sessionId,payloadFingerprint:n.payloadFingerprint}}function op(e){let t=jn(e);if(t)return t.createdAt;try{return Ms(e).mtimeMs}catch{return}}function sp(e,t,n){let r=op(e);return r===void 0?!0:t-r>n}function Ts(e,t,n){if(!In(e))return!0;if(!sp(e,t,n))return!1;let r=jn(e);if(r){let o=jn(e);if(!o||o.token!==r.token||o.createdAt!==r.createdAt||t-o.createdAt<=n)return!1}else{let o=0;try{o=t-Ms(e).mtimeMs}catch{return!0}if(o<=n)return!1}try{return Dd(e,{force:!0}),!0}catch{return!1}}function ip(e,t,n,r,o){let s;try{s=Fd(e)}catch{return 0}let i=0,a=0;for(let c of s.sort()){if(i>=r)break;if(!c.endsWith(".json"))continue;let u=De(e,c);o&&u===o||(i+=1,Ts(u,t,n)&&(a+=1))}return a}function Rs(e){let t=As(e.ttlMs??Jd,"ttlMs"),n=As(e.cleanupLimit??Vd,"cleanupLimit"),r=e.nowMs??Date.now(),o=np(e),s=Zd(e.input,o.projectRoot),i=rp(e,o,s),a=De(o.directory,`${i}.json`);$d(o.directory,{recursive:!0,mode:448}),ip(o.directory,r,t,n,a);for(let c=0;c<2;c+=1){let u=Nd();try{let l=Ld(a,"wx",384),d={version:xn,token:u,createdAt:r,...o.projectId?{projectId:o.projectId}:{},agent:e.agent,event:e.event,sessionId:Es(e.input),payloadFingerprint:s};try{Wd(l,`${JSON.stringify(d)}
|
|
123
|
-
`,"utf8"),
|
|
121
|
+
${o}`:o,Hd(n,`${a.trim()}
|
|
122
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as Ls,mkdirSync as Vd,readFileSync as Bd}from"node:fs";import{join as An}from"node:path";function $s(e){return An(e.rootPath,".toolnet","memory","checkpoints")}function Ds(e){return An($s(e),"latest.json")}function Gd(e){let t=Ds(e);if(!Ls(t))return null;try{let n=JSON.parse(Bd(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Ud(e){return["rule","architecture","decision","fix"].includes(e)}function Yd(e,t){return t.length===0?[]:yt(e,t).candidates.filter(r=>Ud(r.kind)&&r.knowledgeClass!=="transient"&&r.importanceScore>=.65).map(r=>({fingerprint:r.fingerprint,kind:r.kind,content:r.content,knowledgeClass:r.knowledgeClass,importanceScore:r.importanceScore,confidence:r.confidence,createdAt:r.createdAt,agent:e.agent,nativeSessionId:e.nativeSessionId}))}function Xd(e,t){let n=new Map;for(let r of[...e,...t]){let o=n.get(r.fingerprint);(!o||r.importanceScore>o.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,o)=>o.importanceScore-r.importanceScore||o.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Qd(e){return{request:e.currentRequest,activity:e.currentActivity,goal:e.goal,phase:e.currentPhase?{title:e.currentPhase.title,status:e.currentPhase.status}:void 0,task:e.currentTask?{title:e.currentTask.title,status:e.currentTask.status}:void 0,phases:e.phases.map(t=>({title:t.title,status:t.status})),tasks:e.tasks.map(t=>({title:t.title,status:t.status})),activeFiles:e.activeFiles??[],modifiedFiles:e.modifiedFiles??[],createdFiles:e.createdFiles??[],deletedFiles:e.deletedFiles??[],checks:e.checks??[],blockers:e.blockers,decisions:e.decisions,nextActions:e.nextActions}}function Fs(e,t,n,r){let o=Gd(e),s=Xd(o?.durableFacts??[],Yd(t,n)),i=n.at(-1)?.sequence??o?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),d={work:Qd(r),durableFacts:s.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(d)).slice(0,32),f={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:l},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:s,stateDigest:p},m=$s(e);Vd(m,{recursive:!0,mode:448});let S=An(m,`${p}.json`);return Ls(S)||N(S,f),N(Ds(e),f),f}function Rt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=At(t,n);if(r.length===0)return{updated:!1,observations:0};let o=Ps(e,r);Ks(e,o),Kr(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{Fs(e,t,n,o)}catch{}try{Rs({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var Nt=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=ct(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new fe(this.identity,t.eventContext),this.remote=new ut(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new It({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Pt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new Ct({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new Ot({project:t.project,storage:t.storage,identity:this.identity})}sanitizeEvent(t){let n=t.provenance?{...t.provenance,metadata:this.sanitizer.sanitizeValue(t.provenance.metadata)}:void 0;return{...t,data:this.sanitizer.sanitizeValue(t.data??{}),provenance:n}}checkpointLocal(t){if(t.length!==0)try{Rt(this.project,this.identity,t)}catch{}}start(t={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:t,provenance:{source:this.identity.agent}})}record(t){let n=this.wal.append([this.sanitizeEvent(t)]);return this.checkpointLocal(n),n[0]}recordMany(t){let n=this.wal.append(t.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(t,n){this.wal.setSourceCursor(t,n)}async flush(){let t=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,t.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(t.events.length>0){let o=t.events[t.events.length-1];this.wal.markRemote(o.sequence,t.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&t.events.length>0)try{let o=t.events[t.events.length-1],s=["session_idle","session_end","session_compact"].includes(o.type)?o.type:"checkpoint";await this.handoff.capture(s,o.sequence)}catch{}return r}async idle(t={}){return this.record({type:"session_idle",data:t,provenance:{source:this.identity.agent}}),this.flush()}async end(t={}){return this.record({type:"session_end",data:t,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};var _t=4e3,En=20,Pn=30,Ws=4,Mn=20;function Cn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Kt(e,t=0){if(t>=Ws)return typeof e=="string"?e.length>_t?`${e.slice(0,_t)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:Cn(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>_t?`${e.slice(0,_t)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,En).map(r=>Kt(r,t+1));return e.length>En&&n.push(`[+${e.length-En} items]`),n}if(Cn(e)){let n={},r=Object.entries(e);for(let[o,s]of r.slice(0,Pn))n[o]=Kt(s,t+1);return r.length>Pn&&(n.__truncatedKeys=r.length-Pn),n}return e}function Tn(e,t,n=0){if(!(n>Ws||t.size>=Mn)){if(Array.isArray(e)){for(let r of e)if(Tn(r,t,n+1),t.size>=Mn)break;return}if(Cn(e))for(let[r,o]of Object.entries(e)){let s=r.toLowerCase().replace(/[^a-z]/g,"");if((s==="path"||s==="filepath"||s==="filename")&&typeof o=="string"&&o.trim()&&t.add(o.trim()),Tn(o,t,n+1),t.size>=Mn)break}}}function He(e){try{return w(Ye(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function Zd(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function ep(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function On(e,t){let r={timestamp:Zd(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let o=e.prompt?.trim();return o?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+He(o),data:{content:o}}]:[]}if(e.event==="PostToolUse"){let o=new Set;Tn(e.toolInput,o);let s=[...o],i=ep(e.toolName,s);if(!i)return[];let a=Kt(e.toolInput),c=Kt(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",He({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:s},provenance:{source:`${e.agent}-hook`,files:s.length>0?s:void 0}}]}if(e.event==="AssistantMessage"){let o=e.assistantResponse?.trim();return o?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+He(o),data:{content:o}}]:[]}if(e.event==="Stop"){let o=[],s=e.assistantResponse?.trim();return s&&o.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+He(s),data:{content:s}}),o.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+He({sessionId:e.sessionId,response:s??""}),data:{sessionId:e.sessionId}}),o}return[]}function rp(e){let t=Zn(e);if(!t||!tp(np(t,".toolnet","project.json")))return null;try{return new rt().detect(t)}catch{return null}}function op(e,t){let n=On(t,e);if(n.length===0)return 0;let r=ct(e,t.agent,t.sessionId),s=new fe(r,{source:t.agent,cwd:t.cwd}).append(n);return Rt(e,r,s),s.length}async function sp(e,t,n,r){let o=Qe(),s=Or(Cr({provider:o.storage.provider,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),{attempts:2}),i=new it(s,e.id,e.name,e.remote??e.name);await new Nt({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function zs(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=rp(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=op(n,e)}catch(s){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:s instanceof Error?s.message:String(s)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{$r(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let o=t.flushSession??sp;try{return await o(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(s){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:s instanceof Error?s.message:String(s)}}}function Hs(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function qe(...e){for(let t of e){let n=Hs(t);if(n)return n}}function ip(e){switch(Hs(e)){case"SessionStart":case"sessionStart":case"session_start":return"SessionStart";case"UserPromptSubmit":case"userPromptSubmit":case"user_prompt_submit":return"UserPromptSubmit";case"PostToolUse":case"postToolUse":case"post_tool_use":return"PostToolUse";case"Stop":case"stop":return"Stop";default:return null}}function qs(e,t=process.env){let n=ip(t.TOOLNET_HOOK_EVENT??e.hookEventName??e.hook_event_name);if(!n)return null;let r=qe(e.sessionId,e.session_id,t.GROK_SESSION_ID),o=qe(e.cwd,e.workspaceRoot,t.GROK_WORKSPACE_ROOT,t.CLAUDE_PROJECT_DIR);return!r||!o?null:{agent:"grok",event:n,sessionId:r,cwd:o,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:qe(e.prompt),toolName:qe(e.toolName,e.tool_name),toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResult??e.tool_result??e.toolResponse,assistantResponse:qe(e.response,e.assistantResponse,e.lastAssistantMessage)}}async function Js(e,t={},n=process.env){let r=qs(e,n);return r?zs(r,t):{active:!1,captured:0,flushed:!1}}import{createHash as ap,randomUUID as cp}from"node:crypto";import{closeSync as up,existsSync as _n,fsyncSync as lp,mkdirSync as dp,openSync as pp,readFileSync as Bs,readdirSync as fp,rmSync as mp,statSync as Gs,writeFileSync as gp}from"node:fs";import{tmpdir as yp}from"node:os";import{dirname as hp,join as Je,parse as Sp,resolve as Ve}from"node:path";var kp=1e4,vp=64,Rn=2;function x(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Us(e){return ap("sha256").update(e).digest("hex")}function Be(e){if(Array.isArray(e))return e.map(Be);if(e&&typeof e=="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map(n=>[n,Be(t[n])]))}return e}function Ys(e){return x(e.sessionId)??x(e.session_id)??x(e.conversation_id)??x(e.conversationId)??"unknown-session"}function wp(e){return x(e.toolUseId)??x(e.tool_use_id)??x(e.toolCallId)??x(e.tool_call_id)??x(e.callId)??x(e.call_id)??x(e.generation_id)??x(e.generationId)??x(e.sourceEventId)??x(e.source_event_id)}function bp(e){return x(e.prompt)??x(e.userPrompt)??x(e.user_prompt)??x(e.originalPrompt)??x(e.original_prompt)}function xp(e){let t=e.timestamp;return typeof t=="string"||typeof t=="number"?String(t):void 0}var Ip=new Set(["pid","processId","process_id","cwd","projectRoot","project_root","hookSource","hook_source","transformedPrompt","transformed_prompt","sessionId","session_id","conversation_id","conversationId","toolUseId","tool_use_id","toolCallId","tool_call_id","callId","call_id","generation_id","generationId","sourceEventId","source_event_id","timestamp"]);function jp(e,t){if(!t)return e;let n=e.replaceAll("\\","/"),r=Ve(t).replaceAll("\\","/").replace(/\/+$/u,"");return!r||!n.includes(r)?e:n.split(r).join("<PROJECT>")}function Lt(e,t){if(typeof e=="string")return jp(e,t);if(Array.isArray(e))return e.map(n=>Lt(n,t));if(e&&typeof e=="object"){let n=e,r={};for(let o of Object.keys(n).sort())Ip.has(o)||(r[o]=Lt(n[o],t));return r}return e}function Ap(e,t){let n=Lt(e,t);return Us(JSON.stringify(Be(n)))}function Ep(e){return Je(e,".toolnet","project.json")}function Xs(e){let t=Ve(e),n=Ep(t);if(!_n(n))return null;let r;try{r=JSON.parse(Bs(n,"utf8"))}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let o=x(r.id);return o?{root:t,id:o}:null}function Pp(e){let t=Ve(e),n=Sp(t).root;for(;;){let r=Xs(t);if(r)return r;if(t===n)return null;let o=hp(t);if(o===t)return null;t=o}}function Mp(e){return x(e.cwd)??x(e.projectRoot)??x(e.project_root)}function Vs(e,t){if(!Number.isSafeInteger(e)||e<1)throw new Error(`${t} must be a positive integer`);return e}function Cp(e){if(e.directory)return{directory:Ve(e.directory),scope:"explicit",...e.projectRoot?{projectRoot:Ve(e.projectRoot)}:{},...e.projectId?{projectId:e.projectId}:{}};let t=null;if(e.projectRoot&&(t=Xs(e.projectRoot)),!t){let n=Mp(e.input)??process.cwd();t=Pp(n)}if(t){if(e.projectId&&e.projectId!==t.id)throw new Error(["Hook dedupe project mismatch.",`Expected: ${e.projectId}.`,`Resolved: ${t.id}.`].join(" "));return{directory:Je(t.root,".toolnet","runtime","dedupe","hooks"),scope:"project",projectRoot:t.root,projectId:t.id}}return{directory:Je(yp(),"toolnet-memory-hook-dedupe"),scope:"temporary",...e.projectId?{projectId:e.projectId}:{}}}function Tp(e,t,n){let r=wp(e.input),o=bp(e.input),s=xp(e.input),i={projectId:t.projectId??e.projectId??"unscoped",agent:e.agent,event:e.event,session:Ys(e.input),payloadFingerprint:n},a=r?{...i,nativeId:r}:o?{...i,prompt:o,timestamp:s}:{...i,input:Be(Lt(e.input,t.projectRoot))};return Us(JSON.stringify(Be(a)))}function Nn(e){if(!_n(e))return null;let t;try{t=JSON.parse(Bs(e,"utf8"))}catch{return null}if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return n.version!==Rn||typeof n.token!="string"||!n.token||typeof n.createdAt!="number"||!Number.isFinite(n.createdAt)||typeof n.agent!="string"||typeof n.event!="string"||typeof n.sessionId!="string"||typeof n.payloadFingerprint!="string"?null:{version:Rn,token:n.token,createdAt:n.createdAt,...typeof n.projectId=="string"&&n.projectId?{projectId:n.projectId}:{},agent:n.agent,event:n.event,sessionId:n.sessionId,payloadFingerprint:n.payloadFingerprint}}function Op(e){let t=Nn(e);if(t)return t.createdAt;try{return Gs(e).mtimeMs}catch{return}}function Rp(e,t,n){let r=Op(e);return r===void 0?!0:t-r>n}function Qs(e,t,n){if(!_n(e))return!0;if(!Rp(e,t,n))return!1;let r=Nn(e);if(r){let o=Nn(e);if(!o||o.token!==r.token||o.createdAt!==r.createdAt||t-o.createdAt<=n)return!1}else{let o=0;try{o=t-Gs(e).mtimeMs}catch{return!0}if(o<=n)return!1}try{return mp(e,{force:!0}),!0}catch{return!1}}function Np(e,t,n,r,o){let s;try{s=fp(e)}catch{return 0}let i=0,a=0;for(let c of s.sort()){if(i>=r)break;if(!c.endsWith(".json"))continue;let u=Je(e,c);o&&u===o||(i+=1,Qs(u,t,n)&&(a+=1))}return a}function Zs(e){let t=Vs(e.ttlMs??kp,"ttlMs"),n=Vs(e.cleanupLimit??vp,"cleanupLimit"),r=e.nowMs??Date.now(),o=Cp(e),s=Ap(e.input,o.projectRoot),i=Tp(e,o,s),a=Je(o.directory,`${i}.json`);dp(o.directory,{recursive:!0,mode:448}),Np(o.directory,r,t,n,a);for(let c=0;c<2;c+=1){let u=cp();try{let l=pp(a,"wx",384),d={version:Rn,token:u,createdAt:r,...o.projectId?{projectId:o.projectId}:{},agent:e.agent,event:e.event,sessionId:Ys(e.input),payloadFingerprint:s};try{gp(l,`${JSON.stringify(d)}
|
|
123
|
+
`,"utf8"),lp(l)}finally{up(l)}return{duplicate:!1,key:i,file:a,directory:o.directory,scope:o.scope,...o.projectId?{projectId:o.projectId}:{},payloadFingerprint:s}}catch(l){if((l&&typeof l=="object"&&"code"in l?String(l.code):"")!=="EEXIST")throw l;if(c===0&&Qs(a,r,t))continue;return{duplicate:!0,key:i,file:a,directory:o.directory,scope:o.scope,...o.projectId?{projectId:o.projectId}:{},payloadFingerprint:s}}}return{duplicate:!0,key:i,file:a,directory:o.directory,scope:o.scope,...o.projectId?{projectId:o.projectId}:{},payloadFingerprint:s}}import{spawn as _p}from"node:child_process";function ei(e){return(e??"").trim()}function ti(e,t={}){let n=ei(e);if(!n)return!1;let r=ei(t.binary??process.env.TOOLNET_MEMORY_BIN)||"toolnet-memory";try{let o=_p(r,["background:refresh","--project",n,"--quiet"],{detached:!0,stdio:"ignore",env:process.env});return o.on("error",()=>{}),o.unref(),!0}catch{return!1}}async function Kp(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function Lp(){let e=await Kp(),t=nr(e);if(t==="PreToolUse"||t==="preToolUse"||t==="pre_tool_use"){let o=rr(e);o.blocked&&process.stdout.write(JSON.stringify(or(o.reason??"ToolNet continuity guard blocked this tool.")));return}if(t&&Zs({agent:"grok",event:t,input:e,directory:process.env.TOOLNET_HOOK_DEDUPE_DIR}).duplicate)return;let n=await Js(e);(t==="SessionStart"||t==="sessionStart"||t==="session_start"||t==="Stop"||t==="stop")&&n.projectRoot&&ti(n.projectRoot)}Lp().catch(()=>{process.exitCode=0});
|