toolnet-memory 0.3.15 → 0.3.16
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/.release-target +1 -1
- package/README.md +158 -6
- package/bundle/agy-hook.js +66 -66
- package/bundle/agy.js +59 -59
- package/bundle/api.js +15 -15
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +49 -49
- package/bundle/codex-context.js +29 -29
- package/bundle/codex.js +71 -71
- package/bundle/context-runtime.js +44 -44
- package/bundle/context.js +14 -14
- package/bundle/copilot-hook.js +77 -77
- package/bundle/cursor-hook.js +78 -78
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +19 -19
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +55 -55
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +3 -3
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -5
- package/bundle/init.js +36 -35
- package/bundle/kiro-hook.js +86 -86
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +6 -6
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +73 -73
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +9 -9
- package/bundle/runtime.js +13 -13
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +48 -48
- package/bundle/work-continuity.js +7 -7
- package/package.json +14 -2
- package/release-manifest.json +51 -1
package/bundle/agy-hook.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),mo(s,r)}function It(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}var De=class{findExisting(t=process.cwd()){let n=se(t),r=dn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Ke(ge(r,c))),i=ln(n,o?r:void 0);if(!i)return null;let a=fn(We(i));return It(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=se(t),r=dn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>Ke(ge(r,f))),i=ln(n,o?r:void 0);if(i){let f=We(i),l=fn(f);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),pn(i,l)),It(l,i)}let a=new Date().toISOString(),c=yo(r),u={version:1,id:ko(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return pn(r,u),It(u,r)}};var vo=[{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"}],wo=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function yn(e){return e.normalize("NFKC").trim().toLowerCase()}function bo(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let s=r/e.length;n-=s*Math.log2(s)}return n}function xo(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function jo(e,t,n){let r=e.slice(Math.max(0,t-48),t),s=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${s}`)}function Mo(e,t){return e.start<t.end&&t.start<e.end}function hn(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var ze=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=yn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let o of vo){let i=new RegExp(o.regex.source,o.regex.flags);for(let a of t.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(t));let r=hn(n),s=[];for(let o of r)s.some(i=>Mo(i,o))||s.push(o);return hn(s)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=yn(t);return wo.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let s of t.matchAll(r)){if(s.index===void 0||!s[0])continue;let o=s[0];this.allowed(o)||xo(o)||!/[A-Za-z]/u.test(o)||!/[0-9]/u.test(o)||jo(t,s.index,s.index+o.length)&&(bo(o)<3.7||n.push({type:"high_entropy_secret",value:o,start:s.index,end:s.index+o.length,confidence:"heuristic"}))}return n}};var V=class{scanner;constructor(t={}){this.scanner=new ze(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,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(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,s]of Object.entries(t)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");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 t}};var Ao=new V;function ye(e){return Ao.sanitizeValue(e)}import{homedir as Uo}from"node:os";import{join as Yo}from"node:path";import{DeleteObjectCommand as Io,GetObjectCommand as Po,HeadObjectCommand as Co,ListObjectsV2Command as To,PutObjectCommand as Eo,S3Client as Oo}from"@aws-sdk/client-s3";import{getSignedUrl as Ro}from"@aws-sdk/s3-request-presigner";var qe=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Oo({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Eo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ro(this.client,new Po({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new Co({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new Io({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new To({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as kn,mkdir as No,readFile as _o,readdir as $o,rm as Fo,stat as Sn,writeFile as Ko}from"node:fs/promises";import{dirname as Lo,join as Wo,relative as vn,resolve as Do}from"node:path";var he=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Do(this.root,n)}async put(t,n){let r=this.path(t);await No(Lo(r),{recursive:!0}),await Ko(r,n)}async get(t){try{return await _o(this.path(t))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await kn(this.path(t)),!0}catch{return!1}}async delete(t){await Fo(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await kn(n)}catch{return r}let s=async i=>{let a=await $o(i,{withFileTypes:!0});for(let c of a){let u=Wo(i,c.name);if(c.isDirectory()){await s(u);continue}let f=await Sn(u);r.push({key:vn(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Sn(n);return o.isDirectory()?await s(n):r.push({key:vn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as zo,GetObjectCommand as qo,HeadObjectCommand as Bo,ListObjectsV2Command as Vo,PutObjectCommand as Ho,S3Client as Jo}from"@aws-sdk/client-s3";import{getSignedUrl as Go}from"@aws-sdk/s3-request-presigner";var ke=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Jo({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Ho({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Go(this.client,new qo({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new Bo({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new zo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Vo({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function Pt(e,t){return console.warn(t),new he(e)}function wn(e){let t=e.localRoot??Yo(Uo(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ke({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Pt(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new ke({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Pt(t,"[storage] S3 credentials missing. Using local fallback.")}if(e.provider==="huggingface"){let n=e.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new qe({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Pt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new he(t)}function Qo(e){return new Promise(t=>setTimeout(t,e))}async function bn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Qo(c+u)}throw o}var Xo=new Set(["put","get","getText","delete","list"]);function xn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Xo.has(r)?(...o)=>bn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function jn(e){let t=e.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function Mn(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:t))}var Be=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=jn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
6
|
-
`))))}function
|
|
7
|
-
`).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
|
|
8
|
-
`,a=w(n.map(
|
|
9
|
-
`)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${
|
|
10
|
-
`,"application/json"),
|
|
1
|
+
import{existsSync as gs,readFileSync as ys}from"node:fs";import{homedir as hs}from"node:os";import{join as ks}from"node:path";function Ss(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function vs(){let e=process.env.TOOLNET_GLOBAL_ENV??ks(hs(),".config","toolnet-memory",".env");if(!gs(e))return;let t=ys(e,"utf8");for(let n of t.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let s=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Ss(r.slice(o+1)))}}vs();function ge(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function ye(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function We(){return{memory:{autoCapture:ge(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ge(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ge(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ge(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ye(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ye(process.env.MEMORY_RERANK_TOP,10),finalContext:ye(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ye(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:ge(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:ye(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Is}from"node:crypto";import{existsSync as qe,mkdirSync as Cs,readFileSync as Ps,renameSync as Es,writeFileSync as Ts}from"node:fs";import{basename as Os,dirname as Be,join as ke,parse as xn,resolve as X}from"node:path";import{createHash as kn}from"node:crypto";import{spawnSync as ws}from"node:child_process";var he="git-remote-v1",bs=new Set(["github.com","gitlab.com","bitbucket.org"]);function Sn(e,t){let n=t.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!n||n==="."||n===".."||n.split("/").some(r=>!r||r==="."||r==="..")?null:(bs.has(e)&&(n=n.toLowerCase()),n)}function xs(e){let t;try{t=new URL(e)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(t.protocol))return null;let n=t.hostname.trim().toLowerCase();if(!n)return null;let r=t.protocol==="https:"&&t.port==="443"||t.protocol==="http:"&&t.port==="80"||t.protocol==="ssh:"&&t.port==="22",o=t.port&&!r?`${n}:${t.port}`:n,s=Sn(n,t.pathname);return s?`${o}/${s}`:null}function js(e){let t=e.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!t)return null;let n=t[1]?.trim().toLowerCase();if(!n||n.length===1)return null;let r=Sn(n,t[2]??"");return r?`${n}/${r}`:null}function yn(e){let t=e.trim();return t?t.includes("://")?xs(t):js(t):null}function Ms(e){return kn("sha256").update(`${he}:${e}`).digest("hex")}function vn(e){return kn("sha256").update(`toolnet-project:${he}:${e}`).digest("hex").slice(0,16)}function As(e){return e.split("/").filter(Boolean).at(-1)?.trim()||null}function Tt(e,t){let n=ws("git",["-C",e,...t],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return n.error||n.status!==0?null:n.stdout?.trim()||null}function hn(e,t){let n=As(e);return n?{scheme:he,canonicalRemote:e,fingerprint:Ms(e),repositoryName:n,source:t}:null}function wn(e){let t=Tt(e,["remote","get-url","origin"]);if(t){let o=yn(t);if(o)return hn(o,"origin")}let n=Tt(e,["remote"]);if(!n)return null;let r=new Set;for(let o of n.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=Tt(e,["remote","get-url",o]);if(!s)continue;let i=yn(s);i&&r.add(i)}return r.size!==1?null:hn([...r][0],"unique-remote")}var jn=".toolnet",Rs="project.json";function Ns(e){return Is("sha256").update(e).digest("hex").slice(0,16)}function ie(e){return ke(e,jn,Rs)}function Mn(e){return qe(ie(e))}function bn(e,t){let n=X(e),r=xn(n).root;for(;;){if(Mn(n))return n;if(n===r||t&&n===X(t))break;let o=Be(n);if(o===n)break;n=o}return null}function Ot(e){let t=X(e),n=xn(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>qe(ke(t,s))))return t;if(t===n)break;let o=Be(t);if(o===t)break;t=o}return X(e)}function De(e){let t;try{t=JSON.parse(Ps(e,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${e}: ${o instanceof Error?o.message:String(o)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let n=t;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Be(Be(e)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function ze(e,t){let n=ke(e,jn);Cs(n,{recursive:!0});let r=ie(e),o=`${r}.tmp-${process.pid}`;Ts(o,JSON.stringify(t,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Es(o,r)}function Q(e,t){return{id:e.id,name:e.name,remote:e.remote,rootPath:t,createdAt:e.createdAt,updatedAt:e.updatedAt,graphVersion:e.graphVersion,memoryVersion:e.memoryVersion,metadata:e.metadata}}function Rt(e){return{version:1,scheme:he,canonicalRemote:e.canonicalRemote,fingerprint:e.fingerprint,repositoryName:e.repositoryName}}function _s(e){let t=e.metadata?.toolnetIdentity;if(!t||typeof t!="object"||Array.isArray(t))return null;let n=t;return typeof n.fingerprint=="string"?n.fingerprint:null}var Ve=class{adopt(t,n){let r=Ot(X(t));if(!n.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!n.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!n.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(Mn(r)){let a=De(ie(r));if(a.id!==n.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${n.id}`].join(" "));return Q(a,r)}let o=new Date().toISOString(),s={...n.metadata};n.gitIdentity&&(s.toolnetIdentity=Rt(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 ze(r,i),Q(i,r)}recordGitIdentity(t,n,r={}){let o=this.requireExisting(t),s=ie(o.rootPath),i=De(s),a=_s(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:Rt(n)},i.updatedAt=new Date().toISOString(),ze(o.rootPath,i)),Q(i,o.rootPath)}findExisting(t=process.cwd()){let n=X(t),r=Ot(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>qe(ke(r,c))),i=bn(n,s?r:void 0);if(!i)return null;let a=De(ie(i));return Q(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=X(t),r=Ot(n),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>qe(ke(r,l))),i=bn(n,s?r:void 0);if(i){let l=ie(i),f=De(l);return f.rootPath!==i&&(f.rootPath=i,f.updatedAt=new Date().toISOString(),ze(i,f)),Q(f,i)}let a=new Date().toISOString(),c=Os(r),u=wn(r),p={version:1,id:u?vn(u.canonicalRemote):Ns(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:Rt(u)}:void 0};return ze(r,p),Q(p,r)}};var $s=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],Fs=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function An(e){return e.normalize("NFKC").trim().toLowerCase()}function Ks(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let o=r/e.length;n-=o*Math.log2(o)}return n}function Ls(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function Ws(e,t,n){let r=e.slice(Math.max(0,t-48),t),o=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function Ds(e,t){return e.start<t.end&&t.start<e.end}function In(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var He=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=An(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let s of $s){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=In(n),o=[];for(let s of r)o.some(i=>Ds(i,s))||o.push(s);return In(o)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=An(t);return Fs.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of t.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||Ls(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Ws(t,o.index,o.index+s.length)&&(Ks(s)<3.7||n.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return n}};var V=class{scanner;constructor(t={}){this.scanner=new He(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,o=[...n].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...s].sort()}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,o]of Object.entries(t)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(o)}return n}return t}};var zs=new V;function Se(e){return zs.sanitizeValue(e)}import{homedir as di}from"node:os";import{join as fi}from"node:path";import{DeleteObjectCommand as qs,GetObjectCommand as Bs,HeadObjectCommand as Vs,ListObjectsV2Command as Hs,PutObjectCommand as Js,S3Client as Gs}from"@aws-sdk/client-s3";import{getSignedUrl as Us}from"@aws-sdk/s3-request-presigner";var Je=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Gs({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Js({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await Us(this.client,new Bs({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new Vs({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new qs({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new Hs({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};import{access as Cn,mkdir as Ys,readFile as Qs,readdir as Xs,rm as Zs,stat as Pn,writeFile as ei}from"node:fs/promises";import{dirname as ti,join as ni,relative as En,resolve as ri}from"node:path";var ve=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return ri(this.root,n)}async put(t,n){let r=this.path(t);await Ys(ti(r),{recursive:!0}),await ei(r,n)}async get(t){try{return await Qs(this.path(t))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await Cn(this.path(t)),!0}catch{return!1}}async delete(t){await Zs(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await Cn(n)}catch{return r}let o=async i=>{let a=await Xs(i,{withFileTypes:!0});for(let c of a){let u=ni(i,c.name);if(c.isDirectory()){await o(u);continue}let p=await Pn(u);r.push({key:En(this.root,u),size:p.size,updatedAt:p.mtime.toISOString()})}},s=await Pn(n);return s.isDirectory()?await o(n):r.push({key:En(this.root,n),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as oi,GetObjectCommand as si,HeadObjectCommand as ii,ListObjectsV2Command as ai,PutObjectCommand as ci,S3Client as ui}from"@aws-sdk/client-s3";import{getSignedUrl as li}from"@aws-sdk/s3-request-presigner";var we=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new ui({region:t.region??"us-east-1",endpoint:t.endpoint||void 0,forcePathStyle:t.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let o=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new ci({Bucket:this.bucket,Key:t,Body:o,ContentType:r}))}async get(t){let n=await li(this.client,new si({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new ii({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new oi({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let o=await this.client.send(new ai({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&n.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return n}};function Nt(e,t){return console.warn(t),new ve(e)}function Tn(e){let t=e.localRoot??fi(di(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new we({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(t,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(e.provider==="s3"){let n=e.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new we({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(t,"[storage] S3 credentials missing. Using local fallback.")}if(e.provider==="huggingface"){let n=e.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Je({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Nt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ve(t)}function pi(e){return new Promise(t=>setTimeout(t,e))}async function On(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,o=t.maxDelayMs??2e3,s;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(s=a,i>=n)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await pi(c+u)}throw s}var mi=new Set(["put","get","getText","delete","list"]);function Rn(e,t={}){return new Proxy(e,{get(n,r){let o=Reflect.get(n,r,n);return typeof o!="function"?o:mi.has(r)?(...s)=>On(()=>Promise.resolve(o.apply(n,s)),t):o.bind(n)}})}function Nn(e){let t=e.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function _n(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let o=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:t))}var Ge=class{constructor(t,n,r,o){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Nn(o??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,o=await this.provider.getText(t);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(s,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=_n(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,n,r){return await this.ensureRegistered(),this.provider.put(this.key(t),n,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{spawn as gi}from"node:child_process";function $n(e){return(e??"").trim()}function Fn(e,t={}){let n=$n(e);if(!n)return!1;let r=$n(t.binary??process.env.TOOLNET_MEMORY_BIN)||"toolnet-memory";try{let o=gi(r,["background:refresh","--project",n,"--quiet"],{detached:!0,stdio:"ignore",env:process.env});return o.on("error",()=>{}),o.unref(),!0}catch{return!1}}import{createHash as yi}from"node:crypto";import{dirname as hi}from"node:path";import{mkdirSync as ki,readFileSync as Si,renameSync as vi,writeFileSync as wi}from"node:fs";function w(e){return yi("sha256").update(e).digest("hex")}function _t(e){if(Array.isArray(e))return e.map(_t);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=_t(t[r]);return n}return e}function Kn(e){return JSON.stringify(_t(e))}function Ln(e){try{return JSON.parse(Si(e,"utf8"))}catch{return null}}function T(e,t){ki(hi(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;wi(n,JSON.stringify(t,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),vi(n,e)}function Wn(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function xe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function be(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let o of e.slice(0,50))be(o,t,n+1);return}let r=Wn(e);if(r)for(let[o,s]of Object.entries(r))t(o,s,r),be(s,t,n+1)}function ae(e,t){let n=[];return be(e,(r,o)=>{t.has(xe(r))&&typeof o=="string"&&o.trim()&&n.push(o.trim())}),n}function bi(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Wn(JSON.parse(t))}catch{return null}}function xi(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let o=t[r];if(typeof o=="string"&&o.trim())return o.trim().toLowerCase()}let n="";return be(t,(r,o,s)=>{if(n)return;let i=xe(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 ji(e){let t=ae(e.data,new Set(["command","cmd","script"])),n=ae(e.data,new Set(["arguments","args"]));for(let r of n){let o=bi(r);if(o)for(let s of ae(o,new Set(["command","cmd","script"])))t.push(s)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function Mi(e){let t=ae(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(xe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
|
|
6
|
+
`))))}function Ai(e,t){return e.type==="file_edit"||e.type==="file_write"?"modified":/\b(delete|remove|unlink)\b/iu.test(t)?"deleted":/\b(create|add[_-]?file|new[_-]?file)\b/iu.test(t)?"created":/\b(edit|write|patch|apply[_-]?patch|replace|update[_-]?file)\b/iu.test(t)?"modified":null}function Ii(e){let t=ae(e.data,new Set(["patch","diff","arguments","input"].map(xe))),n=[];for(let r of t){let o=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let s of o)for(let i of r.matchAll(s.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:s.action,confidence:.99})}}return n}function Ci(e){let t=e.toLowerCase();return/\b(typecheck|type-check)\b/u.test(t)||/\btsc\b[\s\S]*--noemit\b/u.test(t)?"typecheck":/\b(eslint|lint)\b/u.test(t)?"lint":/\b(vitest|jest|pytest)\b/u.test(t)||/\bgo\s+test\b/u.test(t)||/\bcargo\s+test\b/u.test(t)||/\b(npm|pnpm|yarn)\s+(run\s+)?test\b/u.test(t)?"test":/\b(npm|pnpm|yarn)\s+(run\s+)?build\b/u.test(t)||/\bcargo\s+build\b/u.test(t)||/\bgo\s+build\b/u.test(t)||/\btsc\b/u.test(t)?"build":null}function Pi(e){let t=null;return be(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(xe(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let o=Number(r);Number.isFinite(o)&&(t=o)}}}),t}function Ei(e){return ae(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function Ti(e){let t=Pi(e.data);if(t!==null)return t===0?"passed":"failed";let n=Ei(e.data).join(`
|
|
7
|
+
`).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 Oi(e){let t=[],n=new Set;for(let r of e){let o=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(o)||(n.add(o),t.push(r))}return t}function Dn(e){let t=[],n=xi(e),r=Ai(e,n);if(r)for(let o of Mi(e))t.push({kind:"file",text:o,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...Ii(e));for(let o of ji(e)){t.push({kind:"command",text:o,confidence:.98});let s=Ci(o);s&&t.push({kind:"test",text:o,checkKind:s,checkStatus:Ti(e),confidence:.98})}return Oi(t)}var Ri=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ee(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function qn(e){return ee(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Z(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))Z(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Ri.has(r)||["data","payload","parts","messages"].includes(r))&&Z(o,t,n+1)}}function Ue(e){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(e)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(e)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(e)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(e)?"in_progress":"pending"}function zn(e){let t=ee(e);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(t)}function I(e,t,n,r,o={}){let s=ee(r),i=o.key??qn(s);return{version:1,id:w([e.projectId,n,i,t.id,s,o.status??"",o.fileAction??"",o.checkKind??"",o.checkStatus??"",o.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:s,status:o.status,fileAction:o.fileAction,checkKind:o.checkKind,checkStatus:o.checkStatus,order:o.order,confidence:o.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function Ni(e,t,n){let r=ee(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(I(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&o.push(I(e,t,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!s&&(u=c.exec(r));){let f=Number(u[1]),d=ee(u[2]??""),m=d&&!zn(d)?`Phase ${f} - ${d}`:`Phase ${f}`;o.push(I(e,t,"phase",m,{key:`phase:${f}`,order:f,status:Ue(r),confidence:.93}))}let p=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);p?.[2]&&o.push(I(e,t,"task",p[2],{status:p[1].trim()?"completed":Ue(p[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let f=l[1]?Number(l[1]):void 0,d=ee(l[2]),m=zn(d);o.push(I(e,t,"task",m&&f!==void 0?`TODO ${f}`:d,{key:f!==void 0?`task:${f}`:qn(d),order:f,status:Ue(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let f=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");f&&o.push(I(e,t,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&o.push(I(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&o.push(I(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&o.push(I(e,t,"decision",r,{confidence:.9})),r.length<=300&&/^(?:đang\s+(?:sửa|cập nhật|triển khai|xử lý|làm|refactor|fix)|(?:i(?:'m| am)\s+)?(?:working on|implementing|fixing|refactoring|updating|editing)\b)/iu.test(r)&&o.push(I(e,t,"activity",r,{confidence:.86})),o}function Ye(e,t){if(t.length===0)return[];let n=[],r=new Set;function o(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let c=[];Z(i.data,c);let u=c.map(p=>ee(p)).find(p=>p.length>=8&&p.length<=1200&&!/^\[?toolnet\b/iu.test(p));u&&o(I(e,i,"request",u,{confidence:.96}))}for(let c of Dn(i))o(I(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];Z(i.data,c);for(let u of c)o(I(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];Z(i.data,c);for(let u of c)o(I(e,i,"task",u,{status:Ue(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&o(I(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];Z(i.data,c);for(let u of c)o(I(e,i,"test",u,{confidence:1}))}let a=[];Z(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let p of Ni(e,i,u))o(p)}let s=t[t.length-1];return o(I(e,s,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function Bn(e){return String(e).padStart(12,"0")}var Qe=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(p=>p.sequence)),o=Math.max(...n.map(p=>p.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(p=>p.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:o,observations:n},i=JSON.stringify(s,null,2)+`
|
|
8
|
+
`,a=w(n.map(p=>JSON.stringify(p)).sort().join(`
|
|
9
|
+
`)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${Bn(r)}-${Bn(o)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as Vn}from"node:path";import{mkdirSync as _i}from"node:fs";function Jn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function F(e,t=20){let n=[],r=new Set;for(let o of e.slice().reverse()){let s=Jn(o);if(!(!s||r.has(s))&&(r.add(s),n.push(o),n.length>=t))break}return n.reverse()}function $i(e,t=20){let n=new Map;for(let r of e){let o=`${r.kind}|${Jn(r.command)}`;n.delete(o),n.set(o,r)}return Array.from(n.values()).slice(-t)}function Fi(e){return e.kind==="phase"?/^Phase\s+\d+$/iu.test(e.text):e.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(e.text):!1}function Hn(e,t){let n=t.status??e?.status??"pending",r=n;e&&(e.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status));let o=e&&Fi(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:o,status:r,order:t.order??e?.order,confidence:Math.max(t.confidence,e?.confidence??0),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}async function Gn(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}async function je(e,t){let r=(await Gn(e,t)).flatMap(y=>y.observations).sort((y,S)=>{let E=y.occurredAt.localeCompare(S.occurredAt);if(E!==0)return E;let B=y.sequence-S.sequence;return B!==0?B:y.id.localeCompare(S.id)}),o=new Map,s=new Map,i,a,c,u,p,l=[],f=[],d=[],m=[],k=[],g=new Map,h=[],v=[],x=[],O=[],P=[],R=[];for(let y of r)switch(y.kind){case"request":i=y.text;break;case"activity":a=y.text;break;case"goal":c=y.text;break;case"plan":u=y.text;break;case"phase":o.set(y.key,Hn(o.get(y.key),y));break;case"task":s.set(y.key,Hn(s.get(y.key),y));break;case"decision":l.push(y.text);break;case"blocker":f.push(y.text);break;case"warning":d.push(y.text);break;case"next_action":m.push(y.text);break;case"file":{k.push(y.text);let S=y.fileAction??"active";g.delete(y.text),g.set(y.text,S),S==="modified"?h.push(y.text):S==="created"?v.push(y.text):S==="deleted"&&x.push(y.text);break}case"command":O.push(y.text);break;case"test":P.push(y.text),y.checkKind&&R.push({kind:y.checkKind,command:y.text,status:y.checkStatus??"unknown",updatedAt:y.occurredAt,agent:y.agent,nativeSessionId:y.nativeSessionId});break;case"session":p={agent:y.agent,nativeSessionId:y.nativeSessionId,sessionKey:y.sessionKey,updatedAt:y.occurredAt};break}let j=Array.from(o.values()).sort((y,S)=>(y.order??Number.MAX_SAFE_INTEGER)-(S.order??Number.MAX_SAFE_INTEGER)),b=Array.from(s.values()).sort((y,S)=>(y.order??Number.MAX_SAFE_INTEGER)-(S.order??Number.MAX_SAFE_INTEGER)),D=j.find(y=>y.status==="in_progress")??j.find(y=>y.status==="blocked")??j.find(y=>y.status==="pending"),z=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),Pt=F([...m,...z?[z.title]:[],...!z&&D?[D.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),Et=F([...f,...j.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),me={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:j,tasks:b,decisions:F(l,20),blockers:Et,warnings:F(d,20),nextActions:Pt,filesTouched:F(k,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:F(h,30),createdFiles:F(v,30),deletedFiles:F(x,30),commands:F(O,20),tests:F(P,20),checks:$i(R,20),currentPhase:D,currentTask:z,progress:{phasesTotal:j.length,phasesCompleted:j.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:j.filter(y=>y.status==="blocked").length+b.filter(y=>y.status==="blocked").length},lastSession:p,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},Le=Vn(e.rootPath,".toolnet","work");return _i(Le,{recursive:!0}),T(Vn(Le,"current.json"),me),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(me,null,2)+`
|
|
10
|
+
`,"application/json"),me}async function ce(e,t){if((await Gn(e,t)).length>0)return je(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{closeSync as Ki,existsSync as Li,openSync as Wi,readSync as Di,statSync as zi}from"node:fs";function qi(e,t){if(!Li(e))return{events:[],nextOffset:t};let n=zi(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=Wi(e,"r");try{Di(i,s,0,o,r)}finally{Ki(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
11
11
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
12
|
-
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
12
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Xe=class{constructor(t){this.options=t;this.journal=new Qe(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=qi(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=Ye(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await je(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{existsSync as $a,mkdirSync as Fa}from"node:fs";import{join as $t}from"node:path";import{existsSync as Qn,mkdirSync as Bi,readFileSync as Vi,statSync as Un,writeFileSync as Hi}from"node:fs";import{dirname as Ji,join as Gi}from"node:path";var Yn=64*1024,Ui=`# ToolNet Project Operating Manual
|
|
13
13
|
|
|
14
14
|
This file contains persistent instructions for AI agents working on this project.
|
|
15
15
|
|
|
@@ -52,44 +52,44 @@ Things an AI agent should always remember.
|
|
|
52
52
|
<!--
|
|
53
53
|
- [advisory] Prefer small focused files.
|
|
54
54
|
-->
|
|
55
|
-
`;function
|
|
56
|
-
`,{encoding:"utf8"}),
|
|
57
|
-
`,{encoding:"utf8"}),
|
|
58
|
-
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function
|
|
59
|
-
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(
|
|
60
|
-
`,"application/json"),
|
|
61
|
-
`,"application/json"),d}async function
|
|
62
|
-
`);if(
|
|
63
|
-
`)),i=Math.max(0,t-
|
|
64
|
-
`).trim()}async function
|
|
65
|
-
`,"application/json"),c}};import{closeSync as
|
|
55
|
+
`;function Ze(e){return Gi(e.rootPath,".toolnet","PROJECT.md")}function Yi(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Qi(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,o;for(;o=r.exec(e);){let s=o[1].toLowerCase(),i=Yi(o[2]);if(!i)continue;let a=`${s}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:s,text:i,source:"manual"}))}return t}function Xi(e){let t=Ze(e);return Qn(t)||(Bi(Ji(t),{recursive:!0}),Hi(t,Ui,{encoding:"utf8",mode:384})),t}function et(e,t=!1){let n=t?Xi(e):Ze(e);if(!Qn(n))return null;if(Un(n).size>Yn)throw new Error(`PROJECT.md exceeds ${Yn} bytes`);let o=Vi(n,"utf8");return{path:n,content:o,digest:w(o),rules:Qi(o),bytes:Buffer.byteLength(o,"utf8"),updatedAt:new Date(Un(n).mtimeMs).toISOString()}}import{randomUUID as Zi}from"node:crypto";import{closeSync as ea,existsSync as Xn,fsyncSync as ta,mkdirSync as na,openSync as ra,readFileSync as oa,statSync as sa,unlinkSync as Zn,writeFileSync as ia}from"node:fs";import{dirname as aa,join as ca}from"node:path";var ua=new Int32Array(new SharedArrayBuffer(4));function la(e){e<=0||Atomics.wait(ua,0,0,e)}function da(e){return ca(e.rootPath,".toolnet","work",".current.lock")}function fa(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function er(e){if(!Xn(e))return null;try{let t=JSON.parse(oa(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function pa(e){try{return Date.now()-sa(e).mtimeMs}catch{return 0}}function ma(e,t){if(!Xn(e)||pa(e)<t)return!1;let n=er(e);return n?!fa(n.pid):!0}function ga(e,t){if(!ma(e,t))return!1;try{return Zn(e),!0}catch{return!1}}function ya(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=ra(e,"wx",384);try{ia(r,`${JSON.stringify(n,null,2)}
|
|
56
|
+
`,{encoding:"utf8"}),ta(r)}finally{ea(r)}}function ha(e,t){if(er(e)?.token===t)try{Zn(e)}catch{}}function ka(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),o=Math.max(n*2,t.staleMs??3e4),s=da(e);na(aa(s),{recursive:!0});let i=Zi(),a=Date.now()+n;for(;;)try{ya(s,i);let c=!1;return()=>{c||(c=!0,ha(s,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(ga(s,o))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${s}`);la(r)}}function tr(e,t,n={}){let r=ka(e,n);try{return t()}finally{r()}}import{closeSync as Sa,existsSync as va,fsyncSync as wa,mkdirSync as ba,openSync as xa,readFileSync as ja,renameSync as Ma,writeFileSync as Aa}from"node:fs";import{dirname as Ia,join as Ca}from"node:path";function Pa(e,t){ba(Ia(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=xa(n,"w",384);try{Aa(r,`${JSON.stringify(t,null,2)}
|
|
57
|
+
`,{encoding:"utf8"}),wa(r)}finally{Sa(r)}Ma(n,e)}function ar(e){return Ca(e.rootPath,".toolnet","work","current.json")}function Me(e){let t=ar(e);if(!va(t))return null;try{let n=JSON.parse(ja(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function tt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(e,t,n){let r=[],o=new Set;for(let s of[...e,...t].reverse()){let i=tt(s);if(!(!i||o.has(i))&&(o.add(i),r.push(s),r.length>=n))break}return r.reverse()}function Ea(e,t,n=20){let r=new Map;for(let o of[...e,...t]){let s=`${o.kind}|${tt(o.command)}`;r.delete(s),r.set(s,o)}return Array.from(r.values()).slice(-n)}function Ta(e){return e.kind==="phase"?/^Phase\s+\d+$/iu.test(e.text):e.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(e.text):!1}function nr(e,t){let n=t.status??e?.status??"pending",r=n;e?.status==="completed"&&n!=="completed"&&(r="completed"),e&&n==="pending"&&(e.status==="in_progress"||e.status==="blocked")&&(r=e.status);let o=e&&Ta(t)?e.title:t.text;return{id:e?.id??t.id,title:o,status:r,order:t.order??e?.order,confidence:Math.max(e?.confidence??0,t.confidence),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}function rr(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:tt(n.title);t.set(r,n)}return t}function or(e){return e.order!==void 0?`order:${e.order}`:tt(e.key||e.text)}function sr(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,o=n.order??Number.MAX_SAFE_INTEGER;return r!==o?r-o:t.updatedAt.localeCompare(n.updatedAt)})}function ir(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function Oa(e,t){let n=Me(e),r=rr(n?.phases??[]),o=rr(n?.tasks??[]),s=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,p=[],l=[],f=[],d=[],m=[],k=[...n?.activeFiles??[]],g=[],h=[],v=[],x=[],O=[],P=[],R=[...t].sort((S,E)=>{let B=S.occurredAt.localeCompare(E.occurredAt);return B!==0?B:S.sequence-E.sequence});for(let S of R)switch(S.kind){case"request":s=S.text;break;case"activity":i=S.text;break;case"goal":a=S.text;break;case"plan":c=S.text;break;case"phase":{let E=or(S);r.set(E,nr(r.get(E),S));break}case"task":{let E=or(S);o.set(E,nr(o.get(E),S));break}case"decision":p.push(S.text);break;case"blocker":l.push(S.text);break;case"warning":f.push(S.text);break;case"next_action":d.push(S.text);break;case"file":{m.push(S.text);let E=S.fileAction??"active",B=k.indexOf(S.text);B>=0&&k.splice(B,1),E!=="deleted"&&k.push(S.text),E==="modified"?g.push(S.text):E==="created"?h.push(S.text):E==="deleted"&&v.push(S.text);break}case"command":x.push(S.text);break;case"test":O.push(S.text),S.checkKind&&P.push({kind:S.checkKind,command:S.text,status:S.checkStatus??"unknown",updatedAt:S.occurredAt,agent:S.agent,nativeSessionId:S.nativeSessionId});break;case"session":u={agent:S.agent,nativeSessionId:S.nativeSessionId,sessionKey:S.sessionKey,updatedAt:S.occurredAt};break}let j=sr(r.values()),b=sr(o.values()),D=ir(j),z=ir(b),Pt=_(n?.nextActions??[],[...d,...z?[z.title]:[],...!z&&D?[D.title]:[],...b.filter(S=>S.status==="pending").slice(0,5).map(S=>S.title)],8),Et=_(n?.blockers??[],[...l,...j.filter(S=>S.status==="blocked").map(S=>S.title),...b.filter(S=>S.status==="blocked").map(S=>S.title)],20),me=R.length>0?R[R.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),Le={version:1,projectId:e.id,projectName:e.name,currentRequest:s,currentActivity:i,goal:a,plan:c,phases:j,tasks:b,decisions:_(n?.decisions??[],p,20),blockers:Et,warnings:_(n?.warnings??[],f,20),nextActions:Pt,filesTouched:_(n?.filesTouched??[],m,30),activeFiles:_([],k,5),modifiedFiles:_(n?.modifiedFiles??[],g,30),createdFiles:_(n?.createdFiles??[],h,30),deletedFiles:_(n?.deletedFiles??[],v,30),commands:_(n?.commands??[],x,20),tests:_(n?.tests??[],O,20),checks:Ea(n?.checks??[],P,20),currentPhase:D,currentTask:z,progress:{phasesTotal:j.length,phasesCompleted:j.filter(S=>S.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(S=>S.status==="completed").length,blocked:j.filter(S=>S.status==="blocked").length+b.filter(S=>S.status==="blocked").length},lastSession:u,updatedAt:me},y=Se(Le);return Pa(ar(e),y),y}function cr(e,t){return tr(e,()=>Oa(e,t))}function C(e,t){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/g," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function ur(e){if(e)return{id:e.id,title:e.title,status:e.status}}function Ra(e,t=[]){let n=t.slice(-10);if(n.some(o=>o.status==="failed"))return"failing";if(n.some(o=>o.status==="passed"))return"passing";let r=e.slice(-10).join(`
|
|
58
|
+
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Na(e){return w(JSON.stringify(e))}function _a(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let o of r){let s=o.replace(/[.,;:!?]+$/gu,"").trim();s&&t.push(s)}}return C(t,30)}function lr(e){let{project:t,identity:n,state:r}=e,o=r.activeFiles?.at(-1)??r.filesTouched.at(-1),s=r.phases.filter(v=>v.status==="completed").map(v=>v.title),i=r.tasks.filter(v=>v.status==="completed").map(v=>v.title),a=r.phases.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),c=r.tasks.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),u=new Set(r.tasks.filter(v=>v.status==="completed").map(v=>v.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),p=C(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),l=C([...c,...p],15),f=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:t.id,name:t.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:e.sequence,reason:e.reason},capturedAt:e.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:ur(r.currentPhase),task:ur(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:p[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:Ra(r.tests,r.checks),recent:f,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:_a([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(e.attention??[],20),progress:r.progress},{capturedAt:k,source:g,...h}=m;return{...m,stateDigest:Na(h)}}function Ka(e){return!!(e.currentRequest||e.currentActivity||e.goal||e.plan||e.phases.length>0||e.tasks.length>0||e.nextActions.length>0||e.blockers.length>0||e.decisions.length>0||e.filesTouched.length>0)}function dr(e,t,n,r,o){if(!Ka(n))return null;let s=et(e,!1),a=[...s?s.rules.filter(l=>l.mode==="enforce").map(l=>l.text):[],...n.warnings].slice(0,20),c=lr({project:e,identity:t,state:n,reason:r,sequence:o,attention:a}),u=c.stateDigest;return{version:1,id:w([e.id,t.sessionKey,u].join("|")).slice(0,24),projectId:e.id,projectName:e.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:o},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(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 fr(e,t){let n=$t(e.rootPath,".toolnet","work","handoffs");Fa(n,{recursive:!0});let r=$t(n,`${t.id}.json`);$a(r)||T(r,t),T($t(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function pr(e){let t=dr(e.project,e.identity,e.state,e.reason,e.sequence);return t?(fr(e.project,t),t):null}var nt=class{constructor(t){this.options=t}options;async capture(t,n){let r=Me(this.options.project);r||(r=await ce(this.options.project,this.options.storage)),r||(r=await je(this.options.project,this.options.storage));let o=dr(this.options.project,this.options.identity,r,t,n);if(!o)return null;fr(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)+`
|
|
59
|
+
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(o,null,2)+`
|
|
60
|
+
`,"application/json"),o}};async function mr(e,t){let n=await t.getText(`projects/${e.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{mkdirSync as La}from"node:fs";import{join as gr}from"node:path";function Wa(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function Da(e,t){if(!t)return!0;let n=e.evidence.occurredAt.localeCompare(t.evidence.occurredAt);return n!==0?n>0:e.evidence.sessionKey===t.evidence.sessionKey?e.evidence.sequence>=t.evidence.sequence:e.confidence>=t.confidence}function H(e,t){return Da(t,e)?t:e}function J(e,t=30){let n=new Set,r=[];for(let o of e){let s=o.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!s||n.has(s)||(n.add(s),r.push(o))}return r.slice(-t)}async function za(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),o=[];for(let s of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(s.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&o.push(a)}catch{}}return o}function qa(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function yr(e,t){let r=(await za(e,t)).flatMap(k=>k.observations).sort((k,g)=>{let h=k.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return h!==0?h:k.evidence.sessionKey===g.evidence.sessionKey?k.evidence.sequence-g.evidence.sequence:k.id.localeCompare(g.id)}),o,s,i,a,c,u=new Map,p=[],l=[],f=[];for(let k of r){let g=Wa(k);if(k.scope==="phase"&&k.scopeKey){let h=u.get(k.scopeKey)??qa(k);switch(k.kind){case"phase_objective":h.objective=H(h.objective,g);break;case"phase_why":h.why=H(h.why,g);break;case"phase_deliverable":h.deliverable=H(h.deliverable,g);break;case"acceptance_criterion":h.acceptanceCriteria.push(g);break;case"dependency":h.dependencies.push(g);break;case"open_question":h.openQuestions.push(g);break;case"constraint":h.constraints.push(g);break;case"note":h.notes.push(g);break}u.set(h.key,h);continue}switch(k.kind){case"mission":o=H(o,g);break;case"objective":s=H(s,g);break;case"why":i=H(i,g);break;case"desired_outcome":a=H(a,g);break;case"plan_rationale":c=H(c,g);break;case"open_question":p.push(g);break;case"constraint":l.push(g);break;case"note":f.push(g);break}}for(let k of u.values())k.acceptanceCriteria=J(k.acceptanceCriteria,20),k.dependencies=J(k.dependencies,15),k.openQuestions=J(k.openQuestions,15),k.constraints=J(k.constraints,15),k.notes=J(k.notes,20);let d={version:1,projectId:e.id,projectName:e.name,mission:o,activeObjective:s,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((k,g)=>k.order-g.order),openQuestions:J(p,20),constraints:J(l,20),notes:J(f,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=gr(e.rootPath,".toolnet","work");return La(m,{recursive:!0}),T(gr(m,"semantic-current.json"),d),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
|
|
61
|
+
`,"application/json"),d}async function hr(e,t){let n=await t.getText(`projects/${e.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Ft(e){if(!e)return 0;let t=Array.from(e).length,n=e.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(t/3.5,n*1.3))}function M(e,t){let n=e.replace(/\s+/g," ").trim();return n.length<=t?n:n.slice(0,Math.max(0,t-1)).trimEnd()+"\u2026"}function Ba(e){let t=[],n=!1;for(let r of e.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&&t.push(M(o,280)),t.length>=16))break}return t}function Va(e){let t=[],n=[];for(let r of e.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")?t.push(c):n.push(c))}return{enforce:t,advisory:n}}function Ha(e,t){let n=[];for(let r of e){let o=[...n,r].join(`
|
|
62
|
+
`);if(Ft(o)<=t){n.push(r);continue}let s=Ft(n.join(`
|
|
63
|
+
`)),i=Math.max(0,t-s);if(i>=16){let a=Math.floor(i*3.2),c=M(r,a);c&&n.push(c)}break}return n.join(`
|
|
64
|
+
`).trim()}async function kr(e){let t=Math.max(256,Math.min(2e3,e.maxTokens??1e3)),n=et(e.project,!1),r=n?.content??"";r||(r=await e.storage.getText(`projects/${e.project.id}/project/manual.md`)??"");let o=Va(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?Ba(r):[],c=await ce(e.project,e.storage),u=await hr(e.project,e.storage),p=await mr(e.project,e.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${e.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: ${Ze(e.project)}`),s.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of s.slice(0,24))l.push(`- [ENFORCE] ${M(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${M(d,220)}`)}if(u&&(u.mission&&l.push("","MISSION",M(u.mission.value,420)),u.activeObjective&&l.push("","CURRENT OBJECTIVE",M(u.activeObjective.value,420)),u.why&&l.push("","WHY THIS WORK MATTERS",M(u.why.value,420)),u.desiredOutcome&&l.push("","DESIRED OUTCOME",M(u.desiredOutcome.value,420)),u.planRationale&&l.push("","WHY THIS APPROACH",M(u.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${M(c.goal,320)}`),c.plan&&l.push(`Plan: ${M(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: ${M(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${M(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${M(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(m=>M(m.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(m=>{l.push(`- ${M(m.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(m=>{l.push(`- ${M(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}. ${M(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${M(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${M(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${M(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(`- ${M(d.value,260)}`)})),p&&l.push(`Latest handoff: ${p.reason} / ${p.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 f=Ha(l,t);return{version:1,projectId:e.project.id,projectName:e.project.name,text:f,estimatedTokens:Ft(f),maxTokens:t,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!p,generatedAt:new Date().toISOString()}}var Ja=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ue(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Kt(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))Kt(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,o]of Object.entries(e))(Ja.has(r)||["data","payload","parts","messages"].includes(r))&&Kt(o,t,n+1)}}function $(e,t,n,r,o,s=.95){let i=ue(r);return{version:1,id:w([e.projectId,n,o.type,o.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:o.type,scopeKey:o.key,scopeOrder:o.order,confidence:s,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function K(e,t){let n=e.toLowerCase();for(let r of t){let o=r.toLowerCase();if(n.startsWith(`${o}:`)||n.startsWith(`${o} -`)||n.startsWith(`${o} \u2014`))return ue(e.slice(r.length+1))}return null}function Ga(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Ua(e){return ue(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Sr(e,t){let n=[],r=new Set;function o(s){!s.value||s.value.length<3||r.has(s.id)||(r.add(s.id),n.push(s))}for(let s of t){let i=[];Kt(s.data,i);for(let a of i){let c={type:"project"},u=null;for(let p of a.split(/\r?\n/u)){let l=ue(p);if(!l){u=null;continue}let f=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let b=Number(f[1]);c={type:"phase",key:`phase:${b}`,order:b,title:ue(f[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:ue(d[2]??"")},u=null;continue}let m=K(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){o($(e,s,"mission",m,{type:"project"},.99)),u=null;continue}let k=K(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(k){o($(e,s,c.type==="phase"?"phase_objective":"objective",k,c,.98)),u=null;continue}let g=K(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){o($(e,s,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let h=K(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(h){o($(e,s,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let v=K(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($(e,s,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=K(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){o($(e,s,"phase_deliverable",x,c,.97)),u=null;continue}let O=K(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(O){o($(e,s,"acceptance_criterion",O,c,.98)),u="acceptance_criterion";continue}let P=K(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(P){o($(e,s,"dependency",P,c,.97)),u="dependency";continue}let R=K(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){o($(e,s,"open_question",R,c,.95)),u="open_question";continue}let j=K(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(j){o($(e,s,"constraint",j,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(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&&Ga(p)){o($(e,s,u,Ua(p),c,.96));continue}u=null}}}return n}function vr(e){return String(e).padStart(12,"0")}var rt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),o=Math.max(...n.map(u=>u.evidence.sequence)),s={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:o,createdAt:new Date().toISOString(),observations:n},i=w(n.map(u=>u.id).sort().join("|")).slice(0,16),a=w(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${vr(r)}-${vr(o)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(s,null,2)+`
|
|
65
|
+
`,"application/json"),c}};import{closeSync as Ya,existsSync as Qa,openSync as Xa,readSync as Za,statSync as ec}from"node:fs";function tc(e,t){if(!Qa(e))return{events:[],nextOffset:t};let n=ec(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=Buffer.alloc(n-r),s=Xa(e,"r");try{Za(s,o,0,o.length,r)}finally{Ya(s)}let i=o.toString("utf8"),a=i.lastIndexOf(`
|
|
66
66
|
`);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
|
|
67
|
-
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var
|
|
68
|
-
`),a=Math.max(
|
|
67
|
+
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ot=class{constructor(t){this.options=t;this.journal=new rt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=tc(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=Sr(this.options.identity,r.events),s=!1,i=!1;return o.length>0&&(s=!!await this.journal.write(this.options.identity,o),s&&(await yr(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 nc,mkdirSync as rc,readFileSync as oc,writeFileSync as sc}from"node:fs";import{dirname as ic,join as wr}from"node:path";function st(e){return e?Math.ceil(e.length/3.5):0}function it(e,t){if(!e)return"";if(st(e)<=t)return e;let r=Math.floor(t*3.5),o=e.slice(0,r),s=o.lastIndexOf("."),i=o.lastIndexOf(`
|
|
68
|
+
`),a=Math.max(s,i);return a>r*.7?o.slice(0,a+1):o}function br(e){return wr(e.rootPath,".toolnet","context","startup.md")}function ac(e){return wr(e.rootPath,".toolnet","context","startup.json")}function xr(e,t){let n=br(e);rc(ic(n),{recursive:!0}),sc(n,t.text.endsWith(`
|
|
69
69
|
`)?t.text:t.text+`
|
|
70
|
-
`,{encoding:"utf8",mode:384}),
|
|
70
|
+
`,{encoding:"utf8",mode:384}),T(ac(e),t)}async function Lt(e,t,n=800){let o=(await kr({project:e,storage:t,maxTokens:n})).text;st(o)>n&&(o=it(o,n),o+=`
|
|
71
71
|
|
|
72
72
|
[Context trimmed by ToolNet Memory token budget]
|
|
73
|
-
`);let i={version:1,projectId:e.id,projectName:e.name,text:
|
|
73
|
+
`);let i={version:1,projectId:e.id,projectName:e.name,text:o,digest:w(o),estimatedTokens:st(o),generatedAt:new Date().toISOString()};return xr(e,i),await t.put(`projects/${e.id}/context/startup.md`,i.text+`
|
|
74
74
|
`,"text/markdown"),await t.put(`projects/${e.id}/context/startup.json`,JSON.stringify(i,null,2)+`
|
|
75
|
-
`,"application/json"),i}async function
|
|
75
|
+
`,"application/json"),i}async function jr(e,t,n=900){try{let o=await t.getText(`projects/${e.id}/context/startup.md`);if(o&&o.trim()){let s=o.trim(),i={version:1,projectId:e.id,projectName:e.name,text:s,digest:w(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()};return xr(e,i),i}}catch{}let r=br(e);if(nc(r))try{let o=oc(r,"utf8").trim();if(o)return{version:1,projectId:e.id,projectName:e.name,text:o,digest:w(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await Lt(e,t,n)}catch{return null}}import{existsSync as $r,mkdirSync as Mc,readFileSync as Fr}from"node:fs";import{homedir as Ac}from"node:os";import{dirname as Ic,join as Bt}from"node:path";var Wt="memory_agent_ask";function Mr(){return`
|
|
76
76
|
[TOOLNET MEMORY AGENT]
|
|
77
77
|
|
|
78
78
|
Tool:
|
|
79
|
-
- ${
|
|
79
|
+
- ${Wt}
|
|
80
80
|
|
|
81
81
|
For resume/continue requests:
|
|
82
82
|
|
|
83
83
|
1. Use the injected ToolNet continuity handoff FIRST.
|
|
84
84
|
2. If the handoff is missing or ambiguous, invoke
|
|
85
|
-
${
|
|
85
|
+
${Wt} directly BEFORE repository/history exploration.
|
|
86
86
|
3. NEVER reconstruct prior work from:
|
|
87
87
|
- .toolnet/journal/**, .toolnet/runtime/sources/**, and legacy .toolnet/sessions/**
|
|
88
88
|
- state.json
|
|
89
89
|
- events.jsonl
|
|
90
90
|
- raw transcripts
|
|
91
91
|
4. NEVER search for the implementation/schema of
|
|
92
|
-
${
|
|
92
|
+
${Wt}; invoke the MCP tool directly.
|
|
93
93
|
5. Inspect git/source only AFTER continuity context is known.
|
|
94
94
|
|
|
95
95
|
Use:
|
|
@@ -97,60 +97,60 @@ Use:
|
|
|
97
97
|
- No AI/LLM mode exists.
|
|
98
98
|
|
|
99
99
|
Current repository evidence overrides stale memory.
|
|
100
|
-
`.trim()}import{createHash as
|
|
101
|
-
`)}function
|
|
102
|
-
`;
|
|
103
|
-
`).length>
|
|
104
|
-
`)}function
|
|
105
|
-
`)}async function
|
|
100
|
+
`.trim()}import{createHash as cc}from"node:crypto";import{chmodSync as Ir,existsSync as uc,mkdirSync as lc,readFileSync as dc,renameSync as fc,writeFileSync as Cr}from"node:fs";import{dirname as Pr,join as at}from"node:path";var qt="toolnet.context-offload.v1",pc="toolnet.context-offload-asset.v1",mc=256,gc=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Er(e){return at(e,".toolnet","offload")}function yc(e){return at(Er(e),"assets")}function Tr(e){return at(Er(e),"graph.json")}function Or(e){lc(e,{recursive:!0,mode:448});try{Ir(e,448)}catch{}}function hc(e,t){Or(Pr(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;Cr(n,t,{encoding:"utf8",mode:384}),fc(n,e);try{Ir(e,384)}catch{}}function zt(e){return Array.isArray(e)?e.map(zt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,zt(n)])):e}function kc(e){return cc("sha256").update(JSON.stringify(zt(e)),"utf8").digest("hex")}function Dt(){return{schema:qt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Rr(e){let t=Tr(e);if(!uc(t))return Dt();try{let n=JSON.parse(dc(t,"utf8"));return n.schema!==qt||n.version!==1||!Array.isArray(n.nodes)?Dt():n}catch{return Dt()}}function Sc(e,t){hc(Tr(e),JSON.stringify(t,null,2)+`
|
|
101
|
+
`)}function vc(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function wc(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let o=vc(r);if(!(!o||n.includes(o))&&(n.push(o),n.length===3))break}return n}function bc(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function xc(e,t){Or(Pr(e));try{return Cr(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function jc(e,t){let n=e.nodes.find(o=>o.id===t.id),r=n?{...n,kind:t.kind,bytes:t.bytes,sourceRefs:Array.from(new Set([...n.sourceRefs,...t.sourceRefs])).slice(-8),files:Array.from(new Set([...n.files,...t.files])).slice(0,6)}:t;return{schema:qt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(o=>o.id!==t.id),r].slice(-mc)}}function Nr(e,t){let n=Rr(e),r=0,o=0,s=0,i=[];for(let a of t){if(!gc.has(a.type))continue;r+=1;let c=kc({type:a.type,data:a.data}),u={schema:pc,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},p=JSON.stringify(u,null,2)+`
|
|
102
|
+
`;xc(at(yc(e),`${c}.json`),p)?o+=1:s+=1,i.push(c),n=jc(n,{id:c,kind:a.type,bytes:Buffer.byteLength(p,"utf8"),createdAt:a.timestamp,sourceRefs:[bc(a)],files:wc(a)})}return r>0&&Sc(e,n),{eligible:r,written:o,deduped:s,graphNodes:n.nodes.length,assetIds:i}}function Ar(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function _r(e,t={}){let n=Rr(e);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,t.maxAssets??6)),o=Math.max(320,Math.min(2400,t.maxChars??900)),s=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let a=Ar(i.sourceRefs.at(-1)??"unknown",72),c=i.files.length>0?` files=${Ar(i.files.join(","),120)}`:"",u=`event:${a} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${c}`;if([...s,u].join(`
|
|
103
|
+
`).length>o)break;s.push(u)}return s.join(`
|
|
104
|
+
`)}function Cc(e,t,n){let r=n??Bt(Ac(),".config","toolnet-memory","injections","agy");return Bt(r,`${e.id}-${t}.json`)}function Pc(e){if(!$r(e))return null;try{return JSON.parse(Fr(e,"utf8"))}catch{return null}}function G(e,t=280){let n=(e??"").replace(/\s+/g," ").trim();return n.length<=t?n:n.slice(0,Math.max(0,t-1)).trimEnd()+"\u2026"}function Ec(e){let t=Bt(e.rootPath,".toolnet","work","current.json");if(!$r(t))return null;try{let n=JSON.parse(Fr(t,"utf8"));if(n.version===1&&n.projectId===e.id)return n}catch{}return null}function Tc(e,t){let n=t.tasks.filter(i=>i.status==="completed").slice(-3).map(i=>G(i.title,220)),r=Array.from(new Set([...t.currentTask?[t.currentTask.title]:[],...t.tasks.filter(i=>i.status==="in_progress"||i.status==="blocked"||i.status==="pending").slice(0,4).map(i=>i.title)].map(i=>G(i,220)).filter(Boolean))),o=t.filesTouched.at(-1),s=["[TOOLNET CONTINUITY HANDOFF]",`Project: ${e.name}`];return t.currentTask?.title?s.push(`Task: ${G(t.currentTask.title)}`):t.currentPhase?.title?s.push(`Task: ${G(t.currentPhase.title)}`):t.goal&&s.push(`Task: ${G(t.goal)}`),n.length&&s.push(`Completed: ${n.join("; ")}`),o&&s.push(`Current file: ${G(o,260)}`),r.length&&s.push(`TODO: ${r.join("; ")}`),t.nextActions.length&&s.push(`Next action: ${G(t.nextActions[0])}`),t.blockers.length&&s.push(`Blocker: ${G(t.blockers[0])}`),s.push("","CONTINUATION CONTRACT:","- Continue from this compact handoff; do not reconstruct the prior session.","- NEVER inspect .toolnet/sessions/** (legacy), .toolnet/journal/**, or .toolnet/runtime/sources/**, state.json, events.jsonl, or raw transcripts.","- If this handoff is insufficient, invoke memory_agent_ask directly.","- Do not search for memory_agent_ask implementation/schema.","- Inspect git/source only to validate current code after continuity is resolved."),s.join(`
|
|
105
|
+
`)}async function Oc(e){let t=Ec(e.project);if(!t)try{t=await ce(e.project,e.storage)}catch{t=null}let n=t?Tc(e.project,t):"";if(!n)try{n=(await jr(e.project,e.storage,700))?.text??""}catch{n=""}let r=_r(e.project.rootPath,{maxAssets:6,maxChars:900});return[n,r,Mr()].filter(Boolean).join(`
|
|
106
106
|
|
|
107
|
-
`).trim()}async function
|
|
108
|
-
`,{encoding:"utf8",mode:384}),
|
|
109
|
-
`)}function
|
|
107
|
+
`).trim()}async function Kr(e){let t=e.now??Date.now(),n=e.resumeAfterMs??360*60*1e3,r=Cc(e.project,e.conversationId,e.markerDirectory),o=Pc(r),s=o?Date.parse(o.injectedAt):0,i=s?t-s:Number.POSITIVE_INFINITY;if(o&&i<6e4)return{};let a=e.invocationNum===0,c=i>=n;if(o&&!a&&!c)return{};let u=await Oc({project:e.project,storage:e.storage});return u?(Mc(Ic(r),{recursive:!0}),T(r,{digest:w(u),injectedAt:new Date(t).toISOString()}),{injectSteps:[{ephemeralMessage:u}]}):{}}import{existsSync as yg,mkdirSync as Rc,readFileSync as hg,renameSync as Nc,writeFileSync as _c}from"node:fs";import{dirname as $c,join as Fc}from"node:path";function Kc(e){return Fc(e.rootPath,".toolnet","context","session-origin.json")}function Lc(e,t){Rc($c(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;_c(n,`${JSON.stringify(t,null,2)}
|
|
108
|
+
`,{encoding:"utf8",mode:384}),Nc(n,e)}function ct(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let o=n.occurredAt.localeCompare(r.occurredAt);return o!==0?o:n.sequence-r.sequence}).at(-1)}function Lr(e,t){let n=ct(t.observations,"file"),r=ct(t.observations,"next_action"),o=ct(t.observations,"blocker"),s=ct(t.observations,"decision"),i={version:1,projectId:e.id,agent:t.agent,nativeSessionId:t.nativeSessionId,updatedAt:t.workState.updatedAt,currentRequest:t.workState.currentRequest,currentActivity:t.workState.currentActivity,currentTask:t.workState.currentTask?.title,currentPhase:t.workState.currentPhase?.title,lastTouchedFile:n?.text??t.workState.activeFiles?.at(-1)??t.workState.filesTouched.at(-1),latestNextAction:r?.text??t.workState.nextActions.at(-1),latestBlocker:o?.text??t.workState.blockers.at(-1),latestDecision:s?.text??t.workState.decisions.at(-1)};return Lc(Kc(e),i),i}import{existsSync as Wc,readFileSync as Dc,writeFileSync as zc}from"node:fs";import{join as qc}from"node:path";var Dr="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Vt="<!-- TOOLNET:STABLE-WORK:END -->";function Ht(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function L(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Wr(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${Ht(n)} ${n.title}`)]:[]}function Bc(e){let t=[Dr,"# ToolNet Stable Work State","",`Updated: ${e.updatedAt}`];return e.lastSession&&t.push(`Last agent: ${e.lastSession.agent}`,`Last session: ${e.lastSession.nativeSessionId}`),e.currentRequest&&t.push("","Current request:",e.currentRequest),e.currentActivity&&t.push("","Current activity:",e.currentActivity),e.goal&&t.push("","Goal:",e.goal),e.plan&&t.push("","Plan:",e.plan),e.currentPhase&&t.push("","Current phase:",`${Ht(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${Ht(e.currentTask)} ${e.currentTask.title}`),t.push(...Wr("Phases",e.phases)),t.push(...Wr("TODO / Tasks",e.tasks)),t.push(...L("Next actions",e.nextActions)),t.push(...L("Blockers",e.blockers)),t.push(...L("Important decisions",e.decisions)),t.push(...L("Active files",e.activeFiles??[])),t.push(...L("Modified files",e.modifiedFiles??[])),t.push(...L("Created files",e.createdFiles??[])),t.push(...L("Deleted files",e.deletedFiles??[])),t.push(...L("Files touched",e.filesTouched)),t.push(...L("Recent commands",e.commands??[])),t.push(...L("Checks",(e.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),t.push("","Progress:",`- Phases: ${e.progress.phasesCompleted}/${e.progress.phasesTotal}`,`- Tasks: ${e.progress.tasksCompleted}/${e.progress.tasksTotal}`,`- Blocked: ${e.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",Vt),t.join(`
|
|
109
|
+
`)}function zr(e,t){let n=qc(e.rootPath,".toolnet","current.md"),r="";if(Wc(n))try{r=Dc(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let o=Bc(t),s=r.indexOf(Dr),i=r.indexOf(Vt),a;s>=0&&i>=s?a=[r.slice(0,s).trimEnd(),o,r.slice(i+Vt.length).trimStart()].filter(Boolean).join(`
|
|
110
110
|
|
|
111
111
|
`):a=r.trim()?`${r.trim()}
|
|
112
112
|
|
|
113
|
-
${
|
|
114
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as
|
|
115
|
-
`)}function
|
|
116
|
-
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let
|
|
113
|
+
${o}`:o,zc(n,`${a.trim()}
|
|
114
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as io,mkdirSync as Tu,readFileSync as Ou}from"node:fs";import{join as Xt}from"node:path";var Hc=new Set(["rule","blocker","architecture","deploy"]),Jc=new Set(["fix","todo","context","next_action"]);function Jt(e){return e<0?0:e>1?1:e}function qr(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function Gc(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function Gt(){return{mode:Gc(process.env.TOOLNET_MEMORY_PROMOTION),minScore:Jt(qr(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:Jt(qr(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Uc(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Yc(e){let t=Jt(Uc(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function Qc(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Xc(e,t=Gt()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=Qc(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="next_action"||e.kind==="fix"?"task":"session"}function Zc(e,t=Gt()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return Hc.has(e)&&(r=Math.max(.5,r-.1)),Jc.has(e)&&(r=Math.max(.5,r-.05)),r}function Ut(e,t=Gt()){let n=Xc(e,t),r=Yc(e),o=Zc(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:o,persist:!1}:{knowledgeClass:n,score:r,threshold:o,persist:r>=o}}function Br(e,t){let n=t.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":e==="rule"||e==="decision"?"high":e==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var Gr=[/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],eu=[/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],tu=[/\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],nu=[/\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],ru=[/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],ou=[/đã 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],Vr=[/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],su=[/\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],iu=[/đườ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],au=[/\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],Hr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),cu=new Set(["payload","data","content","message","messages","parts","summary"]);function N(e,t){return t.some(n=>n.test(e))}function Ur(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function uu(e){return Ur(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function lu(e){return!(e.length<12||e.length>1e3||(e.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(e))}function Yt(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!Hr.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let o of e.slice(0,50))Yt(o,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[o,s]of Object.entries(e))(Hr.has(o)||cu.has(o))&&Yt(s,o,n,r+1)}}function du(e){let t=[];Yt(e.data,void 0,t);let n=[],r=new Set;for(let o of t)for(let s of o.split(/\n+|(?<=[.!?])\s+/u)){let i=Ur(s);if(lu(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Jr(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function fu(e,t,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message";return r&&N(e,Gr)?{kind:"rule",confidence:.98}:r&&N(e,eu)?{kind:"rule",confidence:.92}:N(e,tu)?{kind:N(e,Vr)?"architecture":"decision",confidence:r?.93:.86}:r&&N(e,ru)?{kind:"next_action",confidence:.88}:r&&N(e,nu)?{kind:"todo",confidence:.87}:N(e,Vr)&&N(e,su)?{kind:"architecture",confidence:r?.88:.82}:o&&N(e,ou)?{kind:"fix",confidence:.8}:r&&N(e,iu)&&N(e,au)?{kind:"context",confidence:.79}:null}function pu(e,t,n){let r=t==="user"||n.type==="user_prompt",o=t==="assistant"||n.type==="assistant_message",s=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:s,testVerified:i,crossSessionConfirmations:1,assistantDerived:o}}function mu(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":case"next_action":return"todo";case"fix":case"context":return"code"}}function gu(e,t,n){return e==="rule"&&N(n,Gr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Br(t,n)}function Yr(e,t){let n=[],r=new Set,o=new Map;for(let s of t){let i=typeof s.data.messageId=="string"?s.data.messageId:void 0,a=Jr(s);i&&a&&o.set(i,a)}for(let s of t){let i=Jr(s),a=typeof s.data.messageId=="string"?s.data.messageId:void 0;!i&&a&&(i=o.get(a)??"");for(let c of du(s)){let u=fu(c,i,s);if(!u||u.confidence<.75)continue;let p=mu(u.kind),l=uu(c),f=w([e.projectId,u.kind,l].join("|"));if(r.has(f))continue;r.add(f);let d=s.provenance.sourcePath?[s.provenance.sourcePath]:[],m=s.sourceEventId?[s.sourceEventId]:[];n.push({version:1,fingerprint:f,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:p,content:c,confidence:u.confidence,importance:gu(u.kind,p,c),evidence:pu(u.kind,i,s),tags:[p],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[s.id],sourceEventIds:m,sourcePaths:d,firstSequence:s.sequence,lastSequence:s.sequence},createdAt:s.timestamp})}}return n}import{createHash as yu}from"node:crypto";var hu=["project-knowledge","implementation","continuation","session-context"],ku={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Qt(e){return yu("sha256").update(e).digest("hex")}function ut(e,t){return`${e}:${Qt(t).slice(0,24)}`}function Su(e){try{return Qt(JSON.stringify(e))}catch{return Qt(String(e))}}function te(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function Xr(e,t=420){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-1)).trimEnd()}\u2026`}function vu(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function Qr(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function wu(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,5).map(t=>Xr(t.content)).join(" | ")}function bu(e){return e.slice().sort((t,n)=>n.importanceScore-t.importanceScore||n.confidence-t.confidence||t.id.localeCompare(n.id)).slice(0,6).map(t=>Xr(t.content)).join(`
|
|
115
|
+
`)}function Zr(e,t){let n=e.slice().sort((f,d)=>f.sequence-d.sequence||f.timestamp.localeCompare(d.timestamp)||f.id.localeCompare(d.id)),r=n.map(f=>({id:ut("raw",[f.projectId,f.agent,f.nativeSessionId,f.id,String(f.sequence)].join("|")),level:"raw",eventId:f.id,sourceEventId:f.sourceEventId,sequence:f.sequence,type:f.type,role:f.role,timestamp:f.timestamp,sourcePath:f.provenance.sourcePath,payloadDigest:Su(f.data)})),o=new Map,s=new Map;n.forEach((f,d)=>{let m=r[d];m&&(o.set(f.id,m.id),f.sourceEventId&&s.set(f.sourceEventId,m.id))});let i=t.map(f=>{let d=te([...f.provenance.eventIds.map(m=>o.get(m)),...f.provenance.sourceEventIds.map(m=>s.get(m))]);return{id:ut("fact",f.fingerprint),level:"fact",fingerprint:f.fingerprint,kind:f.kind,type:f.type,content:f.content,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,confidence:f.confidence,tags:te([...f.tags,"level:fact",`class:${f.knowledgeClass}`,`kind:${f.kind}`]),rawIds:d,sourcePaths:te(f.provenance.sourcePaths)}}),a=new Map;for(let f of i){let d=vu(f.kind),m=a.get(d)??[];m.push(f),a.set(d,m)}let c=[];for(let f of hu){let d=a.get(f);if(!d?.length)continue;let m=d.slice().sort((g,h)=>h.importanceScore-g.importanceScore||h.confidence-g.confidence||g.id.localeCompare(h.id)),k=m.map(g=>g.id);c.push({id:ut("scene",`${f}|${k.join("|")}`),level:"scene",kind:f,title:ku[f],summary:wu(m),factIds:k,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:Qr(m.map(g=>g.confidence)),tags:te(["level:scene",`scene:${f}`,...m.flatMap(g=>g.tags)]),sourcePaths:te(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(f=>[f.id,f])),p=[];for(let f of c){let m=f.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(m.length===0)continue;let k=m.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",g=bu(m);p.push({id:ut("knowledge",`${f.id}|${k}|${m.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:k,title:f.title,content:g,sceneIds:[f.id],factIds:m.map(h=>h.id),importanceScore:Math.max(...m.map(h=>h.importanceScore)),confidence:Qr(m.map(h=>h.confidence)),tags:te(["level:knowledge",`class:${k}`,`scene:${f.kind}`,...m.flatMap(h=>h.tags)]),sourcePaths:te(m.flatMap(h=>h.sourcePaths))})}let l=[];for(let f of i)for(let d of f.rawIds)l.push({from:d,to:f.id,type:"supports"});for(let f of c)for(let d of f.factIds)l.push({from:d,to:f.id,type:"belongs_to"});for(let f of p)for(let d of f.sceneIds)l.push({from:d,to:f.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:p,links:l,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:p.length,links:l.length}}}function ne(){let e=We(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",o=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),s=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:o,sessionSummaryMaxTokens:s,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function eo(e){return(e||ne()).rawTranscript}function to(e){return(e||ne()).durableMemoryMaxItemsPerSession}function no(e){return(e||ne()).sessionSummaryMaxTokens}function ro(e){return(e||ne()).archiveRemote}var oo=new V;function so(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(oo.sanitizeValue(r))}catch{}let n=oo.sanitize(e).text;return n=n.replace(/("(?:api[_-]?key|token|secret|password|cookie|authorization)"\s*:\s*)"[^"]*"/gi,'$1"[REDACTED]"').replace(/('(?:api[_-]?key|token|secret|password|cookie|authorization)'\s*:\s*)'[^']*'/gi,"$1'[REDACTED]'").replace(/\b(api[_-]?key|token|secret|password|cookie|authorization)\b\s*[:=]\s*[^\s,;]+/gi,"$1=[REDACTED]").replace(/\bbearer\s+[A-Za-z0-9._~+/=-]+/gi,"Bearer [REDACTED]"),n}function xu(e,t){let n=e.toLowerCase(),r=.5,o=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of o)n.includes(i)&&(r+=.15);t==="rule"||t==="architecture"||t==="blocker"?r+=.2:t==="decision"||t==="deploy"?r+=.15:(t==="fix"||t==="next_action")&&(r+=.1),e.length<20?r-=.3:e.length>500&&(r-=.1);let s=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of s)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function ju(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
|
|
116
|
+
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let p=u.toLowerCase().replace(/\s+/g," ");if(r.has(p))continue;r.add(p);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 f=xu(u,l);if(f<.3)continue;let d=so(u);n.push({category:l,text:d,importance:f,sourceSessionId:t})}}let o=ne(),s=to(o);return n.sort((i,a)=>a.importance-i.importance).slice(0,s)}function Mu(e){let t=ne(),n=no(t),s=e.join(`
|
|
117
117
|
|
|
118
118
|
`).split(`
|
|
119
|
-
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>
|
|
120
|
-
`);return
|
|
119
|
+
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>so(i)).join(`
|
|
120
|
+
`);return it(s,n)}function lt(e,t){let r=(Array.isArray(e)?e:e.split(`
|
|
121
121
|
|
|
122
|
-
`).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),
|
|
123
|
-
`,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),
|
|
124
|
-
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||
|
|
122
|
+
`).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),o=ju(r,t),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),p=o.filter(d=>d.category==="next_action").map(d=>d.text),l=o.filter(d=>d.category==="deploy").map(d=>d.text);return{summary:Mu(r),decisions:s,projectRules:i,filesChanged:a,bugsFixed:c,commands:l,blockers:u,nextActions:p,durableFacts:o}}function U(e){let t=new Set,n=[];for(let r of e){let o=r?.replace(/\s+/g," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function Au(e){let t=new Map;for(let n of e){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,o=t.get(r);(!o||n.sequence>o.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Iu(e){let t=e.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of t)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function Cu(e){let t=Ut(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:Iu(e.content),tags:U([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function Pu(e){return e.map(t=>{try{return JSON.stringify({type:t.type,role:t.role,data:t.data,provenance:{sourcePath:t.provenance.sourcePath,files:t.provenance.files}})}catch{return""}}).filter(Boolean)}function Eu(e,t,n){let r=lt(Pu(t),e.nativeSessionId),o=n.filter(u=>u.kind==="todo"||u.kind==="next_action").map(u=>u.content),s=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=U([...o,...r.nextActions]),c=U([...r.nextActions,...o]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:U(r.decisions),files:U([...r.filesChanged,...s]),todos:a,completed:U(r.bugsFixed),blockers:U(r.blockers),nextActions:c,architecture:U(i)}}}function dt(e,t){let n=Au(t),r=Yr(e,n).map(Cu),o=r.filter(p=>Ut(p).persist).sort((p,l)=>l.importanceScore-p.importanceScore),{summary:s,state:i}=Eu(e,n,o),a=o.map(p=>({fingerprint:p.fingerprint,kind:p.kind,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,content:p.content,terms:p.retrievalTerms})),c=Zr(n,o),u=p=>r.filter(l=>l.knowledgeClass===p).length;return{version:2,normalizedEvents:n,summary:s,state:i,candidates:o,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:o.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}function ao(e){return Xt(e.rootPath,".toolnet","memory","checkpoints")}function co(e){return Xt(ao(e),"latest.json")}function Ru(e){let t=co(e);if(!io(t))return null;try{let n=JSON.parse(Ou(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Nu(e){return["rule","architecture","decision","fix"].includes(e)}function _u(e,t){return t.length===0?[]:dt(e,t).candidates.filter(r=>Nu(r.kind)&&r.knowledgeClass!=="transient"&&r.importanceScore>=.65).map(r=>({fingerprint:r.fingerprint,kind:r.kind,content:r.content,knowledgeClass:r.knowledgeClass,importanceScore:r.importanceScore,confidence:r.confidence,createdAt:r.createdAt,agent:e.agent,nativeSessionId:e.nativeSessionId}))}function $u(e,t){let n=new Map;for(let r of[...e,...t]){let o=n.get(r.fingerprint);(!o||r.importanceScore>o.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,o)=>o.importanceScore-r.importanceScore||o.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Fu(e){return{request:e.currentRequest,activity:e.currentActivity,goal:e.goal,phase:e.currentPhase?{title:e.currentPhase.title,status:e.currentPhase.status}:void 0,task:e.currentTask?{title:e.currentTask.title,status:e.currentTask.status}:void 0,phases:e.phases.map(t=>({title:t.title,status:t.status})),tasks:e.tasks.map(t=>({title:t.title,status:t.status})),activeFiles:e.activeFiles??[],modifiedFiles:e.modifiedFiles??[],createdFiles:e.createdFiles??[],deletedFiles:e.deletedFiles??[],checks:e.checks??[],blockers:e.blockers,decisions:e.decisions,nextActions:e.nextActions}}function uo(e,t,n,r){let o=Ru(e),s=$u(o?.durableFacts??[],_u(t,n)),i=n.at(-1)?.sequence??o?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),p=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l={work:Fu(r),durableFacts:s.map(g=>g.fingerprint).sort()},f=w(JSON.stringify(l)).slice(0,32),d={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:p},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:f},m=ao(e);Tu(m,{recursive:!0,mode:448});let k=Xt(m,`${f}.json`);return io(k)||T(k,d),T(co(e),d),d}import{existsSync as Ku}from"node:fs";import{dirname as Lu,join as Wu,parse as Du,resolve as zu}from"node:path";function lo(e){for(let t of e){let n=zu(t),r=Du(n).root;for(;;){if(Ku(Wu(n,".toolnet","project.json")))return new Ve().detect(n);if(n===r)break;let o=Lu(n);if(o===n)break;n=o}}return null}import{homedir as ps}from"node:os";import{join as Ad,resolve as Id}from"node:path";import{join as qu}from"node:path";function fo(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),o=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${o}`;let s=r.slice(0,100);return s===n&&n.length<=100?s:`${s.slice(0,85)}--${o}`}function po(e,t,n){let r=t.trim(),o=n.trim();if(!r)throw new Error("Session agent is required");if(!o)throw new Error("Native session ID is required");let s=fo(r.toLowerCase(),"agent"),i=fo(o,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:o,sessionKey:`${r}:${o}`,remotePrefix:["projects",e.id,"runtime","sources",s,i].join("/"),localDirectory:qu(e.rootPath,".toolnet","runtime","sources",s,i)}}function mo(e){return String(e).padStart(12,"0")}var ft=class{constructor(t,n=100,r=512*1024){this.storage=t;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(t){let n=await this.storage.getText(t);return n?JSON.parse(n):null}async putJson(t,n){await this.storage.put(t,JSON.stringify(n,null,2)+`
|
|
123
|
+
`,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),o=[],s=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(o.push({key:i.key,start:c,end:u}),s=Math.max(s,u))}return o.sort((i,a)=>i.start-a.start),{chunks:o,maxSequence:s}}split(t){let n=[],r=[],o=0;for(let s of t){let i=Buffer.byteLength(JSON.stringify(s)+`
|
|
124
|
+
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||o+i>this.maxChunkBytes)&&(n.push(r),r=[],o=0),r.push(s),o+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,o={}){let s=await this.loadManifest(t),i=await this.scan(t),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let h=g[0],v=g[g.length-1],x=g.map(R=>JSON.stringify(R)).join(`
|
|
125
125
|
`)+`
|
|
126
|
-
`,O=w(x).slice(0,16),
|
|
127
|
-
`,null,"utf8"),
|
|
128
|
-
`,null,"utf8"),
|
|
126
|
+
`,O=w(x).slice(0,16),P=[t.remotePrefix,"events",`${mo(h.sequence)}-${mo(v.sequence)}-${O}.jsonl`].join("/");await this.storage.exists(P)||await this.storage.put(P,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(t),p=n[n.length-1],l=s?.status??"active";p?.type==="session_end"||p?.type==="session_idle"?l="idle":p?.type==="error"?l="error":n.length>0&&(l="active");let f=new Date().toISOString(),d=n[0],m={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:l,createdAt:s?.createdAt??d?.timestamp??f,updatedAt:p?.timestamp??f,firstEventAt:s?.firstEventAt??d?.timestamp,lastEventAt:p?.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 k={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:f};return await this.putJson(`${t.remotePrefix}/cursor.json`,k),await this.putJson(`${t.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:l}}};import{closeSync as Ce,existsSync as ht,fsyncSync as an,mkdirSync as il,openSync as Pe,readFileSync as Po,readSync as al,rmSync as Ao,statSync as on,truncateSync as cl,writeSync as ul}from"node:fs";import{join as sn}from"node:path";var Bu=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),Vu=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Hu(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Ju(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(Vu.has(r))return n}}return null}function Zt(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(s=>Zt(s,t+1));if(!e||typeof e!="object")return e;let n=e,r=Ju(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let o={};for(let[s,i]of Object.entries(n))Bu.has(Hu(s))||(o[s]=Zt(i,t+1));return o}function Gu(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function re(e){return e?.trim()||void 0}function go(e,t={}){let n={...e.provenance??{}},r=re(e.source)??re(t.source)??re(n.source);return{...e,timestamp:Gu(e.timestamp),source:r,turnId:re(e.turnId)??re(t.turnId),cwd:re(e.cwd)??re(t.cwd),data:Zt(e.data??{}),provenance:n}}import{randomUUID as en}from"node:crypto";import{closeSync as le,existsSync as de,fsyncSync as Ae,mkdirSync as tn,openSync as Ie,readFileSync as nn,readdirSync as Uu,renameSync as Yu,rmSync as pt,statSync as Qu,writeSync as mt}from"node:fs";import{join as Y}from"node:path";var Xu=12e4,Zu=80,el="reconcile-required";function tl(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function fe(e){return Y(e,".toolnet","journal")}function ko(e){return Y(fe(e),"events.jsonl")}function gt(e){return Y(fe(e),el)}function nl(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function So(e){if(!de(e))return null;try{let t=JSON.parse(nn(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function rl(e){if(!de(e))return!1;let t=0;try{t=Date.now()-Qu(e).mtimeMs}catch{return!1}if(t<=Xu)return!1;let n=So(e);return n?!nl(n.pid):!0}function ol(e){if(!rl(e))return!1;try{return pt(e,{force:!0}),!0}catch{return!1}}function vo(e){for(let t=0;t<Zu;t+=1){let n=en();try{let r=Ie(e,"wx",384),o={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return mt(r,`${JSON.stringify(o)}
|
|
127
|
+
`,null,"utf8"),Ae(r),{fd:r,token:n}}catch(s){throw le(r),pt(e,{force:!0}),s}}catch(r){if(r?.code!=="EEXIST")throw r;if(ol(e))continue;tl(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function wo(e,t){le(t.fd),So(e)?.token===t.token&&pt(e,{force:!0})}function yo(e){if(!de(e))return[];let t="";try{t=nn(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=r.trim();if(o)try{let s=JSON.parse(o);if(s.version!==1||typeof s.id!="string"||s.id.length===0||typeof s.projectId!="string"||s.projectId.length===0)continue;n.push(s)}catch{}}return n}function bo(e){if(!de(e))return[];let t=[];for(let n of Uu(e,{withFileTypes:!0})){let r=Y(e,n.name);if(n.isDirectory()){t.push(...bo(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function yt(e){let t=null;try{t=Ie(e,"r"),Ae(t)}catch{}finally{if(t===null)return;le(t)}}function ho(e){let t=gt(e);if(!de(t))return null;try{return nn(t,"utf8").trim()||null}catch{return null}}function rn(e){let t=fe(e);tn(t,{recursive:!0,mode:448});let n=gt(e),r=[en(),new Date().toISOString()].join("|"),o=Ie(n,"w",384);try{mt(o,`${r}
|
|
128
|
+
`,null,"utf8"),Ae(o)}finally{le(o)}yt(t)}function sl(e,t,n){let r=Y(e,`.events.jsonl.tmp-${process.pid}-${en()}`),o=Ie(r,"w",384);try{let s=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
|
|
129
129
|
`)}
|
|
130
|
-
`;
|
|
130
|
+
`;s&&mt(o,s,null,"utf8"),Ae(o)}finally{le(o)}Yu(r,t),yt(e)}function xo(e){let t=fe(e),n=ko(e),r=Y(e,".toolnet","runtime","sources"),o=ho(e),s=bo(r),i=[],a=new Set;for(let l of yo(n))a.has(l.id)||(a.add(l.id),i.push(l));let c=i.length,u=[];for(let l of s)for(let f of yo(l))a.has(f.id)||(a.add(f.id),u.push(f));u.sort((l,f)=>{let d=l.timestamp.localeCompare(f.timestamp);return d!==0?d:l.id.localeCompare(f.id)}),i.push(...u),sl(t,n,i);let p=ho(e);return o&&p===o&&(pt(gt(e),{force:!0}),yt(t)),{filesScanned:s.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function jo(e){let t=fe(e);tn(t,{recursive:!0,mode:448});let n=Y(t,"journal.lock"),r=vo(n);try{return xo(e)}finally{wo(n,r)}}function Mo(e,t){if(t.length===0)return;let n=fe(e);tn(n,{recursive:!0,mode:448});let r=ko(e),o=Y(n,"journal.lock"),s=vo(o);try{if(de(gt(e))){xo(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
|
|
131
131
|
`)}
|
|
132
|
-
`,a=
|
|
133
|
-
`),
|
|
132
|
+
`,a=Ie(r,"a",384);try{mt(a,i,null,"utf8"),Ae(a)}finally{le(a)}yt(n)}finally{wo(o,s)}}var ll=12e4,dl=80,Io=2e3;function fl(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Eo(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let o=ul(e,n,r,n.length-r);if(o<=0)throw new Error("Unable to write session WAL");r+=o}}function cn(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function pl(e){if(!ht(e))return[];let t="";try{t=Po(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let o=cn(r);o&&n.push(o)}return n}function Co(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function ml(e){if(!ht(e))return!1;let t;try{t=Po(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,o=t.subarray(r).toString("utf8").trim();if(cn(o)){let i=Pe(e,"a");try{Eo(i,`
|
|
133
|
+
`),an(i)}finally{Ce(i)}return!0}cl(e,r);let s=Pe(e,"a");try{an(s)}finally{Ce(s)}return!0}function gl(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var kt=class{constructor(t,n={}){this.identity=t;this.eventContext=n;il(t.localDirectory,{recursive:!0}),this.eventsFile=sn(t.localDirectory,"events.jsonl"),this.stateFile=sn(t.localDirectory,"state.json"),this.lockFile=sn(t.localDirectory,"journal.lock")}identity;eventContext;eventsFile;stateFile;lockFile;initialState(){let t=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:t,updatedAt:t,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return Ln(this.stateFile)??this.initialState()}recoverStateUnsafe(){ml(this.eventsFile);let t=this.loadStateUnsafe(),n=pl(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let l of n)l.sequence<=r.sequence||(r=l);let o=n.slice(-Io).map(l=>l.id),s=ht(this.eventsFile)?on(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,s),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!gl(t.recentEventIds,o)||t.lastLocalEventAt!==r.timestamp))return t;let p={...t,status:Co(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:o};if(this.saveStateUnsafe(p),!c)return p;try{rn(this.identity.projectRoot)}catch{return p}try{jo(this.identity.projectRoot)}catch{}return p}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){T(this.stateFile,t)}acquireLock(){for(let t=0;t<dl;t+=1)try{return Pe(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-on(this.lockFile).mtimeMs>ll){Ao(this.lockFile,{force:!0});continue}}catch{}fl(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Ce(n),Ao(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),o=n.lastSequence,s=[];for(let l of t){let f=go(l,this.eventContext),d=f.timestamp??new Date().toISOString(),m=f.data??{},k=f.provenance?.rawDigest??w(Kn(m)),g=Se(m),h=f.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,f.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,o+1,f.type,d,k].join("|"),v=w(h).slice(0,32);if(r.has(v))continue;o+=1;let x={version:1,id:v,sequence:o,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:f.type,timestamp:d,source:f.source??f.provenance?.source??this.identity.agent,data:g,provenance:{...f.provenance,rawDigest:k}};f.role!==void 0&&(x.role=f.role),f.turnId!==void 0&&(x.turnId=f.turnId),f.cwd!==void 0&&(x.cwd=f.cwd),f.sourceEventId!==void 0&&(x.sourceEventId=f.sourceEventId),f.sourceSequence!==void 0&&(x.sourceSequence=f.sourceSequence),s.push(x),r.add(v)}if(s.length===0)return[];let i=s.map(l=>JSON.stringify(l)).join(`
|
|
134
134
|
`)+`
|
|
135
|
-
`,a=Ae(this.eventsFile,"a",384);try{Ss(a,i),en(a)}finally{Me(a)}try{ms(this.identity.projectRoot,o)}catch{try{Qt(this.identity.projectRoot)}catch{}}let c=o[o.length-1],u=hs(c),f=Array.from(r).slice(-ys);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!pt(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Xt(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=Ae(this.eventsFile,"r");try{Bu(i,o,0,s,r)}finally{Me(i)}let a=[];for(let c of o.toString("utf8").split(/\r?\n/)){let u=tn(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as Bl,existsSync as Vl,openSync as Hl,readSync as Jl,statSync as Gl}from"node:fs";import{createHash as il}from"node:crypto";import{existsSync as al,readdirSync as cl,readFileSync as ul}from"node:fs";import{basename as ll,join as $s}from"node:path";import{randomUUID as bs}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Ie(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function re(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new A("Invalid Wiki slug",400);return t}function vs(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(re(r))}return Ie(t)}function Zu(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function ws(e){return{id:`revision-${bs()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function ne(e){return structuredClone(e)}var gt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:Ie(t.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:t.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return ne([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=re(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new A(`Wiki page not found: ${t}`,404);return ne(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new A("Wiki title is required",400);let o=re(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new A(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${bs()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:Ie(t.tags??[]),links:vs(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(ws(a)),ne(a)})}async updatePage(t,n){return this.mutate(r=>{let s=re(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new A(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new A("Wiki title is required",400);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=vs(o.content)),n.tags!==void 0&&(o.tags=Ie(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(ws(o)),ne(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return ne(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return ne(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(t,n=10){let r=await this.ensureState(),s=Ie(Zu(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),f=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),p=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),p.some(k=>k===m)?d+=5:p.some(k=>k.includes(m))&&(d+=3),f.includes(m)&&(d+=2),l.includes(m)&&(d+=1);d>0&&i.push({page:ne(a),score:d})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var xs="wiki/state.v1.json";function el(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function tl(e,t){let n=JSON.parse(e);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==t.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var yt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(xs);if(!t){let n=el(this.project);return await this.save(n),n}return tl(t,this.project)}async save(t){await this.storage.put(xs,JSON.stringify(t,null,2),"application/json")}};import{createHash as nl,randomUUID as js}from"node:crypto";var Ms="wiki/governance.v1.json",Cs="toolnet.knowledge-governance.v1",As=500,Pe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function rl(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function nn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Is(e){return nl("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function sl(e){let t=[e.title,e.summary??"",e.content.slice(0,2e3),...e.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(t)}function ol(e){let t=e.sourceType==="skill"?.96:e.sourceType==="memory"?.94:.88,n=e.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(t+=.03),e.content.length>=200&&(t+=.02),e.content.length<80&&(t-=.05),e.title.length<4&&(t-=.05),rl(t)}function Ps(e){let t=new Date().toISOString();return{schema:Cs,version:1,projectId:e,policy:{...Pe},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Ts(e){let t=e.autoApproveThreshold??Pe.autoApproveThreshold,n=e.criticalApproveThreshold??Pe.criticalApproveThreshold,r=e.staleAfterDays??Pe.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new A("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new A("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new A("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var ht=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Ms);if(!t){let n=Ps(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Cs||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Ts(n.policy??Pe)}}catch{let n=Ps(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Ms,JSON.stringify(t,null,2),"application/json")}},kt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,s={}){t.audit.push({id:js(),action:n,principal:r,...s.reviewId?{reviewId:s.reviewId}:{},...s.sourceKey?{sourceKey:s.sourceKey}:{},timestamp:new Date().toISOString(),...s.metadata?{metadata:s.metadata}:{}}),t.audit.length>As&&(t.audit=t.audit.slice(-As))}async mutate(t){let n,r=this.queue.then(async()=>{let s=await this.ensureState();n=await t(s),s.updatedAt=new Date().toISOString(),await this.store.save(s)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=Ts({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(s=>s.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,s)=>s.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),s=ol(t),o=nn(t.title),i=n.filter(f=>f.slug!==t.slug&&nn(f.title)===o&&Is(f.content)!==Is(t.content)).map(f=>f.slug),a=sl(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:js(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new A(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new A("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new A("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new A("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new A(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(f=>{let l=s-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>o}}).filter(f=>f.stale).map(({stale:f,...l})=>l),a=new Map;for(let f of r){let l=nn(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 Fs="wiki/automation.v1.json",Ks="toolnet.wiki-automation.v1",on=8e3,Es=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Te(e){return il("sha256").update(JSON.stringify(e)).digest("hex")}function Ce(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Os(e){return Array.isArray(e)?e:[]}function Ls(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function rn(e){return Array.isArray(e)?e.map(Ls).filter(t=>!!t):[]}function W(e,t){for(let n of t){let r=Ls(e[n]);if(r)return r}}function Ee(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function St(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Es.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>St(i,t+1,n));let s=Ce(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Es.has(c)||o.push(...St(a,t+1,i))}return o}function Rs(e){let n=Ee(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>St(e[s],0,s)));return(n.length>0?n:Ee(St(e))).join(`
|
|
135
|
+
`,a=Pe(this.eventsFile,"a",384);try{Eo(a,i),an(a)}finally{Ce(a)}try{Mo(this.identity.projectRoot,s)}catch{try{rn(this.identity.projectRoot)}catch{}}let c=s[s.length-1],u=Co(c),p=Array.from(r).slice(-Io);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:p}),s})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!ht(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=on(this.eventsFile).size,r=Math.min(t.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let o=n-r,s=Buffer.alloc(o),i=Pe(this.eventsFile,"r");try{al(i,s,0,o,r)}finally{Ce(i)}let a=[];for(let c of s.toString("utf8").split(/\r?\n/)){let u=cn(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),o=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:o,updatedAt:o})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ad,existsSync as cd,openSync as ud,readSync as ld,statSync as dd}from"node:fs";import{createHash as xl}from"node:crypto";import{existsSync as jl,readdirSync as Ml,readFileSync as Al}from"node:fs";import{basename as Il,join as Jo}from"node:path";import{randomUUID as Ro}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function Ee(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function se(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new A("Invalid Wiki slug",400);return t}function To(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(se(r))}return Ee(t)}function yl(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Oo(e){return{id:`revision-${Ro()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function oe(e){return structuredClone(e)}var St=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async summary(){let t=await this.ensureState(),n=new Set(t.pages.flatMap(r=>r.links));return{schema:"toolnet.wiki-summary.v1",projectId:t.projectId,pages:t.pages.length,revisions:t.revisions.length,tags:Ee(t.pages.flatMap(r=>r.tags)).sort((r,o)=>r.localeCompare(o)),links:t.pages.reduce((r,o)=>r+o.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(o=>o.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return oe([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=se(t),o=n.pages.find(s=>s.slug===r||s.id===t);if(!o)throw new A(`Wiki page not found: ${t}`,404);return oe(o)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),o=t.content.trim();if(!r)throw new A("Wiki title is required",400);let s=se(t.slug??r);if(n.pages.some(c=>c.slug===s))throw new A(`Wiki page already exists: ${s}`,409);let i=new Date().toISOString(),a={id:`wiki-${Ro()}`,slug:s,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:o,tags:Ee(t.tags??[]),links:To(o),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Oo(a)),oe(a)})}async updatePage(t,n){return this.mutate(r=>{let o=se(t),s=r.pages.find(i=>i.slug===o||i.id===t);if(!s)throw new A(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new A("Wiki title is required",400);s.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?s.summary=i:delete s.summary}return n.content!==void 0&&(s.content=n.content.trim(),s.links=To(s.content)),n.tags!==void 0&&(s.tags=Ee(n.tags)),s.revision+=1,s.updatedAt=new Date().toISOString(),r.revisions.push(Oo(s)),oe(s)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return oe(r.revisions.filter(o=>o.pageId===n.id).sort((o,s)=>s.revision-o.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return oe(r.pages.filter(o=>o.links.includes(n.slug)).sort((o,s)=>o.title.localeCompare(s.title)))}async search(t,n=10){let r=await this.ensureState(),o=Ee(yl(t));if(o.length===0)return[];let s=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),p=a.summary?.toLowerCase()??"",l=a.content.toLowerCase(),f=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),f.some(k=>k===m)?d+=5:f.some(k=>k.includes(m))&&(d+=3),p.includes(m)&&(d+=2),l.includes(m)&&(d+=1);d>0&&i.push({page:oe(a),score:d})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,s)}};var No="wiki/state.v1.json";function hl(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function kl(e,t){let n=JSON.parse(e);if(n.schema!=="toolnet.wiki.v1"||n.version!==1||n.projectId!==t.id||!Array.isArray(n.pages)||!Array.isArray(n.revisions))throw new Error("Invalid ToolNet Wiki state");return n}var vt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(No);if(!t){let n=hl(this.project);return await this.save(n),n}return kl(t,this.project)}async save(t){await this.storage.put(No,JSON.stringify(t,null,2),"application/json")}};import{createHash as Sl,randomUUID as _o}from"node:crypto";var $o="wiki/governance.v1.json",Wo="toolnet.knowledge-governance.v1",Fo=500,Te={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function vl(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function un(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Ko(e){return Sl("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function wl(e){let t=[e.title,e.summary??"",e.content.slice(0,2e3),...e.tags].join(" ").toLowerCase();return/\b(?:architecture|security|authentication|authorization|auth|database|production|deploy|deployment|payment|billing|permission|permissions|acl|credential|secret|migration)\b/u.test(t)}function bl(e){let t=e.sourceType==="skill"?.96:e.sourceType==="memory"?.94:.88,n=e.tags.map(r=>r.toLowerCase());return(n.includes("permanent")||n.includes("task"))&&(t+=.03),e.content.length>=200&&(t+=.02),e.content.length<80&&(t-=.05),e.title.length<4&&(t-=.05),vl(t)}function Lo(e){let t=new Date().toISOString();return{schema:Wo,version:1,projectId:e,policy:{...Te},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Do(e){let t=e.autoApproveThreshold??Te.autoApproveThreshold,n=e.criticalApproveThreshold??Te.criticalApproveThreshold,r=e.staleAfterDays??Te.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new A("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new A("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new A("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var wt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText($o);if(!t){let n=Lo(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Wo||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Do(n.policy??Te)}}catch{let n=Lo(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put($o,JSON.stringify(t,null,2),"application/json")}},bt=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}audit(t,n,r,o={}){t.audit.push({id:_o(),action:n,principal:r,...o.reviewId?{reviewId:o.reviewId}:{},...o.sourceKey?{sourceKey:o.sourceKey}:{},timestamp:new Date().toISOString(),...o.metadata?{metadata:o.metadata}:{}}),t.audit.length>Fo&&(t.audit=t.audit.slice(-Fo))}async mutate(t){let n,r=this.queue.then(async()=>{let o=await this.ensureState();n=await t(o),o.updatedAt=new Date().toISOString(),await this.store.save(o)});return this.queue=r.then(()=>{},()=>{}),await r,n}async policy(){return{...(await this.ensureState()).policy}}async setPolicy(t,n){return this.mutate(r=>(r.policy=Do({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(o=>o.status===r).length;return{schema:"toolnet.knowledge-governance-summary.v1",projectId:t.projectId,pending:n("pending"),approved:n("approved"),rejected:n("rejected"),superseded:n("superseded"),criticalPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="critical").length,conflictPending:t.reviews.filter(r=>r.status==="pending"&&r.risk==="conflict").length,auditEvents:t.audit.length,policy:{...t.policy},updatedAt:t.updatedAt}}async listReviews(t){let n=await this.ensureState();return structuredClone(n.reviews.filter(r=>!t||r.status===t).sort((r,o)=>o.updatedAt.localeCompare(r.updatedAt)))}async auditLog(t=100){let n=await this.ensureState(),r=Math.max(1,Math.min(500,Math.floor(t)));return structuredClone(n.audit.slice(-r).reverse())}async assess(t,n){let r=await this.ensureState(),o=bl(t),s=un(t.title),i=n.filter(p=>p.slug!==t.slug&&un(p.title)===s&&Ko(p.content)!==Ko(t.content)).map(p=>p.slug),a=wl(t),c=[];o<r.policy.autoApproveThreshold&&c.push(`confidence:${o.toFixed(2)}`),a&&o<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:o,risk:u,requiresReview:i.length>0||o<r.policy.autoApproveThreshold||a&&o<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(o=>{let s=o.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(s?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(s)};if(s?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(s)};if(!r.requiresReview)return this.audit(o,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(s?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(s)};let i=new Date().toISOString(),a={id:_o(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return o.reviews.push(a),this.audit(o,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let o=r.reviews.find(s=>s.sourceKey===t&&s.digest===n&&s.status==="approved");o&&(o.appliedAt=new Date().toISOString(),o.updatedAt=o.appliedAt,this.audit(r,"knowledge:applied",o.reviewedBy??"system",{reviewId:o.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async o=>{let s=o.reviews.find(u=>u.id===t);if(!s)throw new A(`Governance review not found: ${t}`,404);if(s.status!=="pending")throw new A("Governance review is already resolved",409);let i=new Date().toISOString();if(s.reviewedAt=i,s.reviewedBy=n.principal,s.updatedAt=i,n.note?.trim()&&(s.reviewNote=n.note.trim()),n.action==="reject")return s.status="rejected",this.audit(o,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s);if(n.action==="supersede")return s.status="superseded",n.targetReviewId&&(s.supersededBy=n.targetReviewId),this.audit(o,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(s);if(n.action==="merge"){if(!n.targetReviewId)throw new A("targetReviewId is required for merge",400);let u=o.reviews.find(p=>p.id===n.targetReviewId);if(!u)throw new A("Merge target review not found",404);return s.status="superseded",s.mergedInto=u.id,this.audit(o,"knowledge:merged",n.principal,{reviewId:t,sourceKey:s.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(s)}s.status="approved";let c=(await r.listPages()).find(u=>u.slug===s.slug);if(c&&!c.tags.includes(s.marker))throw new A(`Wiki page '${s.slug}' is manually managed`,409);return c?await r.updatePage(s.slug,{title:s.title,summary:s.summary??"",content:s.content,tags:s.tags}):await r.createPage({slug:s.slug,title:s.title,...s.summary?{summary:s.summary}:{},content:s.content,tags:s.tags}),s.appliedAt=i,this.audit(o,"knowledge:approved",n.principal,{reviewId:t,sourceKey:s.sourceKey}),structuredClone(s)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),o=Date.now(),s=n.policy.staleAfterDays*864e5,i=r.map(p=>{let l=o-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>s}}).filter(p=>p.stale).map(({stale:p,...l})=>l),a=new Map;for(let p of r){let l=un(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 Go="wiki/automation.v1.json",Uo="toolnet.wiki-automation.v1",fn=8e3,zo=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Re(e){return xl("sha256").update(JSON.stringify(e)).digest("hex")}function Oe(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function qo(e){return Array.isArray(e)?e:[]}function Yo(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function ln(e){return Array.isArray(e)?e.map(Yo).filter(t=>!!t):[]}function W(e,t){for(let n of t){let r=Yo(e[n]);if(r)return r}}function Ne(e){let t=new Set,n=[];for(let r of e){let o=r.replace(/\s+/gu," ").trim();if(!o)continue;let s=o.normalize("NFKC").toLowerCase();t.has(s)||(t.add(s),n.push(o))}return n}function xt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(zo.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>xt(i,t+1,n));let o=Oe(e);if(!o)return[];let s=[];for(let[i,a]of Object.entries(o)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();zo.has(c)||s.push(...xt(a,t+1,i))}return s}function Bo(e){let n=Ne(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(o=>xt(e[o],0,o)));return(n.length>0?n:Ne(xt(e))).join(`
|
|
136
136
|
|
|
137
|
-
`).slice(0,
|
|
137
|
+
`).slice(0,fn)}function Vo(e,t){return W(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Ho(e,t){return W(e,["title","name","topic","label","task","kind","type"])??t}function Cl(e){return(W(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Pl(e){return(W(e,["kind","sceneKind","type"])??"").toLowerCase()}function El(e){let t=Oe(e);if(!t)return[];let n=[],r=qo(t.knowledge);for(let[s,i]of r.entries()){let a=Oe(i);if(!a)continue;let c=Cl(a);if(c==="session"||c==="transient")continue;let u=Bo(a);if(u.length<20)continue;let p=Vo(a,Re(a).slice(0,16)),l=Ho(a,`Durable Memory ${s+1}`);n.push({sourceKey:`memory:${p}`,sourceType:"memory",title:l,summary:W(a,["summary","description"]),content:u,tags:Ne(["toolnet","auto","memory",...c?[c]:[]])})}let o=qo(t.scenes);for(let[s,i]of o.entries()){let a=Oe(i);if(!a)continue;let c=Pl(a);if(c==="session-context")continue;let u=Bo(a);if(u.length<20)continue;let p=Vo(a,Re(a).slice(0,16)),l=Ho(a,`Knowledge Scene ${s+1}`);n.push({sourceKey:`scene:${p}`,sourceType:"scene",title:l,summary:W(a,["summary","description"]),content:u,tags:Ne(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Tl(e){return Jo(e,".toolnet","memory","skills")}function Ol(e){let t=Tl(e);if(!jl(t))return{candidates:[],failed:0};let n=[],r=0,o=Ml(t).filter(s=>s.endsWith(".json")).sort();for(let s of o)try{let i=JSON.parse(Al(Jo(t,s),"utf8")),a=Oe(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=W(a,["id","fingerprint"])??Il(s,".json"),u=W(a,["task"])??"",p=W(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,l=W(a,["summary"])??void 0,f=ln(a.steps),d=ln(a.verification),m=ln(a.files),k=[];u&&k.push(`## Task
|
|
138
138
|
${u}`),l&&k.push(`## Summary
|
|
139
|
-
${l}`),
|
|
140
|
-
${
|
|
139
|
+
${l}`),f.length>0&&k.push(`## Procedure
|
|
140
|
+
${f.map((h,v)=>`${v+1}. ${h}`).join(`
|
|
141
141
|
`)}`),d.length>0&&k.push(`## Verification
|
|
142
142
|
${d.map(h=>`- ${h}`).join(`
|
|
143
143
|
`)}`),m.length>0&&k.push(`## Relevant Files
|
|
144
144
|
${m.map(h=>`- \`${h}\``).join(`
|
|
145
145
|
`)}`);let g=k.join(`
|
|
146
146
|
|
|
147
|
-
`).slice(0,
|
|
148
|
-
`).slice(0,
|
|
149
|
-
`,{encoding:"utf8",mode:384}),
|
|
150
|
-
`,c=w(r.map(l=>l.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),
|
|
151
|
-
`,"application/json"),u}};function
|
|
147
|
+
`).slice(0,fn);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:p,summary:l,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function dn(e){let t=new Date().toISOString();return{schema:Uo,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Rl(e,t){let n=await e.getText(Go);if(!n)return dn(t);try{let r=JSON.parse(n);return r.schema!==Uo||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?dn(t):r}catch{return dn(t)}}async function Nl(e,t){await e.put(Go,JSON.stringify(t,null,2),"application/json")}function _l(e){return`toolnet-auto-${Re(e).slice(0,12)}`}function $l(e){let t=se(e.title).slice(0,72),n=Re(e.sourceKey).slice(0,10);return se(`auto-${e.sourceType}-${t}-${n}`)}function Fl(e){return[`> Auto-generated by ToolNet Knowledge Automation from ${e.sourceType==="skill"?"reusable Skill Memory":e.sourceType==="scene"?"semantic memory scene":"durable memory"}.`,"",e.content].join(`
|
|
148
|
+
`).slice(0,fn)}function Kl(e){return Re({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Ll(e,t){return e.tags.includes(t)}async function Qo(e){let t=El(e.hierarchy),n=Ol(e.project.rootPath),r=new Map;for(let d of[...t,...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:t.length+n.candidates.length,eligible:o.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new St(new vt(e.storage,e.project));await i.initialize();let a=new bt(new wt(e.storage,e.project));await a.initialize();let c=await Rl(e.storage,e.project.id),u=await i.listPages(),p=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=_l(d.sourceKey),k=Kl(d),g=l.get(d.sourceKey),h=g?.slug??$l(d),v=p.get(h);if(v&&!Ll(v,m)){s.skipped+=1;continue}let x=Ne([...d.tags,m]),O=Fl(d),P=await a.gate({sourceKey:d.sourceKey,sourceType:d.sourceType,slug:h,marker:m,digest:k,title:d.title,...d.summary?{summary:d.summary}:{},content:O,tags:x},[...p.values()]);if(!P.allowed){P.mode==="pending-review"?s.reviewPending+=1:s.skipped+=1;continue}P.mode==="auto-approved"?s.autoApproved+=1:P.mode==="review-approved"&&(s.reviewApproved+=1),v?g?.digest!==k?(v=await i.updatePage(h,{title:d.title,summary:d.summary??"",content:O,tags:x}),p.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:h,action:"unchanged"})):(v=await i.createPage({slug:h,title:d.title,summary:d.summary,content:O,tags:x}),p.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(),j={sourceKey:d.sourceKey,sourceType:d.sourceType,slug:h,digest:k,marker:m,updatedAt:R},b=c.entries.findIndex(D=>D.sourceKey===d.sourceKey);b>=0?c.entries[b]=j:c.entries.push(j),l.set(d.sourceKey,j),await a.markApplied(d.sourceKey,k)}catch(m){if(m instanceof A&&m.statusCode===409){s.skipped+=1;continue}s.failed+=1}let f=new Date().toISOString();return c.updatedAt=f,c.lastRunAt=f,c.entries.sort((d,m)=>d.sourceKey.localeCompare(m.sourceKey)),await Nl(e.storage,c),s}import{createHash as Wl}from"node:crypto";import{chmodSync as Zo,existsSync as Dl,mkdirSync as zl,readFileSync as Ah,readdirSync as Ih,renameSync as ql,statSync as Ch,writeFileSync as Bl}from"node:fs";import{join as es}from"node:path";var Vl="toolnet.skill-memory.v1",Xo=5,Hl=16,Jl=24,Gl=32;function Ul(e){return Wl("sha256").update(e).digest("hex")}function $e(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let o of e){let s=o.replace(/\s+/gu," ").trim();if(!s)continue;let i=s.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(s),r.length>=t))break}return r}function pn(e,t=360){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,Math.max(0,t-1)).trimEnd()+"\u2026"}function Yl(e){return e.replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/giu,"Bearer [REDACTED]").replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gu,"[REDACTED]").replace(/\b(api[_-]?key|token|password|passwd|secret)\b(\s*[:=]\s*)(["']?)[^\s"'`]+/giu,"$1$2[REDACTED]")}function q(e,t=360){return e&&pn(Yl(e),t)||void 0}function Fe(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function ts(e,t){for(let n of t){let r=e[n];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()&&Number.isFinite(Number(r)))return Number(r)}}function ns(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let o=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(o))return!0;if(["false","no","fail","failed","error"].includes(o))return!1}}}function rs(e){let t=e.data??{};if(ns(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=ts(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let o=Fe(t,["status","result","outcome"]);return!!(o&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(o))}function _e(e){let t=e.data??{};if(rs(e))return!1;if(ns(t,["passed","pass","success","succeeded","ok"])===!0||ts(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let o=Fe(t,["status","result","outcome"]);return o&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(o)?!0:e.type==="commit"||e.type==="deploy"}function os(e){let t=e.data??{},n=Fe(t,["path","file","filePath","filename","target"]);if(n)return q(n,260);let r=e.provenance?.files;return q(r?.[0],260)}function mn(e){return q(Fe(e.data??{},["command","cmd","script"]),420)}function pe(e){return q(Fe(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Ql(e){let t=[];for(let n of[...e].sort((r,o)=>r.sequence-o.sequence))if(_e(n)){if(n.type==="test"){let r=pe(n)??mn(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=pe(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=pe(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return $e(t,10)}function Xl(e,t){let n=[];for(let r of[...e].sort((o,s)=>o.sequence-s.sequence))switch(r.type){case"file_write":case"file_edit":{let o=os(r);o&&n.push(`Update ${o}`);break}case"command":{if(rs(r))break;let o=mn(r);o&&n.push(`Run: ${o}`);break}case"test":{if(!_e(r))break;let o=pe(r)??mn(r)??"project tests";n.push(`Verify: ${o}`);break}case"commit":{if(!_e(r))break;let o=pe(r);n.push(o?`Commit: ${o}`:"Commit verified changes");break}case"deploy":{if(!_e(r))break;let o=pe(r);n.push(o?`Deploy: ${o}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let o=q(r,260);o&&n.push(`Update ${o}`)}return $e(n,Hl)}function Zl(e,t){let n=[...t.files];for(let r of e){let o=os(r);o&&n.push(o);for(let s of r.provenance?.files??[]){let i=q(s,260);i&&n.push(i)}}return $e(n,Jl)}function ed(e){return $e(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Gl)}function td(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function ss(e,t,n){if(t.length===0)return[];let r=Ql(t),o=$e(n.completed.map(m=>q(m,280)??""),Xo);if(!(o.length>0||t.some(m=>["test","commit","deploy"].includes(m.type)&&_e(m))))return[];let i=q(n.task,280)??q(n.nextActions[0],280),a=o.length>0?o:i?[i]:[];if(a.length===0)return[];let c=Xl(t,n);if(c.length===0)return[];let u=Zl(t,n),p=ed(t),l=Math.min(...t.map(m=>m.sequence)),f=Math.max(...t.map(m=>m.sequence)),d=td(t);return a.slice(0,Xo).map(m=>{let k=[`Reusable procedure learned from successful task: ${m}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),g=JSON.stringify({projectId:e.projectId,task:m,steps:c,verification:r,files:u}),h=Ul(g);return{schema:Vl,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:pn(`SOP: ${m}`,180),task:m,summary:pn(k.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:l,lastSequence:f,eventIds:p},createdAt:d}})}function nd(e){return es(e.rootPath,".toolnet","memory","skills")}function rd(e){let t=nd(e);return zl(t,{recursive:!0,mode:448}),Zo(t,448),t}function is(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=rd(e),r=0,o=0,s=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=es(n,`${i.id}.json`);if(s.push(a),Dl(a)){o+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Bl(c,JSON.stringify(i,null,2)+`
|
|
149
|
+
`,{encoding:"utf8",mode:384}),ql(c,a),Zo(a,384),r+=1}return{written:r,deduped:o,files:s}}function as(e){return String(e).padStart(12,"0")}function od(e){return`projects/${e.projectId}/memory/learned`}var jt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let o=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
|
|
150
|
+
`,c=w(r.map(l=>l.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),p=[od(t),"batches",`${as(o)}-${as(s)}-${u}-${c}.json`].join("/");return await this.storage.exists(p)||await this.storage.put(p,a,"application/json"),p}};import{createHash as sd}from"node:crypto";function cs(e){return String(e).padStart(12,"0")}function us(e){return sd("sha256").update(e).digest("hex")}function id(e){return`projects/${e.projectId}/memory/hierarchy`}var Mt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let o=Math.min(...n.map(p=>p.sequence)),s=Math.max(...n.map(p=>p.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:o,lastSequence:s,hierarchy:r},a=us([...r.facts.map(p=>p.id),...r.knowledge.map(p=>p.id)].sort().join("|")).slice(0,16),c=us(t.sessionKey).slice(0,12),u=[id(t),"batches",`${cs(o)}-${cs(s)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
|
|
151
|
+
`,"application/json"),u}};function fd(e,t){if(!cd(e))return{events:[],nextOffset:t};let n=dd(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let o=n-r,s=Buffer.alloc(o),i=ud(e,"r");try{ld(i,s,0,o,r)}finally{ad(i)}let a=s.toString("utf8"),c=a.lastIndexOf(`
|
|
152
152
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
153
|
-
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
154
|
-
`);if(u<0)return{events:[],nextOffset:
|
|
153
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var At=class{constructor(t){this.options=t;this.journal=new jt(t.storage),this.hierarchyJournal=new Mt(t.storage)}options;journal;hierarchyJournal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,o=fd(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=ss(this.options.identity,o.events,s.state),p=is(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",p.written),this.options.wal.setSourceCursor("memory.skill.deduped",p.deduped);try{let l=Nr(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 Qo({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}}};function ls(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ye(t,n);if(r.length===0)return{updated:!1,observations:0};let o=cr(e,r);zr(e,o),Lr(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:o});try{uo(e,t,n,o)}catch{}try{pr({project:e,identity:t,state:o,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var It=class{identity;wal;remote;sanitizer=new V;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=po(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new kt(this.identity,t.eventContext),this.remote=new ft(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new At({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Xe({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new ot({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new nt({project:t.project,storage:t.storage,identity:this.identity})}sanitizeEvent(t){let n=t.provenance?{...t.provenance,metadata:this.sanitizer.sanitizeValue(t.provenance.metadata)}:void 0;return{...t,data:this.sanitizer.sanitizeValue(t.data??{}),provenance:n}}checkpointLocal(t){if(t.length!==0)try{ls(this.project,this.identity,t)}catch{}}start(t={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:t,provenance:{source:this.identity.agent}})}record(t){let n=this.wal.append([this.sanitizeEvent(t)]);return this.checkpointLocal(n),n[0]}recordMany(t){let n=this.wal.append(t.map(r=>this.sanitizeEvent(r)));return this.checkpointLocal(n),n}setSourceCursor(t,n){this.wal.setSourceCursor(t,n)}async flush(){let t=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,t.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(t.events.length>0){let o=t.events[t.events.length-1];this.wal.markRemote(o.sequence,t.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&t.events.length>0)try{let o=t.events[t.events.length-1],s=["session_idle","session_end","session_compact"].includes(o.type)?o.type:"checkpoint";await this.handoff.capture(s,o.sequence)}catch{}return r}async idle(t={}){return this.record({type:"session_idle",data:t,provenance:{source:this.identity.agent}}),this.flush()}async end(t={}){return this.record({type:"session_end",data:t,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as pd,openSync as md,closeSync as gd,readSync as yd,statSync as hd}from"node:fs";function kd(e){let t=typeof e.role=="string"?e.role:"",n=typeof e.type=="string"?e.type.toLowerCase():"";return t==="user"||n.includes("user")?"user_prompt":t==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in e||"tool_call"in e?"tool_call":n.includes("error")?"error":"message"}function Sd(e){let t=[e.timestamp,e.createdAt,e.time,e.created_at];for(let n of t){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let o=new Date(r);if(!Number.isNaN(o.getTime()))return o.toISOString()}}return new Date().toISOString()}function ds(e,t={offset:0}){if(!pd(e))return{events:[],nextOffset:t.offset,reset:!1};let n=hd(e).size,r=t.offset>n,o=r?0:t.offset;if(o===n)return{events:[],nextOffset:n,reset:r};let s=n-o,i=Buffer.alloc(s),a=md(e,"r");try{yd(a,i,0,s,o)}finally{gd(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
|
|
154
|
+
`);if(u<0)return{events:[],nextOffset:o,reset:r};let p=c.slice(0,u+1),l=Buffer.byteLength(p,"utf8"),f=[],d=0;for(let m of p.split(`
|
|
155
155
|
`)){if(!m)continue;let k=Buffer.byteLength(m+`
|
|
156
|
-
`,"utf8"),g=
|
|
156
|
+
`,"utf8"),g=o+d;d+=k;let h;try{h=JSON.parse(m)}catch{f.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:m},provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:g}});continue}let v=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};f.push({type:kd(v),timestamp:Sd(v),role:typeof v.role=="string"?v.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:v,provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:g}})}return{events:f,nextOffset:o+l,reset:r}}var vd=[/^<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*$/],wd=[/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],bd=["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 xd(e){let t=e.toLowerCase();return bd.some(n=>t.includes(n))}function jd(e){if(!e.trim())return!0;for(let t of vd)if(t.test(e))return!0;return xd(e),!1}function Md(e){let t=e;for(let n of wd)t=t.replace(n,r=>{let o=r.split(/[:\s=]+/);return o.length>1?`${o[0]}: [REDACTED]`:"[REDACTED]"});return t}function gn(e){let t=e.trim();return t?jd(t)?{content:"",filtered:!0,reason:"noise"}:{content:Md(t),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function Ct(e){let t={};for(let[n,r]of Object.entries(e))if(typeof r=="string"){let o=gn(r);o.filtered||(t[n]=o.content)}else r&&typeof r=="object"&&!Array.isArray(r)?t[n]=Ct(r):Array.isArray(r)?t[n]=r.map(o=>{if(typeof o=="string"){let s=gn(o);return s.filtered?null:s.content}return o&&typeof o=="object"?Ct(o):o}).filter(o=>o!==null):t[n]=r;return t}function fs(e){let t=typeof e.type=="string"?e.type.toLowerCase():"";if(t.includes("system")||t.includes("ephemeral")||t==="tool_call"&&!e.result)return!0;if(e.data&&typeof e.data=="object"){let n=e.data,r=typeof n.content=="string"?n.content:"";if(r&&gn(r).filtered)return!0}return!1}function Cd(e){return e==="~"?ps():e.startsWith("~/")?Ad(ps(),e.slice(2)):e}async function ms(e){let t=e.conversationId.trim();if(!t)throw new Error("Agy conversationId is required");let n=Id(Cd(e.transcriptPath)),r=new It({project:e.project,storage:e.storage,agent:"agy",nativeSessionId:t,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:e.workspacePaths??[],artifactDirectoryPath:e.artifactDirectoryPath,modelName:e.modelName},eventContext:{source:"agy",cwd:e.workspacePaths?.[0]??e.project.rootPath}}),o=r.status(),s=o.sourceCursors["agy.transcript.offset"],i=s?Number(s):0,a=ds(n,{offset:Number.isFinite(i)?i:0}),c=[];o.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${t}:start`,data:{workspacePaths:e.workspacePaths??[],transcriptPath:n,modelName:e.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${t}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(f=>!fs(f.data)).map(f=>({...f,data:Ct(f.data)}));c.push(...u),e.phase==="stop"&&(e.error&&c.push({type:"error",sourceEventId:["agy",t,"stop-error",e.terminationReason??"",a.nextOffset].join(":"),data:{error:e.error,terminationReason:e.terminationReason,fullyIdle:e.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),e.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",t,"idle",a.nextOffset].join(":"),data:{terminationReason:e.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let p=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),e.phase&&r.setSourceCursor("agy.last.phase",e.phase),u.length>0)try{let f=u.map(m=>JSON.stringify(m.data)),d=lt(f,t);r.setSourceCursor("agy.session.summary",d.summary),r.setSourceCursor("agy.session.facts_count",d.durableFacts.length),eo()&&(ro()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let l=await r.flush();return{conversationId:t,imported:p.length,eventCount:l.eventCount,chunkCount:l.chunkCount,status:l.status,transcriptOffset:a.nextOffset,reset:a.reset}}async function Pd(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}function Ke(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function Ed(e){let t=typeof e.common=="object"&&e.common!==null?e.common:{},n=typeof e.pre_invocation_hook_args=="object"&&e.pre_invocation_hook_args!==null?e.pre_invocation_hook_args:{},r=typeof e.post_invocation_hook_args=="object"&&e.post_invocation_hook_args!==null?e.post_invocation_hook_args:{},o=typeof e.stop_hook_args=="object"&&e.stop_hook_args!==null?e.stop_hook_args:{},s=(typeof e.conversationId=="string"?e.conversationId:"")||(typeof e.conversation_id=="string"?e.conversation_id:"")||(typeof t.conversation_id=="string"?t.conversation_id:""),i=(typeof e.transcriptPath=="string"?e.transcriptPath:"")||(typeof e.transcript_path=="string"?e.transcript_path:"")||(typeof t.transcript_path=="string"?t.transcript_path:""),a=Ke(e.workspacePaths).length>0?Ke(e.workspacePaths):Ke(e.workspace_paths).length>0?Ke(e.workspace_paths):Ke(t.workspace_paths),c=typeof e.invocationNum=="number"?e.invocationNum:typeof n.invocation_num=="number"?n.invocation_num:typeof e.invocation_num=="number"?e.invocation_num:void 0,u=(typeof e.artifactDirectoryPath=="string"?e.artifactDirectoryPath:"")||(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||void 0,p=(typeof e.modelName=="string"?e.modelName:"")||(typeof t.model_name=="string"?t.model_name:"")||(typeof e.model_name=="string"?e.model_name:"")||void 0,l=o.fully_idle===!0||e.fullyIdle===!0||e.fully_idle===!0,f=(typeof o.termination_reason=="string"?o.termination_reason:"")||(typeof e.terminationReason=="string"?e.terminationReason:"")||(typeof e.termination_reason=="string"?e.termination_reason:"")||void 0,d=(typeof o.error=="string"&&o.error?o.error:"")||(typeof e.error=="string"&&e.error?e.error:"")||void 0;return{conversationId:s,transcriptPath:i,workspacePaths:a,invocationNum:c,artifactDirectoryPath:u,modelName:p,fullyIdle:l,terminationReason:f,error:d}}function Td(e){let t=typeof e.toolCall=="object"&&e.toolCall!==null?e.toolCall:{},n=typeof t.args=="object"&&t.args!==null?t.args:{},r="";try{r=JSON.stringify(n).replace(/\\\\/g,"/").toLowerCase()}catch{r=""}return r.includes(".toolnet/journal")||r.includes(".toolnet/runtime/sources")||r.includes(".toolnet/sessions")?{decision:"deny",reason:"ToolNet continuity guard: do not replay raw .toolnet/journal, .toolnet/runtime/sources or legacy .toolnet/sessions history. Use the injected continuity handoff. If deeper history is required, invoke memory_agent_ask directly."}:{decision:"allow"}}async function Od(){let e=process.argv[2]??"post",t=await Pd();if(e==="pre-tool"){process.stdout.write(JSON.stringify(Td(t)));return}let n=Ed(t),r=n.conversationId,o=n.transcriptPath,s=n.workspacePaths,i=lo(s);i&&(e==="pre"||e==="stop")&&Fn(i.rootPath);let c={};if(i&&r)try{let u=We(),p=Rn(Tn({provider:u.storage.provider,huggingface:u.storage.huggingface,localRoot:u.storage.localRoot}),{attempts:2}),l=new Ge(p,i.id,i.name,i.remote??i.name);if(o)try{await ms({project:i,storage:l,conversationId:r,transcriptPath:o,workspacePaths:s,artifactDirectoryPath:n.artifactDirectoryPath,modelName:n.modelName,phase:e,fullyIdle:n.fullyIdle,terminationReason:n.terminationReason,error:n.error})}catch{}if(e==="pre")try{c=await Kr({project:i,storage:l,conversationId:r,invocationNum:n.invocationNum})}catch{c={}}if(e==="stop")try{await Lt(i,l,800)}catch{}}catch{}if(e==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(c))}Od().catch(()=>{process.argv[2]==="stop"?process.stdout.write('{"decision":"stop"}'):process.argv[2]==="pre-tool"?process.stdout.write('{"decision":"allow"}'):process.stdout.write("{}"),process.exitCode=0});export{Td as buildAgyPreToolUseOutput,Ed as normalizeAgyInput};
|