toolnet-memory 0.3.15 → 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 +316 -6
- package/bin/toolnet-memory +12 -0
- package/bundle/agy-hook.js +66 -66
- package/bundle/agy.js +56 -56
- package/bundle/api.js +15 -15
- package/bundle/audit.js +2 -0
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +49 -49
- package/bundle/code-capabilities.js +2 -0
- package/bundle/codex-context.js +29 -29
- package/bundle/codex.js +71 -71
- package/bundle/context-runtime.js +39 -39
- package/bundle/context.js +15 -15
- package/bundle/copilot-hook.js +78 -78
- package/bundle/cursor-hook.js +78 -78
- package/bundle/docker-healthcheck.js +3 -0
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +22 -21
- 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 +56 -56
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +4 -4
- package/bundle/impact.js +5 -4
- package/bundle/incremental.js +5 -5
- package/bundle/init.js +36 -35
- package/bundle/kiro-hook.js +85 -85
- package/bundle/learner.js +8 -6
- package/bundle/mcp.js +19 -17
- package/bundle/memory-agent.js +6 -6
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +77 -77
- package/bundle/project-manual.js +7 -7
- package/bundle/public/index.html +51 -2
- package/bundle/recovery-certify.js +9 -9
- 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 +46 -46
- package/bundle/work-continuity.js +7 -7
- package/package.json +38 -2
- package/release-manifest.json +143 -4
package/bundle/codex.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import{existsSync as
|
|
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
|
|
3
|
-
`,{encoding:"utf8",mode:384}),Po(s,r)}function Rt(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var se=class{findExisting(e=process.cwd()){let n=re(e),r=kn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Fe(ge(r,c))),i=Sn(n,o?r:void 0);if(!i)return null;let a=vn(We(i));return Rt(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=re(e),r=kn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>Fe(ge(r,p))),i=Sn(n,o?r:void 0);if(i){let p=We(i),l=vn(p);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),wn(i,l)),Rt(l,i)}let a=new Date().toISOString(),c=Oo(r),u={version:1,id:Ro(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return wn(r,u),Rt(u,r)}};var _o=[{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"}],$o=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function jn(t){return t.normalize("NFKC").trim().toLowerCase()}function Ko(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 s=r/t.length;n-=s*Math.log2(s)}return n}function Fo(t){return/^[a-f0-9]{32}$/iu.test(t)||/^[a-f0-9]{40}$/iu.test(t)||/^[a-f0-9]{64}$/iu.test(t)}function Lo(t,e,n){let r=t.slice(Math.max(0,e-48),e),s=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} ${s}`)}function Wo(t,e){return t.start<e.end&&e.start<t.end}function Cn(t){return t.sort((e,n)=>e.start!==n.start?e.start-n.start:n.end-n.start-(e.end-e.start))}var De=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let n of e.allowValues??[]){let r=jn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let n=[];for(let o of _o){let i=new RegExp(o.regex.source,o.regex.flags);for(let a of e.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:o.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:o.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(e));let r=Cn(n),s=[];for(let o of r)s.some(i=>Wo(i,o))||s.push(o);return Cn(s)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let n=jn(e);return $o.has(n)?!0:this.allowValues.has(n)}entropyMatches(e){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let s of e.matchAll(r)){if(s.index===void 0||!s[0])continue;let o=s[0];this.allowed(o)||Fo(o)||!/[A-Za-z]/u.test(o)||!/[0-9]/u.test(o)||Lo(e,s.index,s.index+o.length)&&(Ko(o)<3.7||n.push({type:"high_entropy_secret",value:o,start:s.index,end:s.index+o.length,confidence:"heuristic"}))}return n}};var H=class{scanner;constructor(e={}){this.scanner=new De(e)}sanitize(e){let n=this.scanner.scan(e);if(n.length===0)return{text:e,redacted:0,secretTypes:[]};let r=e,s=[...n].sort((i,a)=>a.start-i.start),o=new Set;for(let i of s)o.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...o].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,s]of Object.entries(e)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(s)}return n}return e}};var Do=new H;function ye(t){return Do.sanitizeValue(t)}import{homedir as li}from"node:os";import{join as di}from"node:path";import{DeleteObjectCommand as zo,GetObjectCommand as qo,HeadObjectCommand as Vo,ListObjectsV2Command as Ho,PutObjectCommand as Bo,S3Client as Jo}from"@aws-sdk/client-s3";import{getSignedUrl as Go}from"@aws-sdk/s3-request-presigner";var ze=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Jo({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Bo({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Go(this.client,new qo({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`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 Vo({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new zo({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Ho({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as In,mkdir as Uo,readFile as Yo,readdir as Xo,rm as Qo,stat as An,writeFile as Zo}from"node:fs/promises";import{dirname as ei,join as ti,relative as Mn,resolve as ni}from"node:path";var he=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return ni(this.root,n)}async put(e,n){let r=this.path(e);await Uo(ei(r),{recursive:!0}),await Zo(r,n)}async get(e){try{return await Yo(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 In(this.path(e)),!0}catch{return!1}}async delete(e){await Qo(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await In(n)}catch{return r}let s=async i=>{let a=await Xo(i,{withFileTypes:!0});for(let c of a){let u=ti(i,c.name);if(c.isDirectory()){await s(u);continue}let p=await An(u);r.push({key:Mn(this.root,u),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await An(n);return o.isDirectory()?await s(n):r.push({key:Mn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as ri,GetObjectCommand as si,HeadObjectCommand as oi,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 Se=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ci({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ai({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await ui(this.client,new si({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 oi({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 ri({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new ii({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function Nt(t,e){return console.warn(e),new he(t)}function Pn(t){let e=t.localRoot??di(li(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Se({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new Se({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ze({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new he(e)}function pi(t){return new Promise(e=>setTimeout(e,t))}async function En(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await pi(c+u)}throw o}var fi=new Set(["put","get","getText","delete","list"]);function On(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:fi.has(r)?(...o)=>En(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Tn(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 Rn(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var qe=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Tn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
6
|
-
`,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),
|
|
7
|
-
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||
|
|
1
|
+
import{existsSync as Rp,readFileSync as Np}from"node:fs";import{spawn as _p}from"node:child_process";import{homedir as Kp}from"node:os";import{join as Lp}from"node:path";import{existsSync as Ys,readFileSync as Xs}from"node:fs";import{homedir as Qs}from"node:os";import{join as Zs}from"node:path";function ei(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 ti(){let t=process.env.TOOLNET_GLOBAL_ENV??Zs(Qs(),".config","toolnet-memory",".env");if(!Ys(t))return;let e=Xs(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]=ei(r.slice(o+1)))}}ti();function Se(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function ke(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function Ve(){return{memory:{autoCapture:Se(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:Se(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:Se(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:Se(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ke(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ke(process.env.MEMORY_RERANK_TOP,10),finalContext:ke(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ke(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:Se(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:ke(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ci}from"node:crypto";import{existsSync as Ge,mkdirSync as ui,readFileSync as li,renameSync as di,writeFileSync as pi}from"node:fs";import{basename as fi,dirname as Ue,join as we,parse as Dn,resolve as Q}from"node:path";import{createHash as Kn}from"node:crypto";import{spawnSync as ni}from"node:child_process";var ve="git-remote-v1",ri=new Set(["github.com","gitlab.com","bitbucket.org"]);function Ln(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:(ri.has(t)&&(n=n.toLowerCase()),n)}function oi(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=Ln(n,e.pathname);return s?`${o}/${s}`:null}function si(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=Ln(n,e[2]??"");return r?`${n}/${r}`:null}function Nn(t){let e=t.trim();return e?e.includes("://")?oi(e):si(e):null}function ii(t){return Kn("sha256").update(`${ve}:${t}`).digest("hex")}function $n(t){return Kn("sha256").update(`toolnet-project:${ve}:${t}`).digest("hex").slice(0,16)}function ai(t){return t.split("/").filter(Boolean).at(-1)?.trim()||null}function zt(t,e){let n=ni("git",["-C",t,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function _n(t,e){let n=ai(t);return n?{scheme:ve,canonicalRemote:t,fingerprint:ii(t),repositoryName:n,source:e}:null}function Fn(t){let e=zt(t,["remote","get-url","origin"]);if(e){let o=Nn(e);if(o)return _n(o,"origin")}let n=zt(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=zt(t,["remote","get-url",o]);if(!s)continue;let i=Nn(s);i&&r.add(i)}return r.size!==1?null:_n([...r][0],"unique-remote")}var zn=".toolnet",mi="project.json";function gi(t){return ci("sha256").update(t).digest("hex").slice(0,16)}function ae(t){return we(t,zn,mi)}function qn(t){return Ge(ae(t))}function Wn(t,e){let n=Q(t),r=Dn(n).root;for(;;){if(qn(n))return n;if(n===r||e&&n===Q(e))break;let o=Ue(n);if(o===n)break;n=o}return null}function qt(t){let e=Q(t),n=Dn(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>Ge(we(e,s))))return e;if(e===n)break;let o=Ue(e);if(o===e)break;e=o}return Q(t)}function Be(t){let e;try{e=JSON.parse(li(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:Ue(Ue(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 Je(t,e){let n=we(t,zn);ui(n,{recursive:!0});let r=ae(t),o=`${r}.tmp-${process.pid}`;pi(o,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),di(o,r)}function X(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 Ht(t){return{version:1,scheme:ve,canonicalRemote:t.canonicalRemote,fingerprint:t.fingerprint,repositoryName:t.repositoryName}}function yi(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 ce=class{adopt(e,n){let r=qt(Q(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(qn(r)){let a=Be(ae(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return X(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=Ht(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 Je(r,i),X(i,r)}recordGitIdentity(e,n,r={}){let o=this.requireExisting(e),s=ae(o.rootPath),i=Be(s),a=yi(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:Ht(n)},i.updatedAt=new Date().toISOString(),Je(o.rootPath,i)),X(i,o.rootPath)}findExisting(e=process.cwd()){let n=Q(e),r=qt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Ge(we(r,c))),i=Wn(n,s?r:void 0);if(!i)return null;let a=Be(ae(i));return X(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=Q(e),r=qt(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Ge(we(r,l))),i=Wn(n,s?r:void 0);if(i){let l=ae(i),p=Be(l);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Je(i,p)),X(p,i)}let a=new Date().toISOString(),c=fi(r),u=Fn(r),f={version:1,id:u?$n(u.canonicalRemote):gi(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:Ht(u)}:void 0};return Je(r,f),X(f,r)}};var hi=[{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"}],Si=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function Hn(t){return t.normalize("NFKC").trim().toLowerCase()}function ki(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 vi(t){return/^[a-f0-9]{32}$/iu.test(t)||/^[a-f0-9]{40}$/iu.test(t)||/^[a-f0-9]{64}$/iu.test(t)}function wi(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 bi(t,e){return t.start<e.end&&e.start<t.end}function Vn(t){return t.sort((e,n)=>e.start!==n.start?e.start-n.start:n.end-n.start-(e.end-e.start))}var Ye=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let n of e.allowValues??[]){let r=Hn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let n=[];for(let s of hi){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=Vn(n),o=[];for(let s of r)o.some(i=>bi(i,s))||o.push(s);return Vn(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let n=Hn(e);return Si.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)||vi(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||wi(e,o.index,o.index+s.length)&&(ki(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var B=class{scanner;constructor(e={}){this.scanner=new Ye(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 xi=new B;function ue(t){return xi.sanitizeValue(t)}import{homedir as ea}from"node:os";import{join as ta}from"node:path";import{DeleteObjectCommand as Ii,GetObjectCommand as Ei,HeadObjectCommand as Ai,ListObjectsV2Command as ji,PutObjectCommand as Pi,S3Client as Ci}from"@aws-sdk/client-s3";import{getSignedUrl as Mi}from"@aws-sdk/s3-request-presigner";var Xe=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ci({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 Ei({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 Ai({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 Ii({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let o=await this.client.send(new ji({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 Bn,mkdir as Ti,readFile as Oi,readdir as Ri,rm as Ni,stat as Jn,writeFile as _i}from"node:fs/promises";import{dirname as Ki,join as Li,relative as Gn,resolve as $i}from"node:path";var be=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return $i(this.root,n)}async put(e,n){let r=this.path(e);await Ti(Ki(r),{recursive:!0}),await _i(r,n)}async get(e){try{return await Oi(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 Bn(this.path(e)),!0}catch{return!1}}async delete(e){await Ni(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Bn(n)}catch{return r}let o=async i=>{let a=await Ri(i,{withFileTypes:!0});for(let c of a){let u=Li(i,c.name);if(c.isDirectory()){await o(u);continue}let f=await Jn(u);r.push({key:Gn(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},s=await Jn(n);return s.isDirectory()?await o(n):r.push({key:Gn(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as Fi,GetObjectCommand as Wi,HeadObjectCommand as Di,ListObjectsV2Command as zi,PutObjectCommand as qi,S3Client as Hi}from"@aws-sdk/client-s3";import{getSignedUrl as Vi}from"@aws-sdk/s3-request-presigner";var xe=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Hi({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 qi({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let n=await Vi(this.client,new Wi({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 Di({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 Fi({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let o=await this.client.send(new zi({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 Bi,createDecipheriv as Ji,createHash as Gi,randomBytes as Ui,timingSafeEqual as Yi}from"node:crypto";import{readFileSync as Xi}from"node:fs";var Z=Buffer.from("TNMEME01","ascii"),Yn=1,Ie=8,Ee=12,Vt=16,Xn=Z.length+1+Ie+Ee+Vt,Qi="toolnet-memory:remote-encryption:v1:",Qn="aes-256-gcm",Bt=32,A=class extends Error{constructor(n,r){super(r);this.code=n;this.name="RemoteEncryptionError"}code};function Zi(t){return t?["1","true","yes","on","enabled"].includes(t.trim().toLowerCase()):!1}function Jt(t=process.env){return Zi(t.TOOLNET_REMOTE_ENCRYPTION)}function Un(t){let e=t.trim();if(!e)throw new A("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 A("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");n=Buffer.from(r,"hex")}else if(/^[0-9a-f]{64}$/iu.test(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 A("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");n=Buffer.from(r,r.includes("-")||r.includes("_")?"base64url":"base64")}if(n.length!==Bt)throw new A("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${Bt} bytes.`);return n}function Zn(t=process.env){let e=t.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),n=t.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(e&&n)throw new A("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(e)return Un(e);if(n){let r;try{r=Xi(n,"utf8")}catch(o){throw new A("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${n}.`,o instanceof Error?o.message:String(o)].join(" "))}return Un(r)}}function er(t){return Gi("sha256").update(t).digest().subarray(0,Ie)}function tr(t){return Buffer.from(`${Qi}${t}`,"utf8")}function Gt(t){return t.byteLength<Z.length?!1:Buffer.from(t).subarray(0,Z.length).equals(Z)}function nr(t,e,n){if(n.byteLength!==Bt)throw new A("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=Ui(Ee),s=Bi(Qn,n,o);s.setAAD(tr(t));let i=Buffer.concat([s.update(r),s.final()]),a=s.getAuthTag(),c=Buffer.alloc(Xn),u=0;return Z.copy(c,u),u+=Z.length,c.writeUInt8(Yn,u),u+=1,er(n).copy(c,u),u+=Ie,o.copy(c,u),u+=Ee,a.copy(c,u),Buffer.concat([c,i])}function rr(t,e,n){let r=Buffer.from(e);if(!Gt(r))throw new A("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(r.length<Xn)throw new A("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=Z.length,s=r.readUInt8(o);if(o+=1,s!==Yn)throw new A("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let i=r.subarray(o,o+Ie);o+=Ie;let a=er(n);if(!Yi(i,a))throw new A("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let c=r.subarray(o,o+Ee);o+=Ee;let u=r.subarray(o,o+Vt);o+=Vt;let f=r.subarray(o),l=Ji(Qn,n,c);l.setAAD(tr(t)),l.setAuthTag(u);try{return Buffer.concat([l.update(f),l.final()])}catch{throw new A("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var Ut=class{constructor(e,n){this.inner=e;this.options=n;if(this.name=e.name,n.enabled&&!n.key)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(e,n,r){if(!this.options.enabled){await this.inner.put(e,n,r);return}let o=this.options.key;if(!o)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=nr(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(!Gt(n))return n;if(!this.options.enabled)throw new A("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let r=this.options.key;if(!r)throw new A("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return rr(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 or(t,e=process.env){if(t.name==="local")return Jt(e)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),t;let n=Jt(e),r=n?Zn(e):void 0;return new Ut(t,{enabled:n,key:r})}function Ae(t){return or(t)}function Yt(t,e){return console.warn(e),Ae(new be(t))}function sr(t){let e=t.localRoot??ta(ea(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?Ae(new xe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Yt(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?Ae(new xe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Yt(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?Ae(new Xe({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey})):Yt(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return Ae(new be(e))}function na(t){return new Promise(e=>setTimeout(e,t))}async function ir(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 na(c+u)}throw s}var ra=new Set(["put","get","getText","delete","list"]);function ar(t,e={}){return new Proxy(t,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:ra.has(r)?(...s)=>ir(()=>Promise.resolve(o.apply(n,s)),e):o.bind(n)}})}function cr(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 ur(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 Qe=class{constructor(e,n,r,o){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=cr(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=ur(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{join as la}from"node:path";import{createHash as oa}from"node:crypto";import{dirname as sa}from"node:path";import{mkdirSync as ia,readFileSync as aa,renameSync as ca,writeFileSync as ua}from"node:fs";function w(t){return oa("sha256").update(t).digest("hex")}function Xt(t){if(Array.isArray(t))return t.map(Xt);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Xt(e[r]);return n}return t}function lr(t){return JSON.stringify(Xt(t))}function dr(t){try{return JSON.parse(aa(t,"utf8"))}catch{return null}}function N(t,e){ia(sa(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;ua(n,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),ca(n,t)}function pr(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 Ze(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=pr(r.toLowerCase(),"agent"),i=pr(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:la(t.rootPath,".toolnet","runtime","sources",s,i)}}function fr(t){return String(t).padStart(12,"0")}var et=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 y=g[0],v=g[g.length-1],x=g.map(R=>JSON.stringify(R)).join(`
|
|
8
8
|
`)+`
|
|
9
|
-
`,O=w(x).slice(0,16),
|
|
10
|
-
`,null,"utf8"),
|
|
11
|
-
`,null,"utf8"),
|
|
9
|
+
`,O=w(x).slice(0,16),M=[e.remotePrefix,"events",`${fr(y.sequence)}-${fr(v.sequence)}-${O}.jsonl`].join("/");await this.storage.exists(M)||await this.storage.put(M,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(e),f=n[n.length-1],l=s?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?l="idle":f?.type==="error"?l="error":n.length>0&&(l="active");let p=new Date().toISOString(),d=n[0],m={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:s?.createdAt??d?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:s?.firstEventAt??d?.timestamp,lastEventAt:f?.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:l}}};import{closeSync as Ce,existsSync as st,fsyncSync as sn,mkdirSync as ja,openSync as Me,readFileSync as Pr,readSync as Pa,rmSync as Er,statSync as rn,truncateSync as Ca,writeSync as Ma}from"node:fs";import{join as on}from"node:path";var da=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),pa=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function fa(t){return t.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function ma(t){for(let e of["type","kind"]){let n=t[e];if(typeof n=="string"){let r=n.toLowerCase();if(pa.has(r))return n}}return null}function Qt(t,e=0){if(e>12)return"[ToolNet nested value omitted]";if(Array.isArray(t))return t.map(s=>Qt(s,e+1));if(!t||typeof t!="object")return t;let n=t,r=ma(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))da.has(fa(s))||(o[s]=Qt(i,e+1));return o}function ga(t){if(!t)return new Date().toISOString();let e=new Date(t);return Number.isNaN(e.getTime())?new Date().toISOString():e.toISOString()}function ee(t){return t?.trim()||void 0}function mr(t,e={}){let n={...t.provenance??{}},r=ee(t.source)??ee(e.source)??ee(n.source);return{...t,timestamp:ga(t.timestamp),source:r,turnId:ee(t.turnId)??ee(e.turnId),cwd:ee(t.cwd)??ee(e.cwd),data:Qt(t.data??{}),provenance:n}}import{randomUUID as Zt}from"node:crypto";import{closeSync as le,existsSync as de,fsyncSync as je,mkdirSync as en,openSync as Pe,readFileSync as tn,readdirSync as ya,renameSync as ha,rmSync as tt,statSync as Sa,writeSync as nt}from"node:fs";import{join as J}from"node:path";var ka=12e4,va=80,wa="reconcile-required";function ba(t){t<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function pe(t){return J(t,".toolnet","journal")}function hr(t){return J(pe(t),"events.jsonl")}function rt(t){return J(pe(t),wa)}function xa(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e?.code!=="ESRCH"}}function Sr(t){if(!de(t))return null;try{let e=JSON.parse(tn(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 Ia(t){if(!de(t))return!1;let e=0;try{e=Date.now()-Sa(t).mtimeMs}catch{return!1}if(e<=ka)return!1;let n=Sr(t);return n?!xa(n.pid):!0}function Ea(t){if(!Ia(t))return!1;try{return tt(t,{force:!0}),!0}catch{return!1}}function kr(t){for(let e=0;e<va;e+=1){let n=Zt();try{let r=Pe(t,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return nt(r,`${JSON.stringify(o)}
|
|
10
|
+
`,null,"utf8"),je(r),{fd:r,token:n}}catch(s){throw le(r),tt(t,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(Ea(t))continue;ba(25)}}throw new Error(`Shared project journal is locked: ${t}`)}function vr(t,e){le(e.fd),Sr(t)?.token===e.token&&tt(t,{force:!0})}function gr(t){if(!de(t))return[];let e="";try{e=tn(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 wr(t){if(!de(t))return[];let e=[];for(let n of ya(t,{withFileTypes:!0})){let r=J(t,n.name);if(n.isDirectory()){e.push(...wr(r));continue}n.isFile()&&n.name==="events.jsonl"&&e.push(r)}return e.sort()}function ot(t){let e=null;try{e=Pe(t,"r"),je(e)}catch{}finally{if(e===null)return;le(e)}}function yr(t){let e=rt(t);if(!de(e))return null;try{return tn(e,"utf8").trim()||null}catch{return null}}function nn(t){let e=pe(t);en(e,{recursive:!0,mode:448});let n=rt(t),r=[Zt(),new Date().toISOString()].join("|"),o=Pe(n,"w",384);try{nt(o,`${r}
|
|
11
|
+
`,null,"utf8"),je(o)}finally{le(o)}ot(e)}function Aa(t,e,n){let r=J(t,`.events.jsonl.tmp-${process.pid}-${Zt()}`),o=Pe(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
|
|
12
12
|
`)}
|
|
13
|
-
`;
|
|
13
|
+
`;s&&nt(o,s,null,"utf8"),je(o)}finally{le(o)}ha(r,e),ot(t)}function br(t){let e=pe(t),n=hr(t),r=J(t,".toolnet","runtime","sources"),o=yr(t),s=wr(r),i=[],a=new Set;for(let l of gr(n))a.has(l.id)||(a.add(l.id),i.push(l));let c=i.length,u=[];for(let l of s)for(let p of gr(l))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((l,p)=>{let d=l.timestamp.localeCompare(p.timestamp);return d!==0?d:l.id.localeCompare(p.id)}),i.push(...u),Aa(e,n,i);let f=yr(t);return o&&f===o&&(tt(rt(t),{force:!0}),ot(e)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function xr(t){let e=pe(t);en(e,{recursive:!0,mode:448});let n=J(e,"journal.lock"),r=kr(n);try{return br(t)}finally{vr(n,r)}}function Ir(t,e){if(e.length===0)return;let n=pe(t);en(n,{recursive:!0,mode:448});let r=hr(t),o=J(n,"journal.lock"),s=kr(o);try{if(de(rt(t))){br(t);return}let i=`${e.map(c=>JSON.stringify(c)).join(`
|
|
14
14
|
`)}
|
|
15
|
-
`,a=
|
|
16
|
-
`),
|
|
15
|
+
`,a=Pe(r,"a",384);try{nt(a,i,null,"utf8"),je(a)}finally{le(a)}ot(n)}finally{vr(o,s)}}var Ta=12e4,Oa=80,Ar=2e3;function Ra(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}function Cr(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 an(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 Na(t){if(!st(t))return[];let e="";try{e=Pr(t,"utf8")}catch{return[]}let n=[];for(let r of e.split(/\r?\n/)){let o=an(r);o&&n.push(o)}return n}function jr(t){return t.type==="session_end"||t.type==="session_idle"?"idle":t.type==="error"?"error":"active"}function _a(t){if(!st(t))return!1;let e;try{e=Pr(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(an(o)){let i=Me(t,"a");try{Cr(i,`
|
|
16
|
+
`),sn(i)}finally{Ce(i)}return!0}Ca(t,r);let s=Me(t,"a");try{sn(s)}finally{Ce(s)}return!0}function Ka(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 it=class{constructor(e,n={}){this.identity=e;this.eventContext=n;ja(e.localDirectory,{recursive:!0}),this.eventsFile=on(e.localDirectory,"events.jsonl"),this.stateFile=on(e.localDirectory,"state.json"),this.lockFile=on(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 dr(this.stateFile)??this.initialState()}recoverStateUnsafe(){_a(this.eventsFile);let e=this.loadStateUnsafe(),n=Na(this.eventsFile);if(n.length===0)return e;let r=n[0];for(let l of n)l.sequence<=r.sequence||(r=l);let o=n.slice(-Ar).map(l=>l.id),s=st(this.eventsFile)?rn(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||!Ka(e.recentEventIds,o)||e.lastLocalEventAt!==r.timestamp))return e;let f={...e,status:jr(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(f),!c)return f;try{nn(this.identity.projectRoot)}catch{return f}try{xr(this.identity.projectRoot)}catch{}return f}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(e){N(this.stateFile,e)}acquireLock(){for(let e=0;e<Oa;e+=1)try{return Me(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-rn(this.lockFile).mtimeMs>Ta){Er(this.lockFile,{force:!0});continue}}catch{}Ra(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{Ce(n),Er(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 l of e){let p=mr(l,this.eventContext),d=p.timestamp??new Date().toISOString(),m=p.data??{},S=p.provenance?.rawDigest??w(lr(m)),g=ue(m),y=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,d,S].join("|"),v=w(y).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:d,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(l=>JSON.stringify(l)).join(`
|
|
17
17
|
`)+`
|
|
18
|
-
`,a=
|
|
19
|
-
`)}function
|
|
20
|
-
`),a=Math.max(
|
|
21
|
-
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let
|
|
18
|
+
`,a=Me(this.eventsFile,"a",384);try{Cr(a,i),sn(a)}finally{Ce(a)}try{Ir(this.identity.projectRoot,s)}catch{try{nn(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=jr(c),f=Array.from(r).slice(-Ar);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),s})}readPending(){return this.withLock(()=>{let e=this.recoverStateUnsafe();if(!st(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=rn(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=Me(this.eventsFile,"r");try{Pa(i,s,0,o,r)}finally{Ce(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=an(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 Tu,existsSync as Ou,openSync as Ru,readSync as Nu,statSync as _u}from"node:fs";var La=new Set(["rule","blocker","architecture","deploy"]),$a=new Set(["fix","todo","context","next_action"]);function cn(t){return t<0?0:t>1?1:t}function Mr(t,e){let n=Number.parseFloat(t??"");return Number.isFinite(n)?n:e}function Fa(t){return t==="off"?"off":t==="balanced"?"balanced":t==="aggressive"?"aggressive":"conservative"}function un(){return{mode:Fa(process.env.TOOLNET_MEMORY_PROMOTION),minScore:cn(Mr(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:cn(Mr(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Wa(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Da(t){let e=cn(Wa(t.importance)*.75+t.confidence*.25);return Math.round(e*1e6)/1e6}function za(t){return t.evidence?t.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function qa(t,e=un()){if(t.importance==="temporary"||t.confidence<e.minConfidence)return"transient";let n=za(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 Ha(t,e=un()){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 La.has(t)&&(r=Math.max(.5,r-.1)),$a.has(t)&&(r=Math.max(.5,r-.05)),r}function ln(t,e=un()){let n=qa(t,e),r=Da(t),o=Ha(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 Tr(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 _r=[/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],Va=[/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],Ba=[/\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],Ja=[/\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],Ga=[/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],Ua=[/đã 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],Or=[/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],Ya=[/\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],Xa=[/đườ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],Qa=[/\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],Rr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Za=new Set(["payload","data","content","message","messages","parts","summary"]);function _(t,e){return e.some(n=>n.test(t))}function Kr(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ec(t){return Kr(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function tc(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 dn(t,e,n,r=0){if(!(r>6)&&!(typeof t=="string"&&e&&!Rr.has(e))){if(typeof t=="string"){n.push(t);return}if(Array.isArray(t)){for(let o of t.slice(0,50))dn(o,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[o,s]of Object.entries(t))(Rr.has(o)||Za.has(o))&&dn(s,o,n,r+1)}}function nc(t){let e=[];dn(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=Kr(s);if(tc(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Nr(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function rc(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&&_(t,_r)?{kind:"rule",confidence:.98}:r&&_(t,Va)?{kind:"rule",confidence:.92}:_(t,Ba)?{kind:_(t,Or)?"architecture":"decision",confidence:r?.93:.86}:r&&_(t,Ga)?{kind:"next_action",confidence:.88}:r&&_(t,Ja)?{kind:"todo",confidence:.87}:_(t,Or)&&_(t,Ya)?{kind:"architecture",confidence:r?.88:.82}:o&&_(t,Ua)?{kind:"fix",confidence:.8}:r&&_(t,Xa)&&_(t,Qa)?{kind:"context",confidence:.79}:null}function oc(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 sc(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 ic(t,e,n){return t==="rule"&&_(n,_r)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Tr(e,n)}function Lr(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=Nr(s);i&&a&&o.set(i,a)}for(let s of e){let i=Nr(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of nc(s)){let u=rc(c,i,s);if(!u||u.confidence<.75)continue;let f=sc(u.kind),l=ec(c),p=w([t.projectId,u.kind,l].join("|"));if(r.has(p))continue;r.add(p);let d=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:f,content:c,confidence:u.confidence,importance:ic(u.kind,f,c),evidence:oc(u.kind,i,s),tags:[f],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:d,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as ac}from"node:crypto";var cc=["project-knowledge","implementation","continuation","session-context"],uc={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function pn(t){return ac("sha256").update(t).digest("hex")}function at(t,e){return`${t}:${pn(e).slice(0,24)}`}function lc(t){try{return pn(JSON.stringify(t))}catch{return pn(String(t))}}function te(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 Fr(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 dc(t){return t==="rule"||t==="architecture"?"project-knowledge":t==="decision"||t==="fix"?"implementation":t==="todo"?"continuation":"session-context"}function $r(t){return t.length===0?0:t.reduce((e,n)=>e+n,0)/t.length}function pc(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=>Fr(e.content)).join(" | ")}function fc(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=>Fr(e.content)).join(`
|
|
19
|
+
`)}function Wr(t,e){let n=t.slice().sort((p,d)=>p.sequence-d.sequence||p.timestamp.localeCompare(d.timestamp)||p.id.localeCompare(d.id)),r=n.map(p=>({id:at("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:lc(p.data)})),o=new Map,s=new Map;n.forEach((p,d)=>{let m=r[d];m&&(o.set(p.id,m.id),p.sourceEventId&&s.set(p.sourceEventId,m.id))});let i=e.map(p=>{let d=te([...p.provenance.eventIds.map(m=>o.get(m)),...p.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:at("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:te([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:d,sourcePaths:te(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let d=dc(p.kind),m=a.get(d)??[];m.push(p),a.set(d,m)}let c=[];for(let p of cc){let d=a.get(p);if(!d?.length)continue;let m=d.slice().sort((g,y)=>y.importanceScore-g.importanceScore||y.confidence-g.confidence||g.id.localeCompare(y.id)),S=m.map(g=>g.id);c.push({id:at("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:uc[p],summary:pc(m),factIds:S,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:$r(m.map(g=>g.confidence)),tags:te(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:te(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),f=[];for(let p of c){let m=p.factIds.map(y=>u.get(y)).filter(y=>!!y).filter(y=>(y.knowledgeClass==="permanent"||y.knowledgeClass==="task")&&y.importanceScore>=.55);if(m.length===0)continue;let S=m.some(y=>y.knowledgeClass==="permanent")?"permanent":"task",g=fc(m);f.push({id:at("knowledge",`${p.id}|${S}|${m.map(y=>y.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:g,sceneIds:[p.id],factIds:m.map(y=>y.id),importanceScore:Math.max(...m.map(y=>y.importanceScore)),confidence:$r(m.map(y=>y.confidence)),tags:te(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...m.flatMap(y=>y.tags)]),sourcePaths:te(m.flatMap(y=>y.sourcePaths))})}let l=[];for(let p of i)for(let d of p.rawIds)l.push({from:d,to:p.id,type:"supports"});for(let p of c)for(let d of p.factIds)l.push({from:d,to:p.id,type:"belongs_to"});for(let p of f)for(let d of p.sceneIds)l.push({from:d,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:f,links:l,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:f.length,links:l.length}}}function ct(t){return t?Math.ceil(t.length/3.5):0}function ut(t,e){if(!t)return"";if(ct(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 ne(){let t=Ve(),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 Dr(t){return(t||ne()).rawTranscript}function zr(t){return(t||ne()).durableMemoryMaxItemsPerSession}function qr(t){return(t||ne()).sessionSummaryMaxTokens}function Hr(t){return(t||ne()).archiveRemote}var Vr=new B;function Br(t){let e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))try{let r=JSON.parse(e);return JSON.stringify(Vr.sanitizeValue(r))}catch{}let n=Vr.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 mc(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 gc(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 f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let l="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)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(l="file");let p=mc(u,l);if(p<.3)continue;let d=Br(u);n.push({category:l,text:d,importance:p,sourceSessionId:e})}}let o=ne(),s=zr(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function yc(t){let e=ne(),n=qr(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=>Br(i)).join(`
|
|
25
|
+
`);return ut(s,n)}function lt(t,e){let r=(Array.isArray(t)?t:t.split(`
|
|
26
26
|
|
|
27
|
-
`).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),
|
|
28
|
-
`)}function
|
|
29
|
-
`;Ja(rt(La(t),`${c}.json`),p)?s+=1:o+=1,i.push(c),n=Ga(n,{id:c,kind:a.type,bytes:Buffer.byteLength(p,"utf8"),createdAt:a.timestamp,sourceRefs:[Ba(a)],files:Ha(a)})}return r>0&&qa(t,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as nc}from"node:crypto";import{existsSync as rc,readdirSync as sc,readFileSync as oc}from"node:fs";import{basename as ic,join as Wr}from"node:path";import{randomUUID as Ir}from"node:crypto";var I=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function xe(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function ee(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 I("Invalid Wiki slug",400);return e}function jr(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(ee(r))}return xe(e)}function Ua(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function Cr(t){return{id:`revision-${Ir()}`,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 Z(t){return structuredClone(t)}var st=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let e=await this.ensureState(),n=new Set(e.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:e.projectId,pages:e.pages.length,revisions:e.revisions.length,tags:xe(e.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:e.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:e.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:e.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:e.updatedAt}}async listPages(){let e=await this.ensureState();return Z([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=ee(e),s=n.pages.find(o=>o.slug===r||o.id===e);if(!s)throw new I(`Wiki page not found: ${e}`,404);return Z(s)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),s=e.content.trim();if(!r)throw new I("Wiki title is required",400);let o=ee(e.slug??r);if(n.pages.some(c=>c.slug===o))throw new I(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Ir()}`,slug:o,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:s,tags:xe(e.tags??[]),links:jr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Cr(a)),Z(a)})}async updatePage(e,n){return this.mutate(r=>{let s=ee(e),o=r.pages.find(i=>i.slug===s||i.id===e);if(!o)throw new I(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new I("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=jr(o.content)),n.tags!==void 0&&(o.tags=xe(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Cr(o)),Z(o)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return Z(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(e){let n=await this.getPage(e),r=await this.ensureState();return Z(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(e,n=10){let r=await this.ensureState(),s=xe(Ua(e));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),p=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),f=a.tags.map(m=>m.toLowerCase()),d=0;for(let m of s)u===m&&(d+=12),c===m&&(d+=10),c.includes(m)&&(d+=6),u.includes(m)&&(d+=5),f.some(S=>S===m)?d+=5:f.some(S=>S.includes(m))&&(d+=3),p.includes(m)&&(d+=2),l.includes(m)&&(d+=1);d>0&&i.push({page:Z(a),score:d})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Ar="wiki/state.v1.json";function Ya(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function Xa(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 ot=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Ar);if(!e){let n=Ya(this.project);return await this.save(n),n}return Xa(e,this.project)}async save(e){await this.storage.put(Ar,JSON.stringify(e,null,2),"application/json")}};import{createHash as Qa,randomUUID as Mr}from"node:crypto";var Pr="wiki/governance.v1.json",Rr="toolnet.knowledge-governance.v1",Er=500,je={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Za(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function Zt(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Or(t){return Qa("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ec(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 tc(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),Za(e)}function Tr(t){let e=new Date().toISOString();return{schema:Rr,version:1,projectId:t,policy:{...je},reviews:[],audit:[],createdAt:e,updatedAt:e}}function Nr(t){let e=t.autoApproveThreshold??je.autoApproveThreshold,n=t.criticalApproveThreshold??je.criticalApproveThreshold,r=t.staleAfterDays??je.staleAfterDays;if(!Number.isFinite(e)||e<.5||e>1)throw new I("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new I("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new I("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var it=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(Pr);if(!e){let n=Tr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==Rr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Nr(n.policy??je)}}catch{let n=Tr(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(Pr,JSON.stringify(e,null,2),"application/json")}},at=class{constructor(e){this.store=e}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(e,n,r,s={}){e.audit.push({id:Mr(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),e.audit.length>Er&&(e.audit=e.audit.slice(-Er))}async mutate(e){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await e(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(e,n){return this.mutate(r=>(r.policy=Nr({...r.policy,...e}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let e=await this.ensureState(),n=r=>e.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:e.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:e.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:e.audit.length,policy:{...e.policy},updatedAt:e.updatedAt}}async listReviews(e){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!e||r.status===e).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(e=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(e)));return structuredClone(n.audit.slice(-r).reverse())}async assess(e,n){let r=await this.ensureState(),s=tc(e),o=Zt(e.title),i=n.filter(p=>p.slug!==e.slug&&Zt(p.title)===o&&Or(p.content)!==Or(e.content)).map(p=>p.slug),a=ec(e),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(e,n){let r=await this.assess(e,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===e.sourceKey&&c.digest===e.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:e.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:Mr(),sourceKey:e.sourceKey,sourceType:e.sourceType,slug:e.slug,marker:e.marker,digest:e.digest,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...new Set([...e.tags,e.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(e,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===e&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:e}))})}async decide(e,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===e);if(!o)throw new I(`Governance review not found: ${e}`,404);if(o.status!=="pending")throw new I("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new I("targetReviewId is required for merge",400);let u=s.reviews.find(p=>p.id===n.targetReviewId);if(!u)throw new I("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:e,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new I(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:e,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(e){let n=await this.ensureState(),r=await e.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(p=>{let l=s-Date.parse(p.updatedAt);return{slug:p.slug,title:p.title,updatedAt:p.updatedAt,ageDays:Math.max(0,Math.floor(l/864e5)),stale:Number.isFinite(l)&&l>o}}).filter(p=>p.stale).map(({stale:p,...l})=>l),a=new Map;for(let p of r){let l=Zt(p.title),f=a.get(l)??[];f.push(p),a.set(l,f)}let c=[...a.entries()].filter(([,p])=>p.length>1).map(([p,l])=>({title:p,pages:l.map(f=>f.slug)})),u=n.reviews.filter(p=>p.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(p=>p.tags.some(l=>l.startsWith("toolnet-auto-"))).length,manualPages:r.filter(p=>!p.tags.some(l=>l.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(p=>p.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(p=>p.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Dr="wiki/automation.v1.json",zr="toolnet.wiki-automation.v1",nn=8e3,_r=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Ie(t){return nc("sha256").update(JSON.stringify(t)).digest("hex")}function Ce(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function $r(t){return Array.isArray(t)?t:[]}function qr(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function en(t){return Array.isArray(t)?t.map(qr).filter(e=>!!e):[]}function K(t,e){for(let n of e){let r=qr(t[n]);if(r)return r}}function Ae(t){let e=new Set,n=[];for(let r of t){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function ct(t,e=0,n=""){if(e>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(_r.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=>ct(i,e+1,n));let s=Ce(t);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();_r.has(c)||o.push(...ct(a,e+1,i))}return o}function Kr(t){let n=Ae(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>ct(t[s],0,s)));return(n.length>0?n:Ae(ct(t))).join(`
|
|
27
|
+
`).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),o=gc(r,e),s=o.filter(d=>d.category==="decision").map(d=>d.text),i=o.filter(d=>d.category==="rule").map(d=>d.text),a=o.filter(d=>d.category==="file").map(d=>d.text),c=o.filter(d=>d.category==="fix").map(d=>d.text),u=o.filter(d=>d.category==="blocker").map(d=>d.text),f=o.filter(d=>d.category==="next_action").map(d=>d.text),l=o.filter(d=>d.category==="deploy").map(d=>d.text);return{summary:yc(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:l,blockers:u,nextActions:f,durableFacts:o}}function G(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 hc(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 Sc(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 kc(t){let e=ln(t);return{...t,knowledgeClass:e.knowledgeClass,importanceScore:e.score,retrievalTerms:Sc(t.content),tags:G([...t.tags,"level:fact",`class:${e.knowledgeClass}`,`kind:${t.kind}`])}}function vc(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 wc(t,e,n){let r=lt(vc(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=G([...o,...r.nextActions]),c=G([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:G(r.decisions),files:G([...r.filesChanged,...s]),todos:a,completed:G(r.bugsFixed),blockers:G(r.blockers),nextActions:c,architecture:G(i)}}}function dt(t,e){let n=hc(e),r=Lr(t,n).map(kc),o=r.filter(f=>ln(f).persist).sort((f,l)=>l.importanceScore-f.importanceScore),{summary:s,state:i}=wc(t,n,o),a=o.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),c=Wr(n,o),u=f=>r.filter(l=>l.knowledgeClass===f).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 bc}from"node:crypto";import{chmodSync as Jr,existsSync as xc,mkdirSync as Ic,readFileSync as Ec,renameSync as Ac,writeFileSync as Gr}from"node:fs";import{dirname as Ur,join as pt}from"node:path";var gn="toolnet.context-offload.v1",jc="toolnet.context-offload-asset.v1",Pc=256,Cc=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Yr(t){return pt(t,".toolnet","offload")}function Mc(t){return pt(Yr(t),"assets")}function Xr(t){return pt(Yr(t),"graph.json")}function Qr(t){Ic(t,{recursive:!0,mode:448});try{Jr(t,448)}catch{}}function Tc(t,e){Qr(Ur(t));let n=`${t}.${process.pid}.${Date.now()}.tmp`;Gr(n,e,{encoding:"utf8",mode:384}),Ac(n,t);try{Jr(t,384)}catch{}}function mn(t){return Array.isArray(t)?t.map(mn):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,mn(n)])):t}function Oc(t){return bc("sha256").update(JSON.stringify(mn(t)),"utf8").digest("hex")}function fn(){return{schema:gn,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Rc(t){let e=Xr(t);if(!xc(e))return fn();try{let n=JSON.parse(Ec(e,"utf8"));return n.schema!==gn||n.version!==1||!Array.isArray(n.nodes)?fn():n}catch{return fn()}}function Nc(t,e){Tc(Xr(t),JSON.stringify(e,null,2)+`
|
|
28
|
+
`)}function _c(t,e=260){if(typeof t!="string")return null;let n=t.replace(/\s+/gu," ").trim();return n?n.slice(0,e):null}function Kc(t){let e=[...t.provenance.files??[],t.provenance.sourcePath],n=[];for(let r of e){let o=_c(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function Lc(t){return`${t.agent}:${t.sourceEventId??t.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function $c(t,e){Qr(Ur(t));try{return Gr(t,e,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Fc(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:gn,version:1,updatedAt:new Date().toISOString(),nodes:[...t.nodes.filter(o=>o.id!==e.id),r].slice(-Pc)}}function Zr(t,e){let n=Rc(t),r=0,o=0,s=0,i=[];for(let a of e){if(!Cc.has(a.type))continue;r+=1;let c=Oc({type:a.type,data:a.data}),u={schema:jc,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}},f=JSON.stringify(u,null,2)+`
|
|
29
|
+
`;$c(pt(Mc(t),`${c}.json`),f)?o+=1:s+=1,i.push(c),n=Fc(n,{id:c,kind:a.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:a.timestamp,sourceRefs:[Lc(a)],files:Kc(a)})}return r>0&&Nc(t,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Jc}from"node:crypto";import{existsSync as Gc,readdirSync as Uc,readFileSync as Yc}from"node:fs";import{basename as Xc,join as ho}from"node:path";import{randomUUID as no}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Te(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 oe(t){let e=t.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!e)throw new j("Invalid Wiki slug",400);return e}function eo(t){let e=[];for(let n of t.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&e.push(oe(r))}return Te(e)}function Wc(t){return t.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(e=>e.trim()).filter(e=>e.length>=2)}function to(t){return{id:`revision-${no()}`,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 re(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:Te(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 re([...e.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(e){let n=await this.ensureState(),r=oe(e),o=n.pages.find(s=>s.slug===r||s.id===e);if(!o)throw new j(`Wiki page not found: ${e}`,404);return re(o)}async createPage(e){return this.mutate(n=>{let r=e.title.trim(),o=e.content.trim();if(!r)throw new j("Wiki title is required",400);let s=oe(e.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-${no()}`,slug:s,title:r,...e.summary?.trim()?{summary:e.summary.trim()}:{},content:o,tags:Te(e.tags??[]),links:eo(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(to(a)),re(a)})}async updatePage(e,n){return this.mutate(r=>{let o=oe(e),s=r.pages.find(i=>i.slug===o||i.id===e);if(!s)throw new j(`Wiki page not found: ${e}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);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=eo(s.content)),n.tags!==void 0&&(s.tags=Te(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(to(s)),re(s)})}async history(e){let n=await this.getPage(e),r=await this.ensureState();return re(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 re(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=Te(Wc(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(),f=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),d=0;for(let m of o)u===m&&(d+=12),c===m&&(d+=10),c.includes(m)&&(d+=6),u.includes(m)&&(d+=5),p.some(S=>S===m)?d+=5:p.some(S=>S.includes(m))&&(d+=3),f.includes(m)&&(d+=2),l.includes(m)&&(d+=1);d>0&&i.push({page:re(a),score:d})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var ro="wiki/state.v1.json";function Dc(t){let e=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:t.id,pages:[],revisions:[],createdAt:e,updatedAt:e}}function zc(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(ro);if(!e){let n=Dc(this.project);return await this.save(n),n}return zc(e,this.project)}async save(e){await this.storage.put(ro,JSON.stringify(e,null,2),"application/json")}};import{createHash as qc,randomUUID as oo}from"node:crypto";var so="wiki/governance.v1.json",uo="toolnet.knowledge-governance.v1",io=500,Oe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Hc(t,e=0,n=1){return Math.max(e,Math.min(n,t))}function yn(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function ao(t){return qc("sha256").update(t.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Vc(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 Bc(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),Hc(e)}function co(t){let e=new Date().toISOString();return{schema:uo,version:1,projectId:t,policy:{...Oe},reviews:[],audit:[],createdAt:e,updatedAt:e}}function lo(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 j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:e,criticalApproveThreshold:n,staleAfterDays:r}}var gt=class{constructor(e,n){this.storage=e;this.project=n}storage;project;async load(){let e=await this.storage.getText(so);if(!e){let n=co(this.project.id);return await this.save(n),n}try{let n=JSON.parse(e);if(n.schema!==uo||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:lo(n.policy??Oe)}}catch{let n=co(this.project.id);return await this.save(n),n}}async save(e){await this.storage.put(so,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:oo(),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>io&&(e.audit=e.audit.slice(-io))}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=lo({...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=Bc(e),s=yn(e.title),i=n.filter(f=>f.slug!==e.slug&&yn(f.title)===s&&ao(f.content)!==ao(e.content)).map(f=>f.slug),a=Vc(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:oo(),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 j(`Governance review not found: ${e}`,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: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 j("targetReviewId is required for merge",400);let u=o.reviews.find(f=>f.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: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 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: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(f=>{let l=o-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(l/864e5)),stale:Number.isFinite(l)&&l>s}}).filter(f=>f.stale).map(({stale:f,...l})=>l),a=new Map;for(let f of r){let l=yn(f.title),p=a.get(l)??[];p.push(f),a.set(l,p)}let c=[...a.entries()].filter(([,f])=>f.length>1).map(([f,l])=>({title:f,pages:l.map(p=>p.slug)})),u=n.reviews.filter(f=>f.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(f=>f.tags.some(l=>l.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(l=>l.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(f=>f.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(f=>f.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var So="wiki/automation.v1.json",ko="toolnet.wiki-automation.v1",kn=8e3,po=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Ne(t){return Jc("sha256").update(JSON.stringify(t)).digest("hex")}function Re(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function fo(t){return Array.isArray(t)?t:[]}function vo(t){return typeof t!="string"?void 0:t.replace(/\s+/gu," ").trim()||void 0}function hn(t){return Array.isArray(t)?t.map(vo).filter(e=>!!e):[]}function $(t,e){for(let n of e){let r=vo(t[n]);if(r)return r}}function _e(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(po.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=Re(t);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();po.has(c)||s.push(...ht(a,e+1,i))}return s}function mo(t){let n=_e(["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:_e(ht(t))).join(`
|
|
30
30
|
|
|
31
|
-
`).slice(0,
|
|
31
|
+
`).slice(0,kn)}function go(t,e){return $(t,["id","key","fingerprint","knowledgeId","sceneId"])??e}function yo(t,e){return $(t,["title","name","topic","label","task","kind","type"])??e}function Qc(t){return($(t,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Zc(t){return($(t,["kind","sceneKind","type"])??"").toLowerCase()}function eu(t){let e=Re(t);if(!e)return[];let n=[],r=fo(e.knowledge);for(let[s,i]of r.entries()){let a=Re(i);if(!a)continue;let c=Qc(a);if(c==="session"||c==="transient")continue;let u=mo(a);if(u.length<20)continue;let f=go(a,Ne(a).slice(0,16)),l=yo(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:l,summary:$(a,["summary","description"]),content:u,tags:_e(["toolnet","auto","memory",...c?[c]:[]])})}let o=fo(e.scenes);for(let[s,i]of o.entries()){let a=Re(i);if(!a)continue;let c=Zc(a);if(c==="session-context")continue;let u=mo(a);if(u.length<20)continue;let f=go(a,Ne(a).slice(0,16)),l=yo(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:l,summary:$(a,["summary","description"]),content:u,tags:_e(["toolnet","auto","scene",...c?[c]:[]])})}return n}function tu(t){return ho(t,".toolnet","memory","skills")}function nu(t){let e=tu(t);if(!Gc(e))return{candidates:[],failed:0};let n=[],r=0,o=Uc(e).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(Yc(ho(e,s),"utf8")),a=Re(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??Xc(s,".json"),u=$(a,["task"])??"",f=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,l=$(a,["summary"])??void 0,p=hn(a.steps),d=hn(a.verification),m=hn(a.files),S=[];u&&S.push(`## Task
|
|
32
32
|
${u}`),l&&S.push(`## Summary
|
|
33
|
-
${l}`),
|
|
34
|
-
${
|
|
33
|
+
${l}`),p.length>0&&S.push(`## Procedure
|
|
34
|
+
${p.map((y,v)=>`${v+1}. ${y}`).join(`
|
|
35
35
|
`)}`),d.length>0&&S.push(`## Verification
|
|
36
36
|
${d.map(y=>`- ${y}`).join(`
|
|
37
37
|
`)}`),m.length>0&&S.push(`## Relevant Files
|
|
38
38
|
${m.map(y=>`- \`${y}\``).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(l=>l.fingerprint).sort().join("|")).slice(0,16),u=w(e.sessionKey).slice(0,12),
|
|
45
|
-
`,"application/json"),u}};function
|
|
41
|
+
`).slice(0,kn);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:f,summary:l,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Sn(t){let e=new Date().toISOString();return{schema:ko,version:1,projectId:t,entries:[],createdAt:e,updatedAt:e}}async function ru(t,e){let n=await t.getText(So);if(!n)return Sn(e);try{let r=JSON.parse(n);return r.schema!==ko||r.version!==1||r.projectId!==e||!Array.isArray(r.entries)?Sn(e):r}catch{return Sn(e)}}async function ou(t,e){await t.put(So,JSON.stringify(e,null,2),"application/json")}function su(t){return`toolnet-auto-${Ne(t).slice(0,12)}`}function iu(t){let e=oe(t.title).slice(0,72),n=Ne(t.sourceKey).slice(0,10);return oe(`auto-${t.sourceType}-${e}-${n}`)}function au(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,kn)}function cu(t){return Ne({sourceType:t.sourceType,title:t.title,summary:t.summary,content:t.content,tags:t.tags})}function uu(t,e){return t.tags.includes(e)}async function wo(t){let e=eu(t.hierarchy),n=nu(t.project.rootPath),r=new Map;for(let d of[...e,...n.candidates])r.set(d.sourceKey,d);let o=[...r.values()].sort((d,m)=>d.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 ru(t.storage,t.project.id),u=await i.listPages(),f=new Map(u.map(d=>[d.slug,d])),l=new Map(c.entries.map(d=>[d.sourceKey,d]));for(let d of o)try{let m=su(d.sourceKey),S=cu(d),g=l.get(d.sourceKey),y=g?.slug??iu(d),v=f.get(y);if(v&&!uu(v,m)){s.skipped+=1;continue}let x=_e([...d.tags,m]),O=au(d),M=await a.gate({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:y,marker:m,digest:S,title:d.title,...d.summary?{summary:d.summary}:{},content:O,tags:x},[...f.values()]);if(!M.allowed){M.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}M.mode==="auto-approved"?s.autoApproved+=1:M.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==S?(v=await i.updatePage(y,{title:d.title,summary:d.summary??"",content:O,tags:x}),f.set(v.slug,v),s.updated+=1,s.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:v.slug,action:"updated"})):(s.unchanged+=1,s.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:y,action:"unchanged"})):(v=await i.createPage({slug:y,title:d.title,summary:d.summary,content:O,tags:x}),f.set(v.slug,v),s.created+=1,s.pages.push({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:v.slug,action:"created"}));let R=new Date().toISOString(),I={sourceKey:d.sourceKey,sourceType:d.sourceType,slug:y,digest:S,marker:m,updatedAt:R},b=c.entries.findIndex(z=>z.sourceKey===d.sourceKey);b>=0?c.entries[b]=I:c.entries.push(I),l.set(d.sourceKey,I),await a.markApplied(d.sourceKey,S)}catch(m){if(m instanceof j&&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((d,m)=>d.sourceKey.localeCompare(m.sourceKey)),await ou(t.storage,c),s}import{createHash as lu}from"node:crypto";import{chmodSync as xo,existsSync as du,mkdirSync as pu,readFileSync as uy,readdirSync as ly,renameSync as fu,statSync as dy,writeFileSync as mu}from"node:fs";import{join as Io}from"node:path";var gu="toolnet.skill-memory.v1",bo=5,yu=16,hu=24,Su=32;function ku(t){return lu("sha256").update(t).digest("hex")}function Le(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 vn(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 vu(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 H(t,e=360){return t&&vn(vu(t),e)||void 0}function $e(t,e){for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}}function Eo(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 Ao(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 jo(t){let e=t.data??{};if(Ao(e,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Eo(e,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let o=$e(e,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function Ke(t){let e=t.data??{};if(jo(t))return!1;if(Ao(e,["passed","pass","success","succeeded","ok"])===!0||Eo(e,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=$e(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 Po(t){let e=t.data??{},n=$e(e,["path","file","filePath","filename","target"]);if(n)return H(n,260);let r=t.provenance?.files;return H(r?.[0],260)}function wn(t){return H($e(t.data??{},["command","cmd","script"]),420)}function fe(t){return H($e(t.data??{},["name","test","suite","title","message","text","result","status"]),300)}function wu(t){let e=[];for(let n of[...t].sort((r,o)=>r.sequence-o.sequence))if(Ke(n)){if(n.type==="test"){let r=fe(n)??wn(n)??"Tests passed";e.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=fe(n);e.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=fe(n);e.push(r?`Deploy: ${r}`:"Deployment completed")}}return Le(e,10)}function bu(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=Po(r);o&&n.push(`Update ${o}`);break}case"command":{if(jo(r))break;let o=wn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!Ke(r))break;let o=fe(r)??wn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!Ke(r))break;let o=fe(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!Ke(r))break;let o=fe(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=H(r,260);o&&n.push(`Update ${o}`)}return Le(n,yu)}function xu(t,e){let n=[...e.files];for(let r of t){let o=Po(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=H(s,260);i&&n.push(i)}}return Le(n,hu)}function Iu(t){return Le(t.filter(e=>["file_write","file_edit","command","test","commit","deploy"].includes(e.type)).map(e=>e.id),Su)}function Eu(t){return t.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Co(t,e,n){if(e.length===0)return[];let r=wu(e),o=Le(n.completed.map(m=>H(m,280)??""),bo);if(!(o.length>0||e.some(m=>["test","commit","deploy"].includes(m.type)&&Ke(m))))return[];let i=H(n.task,280)??H(n.nextActions[0],280),a=o.length>0?o:i?[i]:[];if(a.length===0)return[];let c=bu(e,n);if(c.length===0)return[];let u=xu(e,n),f=Iu(e),l=Math.min(...e.map(m=>m.sequence)),p=Math.max(...e.map(m=>m.sequence)),d=Eu(e);return a.slice(0,bo).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}),y=ku(g);return{schema:gu,version:1,id:`skill-${y.slice(0,24)}`,fingerprint:y,projectId:t.projectId,title:vn(`SOP: ${m}`,180),task:m,summary:vn(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:l,lastSequence:p,eventIds:f},createdAt:d}})}function Au(t){return Io(t.rootPath,".toolnet","memory","skills")}function ju(t){let e=Au(t);return pu(e,{recursive:!0,mode:448}),xo(e,448),e}function Mo(t,e){if(e.length===0)return{written:0,deduped:0,files:[]};let n=ju(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=Io(n,`${i.id}.json`);if(s.push(a),du(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;mu(c,JSON.stringify(i,null,2)+`
|
|
43
|
+
`,{encoding:"utf8",mode:384}),fu(c,a),xo(a,384),r+=1}return{written:r,deduped:o,files:s}}var xy="0".repeat(64);function To(t){return String(t).padStart(12,"0")}function Pu(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(l=>l.sequence)),s=Math.max(...n.map(l=>l.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(l=>l.fingerprint).sort().join("|")).slice(0,16),u=w(e.sessionKey).slice(0,12),f=[Pu(e),"batches",`${To(o)}-${To(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(f)||await this.storage.put(f,a,"application/json"),f}};import{createHash as Cu}from"node:crypto";function Oo(t){return String(t).padStart(12,"0")}function Ro(t){return Cu("sha256").update(t).digest("hex")}function Mu(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(f=>f.sequence)),s=Math.max(...n.map(f=>f.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=Ro([...r.facts.map(f=>f.id),...r.knowledge.map(f=>f.id)].sort().join("|")).slice(0,16),c=Ro(e.sessionKey).slice(0,12),u=[Mu(e),"batches",`${Oo(o)}-${Oo(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 Ku(t,e){if(!Ou(t))return{events:[],nextOffset:e};let n=_u(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=Ru(t,"r");try{Nu(i,s,0,o,r)}finally{Tu(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(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
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
|
|
50
|
-
`,a=w(n.map(
|
|
51
|
-
`)).slice(0,24),c=w(e.sessionKey).slice(0,12),u=[`projects/${e.projectId}`,"work","observations",`${
|
|
52
|
-
`,"application/json"),
|
|
47
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}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=Ku(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=Co(this.options.identity,o.events,s.state),f=Mo(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",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let l=Zr(this.options.project.rootPath,o.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",l.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",l.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",l.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",l.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let l=await wo({project:this.options.project,storage:this.options.storage,hierarchy:s.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",l.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",l.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",l.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",l.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",l.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",l.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",l.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",l.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",l.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",l.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 Zu,existsSync as el,openSync as tl,readSync as nl,statSync as rl}from"node:fs";function No(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function We(t){return t.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Fe(t,e,n=0){if(n>8)return;if(Array.isArray(t)){for(let o of t.slice(0,50))Fe(o,e,n+1);return}let r=No(t);if(r)for(let[o,s]of Object.entries(r))e(o,s,r),Fe(s,e,n+1)}function me(t,e){let n=[];return Fe(t,(r,o)=>{e.has(We(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function Lu(t){let e=t.trim();if(!e.startsWith("{"))return null;try{return No(JSON.parse(e))}catch{return null}}function $u(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 Fe(e,(r,o,s)=>{if(n)return;let i=We(r);if(["tool","toolname"].includes(i)&&typeof o=="string"){n=o.trim().toLowerCase();return}if(i!=="name"||typeof o!="string")return;let a=typeof s.type=="string"?s.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=o.trim().toLowerCase())}),n}function Fu(t){let e=me(t.data,new Set(["command","cmd","script"])),n=me(t.data,new Set(["arguments","args"]));for(let r of n){let o=Lu(r);if(o)for(let s of me(o,new Set(["command","cmd","script"])))e.push(s)}return Array.from(new Set(e.map(r=>r.trim()).filter(Boolean)))}function Wu(t){let e=me(t.data,new Set(["filepath","file_path","filename","file","path","target"].map(We)));return Array.from(new Set(e.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
|
|
48
|
+
`))))}function Du(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 zu(t){let e=me(t.data,new Set(["patch","diff","arguments","input"].map(We))),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 qu(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 Hu(t){let e=null;return Fe(t,(n,r)=>{if(e===null&&["exitcode","code"].includes(We(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 Vu(t){return me(t,new Set(["status","state","result","output","outputsummary","message","text"]))}function Bu(t){let e=Hu(t.data);if(e!==null)return e===0?"passed":"failed";let n=Vu(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 Ju(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 _o(t){let e=[],n=$u(t),r=Du(t,n);if(r)for(let o of Wu(t))e.push({kind:"file",text:o,fileAction:r,confidence:t.type==="file_edit"||t.type==="file_write"?1:.96});e.push(...zu(t));for(let o of Fu(t)){e.push({kind:"command",text:o,confidence:.98});let s=qu(o);s&&e.push({kind:"test",text:o,checkKind:s,checkStatus:Bu(t),confidence:.98})}return Ju(e)}var Gu=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ie(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Lo(t){return ie(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function se(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))se(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,o]of Object.entries(t))(Gu.has(r)||["data","payload","parts","messages"].includes(r))&&se(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 Ko(t){let e=ie(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 P(t,e,n,r,o={}){let s=ie(r),i=o.key??Lo(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 Uu(t,e,n){let r=ie(n);if(r.length<5||r.length>1200)return[];let o=[],s=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&o.push(P(t,e,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(P(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]),d=ie(u[2]??""),m=d&&!Ko(d)?`Phase ${p} - ${d}`:`Phase ${p}`;o.push(P(t,e,"phase",m,{key:`phase:${p}`,order:p,status:wt(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&o.push(P(t,e,"task",f[2],{status:f[1].trim()?"completed":wt(f[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let p=l[1]?Number(l[1]):void 0,d=ie(l[2]),m=Ko(d);o.push(P(t,e,"task",m&&p!==void 0?`TODO ${p}`:d,{key:p!==void 0?`task:${p}`:Lo(d),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(P(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(P(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(P(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.push(P(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(P(t,e,"activity",r,{confidence:.86})),o}function ge(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=[];se(i.data,c);let u=c.map(f=>ie(f)).find(f=>f.length>=8&&f.length<=1200&&!/^\[?toolnet\b/iu.test(f));u&&o(P(t,i,"request",u,{confidence:.96}))}for(let c of _o(i))o(P(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=[];se(i.data,c);for(let u of c)o(P(t,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];se(i.data,c);for(let u of c)o(P(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(P(t,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];se(i.data,c);for(let u of c)o(P(t,i,"test",u,{confidence:1}))}let a=[];se(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let f of Uu(t,i,u))o(f)}let s=e[e.length-1];return o(P(t,s,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function $o(t){return String(t).padStart(12,"0")}var bt=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(f=>f.sequence)),o=Math.max(...n.map(f=>f.sequence)),s={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:n.map(f=>f.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:o,observations:n},i=JSON.stringify(s,null,2)+`
|
|
50
|
+
`,a=w(n.map(f=>JSON.stringify(f)).sort().join(`
|
|
51
|
+
`)).slice(0,24),c=w(e.sessionKey).slice(0,12),u=[`projects/${e.projectId}`,"work","observations",`${$o(r)}-${$o(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as Fo}from"node:path";import{mkdirSync as Yu}from"node:fs";function Do(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function F(t,e=20){let n=[],r=new Set;for(let o of t.slice().reverse()){let s=Do(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=e))break}return n.reverse()}function Xu(t,e=20){let n=new Map;for(let r of t){let o=`${r.kind}|${Do(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-e)}function Qu(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 Wo(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&&Qu(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 zo(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 De(t,e){let r=(await zo(t,e)).flatMap(h=>h.observations).sort((h,k)=>{let T=h.occurredAt.localeCompare(k.occurredAt);if(T!==0)return T;let V=h.sequence-k.sequence;return V!==0?V:h.id.localeCompare(k.id)}),o=new Map,s=new Map,i,a,c,u,f,l=[],p=[],d=[],m=[],S=[],g=new Map,y=[],v=[],x=[],O=[],M=[],R=[];for(let h of r)switch(h.kind){case"request":i=h.text;break;case"activity":a=h.text;break;case"goal":c=h.text;break;case"plan":u=h.text;break;case"phase":o.set(h.key,Wo(o.get(h.key),h));break;case"task":s.set(h.key,Wo(s.get(h.key),h));break;case"decision":l.push(h.text);break;case"blocker":p.push(h.text);break;case"warning":d.push(h.text);break;case"next_action":m.push(h.text);break;case"file":{S.push(h.text);let k=h.fileAction??"active";g.delete(h.text),g.set(h.text,k),k==="modified"?y.push(h.text):k==="created"?v.push(h.text):k==="deleted"&&x.push(h.text);break}case"command":O.push(h.text);break;case"test":M.push(h.text),h.checkKind&&R.push({kind:h.checkKind,command:h.text,status:h.checkStatus??"unknown",updatedAt:h.occurredAt,agent:h.agent,nativeSessionId:h.nativeSessionId});break;case"session":f={agent:h.agent,nativeSessionId:h.nativeSessionId,sessionKey:h.sessionKey,updatedAt:h.occurredAt};break}let I=Array.from(o.values()).sort((h,k)=>(h.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),b=Array.from(s.values()).sort((h,k)=>(h.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),z=I.find(h=>h.status==="in_progress")??I.find(h=>h.status==="blocked")??I.find(h=>h.status==="pending"),q=b.find(h=>h.status==="in_progress")??b.find(h=>h.status==="blocked")??b.find(h=>h.status==="pending"),Wt=F([...m,...q?[q.title]:[],...!q&&z?[z.title]:[],...b.filter(h=>h.status==="pending").slice(0,5).map(h=>h.title)],8),Dt=F([...p,...I.filter(h=>h.status==="blocked").map(h=>h.title),...b.filter(h=>h.status==="blocked").map(h=>h.title)],20),he={version:1,projectId:t.id,projectName:t.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:I,tasks:b,decisions:F(l,20),blockers:Dt,warnings:F(d,20),nextActions:Wt,filesTouched:F(S,30),activeFiles:Array.from(g.entries()).filter(([,h])=>h!=="deleted").map(([h])=>h).slice(-5),modifiedFiles:F(y,30),createdFiles:F(v,30),deletedFiles:F(x,30),commands:F(O,20),tests:F(M,20),checks:Xu(R,20),currentPhase:z,currentTask:q,progress:{phasesTotal:I.length,phasesCompleted:I.filter(h=>h.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(h=>h.status==="completed").length,blocked:I.filter(h=>h.status==="blocked").length+b.filter(h=>h.status==="blocked").length},lastSession:f,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},He=Fo(t.rootPath,".toolnet","work");return Yu(He,{recursive:!0}),N(Fo(He,"current.json"),he),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(he,null,2)+`
|
|
52
|
+
`,"application/json"),he}async function xt(t,e){if((await zo(t,e)).length>0)return De(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 ol(t,e){if(!el(t))return{events:[],nextOffset:e};let n=rl(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=tl(t,"r");try{nl(i,s,0,o,r)}finally{Zu(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(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
55
|
-
`,"application/json"),c}};import{mkdirSync as
|
|
56
|
-
`,"application/json"),d}async function
|
|
54
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var It=class{constructor(e){this.options=e;this.journal=new bt(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=ol(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=ge(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await De(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:o.length,journalWritten:s,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as fl,existsSync as ml,openSync as gl,readSync as yl,statSync as hl}from"node:fs";var sl=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ye(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function bn(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))bn(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,o]of Object.entries(t))(sl.has(r)||["data","payload","parts","messages"].includes(r))&&bn(o,e,n+1)}}function K(t,e,n,r,o,s=.95){let i=ye(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 W(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 ye(t.slice(r.length+1))}return null}function il(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function al(t){return ye(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function qo(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=[];bn(s.data,i);for(let a of i){let c={type:"project"},u=null;for(let f of a.split(/\r?\n/u)){let l=ye(f);if(!l){u=null;continue}let p=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let b=Number(p[1]);c={type:"phase",key:`phase:${b}`,order:b,title:ye(p[2]??"")},u=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let b=Number(d[1]);c={type:"task",key:`task:${b}`,order:b,title:ye(d[2]??"")},u=null;continue}let m=W(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o(K(t,s,"mission",m,{type:"project"},.99)),u=null;continue}let S=W(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){o(K(t,s,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let g=W(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o(K(t,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let y=W(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(y){o(K(t,s,"desired_outcome",y,{type:"project"},.98)),u=null;continue}let v=W(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(v){o(K(t,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=W(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){o(K(t,s,"phase_deliverable",x,c,.97)),u=null;continue}let O=W(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(O){o(K(t,s,"acceptance_criterion",O,c,.98)),u="acceptance_criterion";continue}let M=W(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(M){o(K(t,s,"dependency",M,c,.97)),u="dependency";continue}let R=W(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){o(K(t,s,"open_question",R,c,.95)),u="open_question";continue}let I=W(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(I){o(K(t,s,"constraint",I,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){u="constraint";continue}if(u&&il(f)){o(K(t,s,u,al(f),c,.96));continue}u=null}}}return n}function Ho(t){return String(t).padStart(12,"0")}var Et=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",`${Ho(r)}-${Ho(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 cl}from"node:fs";import{join as Vo}from"node:path";function ul(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function ll(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 U(t,e){return ll(e,t)?e:t}function Y(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 dl(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 pl(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Bo(t,e){let r=(await dl(t,e)).flatMap(S=>S.observations).sort((S,g)=>{let y=S.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return y!==0?y: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,f=[],l=[],p=[];for(let S of r){let g=ul(S);if(S.scope==="phase"&&S.scopeKey){let y=u.get(S.scopeKey)??pl(S);switch(S.kind){case"phase_objective":y.objective=U(y.objective,g);break;case"phase_why":y.why=U(y.why,g);break;case"phase_deliverable":y.deliverable=U(y.deliverable,g);break;case"acceptance_criterion":y.acceptanceCriteria.push(g);break;case"dependency":y.dependencies.push(g);break;case"open_question":y.openQuestions.push(g);break;case"constraint":y.constraints.push(g);break;case"note":y.notes.push(g);break}u.set(y.key,y);continue}switch(S.kind){case"mission":o=U(o,g);break;case"objective":s=U(s,g);break;case"why":i=U(i,g);break;case"desired_outcome":a=U(a,g);break;case"plan_rationale":c=U(c,g);break;case"open_question":f.push(g);break;case"constraint":l.push(g);break;case"note":p.push(g);break}}for(let S of u.values())S.acceptanceCriteria=Y(S.acceptanceCriteria,20),S.dependencies=Y(S.dependencies,15),S.openQuestions=Y(S.openQuestions,15),S.constraints=Y(S.constraints,15),S.notes=Y(S.notes,20);let d={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:Y(f,20),constraints:Y(l,20),notes:Y(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=Vo(t.rootPath,".toolnet","work");return cl(m,{recursive:!0}),N(Vo(m,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
|
|
56
|
+
`,"application/json"),d}async function Jo(t,e){let n=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Sl(t,e){if(!ml(t))return{events:[],nextOffset:e};let n=hl(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=gl(t,"r");try{yl(s,o,0,o.length,r)}finally{fl(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 At=class{constructor(e){this.options=e;this.journal=new Et(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=Sl(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=qo(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await Bo(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 dd,mkdirSync as pd}from"node:fs";import{join as In}from"node:path";import{existsSync as Yo,mkdirSync as kl,readFileSync as vl,statSync as Go,writeFileSync as wl}from"node:fs";import{dirname as bl,join as xl}from"node:path";var Uo=64*1024,Il=`# ToolNet Project Operating Manual
|
|
59
59
|
|
|
60
60
|
This file contains persistent instructions for AI agents working on this project.
|
|
61
61
|
|
|
@@ -98,52 +98,52 @@ 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
|
|
105
|
-
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(
|
|
106
|
-
`,"application/json"),
|
|
107
|
-
`)}function
|
|
101
|
+
`;function jt(t){return xl(t.rootPath,".toolnet","PROJECT.md")}function El(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Al(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=El(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 jl(t){let e=jt(t);return Yo(e)||(kl(bl(e),{recursive:!0}),wl(e,Il,{encoding:"utf8",mode:384})),e}function Pt(t,e=!1){let n=e?jl(t):jt(t);if(!Yo(n))return null;if(Go(n).size>Uo)throw new Error(`PROJECT.md exceeds ${Uo} bytes`);let o=vl(n,"utf8");return{path:n,content:o,digest:w(o),rules:Al(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(Go(n).mtimeMs).toISOString()}}import{randomUUID as Pl}from"node:crypto";import{closeSync as Cl,existsSync as Xo,fsyncSync as Ml,mkdirSync as Tl,openSync as Ol,readFileSync as Rl,statSync as Nl,unlinkSync as Qo,writeFileSync as _l}from"node:fs";import{dirname as Kl,join as Ll}from"node:path";var $l=new Int32Array(new SharedArrayBuffer(4));function Fl(t){t<=0||Atomics.wait($l,0,0,t)}function Wl(t){return Ll(t.rootPath,".toolnet","work",".current.lock")}function Dl(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e?.code!=="ESRCH"}}function Zo(t){if(!Xo(t))return null;try{let e=JSON.parse(Rl(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 zl(t){try{return Date.now()-Nl(t).mtimeMs}catch{return 0}}function ql(t,e){if(!Xo(t)||zl(t)<e)return!1;let n=Zo(t);return n?!Dl(n.pid):!0}function Hl(t,e){if(!ql(t,e))return!1;try{return Qo(t),!0}catch{return!1}}function Vl(t,e){let n={version:1,token:e,pid:process.pid,acquiredAt:new Date().toISOString()},r=Ol(t,"wx",384);try{_l(r,`${JSON.stringify(n,null,2)}
|
|
102
|
+
`,{encoding:"utf8"}),Ml(r)}finally{Cl(r)}}function Bl(t,e){if(Zo(t)?.token===e)try{Qo(t)}catch{}}function Jl(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=Wl(t);Tl(Kl(s),{recursive:!0});let i=Pl(),a=Date.now()+n;for(;;)try{Vl(s,i);let c=!1;return()=>{c||(c=!0,Bl(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(Hl(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);Fl(r)}}function es(t,e,n={}){let r=Jl(t,n);try{return e()}finally{r()}}import{closeSync as Gl,existsSync as Ul,fsyncSync as Yl,mkdirSync as Xl,openSync as Ql,readFileSync as Zl,renameSync as ed,writeFileSync as td}from"node:fs";import{dirname as nd,join as rd}from"node:path";function od(t,e){Xl(nd(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`,r=Ql(n,"w",384);try{td(r,`${JSON.stringify(e,null,2)}
|
|
103
|
+
`,{encoding:"utf8"}),Yl(r)}finally{Gl(r)}ed(n,t)}function is(t){return rd(t.rootPath,".toolnet","work","current.json")}function xn(t){let e=is(t);if(!Ul(e))return null;try{let n=JSON.parse(Zl(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Ct(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(t,e,n){let r=[],o=new Set;for(let s of[...t,...e].reverse()){let i=Ct(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function sd(t,e,n=20){let r=new Map;for(let o of[...t,...e]){let s=`${o.kind}|${Ct(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function id(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 ts(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&&id(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 ns(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:Ct(n.title);e.set(r,n)}return e}function rs(t){return t.order!==void 0?`order:${t.order}`:Ct(t.key||t.text)}function os(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 ss(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function ad(t,e){let n=xn(t),r=ns(n?.phases??[]),o=ns(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,f=[],l=[],p=[],d=[],m=[],S=[...n?.activeFiles??[]],g=[],y=[],v=[],x=[],O=[],M=[],R=[...e].sort((k,T)=>{let V=k.occurredAt.localeCompare(T.occurredAt);return V!==0?V:k.sequence-T.sequence});for(let k of R)switch(k.kind){case"request":s=k.text;break;case"activity":i=k.text;break;case"goal":a=k.text;break;case"plan":c=k.text;break;case"phase":{let T=rs(k);r.set(T,ts(r.get(T),k));break}case"task":{let T=rs(k);o.set(T,ts(o.get(T),k));break}case"decision":f.push(k.text);break;case"blocker":l.push(k.text);break;case"warning":p.push(k.text);break;case"next_action":d.push(k.text);break;case"file":{m.push(k.text);let T=k.fileAction??"active",V=S.indexOf(k.text);V>=0&&S.splice(V,1),T!=="deleted"&&S.push(k.text),T==="modified"?g.push(k.text):T==="created"?y.push(k.text):T==="deleted"&&v.push(k.text);break}case"command":x.push(k.text);break;case"test":O.push(k.text),k.checkKind&&M.push({kind:k.checkKind,command:k.text,status:k.checkStatus??"unknown",updatedAt:k.occurredAt,agent:k.agent,nativeSessionId:k.nativeSessionId});break;case"session":u={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let I=os(r.values()),b=os(o.values()),z=ss(I),q=ss(b),Wt=L(n?.nextActions??[],[...d,...q?[q.title]:[],...!q&&z?[z.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),Dt=L(n?.blockers??[],[...l,...I.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),he=R.length>0?R[R.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),He={version:1,projectId:t.id,projectName:t.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:I,tasks:b,decisions:L(n?.decisions??[],f,20),blockers:Dt,warnings:L(n?.warnings??[],p,20),nextActions:Wt,filesTouched:L(n?.filesTouched??[],m,30),activeFiles:L([],S,5),modifiedFiles:L(n?.modifiedFiles??[],g,30),createdFiles:L(n?.createdFiles??[],y,30),deletedFiles:L(n?.deletedFiles??[],v,30),commands:L(n?.commands??[],x,20),tests:L(n?.tests??[],O,20),checks:sd(n?.checks??[],M,20),currentPhase:z,currentTask:q,progress:{phasesTotal:I.length,phasesCompleted:I.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:I.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:he},h=ue(He);return od(is(t),h),h}function Mt(t,e){return es(t,()=>ad(t,e))}function C(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 as(t){if(t)return{id:t.id,title:t.title,status:t.status}}function cd(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 ud(t){return w(JSON.stringify(t))}function ld(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 C(e,30)}function cs(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())),f=C(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),l=C([...c,...f],15),p=C(r.tests.slice().reverse(),10),d=C([...(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:as(r.currentPhase),task:as(r.currentTask),file:o},completed:{phases:C(s,20),tasks:C(i,30)},remaining:{phases:C(a,20),tasks:C(c,30),todos:l},nextAction:f[0],blockers:C(r.blockers.slice().reverse(),10),decisions:C(r.decisions.slice().reverse(),10),files:{current:o,recent:d,active:C(r.activeFiles??[],10),modified:C(r.modifiedFiles??[],20),created:C(r.createdFiles??[],20),deleted:C(r.deletedFiles??[],20)},tests:{status:cd(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:C((r.commands??[]).slice().reverse(),20),references:ld([r.currentRequest,r.currentActivity,r.goal,r.plan,...r.decisions,...r.blockers,...r.warnings,...r.nextActions,...r.filesTouched,...r.commands??[],...r.tests,...(r.checks??[]).map(v=>v.command)])},attention:C(t.attention??[],20),progress:r.progress},{capturedAt:S,source:g,...y}=m;return{...m,stateDigest:ud(y)}}function fd(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 us(t,e,n,r,o){if(!fd(n))return null;let s=Pt(t,!1),a=[...s?s.rules.filter(l=>l.mode==="enforce").map(l=>l.text):[],...n.warnings].slice(0,20),c=cs({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(l=>l.status!=="completed"&&l.status!=="cancelled"),incompleteTasks:n.tasks.filter(l=>l.status!=="completed"&&l.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 ls(t,e){let n=In(t.rootPath,".toolnet","work","handoffs");pd(n,{recursive:!0});let r=In(n,`${e.id}.json`);dd(r)||N(r,e),N(In(t.rootPath,".toolnet","work","handoff-latest.json"),e)}function ds(t){let e=us(t.project,t.identity,t.state,t.reason,t.sequence);return e?(ls(t.project,e),e):null}var Tt=class{constructor(e){this.options=e}options;async capture(e,n){let r=xn(this.options.project);r||(r=await xt(this.options.project,this.options.storage)),r||(r=await De(this.options.project,this.options.storage));let o=us(this.options.project,this.options.identity,r,e,n);if(!o)return null;ls(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
|
+
`,"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}};async function ps(t,e){let n=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{existsSync as md,readFileSync as gd,writeFileSync as yd}from"node:fs";import{join as hd}from"node:path";var ms="<!-- TOOLNET:STABLE-WORK:BEGIN -->",En="<!-- TOOLNET:STABLE-WORK:END -->";function An(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function D(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function fs(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${An(n)} ${n.title}`)]:[]}function Sd(t){let e=[ms,"# 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:",`${An(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${An(t.currentTask)} ${t.currentTask.title}`),e.push(...fs("Phases",t.phases)),e.push(...fs("TODO / Tasks",t.tasks)),e.push(...D("Next actions",t.nextActions)),e.push(...D("Blockers",t.blockers)),e.push(...D("Important decisions",t.decisions)),e.push(...D("Active files",t.activeFiles??[])),e.push(...D("Modified files",t.modifiedFiles??[])),e.push(...D("Created files",t.createdFiles??[])),e.push(...D("Deleted files",t.deletedFiles??[])),e.push(...D("Files touched",t.filesTouched)),e.push(...D("Recent commands",t.commands??[])),e.push(...D("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.",En),e.join(`
|
|
107
|
+
`)}function Ot(t,e){let n=hd(t.rootPath,".toolnet","current.md"),r="";if(md(n))try{r=gd(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=Sd(e),s=r.indexOf(ms),i=r.indexOf(En),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+En.length).trimStart()].filter(Boolean).join(`
|
|
108
108
|
|
|
109
109
|
`):a=r.trim()?`${r.trim()}
|
|
110
110
|
|
|
111
|
-
${
|
|
112
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as
|
|
113
|
-
`,{encoding:"utf8",mode:384}),
|
|
114
|
-
`)}import{existsSync as
|
|
115
|
-
`))if(n)try{let r=
|
|
116
|
-
`);if(u<0)return{events:[],nextOffset:
|
|
111
|
+
${o}`:o,yd(n,`${a.trim()}
|
|
112
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as kd,mkdirSync as vd,readFileSync as wd,renameSync as bd,writeFileSync as xd}from"node:fs";import{dirname as Id,join as Ed}from"node:path";function gs(t){return Ed(t.rootPath,".toolnet","context","session-origin.json")}function Ad(t,e){vd(Id(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;xd(n,`${JSON.stringify(e,null,2)}
|
|
113
|
+
`,{encoding:"utf8",mode:384}),bd(n,t)}function Rt(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 Nt(t,e){let n=Rt(e.observations,"file"),r=Rt(e.observations,"next_action"),o=Rt(e.observations,"blocker"),s=Rt(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 Ad(gs(t),i),i}function jd(t){let e=gs(t);if(!kd(e))return null;try{let n=JSON.parse(wd(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function ys(t){let e=jd(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentRequest&&n.push(`- Current request: ${e.currentRequest}`),e.currentActivity&&n.push(`- Current activity: ${e.currentActivity}`),e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
|
|
114
|
+
`)}import{existsSync as hs,mkdirSync as Pd,readFileSync as Cd}from"node:fs";import{join as jn}from"node:path";function Ss(t){return jn(t.rootPath,".toolnet","memory","checkpoints")}function ks(t){return jn(Ss(t),"latest.json")}function Md(t){let e=ks(t);if(!hs(e))return null;try{let n=JSON.parse(Cd(e,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==t.id?null:n}catch{return null}}function Td(t){return["rule","architecture","decision","fix"].includes(t)}function Od(t,e){return e.length===0?[]:dt(t,e).candidates.filter(r=>Td(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 Rd(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 Nd(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 vs(t,e,n,r){let o=Md(t),s=Rd(o?.durableFacts??[],Od(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),f=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l={work:Nd(r),durableFacts:s.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(l)).slice(0,32),d={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:f},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:s,stateDigest:p},m=Ss(t);Pd(m,{recursive:!0,mode:448});let S=jn(m,`${p}.json`);return hs(S)||N(S,d),N(ks(t),d),d}function ws(t,e,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ge(e,n);if(r.length===0)return{updated:!1,observations:0};let o=Mt(t,r);Ot(t,o),Nt(t,{agent:e.agent,nativeSessionId:e.nativeSessionId,observations:r,workState:o});try{vs(t,e,n,o)}catch{}try{ds({project:t,identity:e,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var _t=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;project;title;metadata;constructor(e){this.project=e.project,this.identity=Ze(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new it(this.identity,e.eventContext),this.remote=new et(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 It({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new At({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new Tt({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}checkpointLocal(e){if(e.length!==0)try{ws(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 _d,readFileSync as Kd,readdirSync as Ld,statSync as bs}from"node:fs";import{homedir as $d}from"node:os";import{join as Kt,resolve as xs}from"node:path";function Is(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Fd(){return process.env.CODEX_HOME??Kt($d(),".codex")}function ze(t){let e="";try{e=Kd(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
|
|
115
|
+
`))if(n)try{let r=Is(JSON.parse(n));if(r.type!=="session_meta")continue;let o=Is(r.payload),s=[o.id,o.thread_id,o.threadId,o.session_id,o.sessionId].find(a=>typeof a=="string"),i=typeof o.cwd=="string"?o.cwd:void 0;return{threadId:s,cwd:i,raw:o}}catch{}return{raw:{}}}function Pn(t,e){if(!_d(t))return;let n;try{n=Ld(t,{withFileTypes:!0})}catch{return}for(let r of n){let o=Kt(t,r.name);if(r.isDirectory()){Pn(o,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(o)}}function Cn(){let t=Fd(),e=[];return Pn(Kt(t,"sessions"),e),Pn(Kt(t,"archived_sessions"),e),e.sort((n,r)=>{try{return bs(r).mtimeMs-bs(n).mtimeMs}catch{return 0}})}function Mn(t){let e=Cn(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(ze(r).threadId===t)return r;return null}function Lt(t,e){let n=xs(t),r=xs(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as Wd,existsSync as Dd,openSync as zd,readSync as qd,statSync as Hd}from"node:fs";function Es(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Vd(t){let e=t.timestamp;if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function Bd(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=Es(t.payload),r=typeof n.type=="string"?n.type.toLowerCase():"",o=typeof n.role=="string"?n.role.toLowerCase():void 0;return e==="session_meta"?{type:"custom"}:o==="user"||r==="user_message"?{type:"user_prompt",role:"user"}:o==="assistant"||r==="agent_message"||r==="assistant_message"?{type:"assistant_message",role:"assistant"}:r.includes("function_call")||r.includes("tool_call")||r.includes("exec_command_begin")||r.includes("exec_command_start")?{type:"tool_call"}:r.includes("function_call_output")||r.includes("tool_result")||r.includes("exec_command_end")||r.includes("exec_command_complete")?{type:"tool_result"}:r.includes("error")?{type:"error"}:e.includes("compacted")||r.includes("compacted")?{type:"session_compact"}:{type:"custom",role:o}}function As(t,e=0){if(!Dd(t))return{events:[],nextOffset:e,reset:!1};let n=Hd(t).size,r=e>n,o=r?0:e;if(o>=n)return{events:[],nextOffset:n,reset:r};let s=n-o,i=Buffer.alloc(s),a=zd(t,"r");try{qd(a,i,0,s,o)}finally{Wd(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
|
|
116
|
+
`);if(u<0)return{events:[],nextOffset:o,reset:r};let f=c.slice(0,u+1),l=0,p=[];for(let d of f.split(`
|
|
117
117
|
`)){if(!d)continue;let m=Buffer.byteLength(d+`
|
|
118
|
-
`,"utf8"),S=
|
|
119
|
-
`),a=i.findIndex(
|
|
120
|
-
`);
|
|
118
|
+
`,"utf8"),S=o+l;l+=m;let g;try{g=JSON.parse(d)}catch{continue}let y=Es(g),v=Bd(y);p.push({type:v.type,timestamp:Vd(y),role:v.role,sourceEventId:`rollout:${S}`,sourceSequence:S,data:y,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:S}})}return{events:p,nextOffset:o+Buffer.byteLength(f,"utf8"),reset:r}}var Jd=[/^<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*$/],Gd=[/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],Ud=["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 Yd(t){let e=t.toLowerCase();return Ud.some(n=>e.includes(n))}function Xd(t){if(!t.trim())return!0;for(let e of Jd)if(e.test(t))return!0;return Yd(t),!1}function Qd(t){let e=t;for(let n of Gd)e=e.replace(n,r=>{let o=r.split(/[:\s=]+/);return o.length>1?`${o[0]}: [REDACTED]`:"[REDACTED]"});return e}function Tn(t){let e=t.trim();return e?Xd(e)?{content:"",filtered:!0,reason:"noise"}:{content:Qd(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function $t(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let o=Tn(r);o.filtered||(e[n]=o.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=$t(r):Array.isArray(r)?e[n]=r.map(o=>{if(typeof o=="string"){let s=Tn(o);return s.filtered?null:s.content}return o&&typeof o=="object"?$t(o):o}).filter(o=>o!==null):e[n]=r;return e}function js(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&&Tn(r).filtered)return!0}return!1}async function qe(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=ze(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!Lt(t.project.rootPath,r))throw new Error(`Codex thread does not belong to project: ${r}`);if(n.threadId&&n.threadId!==e)throw new Error(`Codex rollout thread mismatch: expected ${e}, got ${n.threadId}`);let o=new _t({project:t.project,storage:t.storage,agent:"codex",nativeSessionId:e,metadata:{source:"codex-rollout",rolloutPath:t.rolloutPath,cwd:r,client:t.client},eventContext:{source:"codex",cwd:r??t.project.rootPath,turnId:t.turnId}}),s=o.status(),i=s.sourceCursors["codex.rollout.path"],a=Number(s.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(a=0),(!Number.isFinite(a)||a<0)&&(a=0);let c=As(t.rolloutPath,a),u=[];s.lastSequence===0&&u.push({type:"session_start",sourceEventId:`codex:${e}:start`,data:{threadId:e,cwd:r,rolloutPath:t.rolloutPath,sessionMeta:n.raw},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),i&&i!==t.rolloutPath&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),c.reset&&u.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${c.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=c.events.filter(d=>!js(d.data)).map(d=>({...d,data:$t(d.data)}));if(u.push(...f),f.length>0)try{let d=Ze(t.project,"codex",e),m=f.map((y,v)=>({version:1,id:`codex-work-${e}-${y.sourceSequence??v}`,sequence:v+1,projectId:t.project.id,agent:"codex",nativeSessionId:e,type:y.type,timestamp:y.timestamp??new Date().toISOString(),role:y.role,sourceEventId:y.sourceEventId,sourceSequence:y.sourceSequence,data:y.data??{},provenance:y.provenance??{}})),S=ge(d,m),g=Mt(t.project,S);Ot(t.project,g),Nt(t.project,{agent:"codex",nativeSessionId:e,observations:S,workState:g})}catch{}t.idle&&t.turnId&&u.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let l=o.recordMany(u);if(o.setSourceCursor("codex.rollout.path",t.rolloutPath),o.setSourceCursor("codex.rollout.offset",c.nextOffset),t.turnId&&o.setSourceCursor("codex.last.turn",t.turnId),t.idle&&f.length>0)try{let d=f.map(S=>JSON.stringify(S.data)),m=lt(d,e);o.setSourceCursor("codex.session.summary",m.summary),o.setSourceCursor("codex.session.facts_count",m.durableFacts.length),Dr()&&!Hr()&&o.setSourceCursor("codex.raw_transcript.archived","local")}catch{}let p=await o.flush();return{threadId:e,imported:l.length,rolloutEvents:c.events.length,eventCount:p.eventCount,chunkCount:p.chunkCount,status:p.status,rolloutOffset:c.nextOffset,reset:c.reset}}import{existsSync as Zd}from"node:fs";import{dirname as ep,join as tp,parse as np,resolve as rp}from"node:path";function Ps(t){let e=rp(t),n=np(e).root;for(;;){if(Zd(tp(e,".toolnet","project.json")))return new ce().detect(e);if(e===n)break;let r=ep(e);if(r===e)break;e=r}return null}async function Cs(t,e,n=100){let r=[];for(let o of Cn()){let s=ze(o);if(!(!s.threadId||!s.cwd)&&Lt(t.rootPath,s.cwd)&&(r.push(await qe({project:t,storage:e,threadId:s.threadId,rolloutPath:o,cwd:s.cwd})),r.length>=n))break}return r}import{existsSync as op,mkdirSync as Ms,readFileSync as sp,writeFileSync as Ts}from"node:fs";import{homedir as Os}from"node:os";import{dirname as Rs,join as On}from"node:path";function ip(t){let e=[],n=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=n.exec(t);){let o=r[1]??r[2]??"";try{e.push(r[1]!==void 0?JSON.parse(`"${o}"`):o)}catch{e.push(o)}}return e}function Ns(t={}){let e=t.configFile??On(process.env.CODEX_HOME??On(Os(),".codex"),"config.toml"),n=t.previousFile??On(Os(),".config","toolnet-memory","codex-notify-previous.json");Ms(Rs(e),{recursive:!0}),Ms(Rs(n),{recursive:!0});let r=op(e)?sp(e,"utf8"):"",o=t.binary??"toolnet-memory",s=`notify = [${JSON.stringify(o)}, "session:codex-notify"]`,i=r.split(`
|
|
119
|
+
`),a=i.findIndex(p=>/^\s*\[/.test(p));a<0&&(a=i.length);let c=-1,u=-1;for(let p=0;p<a;p+=1)if(/^\s*notify\s*=/.test(i[p])){if(c=p,u=p,i[p].includes("[")&&!i[p].includes("]"))for(;u+1<a&&(u+=1,!i[u].includes("]")););break}let f=[];if(c>=0){let p=i.slice(c,u+1).join(`
|
|
120
|
+
`);f=ip(p),i.splice(c,u-c+1,s)}else a=i.findIndex(p=>/^\s*\[/.test(p)),a<0&&(a=i.length),i.splice(a,0,s);let l=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!l&&Ts(n,JSON.stringify(f,null,2)+`
|
|
121
121
|
`,{encoding:"utf8",mode:384}),r=i.join(`
|
|
122
122
|
`),r.endsWith(`
|
|
123
123
|
`)||(r+=`
|
|
124
|
-
`),
|
|
125
|
-
`,{encoding:"utf8",mode:384}),e}import{existsSync as
|
|
126
|
-
`);if(
|
|
127
|
-
`)),i=Math.max(0,e-
|
|
128
|
-
`).trim()}async function
|
|
124
|
+
`),Ts(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:f.length>0&&!l}}import{existsSync as ap,mkdirSync as cp,readFileSync as up,writeFileSync as lp}from"node:fs";import{homedir as dp}from"node:os";import{dirname as pp,join as _s}from"node:path";function fp(t){return`'${t.replace(/'/g,"'\\''")}'`}function Ks(t={}){let e=t.hooksFile??_s(process.env.CODEX_HOME??_s(dp(),".codex"),"hooks.json");cp(pp(e),{recursive:!0});let n={};if(ap(e))try{n=JSON.parse(up(e,"utf8"))}catch(a){throw new Error(`Invalid existing Codex hooks.json: ${a instanceof Error?a.message:String(a)}`)}let r=n.hooks&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)?n.hooks:{};n.hooks=r;let s=(Array.isArray(r.SessionStart)?r.SessionStart:[]).filter(a=>{try{return!JSON.stringify(a).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return s.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${fp(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=s,lp(e,JSON.stringify(n,null,2)+`
|
|
125
|
+
`,{encoding:"utf8",mode:384}),e}import{existsSync as ek,mkdirSync as hp,readFileSync as tk,writeFileSync as Sp}from"node:fs";import{dirname as kp,join as $s}from"node:path";function Rn(t){if(!t)return 0;let e=Array.from(t).length,n=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,n*1.3))}function E(t,e){let n=t.replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function mp(t){let e=[],n=!1;for(let r of t.split(/\r?\n/u)){let o=r.trim();if(o.includes("<!--")&&(n=!0),n){o.includes("-->")&&(n=!1);continue}let s=o.toLowerCase();if(!(!o||o.startsWith("#")||o==="```"||s.startsWith("- [enforce]")||s.startsWith("* [enforce]")||s.startsWith("- [advisory]")||s.startsWith("* [advisory]"))&&(o=o.replace(/^[-*]\s+/u,""),o&&e.push(E(o,280)),e.length>=16))break}return e}function gp(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let o=r.trim(),s=o.toLowerCase(),a=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>s.startsWith(u));if(!a)continue;let c=o.slice(a.length).trim();c&&(a.includes("enforce")?e.push(c):n.push(c))}return{enforce:e,advisory:n}}function yp(t,e){let n=[];for(let r of t){let o=[...n,r].join(`
|
|
126
|
+
`);if(Rn(o)<=e){n.push(r);continue}let s=Rn(n.join(`
|
|
127
|
+
`)),i=Math.max(0,e-s);if(i>=16){let a=Math.floor(i*3.2),c=E(r,a);c&&n.push(c)}break}return n.join(`
|
|
128
|
+
`).trim()}async function Ls(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=Pt(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let o=gp(r),s=n?n.rules.filter(d=>d.mode==="enforce").map(d=>d.text):o.enforce,i=n?n.rules.filter(d=>d.mode==="advisory").map(d=>d.text):o.advisory,a=r?mp(r):[],c=await xt(t.project,t.storage),u=await Jo(t.project,t.storage),f=await ps(t.project,t.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${t.project.name}`),l.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&l.push(`Full operating manual: ${jt(t.project)}`),s.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of s.slice(0,24))l.push(`- [ENFORCE] ${E(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${E(d,220)}`)}if(u&&(u.mission&&l.push("","MISSION",E(u.mission.value,420)),u.activeObjective&&l.push("","CURRENT OBJECTIVE",E(u.activeObjective.value,420)),u.why&&l.push("","WHY THIS WORK MATTERS",E(u.why.value,420)),u.desiredOutcome&&l.push("","DESIRED OUTCOME",E(u.desiredOutcome.value,420)),u.planRationale&&l.push("","WHY THIS APPROACH",E(u.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${E(c.goal,320)}`),c.plan&&l.push(`Plan: ${E(c.plan,320)}`),l.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&l.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&u){let d=u.phases.find(m=>m.order===c.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${E(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${E(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${E(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(m=>E(m.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(m=>{l.push(`- ${E(m.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(m=>{l.push(`- ${E(m.value,260)}`)})))}c.currentTask&&l.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(l.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((d,m)=>{l.push(`${m+1}. ${E(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${E(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${E(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${E(d,260)}`)})),c.lastSession&&l.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${E(d.value,260)}`)})),f&&l.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),a.length){l.push("","OPERATING NOTES");for(let d of a)l.push(`- ${d}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=yp(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:p,estimatedTokens:Rn(p),maxTokens:e,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!f,generatedAt:new Date().toISOString()}}function vp(t){return $s(t.rootPath,".toolnet","context","startup.md")}function wp(t){return $s(t.rootPath,".toolnet","context","startup.json")}function bp(t,e){let n=vp(t);hp(kp(n),{recursive:!0}),Sp(n,e.text.endsWith(`
|
|
129
129
|
`)?e.text:e.text+`
|
|
130
|
-
`,{encoding:"utf8",mode:384}),
|
|
130
|
+
`,{encoding:"utf8",mode:384}),N(wp(t),e)}async function Fs(t,e,n=800){let o=(await Ls({project:t,storage:e,maxTokens:n})).text;ct(o)>n&&(o=ut(o,n),o+=`
|
|
131
131
|
|
|
132
132
|
[Context trimmed by ToolNet Memory token budget]
|
|
133
|
-
`);let i={version:1,projectId:t.id,projectName:t.name,text:
|
|
133
|
+
`);let i={version:1,projectId:t.id,projectName:t.name,text:o,digest:w(o),estimatedTokens:ct(o),generatedAt:new Date().toISOString()};return bp(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
|
|
134
134
|
`,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(i,null,2)+`
|
|
135
|
-
`,"application/json"),i}import{existsSync as
|
|
135
|
+
`,"application/json"),i}import{existsSync as Pp,readFileSync as Cp}from"node:fs";import{join as Mp}from"node:path";import{existsSync as Ws,mkdirSync as xp,readFileSync as Ds,renameSync as Ip,writeFileSync as Ep}from"node:fs";import{dirname as Ap,join as zs}from"node:path";function qs(t){return zs(t.rootPath,".toolnet","context","handoff.md")}function Hs(t){return zs(t.rootPath,".toolnet","context","handoff.json")}function Vs(t,e){xp(Ap(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Ep(n,e.endsWith(`
|
|
136
136
|
`)?e:`${e}
|
|
137
|
-
`,{encoding:"utf8",mode:384}),
|
|
138
|
-
`)}function
|
|
139
|
-
`).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return
|
|
140
|
-
`).trim(),r=2400,
|
|
137
|
+
`,{encoding:"utf8",mode:384}),Ip(n,t)}function jp(t,e){Vs(t,`${JSON.stringify(e,null,2)}
|
|
138
|
+
`)}function Bs(t,e){let n=e.replace(/\r\n/g,`
|
|
139
|
+
`).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return Vs(qs(t),n),jp(Hs(t),r),r}function Js(t){let e=qs(t);if(!Ws(e))return null;try{let n=Ds(e,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),o=Hs(t);if(Ws(o))try{let s=JSON.parse(Ds(o,"utf8"));typeof s.generatedAt=="string"&&(r=s.generatedAt)}catch{}return{version:1,projectId:t.id,projectName:t.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function Tp(t){let e=Mp(t.rootPath,".toolnet","current.md");if(!Pp(e))return null;try{return Cp(e,"utf8").trim()}catch{return null}}function Op(t,e){let n=e.replace(/\r\n/g,`
|
|
140
|
+
`).trim(),r=2400,o=n.length>r?`${n.slice(0,r)}
|
|
141
141
|
|
|
142
|
-
[Current work truncated for fast handoff]`:n,
|
|
143
|
-
`)}function
|
|
142
|
+
[Current work truncated for fast handoff]`:n,s=ys(t);return["# ToolNet Fast Handoff","",`Project: ${t.name}`,"",...s?[s,""]:[],o,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
|
|
143
|
+
`)}function Gs(t){let e=Tp(t);if(e===null)return{updated:!1,reason:"missing-current",chars:0};if(!e.trim())return{updated:!1,reason:"empty-current",chars:0};let n=Op(t,e);return Js(t)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(Bs(t,n),{updated:!0,reason:"updated",chars:n.length})}function Ft(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Us(t){let e=Ve(),n=ar(sr({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new Qe(n,t.id,t.name,t.remote??t.name)}async function $p(t){for(let e=0;e<10;e+=1){let n=Mn(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function Fp(t){let e=Lp(Kp(),".config","toolnet-memory","codex-notify-previous.json");if(Rp(e))try{let n=JSON.parse(Np(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(o=>typeof o=="string"))return;_p(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Wp(t){let e;try{e=JSON.parse(t)}catch{return}if(e.type!=="agent-turn-complete")return;let r=typeof e["thread-id"]=="string"?e["thread-id"]:"",o=typeof e["turn-id"]=="string"?e["turn-id"]:"",s=typeof e.cwd=="string"?e.cwd:"",i=typeof e.client=="string"?e.client:void 0;if(!r||!s)return;let a=Ps(s);if(!a)return;let c=await $p(r);if(!c)return;let u=Us(a);await qe({project:a,storage:u,threadId:r,rolloutPath:c,cwd:s,turnId:o,client:i,idle:!0});try{await Fs(a,u,800)}catch{}try{Gs(a)}catch{}}async function Dp(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let s=Ft(e,"--bin"),i=Ns({binary:s}),a=Ks({binary:s});console.log(`\u2705 Codex notify installed: ${i.configFile}`),i.preservedPrevious&&console.log(`\u2705 Previous notify preserved: ${i.previousFile}`),console.log(`\u2705 Codex SessionStart context hook: ${a}`);return}if(t==="notify"){let s=e[e.length-1]??"";try{await Wp(s)}finally{Fp(s)}return}let n=Ft(e,"--project")??process.cwd(),r=new ce().detect(n),o=Us(r);if(t==="sync"){let s=e[0];if(!s)throw new Error("Usage: sync <thread-id>");let i=Ft(e,"--rollout")??Mn(s);if(!i)throw new Error(`Codex rollout not found for ${s}`);let a=await qe({project:r,storage:o,threadId:s,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(a,null,2));return}if(t==="recover"){let s=Number(Ft(e,"--limit")??100),i=await Cs(r,o,Number.isFinite(s)?s:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((a,c)=>a+c.imported,0)},null,2));return}console.log(`Codex Session Adapter
|
|
144
144
|
|
|
145
145
|
Commands:
|
|
146
146
|
install-notify
|
|
147
147
|
sync <thread-id> [--project PATH]
|
|
148
148
|
recover [--project PATH] [--limit N]
|
|
149
|
-
`)}
|
|
149
|
+
`)}Dp().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});
|