toolnet-memory 0.3.16 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +74 -0
- package/.release-target +1 -1
- package/README.md +165 -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 +51 -2
- 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 +94 -5
package/bundle/agy.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):
|
|
3
|
-
`,{encoding:"utf8",mode:384}),Ps(o,r)}function U(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 Nt(e){return{version:1,scheme:ye,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function Ns(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 He=class{adopt(t,n){let r=Rt(Y(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(An(r)){let a=qe(oe(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return U(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=Nt(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 Ve(r,i),U(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=oe(o.rootPath),i=qe(s),a=Ns(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:Nt(n)},i.updatedAt=new Date().toISOString(),Ve(o.rootPath,i)),U(i,o.rootPath)}findExisting(t=process.cwd()){let n=Y(t),r=Rt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Je(he(r,c))),i=wn(n,s?r:void 0);if(!i)return null;let a=qe(oe(i));return U(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=Y(t),r=Rt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Je(he(r,p))),i=wn(n,s?r:void 0);if(i){let p=oe(i),d=qe(p);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Ve(i,d)),U(d,i)}let a=new Date().toISOString(),c=Os(r),u=vn(r),l={version:1,id:u?kn(u.canonicalRemote):Rs(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:Nt(u)}:void 0};return Ve(r,l),U(l,r)}};var _s=[{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"}],Ks=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function jn(e){return e.normalize("NFKC").trim().toLowerCase()}function $s(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 Ls(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function Fs(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 Ws(e,t){return e.start<t.end&&t.start<e.end}function In(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var Ge=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=jn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of _s){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=In(n),o=[];for(let s of r)o.some(i=>Ws(i,s))||o.push(s);return In(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=jn(t);return Ks.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)||Ls(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Fs(t,o.index,o.index+s.length)&&($s(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 Ge(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 Ds=new V;function Se(e){return Ds.sanitizeValue(e)}import{homedir as li}from"node:os";import{join as di}from"node:path";import{DeleteObjectCommand as zs,GetObjectCommand as qs,HeadObjectCommand as Vs,ListObjectsV2Command as Js,PutObjectCommand as Bs,S3Client as Hs}from"@aws-sdk/client-s3";import{getSignedUrl as Gs}from"@aws-sdk/s3-request-presigner";var Ue=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Hs({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 Bs({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Gs(this.client,new qs({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 Vs({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 zs({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Js({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 Mn,mkdir as Us,readFile as Ys,readdir as Xs,rm as Zs,stat as Cn,writeFile as Qs}from"node:fs/promises";import{dirname as ei,join as ti,relative as Pn,resolve as ni}from"node:path";var ke=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return ni(this.root,n)}async put(t,n){let r=this.path(t);await Us(ei(r),{recursive:!0}),await Qs(r,n)}async get(t){try{return await Ys(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 Mn(this.path(t)),!0}catch{return!1}}async delete(t){await Zs(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await Mn(n)}catch{return r}let o=async i=>{let a=await Xs(i,{withFileTypes:!0});for(let c of a){let u=ti(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await Cn(u);r.push({key:Pn(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await Cn(n);return s.isDirectory()?await o(n):r.push({key:Pn(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as ri,GetObjectCommand as oi,HeadObjectCommand as si,ListObjectsV2Command as ii,PutObjectCommand as ai,S3Client as ci}from"@aws-sdk/client-s3";import{getSignedUrl as ui}from"@aws-sdk/s3-request-presigner";var ve=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new ci({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 ai({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await ui(this.client,new oi({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 si({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 ri({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new ii({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 _t(e,t){return console.warn(t),new ke(e)}function En(e){let t=e.localRoot??di(li(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ve({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):_t(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 ve({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):_t(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 Ue({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):_t(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ke(t)}function pi(e){return new Promise(t=>setTimeout(t,e))}async function On(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 pi(c+u)}throw s}var fi=new Set(["put","get","getText","delete","list"]);function Tn(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:fi.has(r)?(...s)=>On(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function Rn(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 Nn(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 Ye=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Rn(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)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
6
|
-
`,"application/json")}async scan(
|
|
7
|
-
`,"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(
|
|
1
|
+
import{existsSync as Ve}from"node:fs";import{existsSync as Ns,readFileSync as _s}from"node:fs";import{homedir as Ks}from"node:os";import{join as Ls}from"node:path";function $s(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Ds(){let t=process.env.TOOLNET_GLOBAL_ENV??Ls(Ks(),".config","toolnet-memory",".env");if(!Ns(t))return;let e=_s(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let 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]=$s(r.slice(o+1)))}}Ds();function he(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function Se(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function He(){return{memory:{autoCapture:he(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:he(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:he(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:he(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:Se(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:Se(process.env.MEMORY_RERANK_TOP,10),finalContext:Se(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:Se(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:he(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:Se(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Bs}from"node:crypto";import{existsSync as Ye,mkdirSync as Hs,readFileSync as Gs,renameSync as Us,writeFileSync as Ys}from"node:fs";import{basename as Xs,dirname as Xe,join as ve,parse as Tn,resolve as X}from"node:path";import{createHash as Mn}from"node:crypto";import{spawnSync as Fs}from"node:child_process";var ke="git-remote-v1",Ws=new Set(["github.com","gitlab.com","bitbucket.org"]);function Pn(t,e){let n=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!n||n==="."||n===".."||n.split("/").some(r=>!r||r==="."||r==="..")?null:(Ws.has(t)&&(n=n.toLowerCase()),n)}function zs(t){let e;try{e=new URL(t)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let n=e.hostname.trim().toLowerCase();if(!n)return null;let r=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!r?`${n}:${e.port}`:n,s=Pn(n,e.pathname);return s?`${o}/${s}`:null}function qs(t){let e=t.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let n=e[1]?.trim().toLowerCase();if(!n||n.length===1)return null;let r=Pn(n,e[2]??"");return r?`${n}/${r}`:null}function In(t){let e=t.trim();return e?e.includes("://")?zs(e):qs(e):null}function Vs(t){return Mn("sha256").update(`${ke}:${t}`).digest("hex")}function jn(t){return Mn("sha256").update(`toolnet-project:${ke}:${t}`).digest("hex").slice(0,16)}function Js(t){return t.split("/").filter(Boolean).at(-1)?.trim()||null}function Lt(t,e){let n=Fs("git",["-C",t,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function En(t,e){let n=Js(t);return n?{scheme:ke,canonicalRemote:t,fingerprint:Vs(t),repositoryName:n,source:e}:null}function Cn(t){let e=Lt(t,["remote","get-url","origin"]);if(e){let o=In(e);if(o)return En(o,"origin")}let n=Lt(t,["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=Lt(t,["remote","get-url",o]);if(!s)continue;let i=In(s);i&&r.add(i)}return r.size!==1?null:En([...r][0],"unique-remote")}var Rn=".toolnet",Qs="project.json";function Zs(t){return Bs("sha256").update(t).digest("hex").slice(0,16)}function ie(t){return ve(t,Rn,Qs)}function Nn(t){return Ye(ie(t))}function On(t,e){let n=X(t),r=Tn(n).root;for(;;){if(Nn(n))return n;if(n===r||e&&n===X(e))break;let o=Xe(n);if(o===n)break;n=o}return null}function $t(t){let e=X(t),n=Tn(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>Ye(ve(e,s))))return e;if(e===n)break;let o=Xe(e);if(o===e)break;e=o}return X(t)}function Ge(t){let e;try{e=JSON.parse(Gs(t,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${t}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Xe(Xe(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function Ue(t,e){let n=ve(t,Rn);Hs(n,{recursive:!0});let r=ie(t),o=`${r}.tmp-${process.pid}`;Ys(o,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Us(o,r)}function Y(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}function Dt(t){return{version:1,scheme:ke,canonicalRemote:t.canonicalRemote,fingerprint:t.fingerprint,repositoryName:t.repositoryName}}function ei(t){let e=t.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let n=e;return typeof n.fingerprint=="string"?n.fingerprint:null}var Qe=class{adopt(e,n){let r=$t(X(e));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(Nn(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 Y(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=Dt(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),Y(i,r)}recordGitIdentity(e,n,r={}){let o=this.requireExisting(e),s=ie(o.rootPath),i=Ge(s),a=ei(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:Dt(n)},i.updatedAt=new Date().toISOString(),Ue(o.rootPath,i)),Y(i,o.rootPath)}findExisting(e=process.cwd()){let n=X(e),r=$t(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Ye(ve(r,c))),i=On(n,s?r:void 0);if(!i)return null;let a=Ge(ie(i));return Y(a,i)}requireExisting(e=process.cwd()){let n=this.findExisting(e);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(e=process.cwd()){let n=X(e),r=$t(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>Ye(ve(r,d))),i=On(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)),Y(p,i)}let a=new Date().toISOString(),c=Xs(r),u=Cn(r),l={version:1,id:u?jn(u.canonicalRemote):Zs(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:Dt(u)}:void 0};return Ue(r,l),Y(l,r)}};var ti=[{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"}],ni=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function _n(t){return t.normalize("NFKC").trim().toLowerCase()}function ri(t){if(t.length===0)return 0;let e=new Map;for(let r of t)e.set(r,(e.get(r)??0)+1);let n=0;for(let r of e.values()){let o=r/t.length;n-=o*Math.log2(o)}return n}function oi(t){return/^[a-f0-9]{32}$/iu.test(t)||/^[a-f0-9]{40}$/iu.test(t)||/^[a-f0-9]{64}$/iu.test(t)}function si(t,e,n){let r=t.slice(Math.max(0,e-48),e),o=t.slice(n,Math.min(t.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function ii(t,e){return t.start<e.end&&e.start<t.end}function Kn(t){return t.sort((e,n)=>e.start!==n.start?e.start-n.start:n.end-n.start-(e.end-e.start))}var Ze=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let n of e.allowValues??[]){let r=_n(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let n=[];for(let s of ti){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of e.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(e));let r=Kn(n),o=[];for(let s of r)o.some(i=>ii(i,s))||o.push(s);return Kn(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let n=_n(e);return ni.has(n)?!0:this.allowValues.has(n)}entropyMatches(e){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||oi(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||si(e,o.index,o.index+s.length)&&(ri(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var J=class{scanner;constructor(e={}){this.scanner=new Ze(e)}sanitize(e){let n=this.scanner.scan(e);if(n.length===0)return{text:e,redacted:0,secretTypes:[]};let r=e,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(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,o]of Object.entries(e)){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 e}};var ai=new J;function ae(t){return ai.sanitizeValue(t)}import{homedir as $i}from"node:os";import{join as Di}from"node:path";import{DeleteObjectCommand as ci,GetObjectCommand as ui,HeadObjectCommand as li,ListObjectsV2Command as di,PutObjectCommand as pi,S3Client as fi}from"@aws-sdk/client-s3";import{getSignedUrl as mi}from"@aws-sdk/s3-request-presigner";var et=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new fi({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new pi({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let n=await mi(this.client,new ui({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new li({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new ci({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let o=await this.client.send(new di({Bucket:this.bucket,Prefix:e||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 Ln,mkdir as gi,readFile as yi,readdir as hi,rm as Si,stat as $n,writeFile as ki}from"node:fs/promises";import{dirname as vi,join as wi,relative as Dn,resolve as bi}from"node:path";var we=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return bi(this.root,n)}async put(e,n){let r=this.path(e);await gi(vi(r),{recursive:!0}),await ki(r,n)}async get(e){try{return await yi(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await Ln(this.path(e)),!0}catch{return!1}}async delete(e){await Si(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Ln(n)}catch{return r}let o=async i=>{let a=await hi(i,{withFileTypes:!0});for(let c of a){let u=wi(i,c.name);if(c.isDirectory()){await o(u);continue}let l=await $n(u);r.push({key:Dn(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await $n(n);return s.isDirectory()?await o(n):r.push({key:Dn(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as xi,GetObjectCommand as Ai,HeadObjectCommand as Ii,ListObjectsV2Command as Ei,PutObjectCommand as Mi,S3Client as Pi}from"@aws-sdk/client-s3";import{getSignedUrl as ji}from"@aws-sdk/s3-request-presigner";var be=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Pi({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Mi({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let n=await ji(this.client,new Ai({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Ii({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new xi({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let o=await this.client.send(new Ei({Bucket:this.bucket,Prefix:e||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 Ci,createDecipheriv as Oi,createHash as Ti,randomBytes as Ri,timingSafeEqual as Ni}from"node:crypto";import{readFileSync as _i}from"node:fs";var Q=Buffer.from("TNMEME01","ascii"),Wn=1,xe=8,Ae=12,Ft=16,zn=Q.length+1+xe+Ae+Ft,Ki="toolnet-memory:remote-encryption:v1:",qn="aes-256-gcm",Wt=32,I=class extends Error{constructor(n,r){super(r);this.code=n;this.name="RemoteEncryptionError"}code};function Li(t){return t?["1","true","yes","on","enabled"].includes(t.trim().toLowerCase()):!1}function zt(t=process.env){return Li(t.TOOLNET_REMOTE_ENCRYPTION)}function Fn(t){let e=t.trim();if(!e)throw new I("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let n;if(e.startsWith("hex:")){let r=e.slice(4);if(!/^[0-9a-f]{64}$/iu.test(r))throw new I("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(e))n=Buffer.from(e,"hex");else{let r=e.startsWith("base64:")?e.slice(7):e;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(r))throw new I("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!==Wt)throw new I("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${Wt} bytes.`);return n}function Vn(t=process.env){let e=t.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),n=t.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(e&&n)throw new I("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(e)return Fn(e);if(n){let r;try{r=_i(n,"utf8")}catch(o){throw new I("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${n}.`,o instanceof Error?o.message:String(o)].join(" "))}return Fn(r)}}function Jn(t){return Ti("sha256").update(t).digest().subarray(0,xe)}function Bn(t){return Buffer.from(`${Ki}${t}`,"utf8")}function qt(t){return t.byteLength<Q.length?!1:Buffer.from(t).subarray(0,Q.length).equals(Q)}function Hn(t,e,n){if(n.byteLength!==Wt)throw new I("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let r=typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e),o=Ri(Ae),s=Ci(qn,n,o);s.setAAD(Bn(t));let i=Buffer.concat([s.update(r),s.final()]),a=s.getAuthTag(),c=Buffer.alloc(zn),u=0;return Q.copy(c,u),u+=Q.length,c.writeUInt8(Wn,u),u+=1,Jn(n).copy(c,u),u+=xe,o.copy(c,u),u+=Ae,a.copy(c,u),Buffer.concat([c,i])}function Gn(t,e,n){let r=Buffer.from(e);if(!qt(r))throw new I("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(r.length<zn)throw new I("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=Q.length,s=r.readUInt8(o);if(o+=1,s!==Wn)throw new I("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let i=r.subarray(o,o+xe);o+=xe;let a=Jn(n);if(!Ni(i,a))throw new I("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let c=r.subarray(o,o+Ae);o+=Ae;let u=r.subarray(o,o+Ft);o+=Ft;let l=r.subarray(o),d=Oi(qn,n,c);d.setAAD(Bn(t)),d.setAuthTag(u);try{return Buffer.concat([d.update(l),d.final()])}catch{throw new I("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var Vt=class{constructor(e,n){this.inner=e;this.options=n;if(this.name=e.name,n.enabled&&!n.key)throw new I("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(e,n,r){if(!this.options.enabled){await this.inner.put(e,n,r);return}let o=this.options.key;if(!o)throw new I("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=Hn(e,n,o);await this.inner.put(e,s,"application/octet-stream")}async get(e){let n=await this.inner.get(e);if(!n)return null;if(!qt(n))return n;if(!this.options.enabled)throw new I("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 I("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return Gn(e,n,r)}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){return this.inner.exists(e)}async delete(e){await this.inner.delete(e)}async list(e=""){return this.inner.list(e)}};function Un(t,e=process.env){if(t.name==="local")return zt(e)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),t;let n=zt(e),r=n?Vn(e):void 0;return new Vt(t,{enabled:n,key:r})}function Ie(t){return Un(t)}function Jt(t,e){return console.warn(e),Ie(new we(t))}function Yn(t){let e=t.localRoot??Di($i(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?Ie(new be({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Jt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?Ie(new be({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Jt(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?Ie(new et({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Jt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return Ie(new we(e))}function Fi(t){return new Promise(e=>setTimeout(e,t))}async function Xn(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await t()}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 Fi(c+u)}throw s}var Wi=new Set(["put","get","getText","delete","list"]);function Qn(t,e={}){return new Proxy(t,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:Wi.has(r)?(...s)=>Xn(()=>Promise.resolve(o.apply(n,s)),e):o.bind(n)}})}function Zn(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function er(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var tt=class{constructor(e,n,r,o){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Zn(o??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(s,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=er(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{homedir as An}from"node:os";import{join as ks,resolve as Od}from"node:path";import{join as Gi}from"node:path";import{createHash as zi}from"node:crypto";import{dirname as qi}from"node:path";import{mkdirSync as Vi,readFileSync as Ji,renameSync as Bi,writeFileSync as Hi}from"node:fs";function w(t){return zi("sha256").update(t).digest("hex")}function Bt(t){if(Array.isArray(t))return t.map(Bt);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Bt(e[r]);return n}return t}function tr(t){return JSON.stringify(Bt(t))}function nr(t){try{return JSON.parse(Ji(t,"utf8"))}catch{return null}}function R(t,e){Vi(qi(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;Hi(n,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),Bi(n,t)}function rr(t,e){let n=t.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`${e}--${o}`;let s=r.slice(0,100);return s===n&&n.length<=100?s:`${s.slice(0,85)}--${o}`}function or(t,e,n){let r=e.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=rr(r.toLowerCase(),"agent"),i=rr(o,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:o,sessionKey:`${r}:${o}`,remotePrefix:["projects",t.id,"runtime","sources",s,i].join("/"),localDirectory:Gi(t.rootPath,".toolnet","runtime","sources",s,i)}}function sr(t){return String(t).padStart(12,"0")}var nt=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
|
|
6
|
+
`,"application/json")}async scan(e){let n=`${e.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(e){let n=[],r=[],o=0;for(let s of e){let i=Buffer.byteLength(JSON.stringify(s)+`
|
|
7
|
+
`,"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(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,o={}){let s=await this.loadManifest(e),i=await this.scan(e),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],x=g.map(T=>JSON.stringify(T)).join(`
|
|
8
8
|
`)+`
|
|
9
|
-
`,
|
|
10
|
-
`,null,"utf8"),
|
|
11
|
-
`,null,"utf8"),
|
|
9
|
+
`,O=w(x).slice(0,16),j=[e.remotePrefix,"events",`${sr(h.sequence)}-${sr(v.sequence)}-${O}.jsonl`].join("/");await this.storage.exists(j)||await this.storage.put(j,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(e),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:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:p};return await this.putJson(`${e.remotePrefix}/cursor.json`,S),await this.putJson(`${e.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:d}}};import{closeSync as Pe,existsSync as at,fsyncSync as en,mkdirSync as da,openSync as je,readFileSync as vr,readSync as pa,rmSync as hr,statSync as Qt,truncateSync as fa,writeSync as ma}from"node:fs";import{join as Zt}from"node:path";var Ui=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),Yi=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Xi(t){return t.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Qi(t){for(let e of["type","kind"]){let n=t[e];if(typeof n=="string"){let r=n.toLowerCase();if(Yi.has(r))return n}}return null}function Ht(t,e=0){if(e>12)return"[ToolNet nested value omitted]";if(Array.isArray(t))return t.map(s=>Ht(s,e+1));if(!t||typeof t!="object")return t;let n=t,r=Qi(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))Ui.has(Xi(s))||(o[s]=Ht(i,e+1));return o}function Zi(t){if(!t)return new Date().toISOString();let e=new Date(t);return Number.isNaN(e.getTime())?new Date().toISOString():e.toISOString()}function Z(t){return t?.trim()||void 0}function ir(t,e={}){let n={...t.provenance??{}},r=Z(t.source)??Z(e.source)??Z(n.source);return{...t,timestamp:Zi(t.timestamp),source:r,turnId:Z(t.turnId)??Z(e.turnId),cwd:Z(t.cwd)??Z(e.cwd),data:Ht(t.data??{}),provenance:n}}import{randomUUID as Gt}from"node:crypto";import{closeSync as ce,existsSync as ue,fsyncSync as Ee,mkdirSync as Ut,openSync as Me,readFileSync as Yt,readdirSync as ea,renameSync as ta,rmSync as rt,statSync as na,writeSync as ot}from"node:fs";import{join as B}from"node:path";var ra=12e4,oa=80,sa="reconcile-required";function ia(t){t<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function le(t){return B(t,".toolnet","journal")}function ur(t){return B(le(t),"events.jsonl")}function st(t){return B(le(t),sa)}function aa(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e?.code!=="ESRCH"}}function lr(t){if(!ue(t))return null;try{let e=JSON.parse(Yt(t,"utf8"));return e.version!==1||typeof e.token!="string"||typeof e.pid!="number"||typeof e.acquiredAt!="string"?null:{version:1,token:e.token,pid:e.pid,acquiredAt:e.acquiredAt}}catch{return null}}function ca(t){if(!ue(t))return!1;let e=0;try{e=Date.now()-na(t).mtimeMs}catch{return!1}if(e<=ra)return!1;let n=lr(t);return n?!aa(n.pid):!0}function ua(t){if(!ca(t))return!1;try{return rt(t,{force:!0}),!0}catch{return!1}}function dr(t){for(let e=0;e<oa;e+=1){let n=Gt();try{let r=Me(t,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return ot(r,`${JSON.stringify(o)}
|
|
10
|
+
`,null,"utf8"),Ee(r),{fd:r,token:n}}catch(s){throw ce(r),rt(t,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(ua(t))continue;ia(25)}}throw new Error(`Shared project journal is locked: ${t}`)}function pr(t,e){ce(e.fd),lr(t)?.token===e.token&&rt(t,{force:!0})}function ar(t){if(!ue(t))return[];let e="";try{e=Yt(t,"utf8")}catch{return[]}let n=[];for(let r of e.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 fr(t){if(!ue(t))return[];let e=[];for(let n of ea(t,{withFileTypes:!0})){let r=B(t,n.name);if(n.isDirectory()){e.push(...fr(r));continue}n.isFile()&&n.name==="events.jsonl"&&e.push(r)}return e.sort()}function it(t){let e=null;try{e=Me(t,"r"),Ee(e)}catch{}finally{if(e===null)return;ce(e)}}function cr(t){let e=st(t);if(!ue(e))return null;try{return Yt(e,"utf8").trim()||null}catch{return null}}function Xt(t){let e=le(t);Ut(e,{recursive:!0,mode:448});let n=st(t),r=[Gt(),new Date().toISOString()].join("|"),o=Me(n,"w",384);try{ot(o,`${r}
|
|
11
|
+
`,null,"utf8"),Ee(o)}finally{ce(o)}it(e)}function la(t,e,n){let r=B(t,`.events.jsonl.tmp-${process.pid}-${Gt()}`),o=Me(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
|
|
12
12
|
`)}
|
|
13
|
-
`;s&&
|
|
13
|
+
`;s&&ot(o,s,null,"utf8"),Ee(o)}finally{ce(o)}ta(r,e),it(t)}function mr(t){let e=le(t),n=ur(t),r=B(t,".toolnet","runtime","sources"),o=cr(t),s=fr(r),i=[],a=new Set;for(let d of ar(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 ar(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),la(e,n,i);let l=cr(t);return o&&l===o&&(rt(st(t),{force:!0}),it(e)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function gr(t){let e=le(t);Ut(e,{recursive:!0,mode:448});let n=B(e,"journal.lock"),r=dr(n);try{return mr(t)}finally{pr(n,r)}}function yr(t,e){if(e.length===0)return;let n=le(t);Ut(n,{recursive:!0,mode:448});let r=ur(t),o=B(n,"journal.lock"),s=dr(o);try{if(ue(st(t))){mr(t);return}let i=`${e.map(c=>JSON.stringify(c)).join(`
|
|
14
14
|
`)}
|
|
15
|
-
`,a=
|
|
16
|
-
`),
|
|
15
|
+
`,a=Me(r,"a",384);try{ot(a,i,null,"utf8"),Ee(a)}finally{ce(a)}it(n)}finally{pr(o,s)}}var ga=12e4,ya=80,Sr=2e3;function ha(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function wr(t,e){let n=Buffer.isBuffer(e)?e:Buffer.from(e,"utf8"),r=0;for(;r<n.length;){let o=ma(t,n,r,n.length-r);if(o<=0)throw new Error("Unable to write session WAL");r+=o}}function tn(t){let e=t.trim();if(!e)return null;try{let n=JSON.parse(e);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 Sa(t){if(!at(t))return[];let e="";try{e=vr(t,"utf8")}catch{return[]}let n=[];for(let r of e.split(/\r?\n/)){let o=tn(r);o&&n.push(o)}return n}function kr(t){return t.type==="session_end"||t.type==="session_idle"?"idle":t.type==="error"?"error":"active"}function ka(t){if(!at(t))return!1;let e;try{e=vr(t)}catch{return!1}if(e.length===0||e[e.length-1]===10)return!1;let n=e.lastIndexOf(10),r=n>=0?n+1:0,o=e.subarray(r).toString("utf8").trim();if(tn(o)){let i=je(t,"a");try{wr(i,`
|
|
16
|
+
`),en(i)}finally{Pe(i)}return!0}fa(t,r);let s=je(t,"a");try{en(s)}finally{Pe(s)}return!0}function va(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n+=1)if(t[n]!==e[n])return!1;return!0}var ct=class{constructor(e,n={}){this.identity=e;this.eventContext=n;da(e.localDirectory,{recursive:!0}),this.eventsFile=Zt(e.localDirectory,"events.jsonl"),this.stateFile=Zt(e.localDirectory,"state.json"),this.lockFile=Zt(e.localDirectory,"journal.lock")}identity;eventContext;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return nr(this.stateFile)??this.initialState()}recoverStateUnsafe(){ka(this.eventsFile);let e=this.loadStateUnsafe(),n=Sa(this.eventsFile);if(n.length===0)return e;let r=n[0];for(let d of n)d.sequence<=r.sequence||(r=d);let o=n.slice(-Sr).map(d=>d.id),s=at(this.eventsFile)?Qt(this.eventsFile).size:0,i=Math.max(e.lastSequence,r.sequence),a=Math.min(e.remoteByteOffset,s),c=r.sequence>e.lastSequence;if(!(c||a!==e.remoteByteOffset||!va(e.recentEventIds,o)||e.lastLocalEventAt!==r.timestamp))return e;let l={...e,status:kr(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(l),!c)return l;try{Xt(this.identity.projectRoot)}catch{return l}try{gr(this.identity.projectRoot)}catch{}return l}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(e){R(this.stateFile,e)}acquireLock(){for(let e=0;e<ya;e+=1)try{return je(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Qt(this.lockFile).mtimeMs>ga){hr(this.lockFile,{force:!0});continue}}catch{}ha(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{Pe(n),hr(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),o=n.lastSequence,s=[];for(let d of e){let p=ir(d,this.eventContext),f=p.timestamp??new Date().toISOString(),m=p.data??{},S=p.provenance?.rawDigest??w(tr(m)),g=ae(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 x={version:1,id:v,sequence:o,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:S}};p.role!==void 0&&(x.role=p.role),p.turnId!==void 0&&(x.turnId=p.turnId),p.cwd!==void 0&&(x.cwd=p.cwd),p.sourceEventId!==void 0&&(x.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(x.sourceSequence=p.sourceSequence),s.push(x),r.add(v)}if(s.length===0)return[];let i=s.map(d=>JSON.stringify(d)).join(`
|
|
17
17
|
`)+`
|
|
18
|
-
`,a=
|
|
19
|
-
`)}function
|
|
20
|
-
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}function
|
|
21
|
-
`).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
|
|
18
|
+
`,a=je(this.eventsFile,"a",384);try{wr(a,i),en(a)}finally{Pe(a)}try{yr(this.identity.projectRoot,s)}catch{try{Xt(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=kr(c),l=Array.from(r).slice(-Sr);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:l}),s})}readPending(){return this.withLock(()=>{let e=this.recoverStateUnsafe();if(!at(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=Qt(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let o=n-r,s=Buffer.alloc(o),i=je(this.eventsFile,"r");try{pa(i,s,0,o,r)}finally{Pe(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=tn(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),o=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:o,updatedAt:o})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as yu,existsSync as hu,openSync as Su,readSync as ku,statSync as vu}from"node:fs";var wa=new Set(["rule","blocker","architecture","deploy"]),ba=new Set(["fix","todo","context","next_action"]);function nn(t){return t<0?0:t>1?1:t}function br(t,e){let n=Number.parseFloat(t??"");return Number.isFinite(n)?n:e}function xa(t){return t==="off"?"off":t==="balanced"?"balanced":t==="aggressive"?"aggressive":"conservative"}function rn(){return{mode:xa(process.env.TOOLNET_MEMORY_PROMOTION),minScore:nn(br(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:nn(br(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Aa(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Ia(t){let e=nn(Aa(t.importance)*.75+t.confidence*.25);return Math.round(e*1e6)/1e6}function Ea(t){return t.evidence?t.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Ma(t,e=rn()){if(t.importance==="temporary"||t.confidence<e.minConfidence)return"transient";let n=Ea(t);return t.kind==="rule"&&n.userExplicit?"permanent":t.kind==="rule"?"session":t.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":t.kind==="architecture"?"session":t.kind==="decision"||t.kind==="todo"||t.kind==="next_action"||t.kind==="fix"?"task":"session"}function Pa(t,e=rn()){if(e.mode==="off")return Number.POSITIVE_INFINITY;let n=0;e.mode==="balanced"&&(n=.1),e.mode==="aggressive"&&(n=.15);let r=Math.max(e.mode==="aggressive"?.5:.55,e.minScore-n);return wa.has(t)&&(r=Math.max(.5,r-.1)),ba.has(t)&&(r=Math.max(.5,r-.05)),r}function on(t,e=rn()){let n=Ma(t,e),r=Ia(t),o=Pa(t.kind,e);return n==="transient"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:e.mode==="off"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:{knowledgeClass:n,score:r,threshold:o,persist:r>=o}}function xr(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var Mr=[/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],ja=[/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],Ca=[/\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],Oa=[/\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],Ta=[/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],Ra=[/đã sửa/iu,/đã fix/iu,/đã khắc phục/iu,/đã xử lý/iu,/hoàn tất/iu,/hoàn thành/iu,/\bfixed\b/iu,/\bresolved\b/iu,/\bimplemented\b/iu,/\bcompleted\b/iu,/\bpasses?\b/iu],Ar=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],Na=[/\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],_a=[/đườ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],Ka=[/\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],Ir=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),La=new Set(["payload","data","content","message","messages","parts","summary"]);function N(t,e){return e.some(n=>n.test(t))}function Pr(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function $a(t){return Pr(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Da(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function sn(t,e,n,r=0){if(!(r>6)&&!(typeof t=="string"&&e&&!Ir.has(e))){if(typeof t=="string"){n.push(t);return}if(Array.isArray(t)){for(let o of t.slice(0,50))sn(o,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[o,s]of Object.entries(t))(Ir.has(o)||La.has(o))&&sn(s,o,n,r+1)}}function Fa(t){let e=[];sn(t.data,void 0,e);let n=[],r=new Set;for(let o of e)for(let s of o.split(/\n+|(?<=[.!?])\s+/u)){let i=Pr(s);if(Da(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Er(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Wa(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",o=e==="assistant"||n.type==="assistant_message";return r&&N(t,Mr)?{kind:"rule",confidence:.98}:r&&N(t,ja)?{kind:"rule",confidence:.92}:N(t,Ca)?{kind:N(t,Ar)?"architecture":"decision",confidence:r?.93:.86}:r&&N(t,Ta)?{kind:"next_action",confidence:.88}:r&&N(t,Oa)?{kind:"todo",confidence:.87}:N(t,Ar)&&N(t,Na)?{kind:"architecture",confidence:r?.88:.82}:o&&N(t,Ra)?{kind:"fix",confidence:.8}:r&&N(t,_a)&&N(t,Ka)?{kind:"context",confidence:.79}:null}function za(t,e,n){let r=e==="user"||n.type==="user_prompt",o=e==="assistant"||n.type==="assistant_message",s=!!n.provenance.sourcePath&&(t==="architecture"||t==="context"||t==="fix"),i=t==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:s,testVerified:i,crossSessionConfirmations:1,assistantDerived:o}}function qa(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":case"next_action":return"todo";case"fix":case"context":return"code"}}function Va(t,e,n){return t==="rule"&&N(n,Mr)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":xr(e,n)}function jr(t,e){let n=[],r=new Set,o=new Map;for(let s of e){let i=typeof s.data.messageId=="string"?s.data.messageId:void 0,a=Er(s);i&&a&&o.set(i,a)}for(let s of e){let i=Er(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of Fa(s)){let u=Wa(c,i,s);if(!u||u.confidence<.75)continue;let l=qa(u.kind),d=$a(c),p=w([t.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:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:u.kind,type:l,content:c,confidence:u.confidence,importance:Va(u.kind,l,c),evidence:za(u.kind,i,s),tags:[l],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:f,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as Ja}from"node:crypto";var Ba=["project-knowledge","implementation","continuation","session-context"],Ha={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function an(t){return Ja("sha256").update(t).digest("hex")}function ut(t,e){return`${t}:${an(e).slice(0,24)}`}function Ga(t){try{return an(JSON.stringify(t))}catch{return an(String(t))}}function ee(t){let e=new Set,n=[];for(let r of t){let o=r?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),n.push(o))}return n}function Or(t,e=420){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:`${n.slice(0,Math.max(0,e-1)).trimEnd()}\u2026`}function Ua(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function Cr(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function Ya(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,5).map(e=>Or(e.content)).join(" | ")}function Xa(t){return t.slice().sort((e,n)=>n.importanceScore-e.importanceScore||n.confidence-e.confidence||e.id.localeCompare(n.id)).slice(0,6).map(e=>Or(e.content)).join(`
|
|
19
|
+
`)}function Tr(t,e){let n=t.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:ut("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:Ga(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=e.map(p=>{let f=ee([...p.provenance.eventIds.map(m=>o.get(m)),...p.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:ut("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:ee([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:f,sourcePaths:ee(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=Ua(p.kind),m=a.get(f)??[];m.push(p),a.set(f,m)}let c=[];for(let p of Ba){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:ut("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:Ha[p],summary:Ya(m),factIds:S,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:Cr(m.map(g=>g.confidence)),tags:ee(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:ee(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),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=Xa(m);l.push({id:ut("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:Cr(m.map(h=>h.confidence)),tags:ee(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...m.flatMap(h=>h.tags)]),sourcePaths:ee(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 Qa(t){return t?Math.ceil(t.length/3.5):0}function Rr(t,e){if(!t)return"";if(Qa(t)<=e)return t;let r=Math.floor(e*3.5),o=t.slice(0,r),s=o.lastIndexOf("."),i=o.lastIndexOf(`
|
|
20
|
+
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}function te(){let t=He(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",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"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:o,sessionSummaryMaxTokens:s,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function Nr(t){return(t||te()).rawTranscript}function _r(t){return(t||te()).durableMemoryMaxItemsPerSession}function Kr(t){return(t||te()).sessionSummaryMaxTokens}function Lr(t){return(t||te()).archiveRemote}var $r=new J;function Dr(t){let e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))try{let r=JSON.parse(e);return JSON.stringify($r.sanitizeValue(r))}catch{}let n=$r.sanitize(t).text;return n=n.replace(/("(?:api[_-]?key|token|secret|password|cookie|authorization)"\s*:\s*)"[^"]*"/gi,'$1"[REDACTED]"').replace(/('(?:api[_-]?key|token|secret|password|cookie|authorization)'\s*:\s*)'[^']*'/gi,"$1'[REDACTED]'").replace(/\b(api[_-]?key|token|secret|password|cookie|authorization)\b\s*[:=]\s*[^\s,;]+/gi,"$1=[REDACTED]").replace(/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [REDACTED]"),n}function Za(t,e){let n=t.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);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let 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(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function ec(t,e){let n=[],r=new Set;for(let i of t){let a=i.split(`
|
|
21
|
+
`).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=Za(u,d);if(p<.3)continue;let f=Dr(u);n.push({category:d,text:f,importance:p,sourceSessionId:e})}}let o=te(),s=_r(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function tc(t){let e=te(),n=Kr(e),s=t.join(`
|
|
22
22
|
|
|
23
23
|
`).split(`
|
|
24
|
-
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>
|
|
25
|
-
`);return
|
|
24
|
+
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>Dr(i)).join(`
|
|
25
|
+
`);return Rr(s,n)}function lt(t,e){let r=(Array.isArray(t)?t:t.split(`
|
|
26
26
|
|
|
27
|
-
`).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=
|
|
28
|
-
`)}function
|
|
29
|
-
`;Ua(at(Da(e),`${c}.json`),l)?o+=1:s+=1,i.push(c),n=Ya(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[Ga(a)],files:Ha(a)})}return r>0&&Ja(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as oc}from"node:crypto";import{existsSync as sc,readdirSync as ic,readFileSync as ac}from"node:fs";import{basename as cc,join as qr}from"node:path";import{randomUUID as Pr}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function je(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function te(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new j("Invalid Wiki slug",400);return t}function Mr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(te(r))}return je(t)}function Xa(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Cr(e){return{id:`revision-${Pr()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function ee(e){return structuredClone(e)}var ct=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}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:je(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return ee([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=te(t),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);return ee(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new j("Wiki title is required",400);let s=te(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new j(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${Pr()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:je(t.tags??[]),links:Mr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Cr(a)),ee(a)})}async updatePage(t,n){return this.mutate(r=>{let o=te(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=Mr(s.content)),n.tags!==void 0&&(s.tags=je(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(Cr(s)),ee(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return ee(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return ee(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=je(Xa(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()??"",p=a.content.toLowerCase(),d=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),d.some(S=>S===m)?f+=5:d.some(S=>S.includes(m))&&(f+=3),l.includes(m)&&(f+=2),p.includes(m)&&(f+=1);f>0&&i.push({page:ee(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var Er="wiki/state.v1.json";function Za(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Qa(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 ut=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Er);if(!t){let n=Za(this.project);return await this.save(n),n}return Qa(t,this.project)}async save(t){await this.storage.put(Er,JSON.stringify(t,null,2),"application/json")}};import{createHash as ec,randomUUID as Or}from"node:crypto";var Tr="wiki/governance.v1.json",Kr="toolnet.knowledge-governance.v1",Rr=500,Ie={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function tc(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function en(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Nr(e){return ec("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function nc(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 rc(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),tc(t)}function _r(e){let t=new Date().toISOString();return{schema:Kr,version:1,projectId:e,policy:{...Ie},reviews:[],audit:[],createdAt:t,updatedAt:t}}function $r(e){let t=e.autoApproveThreshold??Ie.autoApproveThreshold,n=e.criticalApproveThreshold??Ie.criticalApproveThreshold,r=e.staleAfterDays??Ie.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var lt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Tr);if(!t){let n=_r(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Kr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:$r(n.policy??Ie)}}catch{let n=_r(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Tr,JSON.stringify(t,null,2),"application/json")}},dt=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:Or(),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>Rr&&(t.audit=t.audit.slice(-Rr))}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=$r({...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=rc(t),s=en(t.title),i=n.filter(l=>l.slug!==t.slug&&en(l.title)===s&&Nr(l.content)!==Nr(t.content)).map(l=>l.slug),a=nc(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:Or(),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 j(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new j("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 j("targetReviewId is required for merge",400);let u=o.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new j("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 j(`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 p=o-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(p/864e5)),stale:Number.isFinite(p)&&p>s}}).filter(l=>l.stale).map(({stale:l,...p})=>p),a=new Map;for(let l of r){let p=en(l.title),d=a.get(p)??[];d.push(l),a.set(p,d)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,p])=>({title:l,pages:p.map(d=>d.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(p=>p.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(p=>p.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 Vr="wiki/automation.v1.json",Jr="toolnet.wiki-automation.v1",rn=8e3,Lr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Ce(e){return oc("sha256").update(JSON.stringify(e)).digest("hex")}function Me(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Fr(e){return Array.isArray(e)?e:[]}function Br(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function tn(e){return Array.isArray(e)?e.map(Br).filter(t=>!!t):[]}function K(e,t){for(let n of t){let r=Br(e[n]);if(r)return r}}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 pt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Lr.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=>pt(i,t+1,n));let o=Me(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Lr.has(c)||s.push(...pt(a,t+1,i))}return s}function Wr(e){let n=Pe(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>pt(e[o],0,o)));return(n.length>0?n:Pe(pt(e))).join(`
|
|
27
|
+
`).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),o=ec(r,e),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:tc(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:o}}function H(t){let e=new Set,n=[];for(let r of t){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),n.push(o))}return n}function nc(t){let e=new Map;for(let n of t){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,o=e.get(r);(!o||n.sequence>o.sequence)&&e.set(r,n)}return[...e.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function rc(t){let e=t.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of e)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function oc(t){let e=on(t);return{...t,knowledgeClass:e.knowledgeClass,importanceScore:e.score,retrievalTerms:rc(t.content),tags:H([...t.tags,"level:fact",`class:${e.knowledgeClass}`,`kind:${t.kind}`])}}function sc(t){return t.map(e=>{try{return JSON.stringify({type:e.type,role:e.role,data:e.data,provenance:{sourcePath:e.provenance.sourcePath,files:e.provenance.files}})}catch{return""}}).filter(Boolean)}function ic(t,e,n){let r=lt(sc(e),t.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=H([...o,...r.nextActions]),c=H([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:H(r.decisions),files:H([...r.filesChanged,...s]),todos:a,completed:H(r.bugsFixed),blockers:H(r.blockers),nextActions:c,architecture:H(i)}}}function dt(t,e){let n=nc(e),r=jr(t,n).map(oc),o=r.filter(l=>on(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:s,state:i}=ic(t,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=Tr(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:e.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 ac}from"node:crypto";import{chmodSync as Fr,existsSync as cc,mkdirSync as uc,readFileSync as lc,renameSync as dc,writeFileSync as Wr}from"node:fs";import{dirname as zr,join as pt}from"node:path";var ln="toolnet.context-offload.v1",pc="toolnet.context-offload-asset.v1",fc=256,mc=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function qr(t){return pt(t,".toolnet","offload")}function gc(t){return pt(qr(t),"assets")}function Vr(t){return pt(qr(t),"graph.json")}function Jr(t){uc(t,{recursive:!0,mode:448});try{Fr(t,448)}catch{}}function yc(t,e){Jr(zr(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;Wr(n,e,{encoding:"utf8",mode:384}),dc(n,t);try{Fr(t,384)}catch{}}function un(t){return Array.isArray(t)?t.map(un):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,un(n)])):t}function hc(t){return ac("sha256").update(JSON.stringify(un(t)),"utf8").digest("hex")}function cn(){return{schema:ln,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Sc(t){let e=Vr(t);if(!cc(e))return cn();try{let n=JSON.parse(lc(e,"utf8"));return n.schema!==ln||n.version!==1||!Array.isArray(n.nodes)?cn():n}catch{return cn()}}function kc(t,e){yc(Vr(t),JSON.stringify(e,null,2)+`
|
|
28
|
+
`)}function vc(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function wc(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let o=vc(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function bc(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function xc(t,e){Jr(zr(t));try{return Wr(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Ac(t,e){let n=t.nodes.find(o=>o.id===e.id),r=n?{...n,kind:e.kind,bytes:e.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...e.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...e.files])).slice(0,6)}:e;return{schema:ln,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(o=>o.id!==e.id),r].slice(-fc)}}function Br(t,e){let n=Sc(t),r=0,o=0,s=0,i=[];for(let a of e){if(!mc.has(a.type))continue;r+=1;let c=hc({type:a.type,data:a.data}),u={schema:pc,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)+`
|
|
29
|
+
`;xc(pt(gc(t),`${c}.json`),l)?o+=1:s+=1,i.push(c),n=Ac(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[bc(a)],files:wc(a)})}return r>0&&kc(t,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Tc}from"node:crypto";import{existsSync as Rc,readdirSync as Nc,readFileSync as _c}from"node:fs";import{basename as Kc,join as uo}from"node:path";import{randomUUID as Ur}from"node:crypto";var E=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Ce(t){let e=new Set,n=[];for(let r of t){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),n.push(o))}return n}function re(t){let e=t.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new E("Invalid Wiki slug",400);return e}function Hr(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(re(r))}return Ce(e)}function Ic(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function Gr(t){return{id:`revision-${Ur()}`,pageId:t.id,slug:t.slug,revision:t.revision,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...t.tags],links:[...t.links],createdAt:t.updatedAt}}function ne(t){return structuredClone(t)}var ft=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=e(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let e=await this.ensureState(),n=new Set(e.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:Ce(e.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:e.pages.reduce((r,o)=>r+o.links.length,0),orphanPages:e.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:e.pages.filter(r=>r.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return ne([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=re(e),o=n.pages.find(s=>s.slug===r||s.id===e);if(!o)throw new E(`Wiki page not found: ${e}`,404);return ne(o)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),o=e.content.trim();if(!r)throw new E("Wiki title is required",400);let s=re(e.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-${Ur()}`,slug:s,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:Ce(e.tags??[]),links:Hr(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Gr(a)),ne(a)})}async updatePage(e,n){return this.mutate(r=>{let o=re(e),s=r.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new E(`Wiki page not found: ${e}`,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=Hr(s.content)),n.tags!==void 0&&(s.tags=Ce(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(Gr(s)),ne(s)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return ne(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(e){let n=await this.getPage(e),r=await this.ensureState();return ne(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(e,n=10){let r=await this.ensureState(),o=Ce(Ic(e));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:ne(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var Yr="wiki/state.v1.json";function Ec(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function Mc(t,e){let n=JSON.parse(t);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==e.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var mt=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Yr);if(!e){let n=Ec(this.project);return await this.save(n),n}return Mc(e,this.project)}async save(e){await this.storage.put(Yr,JSON.stringify(e,null,2),"application/json")}};import{createHash as Pc,randomUUID as Xr}from"node:crypto";var Qr="wiki/governance.v1.json",no="toolnet.knowledge-governance.v1",Zr=500,Oe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function jc(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function dn(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function eo(t){return Pc("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Cc(t){let e=[t.title,t.summary??"",t.content.slice(0,2e3),...t.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(e)}function Oc(t){let e=t.sourceType==="skill"?.96:t.sourceType==="memory"?.94:.88,n=t.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(e+=.03),t.content.length>=200&&(e+=.02),t.content.length<80&&(e-=.05),t.title.length<4&&(e-=.05),jc(e)}function to(t){let e=new Date().toISOString();return{schema:no,version:1,projectId:t,policy:{...Oe},reviews:[],audit:[],createdAt:e,updatedAt:e}}function ro(t){let e=t.autoApproveThreshold??Oe.autoApproveThreshold,n=t.criticalApproveThreshold??Oe.criticalApproveThreshold,r=t.staleAfterDays??Oe.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>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:e,criticalApproveThreshold:n,staleAfterDays:r}}var gt=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Qr);if(!e){let n=to(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==no||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:ro(n.policy??Oe)}}catch{let n=to(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(Qr,JSON.stringify(e,null,2),"application/json")}},yt=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,n,r,o={}){e.audit.push({id:Xr(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),e.audit.length>Zr&&(e.audit=e.audit.slice(-Zr))}async mutate(e){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await e(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(e,n){return this.mutate(r=>(r.policy=ro({...r.policy,...e}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let e=await this.ensureState(),n=r=>e.reviews.filter(o=>o.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!e||r.status===e).sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt)))}async auditLog(e=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(n.audit.slice(-r).reverse())}async assess(e,n){let r=await this.ensureState(),o=Oc(e),s=dn(e.title),i=n.filter(l=>l.slug!==e.slug&&dn(l.title)===s&&eo(l.content)!==eo(e.content)).map(l=>l.slug),a=Cc(e),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(e,n){let r=await this.assess(e,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.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:e.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:Xr(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return 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(e,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===e&&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:e}))})}async decide(e,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===e);if(!s)throw new E(`Governance review not found: ${e}`,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:e,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:e,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:e,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:e,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(e){let n=await this.ensureState(),r=await e.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=dn(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",po="toolnet.wiki-automation.v1",mn=8e3,oo=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Re(t){return Tc("sha256").update(JSON.stringify(t)).digest("hex")}function Te(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function so(t){return Array.isArray(t)?t:[]}function fo(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function pn(t){return Array.isArray(t)?t.map(fo).filter(e=>!!e):[]}function L(t,e){for(let n of e){let r=fo(t[n]);if(r)return r}}function Ne(t){let e=new Set,n=[];for(let r of t){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();e.has(s)||(e.add(s),n.push(o))}return n}function ht(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(oo.has(r))return[];if(typeof t=="string"){let i=t.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(t))return t.flatMap(i=>ht(i,e+1,n));let o=Te(t);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();oo.has(c)||s.push(...ht(a,e+1,i))}return s}function io(t){let n=Ne(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>ht(t[o],0,o)));return(n.length>0?n:Ne(ht(t))).join(`
|
|
30
30
|
|
|
31
|
-
`).slice(0,
|
|
32
|
-
${u}`),
|
|
33
|
-
${
|
|
34
|
-
${
|
|
31
|
+
`).slice(0,mn)}function ao(t,e){return L(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function co(t,e){return L(t,["title","name","topic","label","task","kind","type"])??e}function Lc(t){return(L(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function $c(t){return(L(t,["kind","sceneKind","type"])??"").toLowerCase()}function Dc(t){let e=Te(t);if(!e)return[];let n=[],r=so(e.knowledge);for(let[s,i]of r.entries()){let a=Te(i);if(!a)continue;let c=Lc(a);if(c==="session"||c==="transient")continue;let u=io(a);if(u.length<20)continue;let l=ao(a,Re(a).slice(0,16)),d=co(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${l}`,sourceType:"memory",title:d,summary:L(a,["summary","description"]),content:u,tags:Ne(["toolnet","auto","memory",...c?[c]:[]])})}let o=so(e.scenes);for(let[s,i]of o.entries()){let a=Te(i);if(!a)continue;let c=$c(a);if(c==="session-context")continue;let u=io(a);if(u.length<20)continue;let l=ao(a,Re(a).slice(0,16)),d=co(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${l}`,sourceType:"scene",title:d,summary:L(a,["summary","description"]),content:u,tags:Ne(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Fc(t){return uo(t,".toolnet","memory","skills")}function Wc(t){let e=Fc(t);if(!Rc(e))return{candidates:[],failed:0};let n=[],r=0,o=Nc(e).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(_c(uo(e,s),"utf8")),a=Te(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=L(a,["id","fingerprint"])??Kc(s,".json"),u=L(a,["task"])??"",l=L(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=L(a,["summary"])??void 0,p=pn(a.steps),f=pn(a.verification),m=pn(a.files),S=[];u&&S.push(`## Task
|
|
32
|
+
${u}`),d&&S.push(`## Summary
|
|
33
|
+
${d}`),p.length>0&&S.push(`## Procedure
|
|
34
|
+
${p.map((h,v)=>`${v+1}. ${h}`).join(`
|
|
35
35
|
`)}`),f.length>0&&S.push(`## Verification
|
|
36
36
|
${f.map(h=>`- ${h}`).join(`
|
|
37
37
|
`)}`),m.length>0&&S.push(`## Relevant Files
|
|
38
38
|
${m.map(h=>`- \`${h}\``).join(`
|
|
39
39
|
`)}`);let g=S.join(`
|
|
40
40
|
|
|
41
|
-
`).slice(0,
|
|
42
|
-
`).slice(0,
|
|
43
|
-
`,{encoding:"utf8",mode:384}),
|
|
44
|
-
`,c=w(r.map(
|
|
45
|
-
`,"application/json"),u}};function
|
|
41
|
+
`).slice(0,mn);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 fn(t){let e=new Date().toISOString();return{schema:po,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function zc(t,e){let n=await t.getText(lo);if(!n)return fn(e);try{let r=JSON.parse(n);return r.schema!==po||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?fn(e):r}catch{return fn(e)}}async function qc(t,e){await t.put(lo,JSON.stringify(e,null,2),"application/json")}function Vc(t){return`toolnet-auto-${Re(t).slice(0,12)}`}function Jc(t){let e=re(t.title).slice(0,72),n=Re(t.sourceKey).slice(0,10);return re(`auto-${t.sourceType}-${e}-${n}`)}function Bc(t){return[`> Auto-generated by ToolNet Knowledge Automation from ${t.sourceType==="skill"?"reusable Skill Memory":t.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",t.content].join(`
|
|
42
|
+
`).slice(0,mn)}function Hc(t){return Re({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function Gc(t,e){return t.tags.includes(e)}async function mo(t){let e=Dc(t.hierarchy),n=Wc(t.project.rootPath),r=new Map;for(let f of[...e,...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:e.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 ft(new mt(t.storage,t.project));await i.initialize();let a=new yt(new gt(t.storage,t.project));await a.initialize();let c=await zc(t.storage,t.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=Vc(f.sourceKey),S=Hc(f),g=d.get(f.sourceKey),h=g?.slug??Jc(f),v=l.get(h);if(v&&!Gc(v,m)){s.skipped+=1;continue}let x=Ne([...f.tags,m]),O=Bc(f),j=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:x},[...l.values()]);if(!j.allowed){j.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}j.mode==="auto-approved"?s.autoApproved+=1:j.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==S?(v=await i.updatePage(h,{title:f.title,summary:f.summary??"",content:O,tags:x}),l.set(v.slug,v),s.updated+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"updated"})):(s.unchanged+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,action:"unchanged"})):(v=await i.createPage({slug:h,title:f.title,summary:f.summary,content:O,tags:x}),l.set(v.slug,v),s.created+=1,s.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"created"}));let T=new Date().toISOString(),A={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,digest:S,marker:m,updatedAt:T},b=c.entries.findIndex(W=>W.sourceKey===f.sourceKey);b>=0?c.entries[b]=A:c.entries.push(A),d.set(f.sourceKey,A),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 qc(t.storage,c),s}import{createHash as Uc}from"node:crypto";import{chmodSync as yo,existsSync as Yc,mkdirSync as Xc,readFileSync as $g,readdirSync as Dg,renameSync as Qc,statSync as Fg,writeFileSync as Zc}from"node:fs";import{join as ho}from"node:path";var eu="toolnet.skill-memory.v1",go=5,tu=16,nu=24,ru=32;function ou(t){return Uc("sha256").update(t).digest("hex")}function Ke(t,e=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let o of t){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>=e))break}return r}function gn(t,e=360){let n=t.replace(/\s+/gu," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function su(t){return t.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function q(t,e=360){return t&&gn(su(t),e)||void 0}function Le(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function So(t,e){for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function ko(t,e){for(let n of e){let r=t[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(t){let e=t.data??{};if(ko(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=So(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let o=Le(e,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function _e(t){let e=t.data??{};if(vo(t))return!1;if(ko(e,["passed","pass","success","succeeded","ok"])===!0||So(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=Le(e,["status","result","outcome"]);return o&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(o)?!0:t.type==="commit"||t.type==="deploy"}function wo(t){let e=t.data??{},n=Le(e,["path","file","filePath","filename","target"]);if(n)return q(n,260);let r=t.provenance?.files;return q(r?.[0],260)}function yn(t){return q(Le(t.data??{},["command","cmd","script"]),420)}function de(t){return q(Le(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function iu(t){let e=[];for(let n of[...t].sort((r,o)=>r.sequence-o.sequence))if(_e(n)){if(n.type==="test"){let r=de(n)??yn(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=de(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=de(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return Ke(e,10)}function au(t,e){let n=[];for(let r of[...t].sort((o,s)=>o.sequence-s.sequence))switch(r.type){case"file_write":case"file_edit":{let o=wo(r);o&&n.push(`Update ${o}`);break}case"command":{if(vo(r))break;let o=yn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!_e(r))break;let o=de(r)??yn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!_e(r))break;let o=de(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!_e(r))break;let o=de(r);n.push(o?`Deploy: ${o}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of e.files.slice(0,8)){let o=q(r,260);o&&n.push(`Update ${o}`)}return Ke(n,tu)}function cu(t,e){let n=[...e.files];for(let r of t){let o=wo(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=q(s,260);i&&n.push(i)}}return Ke(n,nu)}function uu(t){return Ke(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),ru)}function lu(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function bo(t,e,n){if(e.length===0)return[];let r=iu(e),o=Ke(n.completed.map(m=>q(m,280)??""),go);if(!(o.length>0||e.some(m=>["test","commit","deploy"].includes(m.type)&&_e(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=au(e,n);if(c.length===0)return[];let u=cu(e,n),l=uu(e),d=Math.min(...e.map(m=>m.sequence)),p=Math.max(...e.map(m=>m.sequence)),f=lu(e);return a.slice(0,go).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:t.projectId,task:m,steps:c,verification:r,files:u}),h=ou(g);return{schema:eu,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:t.projectId,title:gn(`SOP: ${m}`,180),task:m,summary:gn(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:d,lastSequence:p,eventIds:l},createdAt:f}})}function du(t){return ho(t.rootPath,".toolnet","memory","skills")}function pu(t){let e=du(t);return Xc(e,{recursive:!0,mode:448}),yo(e,448),e}function xo(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=pu(t),r=0,o=0,s=[];for(let i of e){if(i.projectId!==t.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${t.id}`);let a=ho(n,`${i.id}.json`);if(s.push(a),Yc(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Zc(c,JSON.stringify(i,null,2)+`
|
|
43
|
+
`,{encoding:"utf8",mode:384}),Qc(c,a),yo(a,384),r+=1}return{written:r,deduped:o,files:s}}var Qg="0".repeat(64);function Ao(t){return String(t).padStart(12,"0")}function fu(t){return`projects/${t.projectId}/memory/learned`}var St=class{constructor(e){this.storage=e}storage;async write(e,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:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
|
|
44
|
+
`,c=w(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=w(e.sessionKey).slice(0,12),l=[fu(e),"batches",`${Ao(o)}-${Ao(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(l)||await this.storage.put(l,a,"application/json"),l}};import{createHash as mu}from"node:crypto";function Io(t){return String(t).padStart(12,"0")}function Eo(t){return mu("sha256").update(t).digest("hex")}function gu(t){return`projects/${t.projectId}/memory/hierarchy`}var kt=class{constructor(e){this.storage=e}storage;async write(e,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:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,hierarchy:r},a=Eo([...r.facts.map(l=>l.id),...r.knowledge.map(l=>l.id)].sort().join("|")).slice(0,16),c=Eo(e.sessionKey).slice(0,12),u=[gu(e),"batches",`${Io(o)}-${Io(s)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
|
|
45
|
+
`,"application/json"),u}};function wu(t,e){if(!hu(t))return{events:[],nextOffset:e};let n=vu(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=Su(t,"r");try{ku(i,s,0,o,r)}finally{yu(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
46
46
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
47
|
-
`).filter(Boolean).flatMap(
|
|
48
|
-
`))))}function
|
|
49
|
-
`).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
|
|
47
|
+
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var vt=class{constructor(e){this.options=e;this.journal=new St(e.storage),this.hierarchyJournal=new kt(e.storage)}options;journal;hierarchyJournal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,o=wu(this.options.wal.eventsFile,r);if(o.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:o.nextOffset};let s=dt(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=bo(this.options.identity,o.events,s.state),l=xo(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=Br(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 mo({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 $u,existsSync as Du,openSync as Fu,readSync as Wu,statSync as zu}from"node:fs";function Mo(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function De(t){return t.toLowerCase().replace(/[^a-z0-9]/gu,"")}function $e(t,e,n=0){if(n>8)return;if(Array.isArray(t)){for(let o of t.slice(0,50))$e(o,e,n+1);return}let r=Mo(t);if(r)for(let[o,s]of Object.entries(r))e(o,s,r),$e(s,e,n+1)}function pe(t,e){let n=[];return $e(t,(r,o)=>{e.has(De(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function bu(t){let e=t.trim();if(!e.startsWith("{"))return null;try{return Mo(JSON.parse(e))}catch{return null}}function xu(t){let e=t.data;for(let r of["tool","toolName","tool_name"]){let o=e[r];if(typeof o=="string"&&o.trim())return o.trim().toLowerCase()}let n="";return $e(e,(r,o,s)=>{if(n)return;let i=De(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 Au(t){let e=pe(t.data,new Set(["command","cmd","script"])),n=pe(t.data,new Set(["arguments","args"]));for(let r of n){let o=bu(r);if(o)for(let s of pe(o,new Set(["command","cmd","script"])))e.push(s)}return Array.from(new Set(e.map(r=>r.trim()).filter(Boolean)))}function Iu(t){let e=pe(t.data,new Set(["filepath","file_path","filename","file","path","target"].map(De)));return Array.from(new Set(e.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
|
|
48
|
+
`))))}function Eu(t,e){return t.type==="file_edit"||t.type==="file_write"?"modified":/\b(delete|remove|unlink)\b/iu.test(e)?"deleted":/\b(create|add[_-]?file|new[_-]?file)\b/iu.test(e)?"created":/\b(edit|write|patch|apply[_-]?patch|replace|update[_-]?file)\b/iu.test(e)?"modified":null}function Mu(t){let e=pe(t.data,new Set(["patch","diff","arguments","input"].map(De))),n=[];for(let r of e){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 Pu(t){let e=t.toLowerCase();return/\b(typecheck|type-check)\b/u.test(e)||/\btsc\b[\s\S]*--noemit\b/u.test(e)?"typecheck":/\b(eslint|lint)\b/u.test(e)?"lint":/\b(vitest|jest|pytest)\b/u.test(e)||/\bgo\s+test\b/u.test(e)||/\bcargo\s+test\b/u.test(e)||/\b(npm|pnpm|yarn)\s+(run\s+)?test\b/u.test(e)?"test":/\b(npm|pnpm|yarn)\s+(run\s+)?build\b/u.test(e)||/\bcargo\s+build\b/u.test(e)||/\bgo\s+build\b/u.test(e)||/\btsc\b/u.test(e)?"build":null}function ju(t){let e=null;return $e(t,(n,r)=>{if(e===null&&["exitcode","code"].includes(De(n))){if(typeof r=="number"&&Number.isFinite(r)){e=r;return}if(typeof r=="string"){let o=Number(r);Number.isFinite(o)&&(e=o)}}}),e}function Cu(t){return pe(t,new Set(["status","state","result","output","outputsummary","message","text"]))}function Ou(t){let e=ju(t.data);if(e!==null)return e===0?"passed":"failed";let n=Cu(t.data).join(`
|
|
49
|
+
`).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 Tu(t){let e=[],n=new Set;for(let r of t){let o=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(o)||(n.add(o),e.push(r))}return e}function Po(t){let e=[],n=xu(t),r=Eu(t,n);if(r)for(let o of Iu(t))e.push({kind:"file",text:o,fileAction:r,confidence:t.type==="file_edit"||t.type==="file_write"?1:.96});e.push(...Mu(t));for(let o of Au(t)){e.push({kind:"command",text:o,confidence:.98});let s=Pu(o);s&&e.push({kind:"test",text:o,checkKind:s,checkStatus:Ou(t),confidence:.98})}return Tu(e)}var Ru=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function se(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Co(t){return se(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function oe(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))oe(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,o]of Object.entries(t))(Ru.has(r)||["data","payload","parts","messages"].includes(r))&&oe(o,e,n+1)}}function wt(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function jo(t){let e=se(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function M(t,e,n,r,o={}){let s=se(r),i=o.key??Co(s);return{version:1,id:w([t.projectId,n,i,e.id,s,o.status??"",o.fileAction??"",o.checkKind??"",o.checkStatus??"",o.order??""].join("|")).slice(0,32),projectId:t.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:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function Nu(t,e,n){let r=se(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(M(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(M(t,e,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!s&&(u=c.exec(r));){let p=Number(u[1]),f=se(u[2]??""),m=f&&!jo(f)?`Phase ${p} - ${f}`:`Phase ${p}`;o.push(M(t,e,"phase",m,{key:`phase:${p}`,order:p,status:wt(r),confidence:.93}))}let l=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);l?.[2]&&o.push(M(t,e,"task",l[2],{status:l[1].trim()?"completed":wt(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=se(d[2]),m=jo(f);o.push(M(t,e,"task",m&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:Co(f),order:p,status:wt(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(M(t,e,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&o.push(M(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(M(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.push(M(t,e,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&o.push(M(t,e,"activity",r,{confidence:.86})),o}function bt(t,e){if(e.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 e){if(i.type==="user_prompt"||i.role==="user"){let c=[];oe(i.data,c);let u=c.map(l=>se(l)).find(l=>l.length>=8&&l.length<=1200&&!/^\[?toolnet\b/iu.test(l));u&&o(M(t,i,"request",u,{confidence:.96}))}for(let c of Po(i))o(M(t,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];oe(i.data,c);for(let u of c)o(M(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];oe(i.data,c);for(let u of c)o(M(t,i,"task",u,{status:wt(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(M(t,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];oe(i.data,c);for(let u of c)o(M(t,i,"test",u,{confidence:1}))}let a=[];oe(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let l of Nu(t,i,u))o(l)}let s=e[e.length-1];return o(M(t,s,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Oo(t){return String(t).padStart(12,"0")}var xt=class{constructor(e){this.storage=e}storage;async write(e,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:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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)+`
|
|
50
50
|
`,a=w(n.map(l=>JSON.stringify(l)).sort().join(`
|
|
51
|
-
`)).slice(0,24),c=w(
|
|
52
|
-
`,"application/json"),
|
|
51
|
+
`)).slice(0,24),c=w(e.sessionKey).slice(0,12),u=[`projects/${e.projectId}`,"work","observations",`${Oo(r)}-${Oo(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as To}from"node:path";import{mkdirSync as _u}from"node:fs";function No(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(t,e=20){let n=[],r=new Set;for(let o of t.slice().reverse()){let s=No(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=e))break}return n.reverse()}function Ku(t,e=20){let n=new Map;for(let r of t){let o=`${r.kind}|${No(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-e)}function Lu(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Ro(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let o=t&&Lu(e)?t.title:e.text;return{id:t?.id??w(e.key).slice(0,24),title:o,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function _o(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.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 e.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 Fe(t,e){let r=(await _o(t,e)).flatMap(y=>y.observations).sort((y,k)=>{let C=y.occurredAt.localeCompare(k.occurredAt);if(C!==0)return C;let V=y.sequence-k.sequence;return V!==0?V:y.id.localeCompare(k.id)}),o=new Map,s=new Map,i,a,c,u,l,d=[],p=[],f=[],m=[],S=[],g=new Map,h=[],v=[],x=[],O=[],j=[],T=[];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,Ro(o.get(y.key),y));break;case"task":s.set(y.key,Ro(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"&&x.push(y.text);break}case"command":O.push(y.text);break;case"test":j.push(y.text),y.checkKind&&T.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 A=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)),W=A.find(y=>y.status==="in_progress")??A.find(y=>y.status==="blocked")??A.find(y=>y.status==="pending"),z=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),_t=$([...m,...z?[z.title]:[],...!z&&W?[W.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),Kt=$([...p,...A.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),ye={version:1,projectId:t.id,projectName:t.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:A,tasks:b,decisions:$(d,20),blockers:Kt,warnings:$(f,20),nextActions:_t,filesTouched:$(S,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:$(h,30),createdFiles:$(v,30),deletedFiles:$(x,30),commands:$(O,20),tests:$(j,20),checks:Ku(T,20),currentPhase:W,currentTask:z,progress:{phasesTotal:A.length,phasesCompleted:A.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:A.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()},Be=To(t.rootPath,".toolnet","work");return _u(Be,{recursive:!0}),R(To(Be,"current.json"),ye),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(ye,null,2)+`
|
|
52
|
+
`,"application/json"),ye}async function Ko(t,e){if((await _o(t,e)).length>0)return Fe(t,e);let r=await e.getText(`projects/${t.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function qu(t,e){if(!Du(t))return{events:[],nextOffset:e};let n=zu(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=Fu(t,"r");try{Wu(i,s,0,o,r)}finally{$u(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
53
53
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
54
|
-
`).filter(Boolean).flatMap(
|
|
55
|
-
`,"application/json"),c}};import{mkdirSync as
|
|
56
|
-
`,"application/json"),f}function
|
|
54
|
+
`).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var At=class{constructor(e){this.options=e;this.journal=new xt(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=qu(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=bt(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await Fe(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 Qu,existsSync as Zu,openSync as el,readSync as tl,statSync as nl}from"node:fs";var Vu=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function fe(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function hn(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))hn(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,o]of Object.entries(t))(Vu.has(r)||["data","payload","parts","messages"].includes(r))&&hn(o,e,n+1)}}function _(t,e,n,r,o,s=.95){let i=fe(r);return{version:1,id:w([t.projectId,n,o.type,o.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:o.type,scopeKey:o.key,scopeOrder:o.order,confidence:s,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function D(t,e){let n=t.toLowerCase();for(let r of e){let o=r.toLowerCase();if(n.startsWith(`${o}:`)||n.startsWith(`${o} -`)||n.startsWith(`${o} \u2014`))return fe(t.slice(r.length+1))}return null}function Ju(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Bu(t){return fe(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Lo(t,e){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 e){let i=[];hn(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=fe(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:fe(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:fe(f[2]??"")},u=null;continue}let m=D(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o(_(t,s,"mission",m,{type:"project"},.99)),u=null;continue}let S=D(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(_(t,s,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let g=D(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o(_(t,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let h=D(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(_(t,s,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let v=D(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(_(t,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=D(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){o(_(t,s,"phase_deliverable",x,c,.97)),u=null;continue}let O=D(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(O){o(_(t,s,"acceptance_criterion",O,c,.98)),u="acceptance_criterion";continue}let j=D(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(j){o(_(t,s,"dependency",j,c,.97)),u="dependency";continue}let T=D(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){o(_(t,s,"open_question",T,c,.95)),u="open_question";continue}let A=D(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(A){o(_(t,s,"constraint",A,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&&Ju(l)){o(_(t,s,u,Bu(l),c,.96));continue}u=null}}}return n}function $o(t){return String(t).padStart(12,"0")}var It=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),o=Math.max(...n.map(u=>u.evidence.sequence)),s={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.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(e.sessionKey).slice(0,12),c=[`projects/${e.projectId}`,"work","semantic","observations",`${$o(r)}-${$o(o)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(s,null,2)+`
|
|
55
|
+
`,"application/json"),c}};import{mkdirSync as Hu}from"node:fs";import{join as Do}from"node:path";function Gu(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Uu(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function G(t,e){return Uu(e,t)?e:t}function U(t,e=30){let n=new Set,r=[];for(let o of t){let s=o.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!s||n.has(s)||(n.add(s),r.push(o))}return r.slice(-e)}async function Yu(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.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 e.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 Xu(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Fo(t,e){let r=(await Yu(t,e)).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=Gu(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??Xu(S);switch(S.kind){case"phase_objective":h.objective=G(h.objective,g);break;case"phase_why":h.why=G(h.why,g);break;case"phase_deliverable":h.deliverable=G(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=G(o,g);break;case"objective":s=G(s,g);break;case"why":i=G(i,g);break;case"desired_outcome":a=G(a,g);break;case"plan_rationale":c=G(c,g);break;case"open_question":l.push(g);break;case"constraint":d.push(g);break;case"note":p.push(g);break}}for(let S of u.values())S.acceptanceCriteria=U(S.acceptanceCriteria,20),S.dependencies=U(S.dependencies,15),S.openQuestions=U(S.openQuestions,15),S.constraints=U(S.constraints,15),S.notes=U(S.notes,20);let f={version:1,projectId:t.id,projectName:t.name,mission:o,activeObjective:s,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,g)=>S.order-g.order),openQuestions:U(l,20),constraints:U(d,20),notes:U(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=Do(t.rootPath,".toolnet","work");return Hu(m,{recursive:!0}),R(Do(m,"semantic-current.json"),f),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
|
|
56
|
+
`,"application/json"),f}function rl(t,e){if(!Zu(t))return{events:[],nextOffset:e};let n=nl(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=Buffer.alloc(n-r),s=el(t,"r");try{tl(s,o,0,o.length,r)}finally{Qu(s)}let i=o.toString("utf8"),a=i.lastIndexOf(`
|
|
57
57
|
`);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
|
|
58
|
-
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var
|
|
58
|
+
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Et=class{constructor(e){this.options=e;this.journal=new It(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=rl(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=Lo(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await Fo(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 Yl,mkdirSync as Xl}from"node:fs";import{join as kn}from"node:path";import{existsSync as qo,mkdirSync as ol,readFileSync as sl,statSync as Wo,writeFileSync as il}from"node:fs";import{dirname as al,join as cl}from"node:path";var zo=64*1024,ul=`# ToolNet Project Operating Manual
|
|
59
59
|
|
|
60
60
|
This file contains persistent instructions for AI agents working on this project.
|
|
61
61
|
|
|
@@ -98,24 +98,24 @@ Things an AI agent should always remember.
|
|
|
98
98
|
<!--
|
|
99
99
|
- [advisory] Prefer small focused files.
|
|
100
100
|
-->
|
|
101
|
-
`;function
|
|
102
|
-
`,{encoding:"utf8"}),
|
|
103
|
-
`,{encoding:"utf8"}),
|
|
104
|
-
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function
|
|
101
|
+
`;function Vo(t){return cl(t.rootPath,".toolnet","PROJECT.md")}function ll(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function dl(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,o;for(;o=r.exec(t);){let s=o[1].toLowerCase(),i=ll(o[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;n.has(a)||(n.add(a),e.push({id:w(a).slice(0,24),mode:s,text:i,source:"manual"}))}return e}function pl(t){let e=Vo(t);return qo(e)||(ol(al(e),{recursive:!0}),il(e,ul,{encoding:"utf8",mode:384})),e}function Jo(t,e=!1){let n=e?pl(t):Vo(t);if(!qo(n))return null;if(Wo(n).size>zo)throw new Error(`PROJECT.md exceeds ${zo} bytes`);let o=sl(n,"utf8");return{path:n,content:o,digest:w(o),rules:dl(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(Wo(n).mtimeMs).toISOString()}}import{randomUUID as fl}from"node:crypto";import{closeSync as ml,existsSync as Bo,fsyncSync as gl,mkdirSync as yl,openSync as hl,readFileSync as Sl,statSync as kl,unlinkSync as Ho,writeFileSync as vl}from"node:fs";import{dirname as wl,join as bl}from"node:path";var xl=new Int32Array(new SharedArrayBuffer(4));function Al(t){t<=0||Atomics.wait(xl,0,0,t)}function Il(t){return bl(t.rootPath,".toolnet","work",".current.lock")}function El(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e?.code!=="ESRCH"}}function Go(t){if(!Bo(t))return null;try{let e=JSON.parse(Sl(t,"utf8"));return e.version!==1||typeof e.token!="string"||typeof e.pid!="number"||typeof e.acquiredAt!="string"?null:{version:1,token:e.token,pid:e.pid,acquiredAt:e.acquiredAt}}catch{return null}}function Ml(t){try{return Date.now()-kl(t).mtimeMs}catch{return 0}}function Pl(t,e){if(!Bo(t)||Ml(t)<e)return!1;let n=Go(t);return n?!El(n.pid):!0}function jl(t,e){if(!Pl(t,e))return!1;try{return Ho(t),!0}catch{return!1}}function Cl(t,e){let n={version:1,token:e,pid:process.pid,acquiredAt:new Date().toISOString()},r=hl(t,"wx",384);try{vl(r,`${JSON.stringify(n,null,2)}
|
|
102
|
+
`,{encoding:"utf8"}),gl(r)}finally{ml(r)}}function Ol(t,e){if(Go(t)?.token===e)try{Ho(t)}catch{}}function Tl(t,e={}){let n=Math.max(100,e.timeoutMs??5e3),r=Math.max(5,e.retryMs??20),o=Math.max(n*2,e.staleMs??3e4),s=Il(t);yl(wl(s),{recursive:!0});let i=fl(),a=Date.now()+n;for(;;)try{Cl(s,i);let c=!1;return()=>{c||(c=!0,Ol(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(jl(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);Al(r)}}function Uo(t,e,n={}){let r=Tl(t,n);try{return e()}finally{r()}}import{closeSync as Rl,existsSync as Nl,fsyncSync as _l,mkdirSync as Kl,openSync as Ll,readFileSync as $l,renameSync as Dl,writeFileSync as Fl}from"node:fs";import{dirname as Wl,join as zl}from"node:path";function ql(t,e){Kl(Wl(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`,r=Ll(n,"w",384);try{Fl(r,`${JSON.stringify(e,null,2)}
|
|
103
|
+
`,{encoding:"utf8"}),_l(r)}finally{Rl(r)}Dl(n,t)}function ts(t){return zl(t.rootPath,".toolnet","work","current.json")}function Sn(t){let e=ts(t);if(!Nl(e))return null;try{let n=JSON.parse($l(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Mt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function K(t,e,n){let r=[],o=new Set;for(let s of[...t,...e].reverse()){let i=Mt(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function Vl(t,e,n=20){let r=new Map;for(let o of[...t,...e]){let s=`${o.kind}|${Mt(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function Jl(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Yo(t,e){let n=e.status??t?.status??"pending",r=n;t?.status==="completed"&&n!=="completed"&&(r="completed"),t&&n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status);let o=t&&Jl(e)?t.title:e.text;return{id:t?.id??e.id,title:o,status:r,order:e.order??t?.order,confidence:Math.max(t?.confidence??0,e.confidence),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}function Xo(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:Mt(n.title);e.set(r,n)}return e}function Qo(t){return t.order!==void 0?`order:${t.order}`:Mt(t.key||t.text)}function Zo(t){return Array.from(t).sort((e,n)=>{let r=e.order??Number.MAX_SAFE_INTEGER,o=n.order??Number.MAX_SAFE_INTEGER;return r!==o?r-o:e.updatedAt.localeCompare(n.updatedAt)})}function es(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function Bl(t,e){let n=Sn(t),r=Xo(n?.phases??[]),o=Xo(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,l=[],d=[],p=[],f=[],m=[],S=[...n?.activeFiles??[]],g=[],h=[],v=[],x=[],O=[],j=[],T=[...e].sort((k,C)=>{let V=k.occurredAt.localeCompare(C.occurredAt);return V!==0?V:k.sequence-C.sequence});for(let k of T)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 C=Qo(k);r.set(C,Yo(r.get(C),k));break}case"task":{let C=Qo(k);o.set(C,Yo(o.get(C),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 C=k.fileAction??"active",V=S.indexOf(k.text);V>=0&&S.splice(V,1),C!=="deleted"&&S.push(k.text),C==="modified"?g.push(k.text):C==="created"?h.push(k.text):C==="deleted"&&v.push(k.text);break}case"command":x.push(k.text);break;case"test":O.push(k.text),k.checkKind&&j.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 A=Zo(r.values()),b=Zo(o.values()),W=es(A),z=es(b),_t=K(n?.nextActions??[],[...f,...z?[z.title]:[],...!z&&W?[W.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),Kt=K(n?.blockers??[],[...d,...A.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),ye=T.length>0?T[T.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),Be={version:1,projectId:t.id,projectName:t.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:A,tasks:b,decisions:K(n?.decisions??[],l,20),blockers:Kt,warnings:K(n?.warnings??[],p,20),nextActions:_t,filesTouched:K(n?.filesTouched??[],m,30),activeFiles:K([],S,5),modifiedFiles:K(n?.modifiedFiles??[],g,30),createdFiles:K(n?.createdFiles??[],h,30),deletedFiles:K(n?.deletedFiles??[],v,30),commands:K(n?.commands??[],x,20),tests:K(n?.tests??[],O,20),checks:Vl(n?.checks??[],j,20),currentPhase:W,currentTask:z,progress:{phasesTotal:A.length,phasesCompleted:A.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:A.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:ye},y=ae(Be);return ql(ts(t),y),y}function ns(t,e){return Uo(t,()=>Bl(t,e))}function P(t,e){let n=new Set,r=[];for(let o of t){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>=e))break}return r}function rs(t){if(t)return{id:t.id,title:t.title,status:t.status}}function Hl(t,e=[]){let n=e.slice(-10);if(n.some(o=>o.status==="failed"))return"failing";if(n.some(o=>o.status==="passed"))return"passing";let r=t.slice(-10).join(`
|
|
104
|
+
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Gl(t){return w(JSON.stringify(t))}function Ul(t){let e=[];for(let n of t){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let o of r){let s=o.replace(/[.,;:!?]+$/gu,"").trim();s&&e.push(s)}}return P(e,30)}function os(t){let{project:e,identity:n,state:r}=t,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=P(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=P([...c,...l],15),p=P(r.tests.slice().reverse(),10),f=P([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),m={schema:"toolnet.handoff.v2",version:2,project:{id:e.id,name:e.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:t.sequence,reason:t.reason},capturedAt:t.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:rs(r.currentPhase),task:rs(r.currentTask),file:o},completed:{phases:P(s,20),tasks:P(i,30)},remaining:{phases:P(a,20),tasks:P(c,30),todos:d},nextAction:l[0],blockers:P(r.blockers.slice().reverse(),10),decisions:P(r.decisions.slice().reverse(),10),files:{current:o,recent:f,active:P(r.activeFiles??[],10),modified:P(r.modifiedFiles??[],20),created:P(r.createdFiles??[],20),deleted:P(r.deletedFiles??[],20)},tests:{status:Hl(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:P((r.commands??[]).slice().reverse(),20),references:Ul([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:P(t.attention??[],20),progress:r.progress},{capturedAt:S,source:g,...h}=m;return{...m,stateDigest:Gl(h)}}function Ql(t){return!!(t.currentRequest||t.currentActivity||t.goal||t.plan||t.phases.length>0||t.tasks.length>0||t.nextActions.length>0||t.blockers.length>0||t.decisions.length>0||t.filesTouched.length>0)}function ss(t,e,n,r,o){if(!Ql(n))return null;let s=Jo(t,!1),a=[...s?s.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=os({project:t,identity:e,state:n,reason:r,sequence:o,attention:a}),u=c.stateDigest;return{version:1,id:w([t.id,e.sessionKey,u].join("|")).slice(0,24),projectId:t.id,projectName:t.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,sequence: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 is(t,e){let n=kn(t.rootPath,".toolnet","work","handoffs");Xl(n,{recursive:!0});let r=kn(n,`${e.id}.json`);Yl(r)||R(r,e),R(kn(t.rootPath,".toolnet","work","handoff-latest.json"),e)}function as(t){let e=ss(t.project,t.identity,t.state,t.reason,t.sequence);return e?(is(t.project,e),e):null}var Pt=class{constructor(e){this.options=e}options;async capture(e,n){let r=Sn(this.options.project);r||(r=await Ko(this.options.project,this.options.storage)),r||(r=await Fe(this.options.project,this.options.storage));let o=ss(this.options.project,this.options.identity,r,e,n);if(!o)return null;is(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)+`
|
|
105
105
|
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(o,null,2)+`
|
|
106
|
-
`,"application/json"),o}};import{existsSync as
|
|
107
|
-
`)}function
|
|
106
|
+
`,"application/json"),o}};import{existsSync as Zl,readFileSync as ed,writeFileSync as td}from"node:fs";import{join as nd}from"node:path";var us="<!-- TOOLNET:STABLE-WORK:BEGIN -->",vn="<!-- TOOLNET:STABLE-WORK:END -->";function wn(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function F(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function cs(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${wn(n)} ${n.title}`)]:[]}function rd(t){let e=[us,"# ToolNet Stable Work State","",`Updated: ${t.updatedAt}`];return t.lastSession&&e.push(`Last agent: ${t.lastSession.agent}`,`Last session: ${t.lastSession.nativeSessionId}`),t.currentRequest&&e.push("","Current request:",t.currentRequest),t.currentActivity&&e.push("","Current activity:",t.currentActivity),t.goal&&e.push("","Goal:",t.goal),t.plan&&e.push("","Plan:",t.plan),t.currentPhase&&e.push("","Current phase:",`${wn(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${wn(t.currentTask)} ${t.currentTask.title}`),e.push(...cs("Phases",t.phases)),e.push(...cs("TODO / Tasks",t.tasks)),e.push(...F("Next actions",t.nextActions)),e.push(...F("Blockers",t.blockers)),e.push(...F("Important decisions",t.decisions)),e.push(...F("Active files",t.activeFiles??[])),e.push(...F("Modified files",t.modifiedFiles??[])),e.push(...F("Created files",t.createdFiles??[])),e.push(...F("Deleted files",t.deletedFiles??[])),e.push(...F("Files touched",t.filesTouched)),e.push(...F("Recent commands",t.commands??[])),e.push(...F("Checks",(t.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),e.push("","Progress:",`- Phases: ${t.progress.phasesCompleted}/${t.progress.phasesTotal}`,`- Tasks: ${t.progress.tasksCompleted}/${t.progress.tasksTotal}`,`- Blocked: ${t.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",vn),e.join(`
|
|
107
|
+
`)}function ls(t,e){let n=nd(t.rootPath,".toolnet","current.md"),r="";if(Zl(n))try{r=ed(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=rd(e),s=r.indexOf(us),i=r.indexOf(vn),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+vn.length).trimStart()].filter(Boolean).join(`
|
|
108
108
|
|
|
109
109
|
`):a=r.trim()?`${r.trim()}
|
|
110
110
|
|
|
111
|
-
${o}`:o,
|
|
112
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as
|
|
113
|
-
`,{encoding:"utf8",mode:384}),
|
|
114
|
-
`);if(u<0)return{events:[],nextOffset:o,reset:r};let l=c.slice(0,u+1),
|
|
111
|
+
${o}`:o,td(n,`${a.trim()}
|
|
112
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as kh,mkdirSync as od,readFileSync as vh,renameSync as sd,writeFileSync as id}from"node:fs";import{dirname as ad,join as cd}from"node:path";function ud(t){return cd(t.rootPath,".toolnet","context","session-origin.json")}function ld(t,e){od(ad(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;id(n,`${JSON.stringify(e,null,2)}
|
|
113
|
+
`,{encoding:"utf8",mode:384}),sd(n,t)}function jt(t,e){return[...t].filter(n=>n.kind===e).sort((n,r)=>{let o=n.occurredAt.localeCompare(r.occurredAt);return o!==0?o:n.sequence-r.sequence}).at(-1)}function ds(t,e){let n=jt(e.observations,"file"),r=jt(e.observations,"next_action"),o=jt(e.observations,"blocker"),s=jt(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentRequest:e.workState.currentRequest,currentActivity:e.workState.currentActivity,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??e.workState.activeFiles?.at(-1)??e.workState.filesTouched.at(-1),latestNextAction:r?.text??e.workState.nextActions.at(-1),latestBlocker:o?.text??e.workState.blockers.at(-1),latestDecision:s?.text??e.workState.decisions.at(-1)};return ld(ud(t),i),i}import{existsSync as ps,mkdirSync as dd,readFileSync as pd}from"node:fs";import{join as bn}from"node:path";function fs(t){return bn(t.rootPath,".toolnet","memory","checkpoints")}function ms(t){return bn(fs(t),"latest.json")}function fd(t){let e=ms(t);if(!ps(e))return null;try{let n=JSON.parse(pd(e,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==t.id?null:n}catch{return null}}function md(t){return["rule","architecture","decision","fix"].includes(t)}function gd(t,e){return e.length===0?[]:dt(t,e).candidates.filter(r=>md(r.kind)&&r.knowledgeClass!=="transient"&&r.importanceScore>=.65).map(r=>({fingerprint:r.fingerprint,kind:r.kind,content:r.content,knowledgeClass:r.knowledgeClass,importanceScore:r.importanceScore,confidence:r.confidence,createdAt:r.createdAt,agent:t.agent,nativeSessionId:t.nativeSessionId}))}function yd(t,e){let n=new Map;for(let r of[...t,...e]){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 hd(t){return{request:t.currentRequest,activity:t.currentActivity,goal:t.goal,phase:t.currentPhase?{title:t.currentPhase.title,status:t.currentPhase.status}:void 0,task:t.currentTask?{title:t.currentTask.title,status:t.currentTask.status}:void 0,phases:t.phases.map(e=>({title:e.title,status:e.status})),tasks:t.tasks.map(e=>({title:e.title,status:e.status})),activeFiles:t.activeFiles??[],modifiedFiles:t.modifiedFiles??[],createdFiles:t.createdFiles??[],deletedFiles:t.deletedFiles??[],checks:t.checks??[],blockers:t.blockers,decisions:t.decisions,nextActions:t.nextActions}}function gs(t,e,n,r){let o=fd(t),s=yd(o?.durableFacts??[],gd(e,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:hd(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:t.id,name:t.name},source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks: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=fs(t);dd(m,{recursive:!0,mode:448});let S=bn(m,`${p}.json`);return ps(S)||R(S,f),R(ms(t),f),f}function ys(t,e,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=bt(e,n);if(r.length===0)return{updated:!1,observations:0};let o=ns(t,r);ls(t,o),ds(t,{agent:e.agent,nativeSessionId:e.nativeSessionId,observations:r,workState:o});try{gs(t,e,n,o)}catch{}try{as({project:t,identity:e,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 J;learner;continuity;semantic;handoff;project;title;metadata;constructor(e){this.project=e.project,this.identity=or(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new ct(this.identity,e.eventContext),this.remote=new nt(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new vt({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new At({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Et({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new Pt({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}checkpointLocal(e){if(e.length!==0)try{ys(this.project,this.identity,e)}catch{}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){let n=this.wal.append([this.sanitizeEvent(e)]);return this.checkpointLocal(n),n[0]}recordMany(e){let n=this.wal.append(e.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let o=e.events[e.events.length-1];this.wal.markRemote(o.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let o=e.events[e.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(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as Sd,openSync as kd,closeSync as vd,readSync as wd,statSync as bd}from"node:fs";function xd(t){let e=typeof t.role=="string"?t.role:"",n=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||n.includes("user")?"user_prompt":e==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":n.includes("error")?"error":"message"}function Ad(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let n of e){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let o=new Date(r);if(!Number.isNaN(o.getTime()))return o.toISOString()}}return new Date().toISOString()}function hs(t,e={offset:0}){if(!Sd(t))return{events:[],nextOffset:e.offset,reset:!1};let n=bd(t).size,r=e.offset>n,o=r?0:e.offset;if(o===n)return{events:[],nextOffset:n,reset:r};let s=n-o,i=Buffer.alloc(s),a=kd(t,"r");try{wd(a,i,0,s,o)}finally{vd(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
|
|
114
|
+
`);if(u<0)return{events:[],nextOffset:o,reset:r};let l=c.slice(0,u+1),d=Buffer.byteLength(l,"utf8"),p=[],f=0;for(let m of l.split(`
|
|
115
115
|
`)){if(!m)continue;let S=Buffer.byteLength(m+`
|
|
116
|
-
`,"utf8"),g=o+f;f+=S;let h;try{h=JSON.parse(m)}catch{
|
|
117
|
-
`,{encoding:"utf8",mode:384}),
|
|
118
|
-
`,{encoding:"utf8",mode:384}),
|
|
116
|
+
`,"utf8"),g=o+f;f+=S;let h;try{h=JSON.parse(m)}catch{p.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:m},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}});continue}let v=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};p.push({type:xd(v),timestamp:Ad(v),role:typeof v.role=="string"?v.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:v,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:g}})}return{events:p,nextOffset:o+d,reset:r}}var Id=[/^<SYSTEM MESSAGE>/i,/^<EPHEMERAL MESSAGE>/i,/^<system>/i,/^<ephemeral>/i,/^ManageTask:/i,/^Task \d+ status:/i,/^Task \d+ killed/i,/^Task \d+ loading/i,/^Thought for \d+ tokens/i,/^Prioritizing Tool Usage/i,/^Tool call:/i,/^Tool response:/i,/^npm notice/i,/^npm WARN/i,/^added \d+ packages/i,/^removed \d+ packages/i,/^up to date/i,/^\d+ packages are looking for funding/i,/^run `npm fund` for details/i,/^[\d.]+%/,/^\[={10,}\]/,/^Loading\.\.\./i,/^Processing\.\.\./i,/^bash-\d+\.\d+\$/,/^\$ /,/^\s*$/],Ed=[/api[_-]?key[:\s=]+[^\s]+/gi,/token[:\s=]+[^\s]+/gi,/secret[:\s=]+[^\s]+/gi,/password[:\s=]+[^\s]+/gi,/bearer\s+[^\s]+/gi,/authorization:\s*[^\s]+/gi],Md=["decision","decided","rule","convention","architecture","pattern","fixed","resolved","implemented","created","updated","deleted","deployed","blocker","blocked","issue","bug","error","next","todo","action","requirement","must","should","important"];function Pd(t){let e=t.toLowerCase();return Md.some(n=>e.includes(n))}function jd(t){if(!t.trim())return!0;for(let e of Id)if(e.test(t))return!0;return Pd(t),!1}function Cd(t){let e=t;for(let n of Ed)e=e.replace(n,r=>{let o=r.split(/[:\s=]+/);return o.length>1?`${o[0]}: [REDACTED]`:"[REDACTED]"});return e}function xn(t){let e=t.trim();return e?jd(e)?{content:"",filtered:!0,reason:"noise"}:{content:Cd(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function Ot(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let o=xn(r);o.filtered||(e[n]=o.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=Ot(r):Array.isArray(r)?e[n]=r.map(o=>{if(typeof o=="string"){let s=xn(o);return s.filtered?null:s.content}return o&&typeof o=="object"?Ot(o):o}).filter(o=>o!==null):e[n]=r;return e}function Ss(t){let e=typeof t.type=="string"?t.type.toLowerCase():"";if(e.includes("system")||e.includes("ephemeral")||e==="tool_call"&&!t.result)return!0;if(t.data&&typeof t.data=="object"){let n=t.data,r=typeof n.content=="string"?n.content:"";if(r&&xn(r).filtered)return!0}return!1}function Td(t){return t==="~"?An():t.startsWith("~/")?ks(An(),t.slice(2)):t}async function Tt(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let n=Od(Td(t.transcriptPath)),r=new Ct({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName},eventContext:{source:"agy",cwd:t.workspacePaths?.[0]??t.project.rootPath}}),o=r.status(),s=o.sourceCursors["agy.transcript.offset"],i=s?Number(s):0,a=hs(n,{offset:Number.isFinite(i)?i:0}),c=[];o.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:n,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(p=>!Ss(p.data)).map(p=>({...p,data:Ot(p.data)}));c.push(...u),t.phase==="stop"&&(t.error&&c.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",a.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",e,"idle",a.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let l=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),t.phase&&r.setSourceCursor("agy.last.phase",t.phase),u.length>0)try{let p=u.map(m=>JSON.stringify(m.data)),f=lt(p,e);r.setSourceCursor("agy.session.summary",f.summary),r.setSourceCursor("agy.session.facts_count",f.durableFacts.length),Nr()&&(Lr()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let d=await r.flush();return{conversationId:e,imported:l.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:a.nextOffset,reset:a.reset}}function vs(t){return ks(An(),".gemini","antigravity-cli","brain",t,".system_generated","logs","transcript.jsonl")}import{existsSync as ep,mkdirSync as Ms,readFileSync as tp,renameSync as np,writeFileSync as rp}from"node:fs";import{dirname as op,join as Nt}from"node:path";import{existsSync as Kd,mkdirSync as Ld,readFileSync as $d,renameSync as Dd,rmSync as Fd,writeFileSync as Wd}from"node:fs";import{dirname as zd,join as qd}from"node:path";import{homedir as Rd}from"node:os";import{join as me}from"node:path";function ws(t={}){return me(t.home??Rd(),".gemini")}function Nd(t={}){return me(ws(t),"antigravity-cli")}function _d(t={}){return me(ws(t),"config")}function We(t={}){return me(_d(t),"mcp_config.json")}function ze(t={}){let e=t.cwd??process.cwd();return me(e,".agents","mcp_config.json")}function ge(t="toolnet-memory",e={}){return me(Nd(e),"plugins",t)}function Vd(t){return`'${t.replace(/'/g,"'\\''")}'`}function Jd(t){if(!Kd(t))return{};let e;try{e=JSON.parse($d(t,"utf8"))}catch{throw new Error(`Invalid existing Agy hooks.json at ${t}: parse error. Not overwriting.`)}if(typeof e!="object"||e===null||Array.isArray(e))throw new Error(`Invalid existing Agy hooks.json at ${t}: root must be a JSON object.`);return e}function Bd(t,e){Ld(zd(t),{recursive:!0,mode:448});let n=`${t}.tmp-${process.pid}-${Date.now()}`;try{Wd(n,`${JSON.stringify(e,null,2)}
|
|
117
|
+
`,{encoding:"utf8",mode:384}),Dd(n,t)}finally{Fd(n,{force:!0})}}function bs(t={}){let e=t.pluginName??"toolnet-memory",n=t.hooksFile??qd(ge(e),"hooks.json"),r=Jd(n),o=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",s=`${Vd(o)} session:agy-hook`;return r["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${s} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${s} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${s} post`,timeout:15}],Stop:[{type:"command",command:`${s} stop`,timeout:30}]},Bd(n,r),n}import{existsSync as Hd,mkdirSync as Gd,readFileSync as Ud,renameSync as Yd,writeFileSync as Xd}from"node:fs";import{dirname as Qd}from"node:path";function qe(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Zd(t,e){Gd(Qd(t),{recursive:!0,mode:448});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Xd(n,`${JSON.stringify(e,null,2)}
|
|
118
|
+
`,{encoding:"utf8",mode:384}),Yd(n,t)}function xs(t){if(!Hd(t))return{};let e=Ud(t,"utf8").trim();if(!e)return{};let n;try{n=JSON.parse(e)}catch{throw new Error(`Invalid existing Agy MCP config at ${t}: parse error. Not overwriting.`)}if(!qe(n))throw new Error(`Invalid existing Agy MCP config at ${t}: root must be a JSON object. Not overwriting.`);return n}function As(t,e){return qe(t)?t.command===e&&Array.isArray(t.args)&&t.args.length===1&&t.args[0]==="mcp":!1}function Rt(t,e,n,r){let o=xs(t),s=o.mcpServers;if(s!==void 0&&!qe(s))throw new Error(`Invalid existing Agy MCP config: mcpServers must be an object in ${t}.`);let i=qe(s)?{...s}:{},a=i[n];if(As(a,e)&&!r)return{installed:!0,changed:!1};i[n]={command:e,args:["mcp"]};let c={...o,mcpServers:i};Zd(t,c);let l=xs(t).mcpServers;if(!qe(l)||!As(l[n],e))throw new Error(`Agy MCP configuration was written but verification failed for ${t}.`);return{installed:!0,changed:!0}}function Is(t={}){let e=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=t.serverName??"toolnet-memory",r=t.scope??"global";if(t.configFile)return{...Rt(t.configFile,e,n,t.force??!1),configFile:t.configFile,serverName:n,command:e,args:["mcp"]};if(r==="both"){let i=We(),a=ze({cwd:t.cwd}),c=Rt(i,e,n,t.force??!1),u=Rt(a,e,n,t.force??!1);return{installed:!0,changed:c.changed||u.changed,configFile:i,serverName:n,command:e,args:["mcp"]}}let o=r==="workspace"?ze({cwd:t.cwd}):We();return{...Rt(o,e,n,t.force??!1),configFile:o,serverName:n,command:e,args:["mcp"]}}var sp=`# ToolNet Memory Continuity
|
|
119
119
|
|
|
120
120
|
ToolNet Memory is the authoritative continuity layer for previous project work.
|
|
121
121
|
|
|
@@ -154,9 +154,9 @@ Invoke the MCP tool directly.
|
|
|
154
154
|
Current repository evidence overrides stale memory after ToolNet has restored the working context.
|
|
155
155
|
|
|
156
156
|
Do not ask the user to repeat context already available through ToolNet Memory.
|
|
157
|
-
`;function
|
|
158
|
-
`),
|
|
159
|
-
`),{installed:!0,pluginRoot:r,files:[o,s,i,a]}}import{existsSync as
|
|
157
|
+
`;function ip(t,e){Ms(op(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;rp(n,e,{encoding:"utf8",mode:384}),np(n,t)}function Es(t,e){ep(t)&&tp(t,"utf8")===e||ip(t,e)}function Ps(t={}){let e=t.pluginName??"toolnet-memory",n=t.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=t.pluginRoot??ge(e),o=Nt(r,"plugin.json"),s=Nt(r,"mcp_config.json"),i=Nt(r,"hooks.json"),a=Nt(r,"rules","toolnet-memory-continuity.md");return Ms(r,{recursive:!0,mode:448}),Es(o,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:e,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
|
|
158
|
+
`),Is({configFile:s,binary:n,serverName:"toolnet-memory",force:t.force}),bs({hooksFile:i,binary:n,pluginName:e}),Es(a,`${sp.trim()}
|
|
159
|
+
`),{installed:!0,pluginRoot:r,files:[o,s,i,a]}}import{existsSync as js}from"node:fs";import{homedir as ap}from"node:os";import{join as cp,resolve as Cs}from"node:path";import{DatabaseSync as up}from"node:sqlite";function Os(t){if(t.startsWith("file://"))try{return decodeURIComponent(new URL(t).pathname)}catch{return t}return t}function lp(t){if(typeof t!="string"||!t)return[];try{let e=JSON.parse(t);if(Array.isArray(e))return e.filter(n=>typeof n=="string").map(Os)}catch{}return[Os(t)]}function dp(t,e){let n=Cs(t.rootPath);return e.some(r=>{let o=Cs(r);return o===n||o.startsWith(n+"/")||n.startsWith(o+"/")})}async function Ts(t,e,n=10){console.log(`Recovering Agy sessions for project: ${t.name}`),console.log(`Limit: ${n} sessions`),console.log("");let r=process.env.AGY_SUMMARY_DB??cp(ap(),".gemini","antigravity-cli","conversation_summaries.db");if(!js(r))throw new Error(`Agy summary database not found: ${r}`);let o=new up(r,{readOnly:!0});o.exec("PRAGMA query_only = ON");let s=o.prepare(`
|
|
160
160
|
SELECT
|
|
161
161
|
conversation_id,
|
|
162
162
|
title,
|
|
@@ -166,7 +166,7 @@ Do not ask the user to repeat context already available through ToolNet Memory.
|
|
|
166
166
|
FROM conversation_summaries
|
|
167
167
|
ORDER BY
|
|
168
168
|
last_user_input_time DESC
|
|
169
|
-
`).all();o.close();let i=[],a=0,c=Math.min(s.length,n);for(let u of s){let l=typeof u.conversation_id=="string"?u.conversation_id:"";if(!l)continue;let
|
|
169
|
+
`).all();o.close();let i=[],a=0,c=Math.min(s.length,n);for(let u of s){let l=typeof u.conversation_id=="string"?u.conversation_id:"";if(!l)continue;let d=lp(u.workspace_uris);if(!dp(t,d))continue;let p=vs(l);if(!js(p))continue;a++,console.log(`[${a}/${c}] Processing conversation: ${l.slice(0,8)}...`);let f=await Tt({project:t,storage:e,conversationId:l,transcriptPath:p,workspacePaths:d,modelName:typeof u.agent_name=="string"?u.agent_name:void 0,phase:"recover"});if(console.log(` \u2713 Imported ${f.imported} events (${f.eventCount} total, ${f.chunkCount} chunks)`),i.push(f),i.length>=n)break}return console.log(""),console.log(`\u2713 Recovery complete: ${i.length} sessions processed`),console.log(`Total events: ${i.reduce((u,l)=>u+l.eventCount,0)}`),console.log(`Total chunks: ${i.reduce((u,l)=>u+l.chunkCount,0)}`),i}import{spawnSync as pp}from"node:child_process";function Je(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Rs(t,e){return t.includes(e)}function fp(t){let e=He(),n=Qn(Yn({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new tt(n,t.id,t.name,t.remote??t.name)}function mp(){return pp("sh",["-lc","command -v agy >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function gp(t){let e=[],n=mp();n||e.push("agy binary not found");let r=We(),o=Ve(r);o||e.push(`Global MCP config missing: ${r}`);let s=ze({cwd:t}),i=Ve(s),a=ge(),c=Ve(a);c||e.push(`Plugin directory missing: ${a}`);let u=`${a}/hooks.json`,l=Ve(u);!l&&c&&e.push(`Hooks file missing: ${u}`);let d=`${a}/rules/toolnet-memory-continuity.md`,p=Ve(d);return!p&&c&&e.push(`Continuity rule missing: ${d}`),{agyBinaryDetected:n,globalMcpReady:o,workspaceMcpReady:i,pluginReady:c,hooksReady:l,continuityRuleReady:p,errors:e}}async function yp(){let[t="help",...e]=process.argv.slice(2),n=Rs(e,"--json"),r=Rs(e,"--force"),o=Je(e,"--scope")??"global",s=Je(e,"--project")??process.cwd();if(t==="status"){let c=gp(s);if(n)console.log(JSON.stringify(c,null,2));else if(console.log("AGY / Antigravity CLI Integration"),console.log("================================="),console.log(""),console.log(`Binary detected : ${c.agyBinaryDetected?"\u2713":"\u2717"}`),console.log(`Global MCP ready : ${c.globalMcpReady?"\u2713":"\u2717"}`),console.log(`Workspace MCP : ${c.workspaceMcpReady?"\u2713":"\u2717"}`),console.log(`Plugin ready : ${c.pluginReady?"\u2713":"\u2717"}`),console.log(`Hooks ready : ${c.hooksReady?"\u2713":"\u2717"}`),console.log(`Continuity rule : ${c.continuityRuleReady?"\u2713":"\u2717"}`),c.errors.length>0){console.log("");for(let u of c.errors)console.log(` \u26A0 ${u}`)}c.agyBinaryDetected||(process.exitCode=1);return}if(t==="install-hooks"||t==="install-plugin"){let c=Ps({binary:Je(e,"--bin"),scope:o,cwd:s,force:r});if(n)console.log(JSON.stringify(c,null,2));else{console.log(`\u2705 ToolNet Antigravity plugin installed: ${c.pluginRoot}`);for(let u of c.files)console.log(` \u2713 ${u}`);console.log(""),console.log("Restart Antigravity CLI before testing.")}return}let i=new Qe().detect(s),a=fp(i);if(t==="sync"){let c=e[0],u=Je(e,"--transcript");if(!c||!u)throw new Error("Usage: sync <conversation-id> --transcript <path>");let l=await Tt({project:i,storage:a,conversationId:c,transcriptPath:u,phase:"recover"});console.log(JSON.stringify(l,null,2));return}if(t==="recover"){let c=Number(Je(e,"--limit")??100),u=await Ts(i,a,Number.isFinite(c)?c:100);console.log(JSON.stringify({project:i.name,sessions:u.length,imported:u.reduce((l,d)=>l+d.imported,0)},null,2));return}console.log(`Agy Session Adapter
|
|
170
170
|
|
|
171
171
|
Commands:
|
|
172
172
|
install-hooks / install-plugin
|
|
@@ -185,4 +185,4 @@ Commands:
|
|
|
185
185
|
recover
|
|
186
186
|
--project PATH Project root
|
|
187
187
|
--limit N Max sessions (default: 100)
|
|
188
|
-
`)}
|
|
188
|
+
`)}yp().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1)});
|