toolnet-memory 0.3.12 → 0.3.13

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.
@@ -1,14 +1,14 @@
1
- import{existsSync as ls,readFileSync as ds}from"node:fs";import{homedir as ps}from"node:os";import{join as fs}from"node:path";function ms(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 gs(){let e=process.env.TOOLNET_GLOBAL_ENV??fs(ps(),".config","toolnet-memory",".env");if(!ls(e))return;let t=ds(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 s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=ms(r.slice(s+1)))}}gs();function ce(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function ue(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Ie(){return{memory:{autoCapture:ce(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ce(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ce(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ce(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ue(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ue(process.env.MEMORY_RERANK_TOP,10),finalContext:ue(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ue(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:ce(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:ue(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as hs}from"node:crypto";import{existsSync as lt,mkdirSync as ys,readFileSync as ks,renameSync as Ss,writeFileSync as vs}from"node:fs";import{basename as ws,dirname as je,join as Ee,parse as Bt,resolve as le}from"node:path";var zt=".toolnet",bs="project.json";function xs(e){return hs("sha256").update(e).digest("hex").slice(0,16)}function dt(e){return Ee(e,zt,bs)}function As(e){return lt(dt(e))}function Is(e,t){let n=le(e),r=Bt(n).root;for(;;){if(As(n))return n;if(n===r||t&&n===le(t))break;let s=je(n);if(s===n)break;n=s}return null}function js(e){let t=le(e),n=Bt(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>lt(Ee(t,o))))return t;if(t===n)break;let s=je(t);if(s===t)break;t=s}return le(e)}function Ps(e){let t;try{t=JSON.parse(ks(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}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:je(je(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 Dt(e,t){let n=Ee(e,zt);ys(n,{recursive:!0});let r=dt(e),s=`${r}.tmp-${process.pid}`;vs(s,JSON.stringify(t,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Ss(s,r)}function Wt(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 Pe=class{detect(t=process.cwd()){let n=le(t),r=js(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>lt(Ee(r,f))),i=Is(n,o?r:void 0);if(i){let f=dt(i),d=Ps(f);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Dt(i,d)),Wt(d,i)}let c=new Date().toISOString(),a=ws(r),u={version:1,id:xs(r),name:a,remote:a,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return Dt(r,u),Wt(u,r)}};var Es=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Me=class{scan(t){let n=[];for(let r of Es){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of t.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(t){return this.scan(t).length>0}};var H=class{scanner=new Me;sanitize(t){let n=t,r=this.scanner.scan(t),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(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,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return t}};import{homedir as Qs}from"node:os";import{join as Xs}from"node:path";import{DeleteObjectCommand as Ms,GetObjectCommand as Cs,HeadObjectCommand as Ts,ListObjectsV2Command as Os,PutObjectCommand as _s,S3Client as Rs}from"@aws-sdk/client-s3";import{getSignedUrl as Ns}from"@aws-sdk/s3-request-presigner";var Ce=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Rs({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 _s({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ns(this.client,new Cs({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 Ts({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 Ms({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Os({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 qt,mkdir as Ls,readFile as Ks,readdir as Fs,rm as $s,stat as Ut,writeFile as Ds}from"node:fs/promises";import{dirname as Ws,join as Bs,relative as Vt,resolve as zs}from"node:path";var de=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return zs(this.root,n)}async put(t,n){let r=this.path(t);await Ls(Ws(r),{recursive:!0}),await Ds(r,n)}async get(t){try{return await Ks(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 qt(this.path(t)),!0}catch{return!1}}async delete(t){await $s(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await qt(n)}catch{return r}let s=async i=>{let c=await Fs(i,{withFileTypes:!0});for(let a of c){let u=Bs(i,a.name);if(a.isDirectory()){await s(u);continue}let f=await Ut(u);r.push({key:Vt(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Ut(n);return o.isDirectory()?await s(n):r.push({key:Vt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as qs,GetObjectCommand as Us,HeadObjectCommand as Vs,ListObjectsV2Command as Gs,PutObjectCommand as Hs,S3Client as Js}from"@aws-sdk/client-s3";import{getSignedUrl as Ys}from"@aws-sdk/s3-request-presigner";var pe=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Js({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 Hs({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ys(this.client,new Us({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 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 s=await this.client.send(new Gs({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 de(e)}function Gt(e){let t=e.localRoot??Xs(Qs(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new pe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):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 pe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):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 Ce({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):pt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(t)}function Zs(e){return new Promise(t=>setTimeout(t,e))}async function Ht(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(c){if(o=c,i>=n)break;let a=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,a*.2));await Zs(a+u)}throw o}var eo=new Set(["put","get","getText","delete","list"]);function Jt(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:eo.has(r)?(...o)=>Ht(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function Yt(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 Qt(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 Te=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Yt(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(c){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${c instanceof Error?c.message:String(c)}`)}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=Qt(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{createHash as to}from"node:crypto";import{dirname as no}from"node:path";import{mkdirSync as ro,readFileSync as so,renameSync as oo,writeFileSync as io}from"node:fs";function v(e){return to("sha256").update(e).digest("hex")}function ft(e){if(Array.isArray(e))return e.map(ft);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=ft(t[r]);return n}return e}function Xt(e){return JSON.stringify(ft(e))}function Zt(e){try{return JSON.parse(so(e,"utf8"))}catch{return null}}function M(e,t){ro(no(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;io(n,JSON.stringify(t,null,2)+`
5
- `,{encoding:"utf8",mode:384}),oo(n,e)}function en(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function me(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function fe(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))fe(s,t,n+1);return}let r=en(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),fe(o,t,n+1)}function ne(e,t){let n=[];return fe(e,(r,s)=>{t.has(me(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function ao(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return en(JSON.parse(t))}catch{return null}}function co(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let s=t[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return fe(t,(r,s,o)=>{if(n)return;let i=me(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let c=typeof o.type=="string"?o.type.toLowerCase():"";(c.includes("tool")||c.includes("function")||c.includes("command"))&&(n=s.trim().toLowerCase())}),n}function uo(e){let t=ne(e.data,new Set(["command","cmd","script"])),n=ne(e.data,new Set(["arguments","args"]));for(let r of n){let s=ao(r);if(s)for(let o of ne(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function lo(e){let t=ne(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(me)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
6
- `))))}function po(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 fo(e){let t=ne(e.data,new Set(["patch","diff","arguments","input"].map(me))),n=[];for(let r of t){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let c=i[1]?.trim();c&&n.push({kind:"file",text:c,fileAction:o.action,confidence:.99})}}return n}function mo(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 go(e){let t=null;return fe(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(me(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(t=s)}}}),t}function ho(e){return ne(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function yo(e){let t=go(e.data);if(t!==null)return t===0?"passed":"failed";let n=ho(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 ko(e){let t=[],n=new Set;for(let r of e){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),t.push(r))}return t}function tn(e){let t=[],n=co(e),r=po(e,n);if(r)for(let s of lo(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...fo(e));for(let s of uo(e)){t.push({kind:"command",text:s,confidence:.98});let o=mo(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:yo(e),confidence:.98})}return ko(t)}var So=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function Y(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function rn(e){return Y(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function J(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))J(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(So.has(r)||["data","payload","parts","messages"].includes(r))&&J(s,t,n+1)}}function Oe(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 nn(e){let t=Y(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 j(e,t,n,r,s={}){let o=Y(r),i=s.key??rn(o);return{version:1,id:v([e.projectId,n,i,t.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function vo(e,t,n){let r=Y(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(j(e,t,"goal",i[1],{confidence:.97}));let c=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);c?.[1]&&s.push(j(e,t,"plan",c[1],{confidence:.95}));let a=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=a.exec(r));){let p=Number(u[1]),l=Y(u[2]??""),g=l&&!nn(l)?`Phase ${p} - ${l}`:`Phase ${p}`;s.push(j(e,t,"phase",g,{key:`phase:${p}`,order:p,status:Oe(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(j(e,t,"task",f[2],{status:f[1].trim()?"completed":Oe(f[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,l=Y(d[2]),g=nn(l);s.push(j(e,t,"task",g&&p!==void 0?`TODO ${p}`:l,{key:p!==void 0?`task:${p}`:rn(l),order:p,status:Oe(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let p=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");p&&s.push(j(e,t,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(j(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(j(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(j(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)&&s.push(j(e,t,"activity",r,{confidence:.86})),s}function _e(e,t){if(t.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let a=[];J(i.data,a);let u=a.map(f=>Y(f)).find(f=>f.length>=8&&f.length<=1200&&!/^\[?toolnet\b/iu.test(f));u&&s(j(e,i,"request",u,{confidence:.96}))}for(let a of tn(i))s(j(e,i,a.kind,a.text,{fileAction:a.fileAction,checkKind:a.checkKind,checkStatus:a.checkStatus,status:a.kind==="test"?a.checkStatus==="passed"?"completed":a.checkStatus==="failed"?"blocked":a.checkStatus==="running"?"in_progress":"pending":void 0,confidence:a.confidence}));if(i.type==="decision"){let a=[];J(i.data,a);for(let u of a)s(j(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let a=[];J(i.data,a);for(let u of a)s(j(e,i,"task",u,{status:Oe(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let a of["filePath","path","file"]){let u=i.data[a];typeof u=="string"&&u&&s(j(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let a=[];J(i.data,a);for(let u of a)s(j(e,i,"test",u,{confidence:1}))}let c=[];J(i.data,c);for(let a of c)for(let u of a.split(/\n+/u))for(let f of vo(e,i,u))s(f)}let o=t[t.length-1];return s(j(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function sn(e){return String(e).padStart(12,"0")}var Re=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.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
8
- `,c=v(n.map(u=>u.id).sort().join("|")).slice(0,16),a=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${sn(r)}-${sn(s)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,i,"application/json"),a}};import{join as on}from"node:path";import{mkdirSync as wo}from"node:fs";function cn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(e,t=20){let n=[],r=new Set;for(let s of e.slice().reverse()){let o=cn(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function bo(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${cn(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function xo(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 an(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 s=e&&xo(t)?e.title:t.text;return{id:e?.id??v(t.key).slice(0,24),title:s,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 Ao(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await t.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}async function Ne(e,t){let r=(await Ao(e,t)).flatMap(m=>m.observations).sort((m,b)=>{let z=m.occurredAt.localeCompare(b.occurredAt);if(z!==0)return z;let $t=m.sequence-b.sequence;return $t!==0?$t:m.id.localeCompare(b.id)}),s=new Map,o=new Map,i,c,a,u,f,d=[],p=[],l=[],g=[],k=[],h=new Map,y=[],S=[],C=[],T=[],E=[],O=[];for(let m of r)switch(m.kind){case"request":i=m.text;break;case"activity":c=m.text;break;case"goal":a=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,an(s.get(m.key),m));break;case"task":o.set(m.key,an(o.get(m.key),m));break;case"decision":d.push(m.text);break;case"blocker":p.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":g.push(m.text);break;case"file":{k.push(m.text);let b=m.fileAction??"active";h.delete(m.text),h.set(m.text,b),b==="modified"?y.push(m.text):b==="created"?S.push(m.text):b==="deleted"&&C.push(m.text);break}case"command":T.push(m.text);break;case"test":E.push(m.text),m.checkKind&&O.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":f={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=Array.from(s.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),w=Array.from(o.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),D=x.find(m=>m.status==="in_progress")??x.find(m=>m.status==="blocked")??x.find(m=>m.status==="pending"),W=w.find(m=>m.status==="in_progress")??w.find(m=>m.status==="blocked")??w.find(m=>m.status==="pending"),ct=L([...g,...W?[W.title]:[],...!W&&D?[D.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),ut=L([...p,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:c,goal:a,plan:u,phases:x,tasks:w,decisions:L(d,20),blockers:ut,warnings:L(l,20),nextActions:ct,filesTouched:L(k,30),activeFiles:Array.from(h.entries()).filter(([,m])=>m!=="deleted").map(([m])=>m).slice(-5),modifiedFiles:L(y,30),createdFiles:L(S,30),deletedFiles:L(C,30),commands:L(T,20),tests:L(E,20),checks:bo(O,20),currentPhase:D,currentTask:W,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+w.filter(m=>m.status==="blocked").length},lastSession:f,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ae=on(e.rootPath,".toolnet","work");return wo(ae,{recursive:!0}),M(on(ae,"current.json"),ie),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ie,null,2)+`
9
- `,"application/json"),ie}async function re(e,t){let n=await t.getText(`projects/${e.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{closeSync as Io,existsSync as jo,openSync as Po,readSync as Eo,statSync as Mo}from"node:fs";function Co(e,t){if(!jo(e))return{events:[],nextOffset:t};let n=Mo(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Po(e,"r");try{Eo(i,o,0,s,r)}finally{Io(i)}let c=o.toString("utf8"),a=c.lastIndexOf(`
1
+ import{existsSync as us,readFileSync as ls}from"node:fs";import{homedir as ds}from"node:os";import{join as ps}from"node:path";function fs(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 ms(){let e=process.env.TOOLNET_GLOBAL_ENV??ps(ds(),".config","toolnet-memory",".env");if(!us(e))return;let t=ls(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 s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=fs(r.slice(s+1)))}}ms();function ce(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function ue(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function Ae(){return{memory:{autoCapture:ce(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:ce(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:ce(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:ce(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:ue(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:ue(process.env.MEMORY_RERANK_TOP,10),finalContext:ue(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:ue(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:ce(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:ue(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as gs}from"node:crypto";import{existsSync as lt,mkdirSync as hs,readFileSync as ys,renameSync as ks,writeFileSync as Ss}from"node:fs";import{basename as vs,dirname as Ie,join as Me,parse as zt,resolve as le}from"node:path";var qt=".toolnet",ws="project.json";function bs(e){return gs("sha256").update(e).digest("hex").slice(0,16)}function dt(e){return Me(e,qt,ws)}function xs(e){return lt(dt(e))}function js(e,t){let n=le(e),r=zt(n).root;for(;;){if(xs(n))return n;if(n===r||t&&n===le(t))break;let s=Ie(n);if(s===n)break;n=s}return null}function As(e){let t=le(e),n=zt(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>lt(Me(t,o))))return t;if(t===n)break;let s=Ie(t);if(s===t)break;t=s}return le(e)}function Is(e){let t;try{t=JSON.parse(ys(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}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:Ie(Ie(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 Lt(e,t){let n=Me(e,qt);hs(n,{recursive:!0});let r=dt(e),s=`${r}.tmp-${process.pid}`;Ss(s,JSON.stringify(t,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),ks(s,r)}function Dt(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 Ce=class{detect(t=process.cwd()){let n=le(t),r=As(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>lt(Me(r,f))),i=js(n,o?r:void 0);if(i){let f=dt(i),d=Is(f);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),Lt(i,d)),Dt(d,i)}let c=new Date().toISOString(),a=vs(r),u={version:1,id:bs(r),name:a,remote:a,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return Lt(r,u),Dt(u,r)}};var Cs=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Pe=class{scan(t){let n=[];for(let r of Cs){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of t.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(t){return this.scan(t).length>0}};var G=class{scanner=new Pe;sanitize(t){let n=t,r=this.scanner.scan(t),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(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,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return t}};import{homedir as Ys}from"node:os";import{join as Qs}from"node:path";import{DeleteObjectCommand as Ms,GetObjectCommand as Ps,HeadObjectCommand as Ts,ListObjectsV2Command as Es,PutObjectCommand as Os,S3Client as Rs}from"@aws-sdk/client-s3";import{getSignedUrl as Ns}from"@aws-sdk/s3-request-presigner";var Te=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Rs({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 Os({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ns(this.client,new Ps({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 Ts({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 Ms({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Es({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 Bt,mkdir as _s,readFile as $s,readdir as Fs,rm as Ks,stat as Vt,writeFile as Ws}from"node:fs/promises";import{dirname as Ls,join as Ds,relative as Jt,resolve as zs}from"node:path";var de=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return zs(this.root,n)}async put(t,n){let r=this.path(t);await _s(Ls(r),{recursive:!0}),await Ws(r,n)}async get(t){try{return await $s(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 Bt(this.path(t)),!0}catch{return!1}}async delete(t){await Ks(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await Bt(n)}catch{return r}let s=async i=>{let c=await Fs(i,{withFileTypes:!0});for(let a of c){let u=Ds(i,a.name);if(a.isDirectory()){await s(u);continue}let f=await Vt(u);r.push({key:Jt(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Vt(n);return o.isDirectory()?await s(n):r.push({key:Jt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as qs,GetObjectCommand as Bs,HeadObjectCommand as Vs,ListObjectsV2Command as Js,PutObjectCommand as Hs,S3Client as Gs}from"@aws-sdk/client-s3";import{getSignedUrl as Us}from"@aws-sdk/s3-request-presigner";var pe=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Gs({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 Hs({Bucket:this.bucket,Key:t,Body:s,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(`${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 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 s=await this.client.send(new Js({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 de(e)}function Ht(e){let t=e.localRoot??Qs(Ys(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new pe({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):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 pe({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):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 Te({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):pt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(t)}function Xs(e){return new Promise(t=>setTimeout(t,e))}async function Gt(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(c){if(o=c,i>=n)break;let a=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,a*.2));await Xs(a+u)}throw o}var Zs=new Set(["put","get","getText","delete","list"]);function Ut(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Zs.has(r)?(...o)=>Gt(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function Yt(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 Qt(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 Ee=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=Yt(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(c){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${c instanceof Error?c.message:String(c)}`)}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=Qt(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{createHash as eo}from"node:crypto";import{dirname as to}from"node:path";import{mkdirSync as no,readFileSync as ro,renameSync as so,writeFileSync as oo}from"node:fs";function v(e){return eo("sha256").update(e).digest("hex")}function ft(e){if(Array.isArray(e))return e.map(ft);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=ft(t[r]);return n}return e}function Xt(e){return JSON.stringify(ft(e))}function Zt(e){try{return JSON.parse(ro(e,"utf8"))}catch{return null}}function P(e,t){no(to(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;oo(n,JSON.stringify(t,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),so(n,e)}function en(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function me(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function fe(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))fe(s,t,n+1);return}let r=en(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),fe(o,t,n+1)}function ne(e,t){let n=[];return fe(e,(r,s)=>{t.has(me(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function io(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return en(JSON.parse(t))}catch{return null}}function ao(e){let t=e.data;for(let r of["tool","toolName","tool_name"]){let s=t[r];if(typeof s=="string"&&s.trim())return s.trim().toLowerCase()}let n="";return fe(t,(r,s,o)=>{if(n)return;let i=me(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let c=typeof o.type=="string"?o.type.toLowerCase():"";(c.includes("tool")||c.includes("function")||c.includes("command"))&&(n=s.trim().toLowerCase())}),n}function co(e){let t=ne(e.data,new Set(["command","cmd","script"])),n=ne(e.data,new Set(["arguments","args"]));for(let r of n){let s=io(r);if(s)for(let o of ne(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function uo(e){let t=ne(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(me)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
6
+ `))))}function lo(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 po(e){let t=ne(e.data,new Set(["patch","diff","arguments","input"].map(me))),n=[];for(let r of t){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let c=i[1]?.trim();c&&n.push({kind:"file",text:c,fileAction:o.action,confidence:.99})}}return n}function fo(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 mo(e){let t=null;return fe(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(me(n))){if(typeof r=="number"&&Number.isFinite(r)){t=r;return}if(typeof r=="string"){let s=Number(r);Number.isFinite(s)&&(t=s)}}}),t}function go(e){return ne(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function ho(e){let t=mo(e.data);if(t!==null)return t===0?"passed":"failed";let n=go(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 yo(e){let t=[],n=new Set;for(let r of e){let s=[r.kind,r.fileAction??"",r.checkKind??"",r.checkStatus??"",r.text].join("|");n.has(s)||(n.add(s),t.push(r))}return t}function tn(e){let t=[],n=ao(e),r=lo(e,n);if(r)for(let s of uo(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...po(e));for(let s of co(e)){t.push({kind:"command",text:s,confidence:.98});let o=fo(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:ho(e),confidence:.98})}return yo(t)}var ko=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function Y(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function rn(e){return Y(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function U(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))U(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(ko.has(r)||["data","payload","parts","messages"].includes(r))&&U(s,t,n+1)}}function Oe(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 nn(e){let t=Y(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,s={}){let o=Y(r),i=s.key??rn(o);return{version:1,id:v([e.projectId,n,i,t.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function So(e,t,n){let r=Y(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(I(e,t,"goal",i[1],{confidence:.97}));let c=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);c?.[1]&&s.push(I(e,t,"plan",c[1],{confidence:.95}));let a=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=a.exec(r));){let p=Number(u[1]),l=Y(u[2]??""),g=l&&!nn(l)?`Phase ${p} - ${l}`:`Phase ${p}`;s.push(I(e,t,"phase",g,{key:`phase:${p}`,order:p,status:Oe(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(I(e,t,"task",f[2],{status:f[1].trim()?"completed":Oe(f[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,l=Y(d[2]),g=nn(l);s.push(I(e,t,"task",g&&p!==void 0?`TODO ${p}`:l,{key:p!==void 0?`task:${p}`:rn(l),order:p,status:Oe(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let p=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");p&&s.push(I(e,t,"next_action",p,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(I(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(I(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.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)&&s.push(I(e,t,"activity",r,{confidence:.86})),s}function Re(e,t){if(t.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let a=[];U(i.data,a);let u=a.map(f=>Y(f)).find(f=>f.length>=8&&f.length<=1200&&!/^\[?toolnet\b/iu.test(f));u&&s(I(e,i,"request",u,{confidence:.96}))}for(let a of tn(i))s(I(e,i,a.kind,a.text,{fileAction:a.fileAction,checkKind:a.checkKind,checkStatus:a.checkStatus,status:a.kind==="test"?a.checkStatus==="passed"?"completed":a.checkStatus==="failed"?"blocked":a.checkStatus==="running"?"in_progress":"pending":void 0,confidence:a.confidence}));if(i.type==="decision"){let a=[];U(i.data,a);for(let u of a)s(I(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let a=[];U(i.data,a);for(let u of a)s(I(e,i,"task",u,{status:Oe(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let a of["filePath","path","file"]){let u=i.data[a];typeof u=="string"&&u&&s(I(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let a=[];U(i.data,a);for(let u of a)s(I(e,i,"test",u,{confidence:1}))}let c=[];U(i.data,c);for(let a of c)for(let u of a.split(/\n+/u))for(let f of So(e,i,u))s(f)}let o=t[t.length-1];return s(I(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function sn(e){return String(e).padStart(12,"0")}var Ne=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.sequence)),s=Math.max(...n.map(u=>u.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
8
+ `,c=v(n.map(u=>u.id).sort().join("|")).slice(0,16),a=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${sn(r)}-${sn(s)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,i,"application/json"),a}};import{join as on}from"node:path";import{mkdirSync as vo}from"node:fs";function cn(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(e,t=20){let n=[],r=new Set;for(let s of e.slice().reverse()){let o=cn(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function wo(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${cn(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function bo(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 an(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 s=e&&bo(t)?e.title:t.text;return{id:e?.id??v(t.key).slice(0,24),title:s,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 xo(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await t.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}async function _e(e,t){let r=(await xo(e,t)).flatMap(m=>m.observations).sort((m,b)=>{let q=m.occurredAt.localeCompare(b.occurredAt);if(q!==0)return q;let Wt=m.sequence-b.sequence;return Wt!==0?Wt:m.id.localeCompare(b.id)}),s=new Map,o=new Map,i,c,a,u,f,d=[],p=[],l=[],g=[],k=[],h=new Map,y=[],S=[],T=[],E=[],M=[],O=[];for(let m of r)switch(m.kind){case"request":i=m.text;break;case"activity":c=m.text;break;case"goal":a=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,an(s.get(m.key),m));break;case"task":o.set(m.key,an(o.get(m.key),m));break;case"decision":d.push(m.text);break;case"blocker":p.push(m.text);break;case"warning":l.push(m.text);break;case"next_action":g.push(m.text);break;case"file":{k.push(m.text);let b=m.fileAction??"active";h.delete(m.text),h.set(m.text,b),b==="modified"?y.push(m.text):b==="created"?S.push(m.text):b==="deleted"&&T.push(m.text);break}case"command":E.push(m.text);break;case"test":M.push(m.text),m.checkKind&&O.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":f={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=Array.from(s.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),w=Array.from(o.values()).sort((m,b)=>(m.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),L=x.find(m=>m.status==="in_progress")??x.find(m=>m.status==="blocked")??x.find(m=>m.status==="pending"),D=w.find(m=>m.status==="in_progress")??w.find(m=>m.status==="blocked")??w.find(m=>m.status==="pending"),ct=$([...g,...D?[D.title]:[],...!D&&L?[L.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),ut=$([...p,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:c,goal:a,plan:u,phases:x,tasks:w,decisions:$(d,20),blockers:ut,warnings:$(l,20),nextActions:ct,filesTouched:$(k,30),activeFiles:Array.from(h.entries()).filter(([,m])=>m!=="deleted").map(([m])=>m).slice(-5),modifiedFiles:$(y,30),createdFiles:$(S,30),deletedFiles:$(T,30),commands:$(E,20),tests:$(M,20),checks:wo(O,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+w.filter(m=>m.status==="blocked").length},lastSession:f,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ae=on(e.rootPath,".toolnet","work");return vo(ae,{recursive:!0}),P(on(ae,"current.json"),ie),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ie,null,2)+`
9
+ `,"application/json"),ie}async function re(e,t){let n=await t.getText(`projects/${e.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}import{closeSync as jo,existsSync as Ao,openSync as Io,readSync as Co,statSync as Mo}from"node:fs";function Po(e,t){if(!Ao(e))return{events:[],nextOffset:t};let n=Mo(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Io(e,"r");try{Co(i,o,0,s,r)}finally{jo(i)}let c=o.toString("utf8"),a=c.lastIndexOf(`
10
10
  `);if(a<0)return{events:[],nextOffset:r};let u=c.slice(0,a+1);return{events:u.split(`
11
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Le=class{constructor(t){this.options=t;this.journal=new Re(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=Co(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=_e(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ne(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as Zo,mkdirSync as ei}from"node:fs";import{join as mt}from"node:path";import{existsSync as dn,mkdirSync as To,readFileSync as Oo,statSync as un,writeFileSync as _o}from"node:fs";import{dirname as Ro,join as No}from"node:path";var ln=64*1024,Lo=`# ToolNet Project Operating Manual
11
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var $e=class{constructor(t){this.options=t;this.journal=new Ne(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=Po(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Re(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await _e(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as Xo,mkdirSync as Zo}from"node:fs";import{join as mt}from"node:path";import{existsSync as dn,mkdirSync as To,readFileSync as Eo,statSync as un,writeFileSync as Oo}from"node:fs";import{dirname as Ro,join as No}from"node:path";var ln=64*1024,_o=`# ToolNet Project Operating Manual
12
12
 
13
13
  This file contains persistent instructions for AI agents working on this project.
14
14
 
@@ -51,26 +51,26 @@ Things an AI agent should always remember.
51
51
  <!--
52
52
  - [advisory] Prefer small focused files.
53
53
  -->
54
- `;function Ke(e){return No(e.rootPath,".toolnet","PROJECT.md")}function Ko(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Fo(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(e);){let o=s[1].toLowerCase(),i=Ko(s[2]);if(!i)continue;let c=`${o}:${i.toLowerCase()}`;n.has(c)||(n.add(c),t.push({id:v(c).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function $o(e){let t=Ke(e);return dn(t)||(To(Ro(t),{recursive:!0}),_o(t,Lo,{encoding:"utf8",mode:384})),t}function Fe(e,t=!1){let n=t?$o(e):Ke(e);if(!dn(n))return null;if(un(n).size>ln)throw new Error(`PROJECT.md exceeds ${ln} bytes`);let s=Oo(n,"utf8");return{path:n,content:s,digest:v(s),rules:Fo(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(un(n).mtimeMs).toISOString()}}import{existsSync as Do,mkdirSync as Wo,readFileSync as Bo,renameSync as zo,writeFileSync as qo}from"node:fs";import{dirname as Uo,join as Vo}from"node:path";function Go(e,t){Wo(Uo(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;qo(n,`${JSON.stringify(t,null,2)}
55
- `,{encoding:"utf8",mode:384}),zo(n,e)}function yn(e){return Vo(e.rootPath,".toolnet","work","current.json")}function ge(e){let t=yn(e);if(!Do(t))return null;try{let n=JSON.parse(Bo(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function $e(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=$e(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Ho(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${$e(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function Jo(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 pn(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 s=e&&Jo(t)?e.title:t.text;return{id:e?.id??t.id,title:s,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 fn(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:$e(n.title);t.set(r,n)}return t}function mn(e){return e.order!==void 0?`order:${e.order}`:$e(e.key||e.text)}function gn(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:t.updatedAt.localeCompare(n.updatedAt)})}function hn(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function kn(e,t){let n=ge(e),r=fn(n?.phases??[]),s=fn(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,c=n?.goal,a=n?.plan,u=n?.lastSession,f=[],d=[],p=[],l=[],g=[],k=[...n?.activeFiles??[]],h=[],y=[],S=[],C=[],T=[],E=[],O=[...t].sort((m,b)=>{let z=m.occurredAt.localeCompare(b.occurredAt);return z!==0?z:m.sequence-b.sequence});for(let m of O)switch(m.kind){case"request":o=m.text;break;case"activity":i=m.text;break;case"goal":c=m.text;break;case"plan":a=m.text;break;case"phase":{let b=mn(m);r.set(b,pn(r.get(b),m));break}case"task":{let b=mn(m);s.set(b,pn(s.get(b),m));break}case"decision":f.push(m.text);break;case"blocker":d.push(m.text);break;case"warning":p.push(m.text);break;case"next_action":l.push(m.text);break;case"file":{g.push(m.text);let b=m.fileAction??"active",z=k.indexOf(m.text);z>=0&&k.splice(z,1),b!=="deleted"&&k.push(m.text),b==="modified"?h.push(m.text):b==="created"?y.push(m.text):b==="deleted"&&S.push(m.text);break}case"command":C.push(m.text);break;case"test":T.push(m.text),m.checkKind&&E.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":u={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=gn(r.values()),w=gn(s.values()),D=hn(x),W=hn(w),ct=_(n?.nextActions??[],[...l,...W?[W.title]:[],...!W&&D?[D.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),ut=_(n?.blockers??[],[...d,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie=O.length>0?O[O.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ae={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:c,plan:a,phases:x,tasks:w,decisions:_(n?.decisions??[],f,20),blockers:ut,warnings:_(n?.warnings??[],p,20),nextActions:ct,filesTouched:_(n?.filesTouched??[],g,30),activeFiles:_([],k,5),modifiedFiles:_(n?.modifiedFiles??[],h,30),createdFiles:_(n?.createdFiles??[],y,30),deletedFiles:_(n?.deletedFiles??[],S,30),commands:_(n?.commands??[],C,20),tests:_(n?.tests??[],T,20),checks:Ho(n?.checks??[],E,20),currentPhase:D,currentTask:W,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+w.filter(m=>m.status==="blocked").length},lastSession:u,updatedAt:ie};return Go(yn(e),ae),ae}function P(e,t){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function Sn(e){if(e)return{id:e.id,title:e.title,status:e.status}}function Yo(e,t=[]){let n=t.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=e.slice(-10).join(`
56
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Qo(e){return v(JSON.stringify(e))}function Xo(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let s of r){let o=s.replace(/[.,;:!?]+$/gu,"").trim();o&&t.push(o)}}return P(t,30)}function vn(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(S=>S.status==="completed").map(S=>S.title),i=r.tasks.filter(S=>S.status==="completed").map(S=>S.title),c=r.phases.filter(S=>S.status!=="completed"&&S.status!=="cancelled").map(S=>S.title),a=r.tasks.filter(S=>S.status!=="completed"&&S.status!=="cancelled").map(S=>S.title),u=new Set(r.tasks.filter(S=>S.status==="completed").map(S=>S.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),f=P(r.nextActions.filter(S=>!u.has(S.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=P([...a,...f],15),p=P(r.tests.slice().reverse(),10),l=P([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={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:Sn(r.currentPhase),task:Sn(r.currentTask),file:s},completed:{phases:P(o,20),tasks:P(i,30)},remaining:{phases:P(c,20),tasks:P(a,30),todos:d},nextAction:f[0],blockers:P(r.blockers.slice().reverse(),10),decisions:P(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:P(r.activeFiles??[],10),modified:P(r.modifiedFiles??[],20),created:P(r.createdFiles??[],20),deleted:P(r.deletedFiles??[],20)},tests:{status:Yo(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(S=>({kind:S.kind,status:S.status,command:S.command}))},evidence:{commands:P((r.commands??[]).slice().reverse(),20),references:Xo([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(S=>S.command)])},attention:P(e.attention??[],20),progress:r.progress},{capturedAt:k,source:h,...y}=g;return{...g,stateDigest:Qo(y)}}function ti(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 wn(e,t,n,r,s){if(!ti(n))return null;let o=Fe(e,!1),c=[...o?o.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),a=vn({project:e,identity:t,state:n,reason:r,sequence:s,attention:c}),u=a.stateDigest;return{version:1,id:v([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:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),incompleteTasks:n.tasks.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),nextActions:a.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:c,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:a}}function bn(e,t){let n=mt(e.rootPath,".toolnet","work","handoffs");ei(n,{recursive:!0});let r=mt(n,`${t.id}.json`);Zo(r)||M(r,t),M(mt(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function xn(e){let t=wn(e.project,e.identity,e.state,e.reason,e.sequence);return t?(bn(e.project,t),t):null}var De=class{constructor(t){this.options=t}options;async capture(t,n){let r=ge(this.options.project);r||(r=await re(this.options.project,this.options.storage)),r||(r=await Ne(this.options.project,this.options.storage));let s=wn(this.options.project,this.options.identity,r,t,n);if(!s)return null;bn(this.options.project,s);let o=`projects/${this.options.project.id}/work/handoffs/${s.id}.json`;return await this.options.storage.exists(o)||await this.options.storage.put(o,JSON.stringify(s,null,2)+`
54
+ `;function Fe(e){return No(e.rootPath,".toolnet","PROJECT.md")}function $o(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Fo(e){let t=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(e);){let o=s[1].toLowerCase(),i=$o(s[2]);if(!i)continue;let c=`${o}:${i.toLowerCase()}`;n.has(c)||(n.add(c),t.push({id:v(c).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function Ko(e){let t=Fe(e);return dn(t)||(To(Ro(t),{recursive:!0}),Oo(t,_o,{encoding:"utf8",mode:384})),t}function Ke(e,t=!1){let n=t?Ko(e):Fe(e);if(!dn(n))return null;if(un(n).size>ln)throw new Error(`PROJECT.md exceeds ${ln} bytes`);let s=Eo(n,"utf8");return{path:n,content:s,digest:v(s),rules:Fo(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(un(n).mtimeMs).toISOString()}}import{existsSync as Wo,mkdirSync as Lo,readFileSync as Do,renameSync as zo,writeFileSync as qo}from"node:fs";import{dirname as Bo,join as Vo}from"node:path";function Jo(e,t){Lo(Bo(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;qo(n,`${JSON.stringify(t,null,2)}
55
+ `,{encoding:"utf8",mode:384}),zo(n,e)}function yn(e){return Vo(e.rootPath,".toolnet","work","current.json")}function ge(e){let t=yn(e);if(!Wo(t))return null;try{let n=JSON.parse(Do(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function We(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function R(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=We(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Ho(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${We(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function Go(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 pn(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 s=e&&Go(t)?e.title:t.text;return{id:e?.id??t.id,title:s,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 fn(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:We(n.title);t.set(r,n)}return t}function mn(e){return e.order!==void 0?`order:${e.order}`:We(e.key||e.text)}function gn(e){return Array.from(e).sort((t,n)=>{let r=t.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:t.updatedAt.localeCompare(n.updatedAt)})}function hn(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function kn(e,t){let n=ge(e),r=fn(n?.phases??[]),s=fn(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,c=n?.goal,a=n?.plan,u=n?.lastSession,f=[],d=[],p=[],l=[],g=[],k=[...n?.activeFiles??[]],h=[],y=[],S=[],T=[],E=[],M=[],O=[...t].sort((m,b)=>{let q=m.occurredAt.localeCompare(b.occurredAt);return q!==0?q:m.sequence-b.sequence});for(let m of O)switch(m.kind){case"request":o=m.text;break;case"activity":i=m.text;break;case"goal":c=m.text;break;case"plan":a=m.text;break;case"phase":{let b=mn(m);r.set(b,pn(r.get(b),m));break}case"task":{let b=mn(m);s.set(b,pn(s.get(b),m));break}case"decision":f.push(m.text);break;case"blocker":d.push(m.text);break;case"warning":p.push(m.text);break;case"next_action":l.push(m.text);break;case"file":{g.push(m.text);let b=m.fileAction??"active",q=k.indexOf(m.text);q>=0&&k.splice(q,1),b!=="deleted"&&k.push(m.text),b==="modified"?h.push(m.text):b==="created"?y.push(m.text):b==="deleted"&&S.push(m.text);break}case"command":T.push(m.text);break;case"test":E.push(m.text),m.checkKind&&M.push({kind:m.checkKind,command:m.text,status:m.checkStatus??"unknown",updatedAt:m.occurredAt,agent:m.agent,nativeSessionId:m.nativeSessionId});break;case"session":u={agent:m.agent,nativeSessionId:m.nativeSessionId,sessionKey:m.sessionKey,updatedAt:m.occurredAt};break}let x=gn(r.values()),w=gn(s.values()),L=hn(x),D=hn(w),ct=R(n?.nextActions??[],[...l,...D?[D.title]:[],...!D&&L?[L.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),ut=R(n?.blockers??[],[...d,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ie=O.length>0?O[O.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ae={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:c,plan:a,phases:x,tasks:w,decisions:R(n?.decisions??[],f,20),blockers:ut,warnings:R(n?.warnings??[],p,20),nextActions:ct,filesTouched:R(n?.filesTouched??[],g,30),activeFiles:R([],k,5),modifiedFiles:R(n?.modifiedFiles??[],h,30),createdFiles:R(n?.createdFiles??[],y,30),deletedFiles:R(n?.deletedFiles??[],S,30),commands:R(n?.commands??[],T,20),tests:R(n?.tests??[],E,20),checks:Ho(n?.checks??[],M,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(m=>m.status==="completed").length,tasksTotal:w.length,tasksCompleted:w.filter(m=>m.status==="completed").length,blocked:x.filter(m=>m.status==="blocked").length+w.filter(m=>m.status==="blocked").length},lastSession:u,updatedAt:ie};return Jo(yn(e),ae),ae}function C(e,t){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/g," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function Sn(e){if(e)return{id:e.id,title:e.title,status:e.status}}function Uo(e,t=[]){let n=t.slice(-10);if(n.some(s=>s.status==="failed"))return"failing";if(n.some(s=>s.status==="passed"))return"passing";let r=e.slice(-10).join(`
56
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Yo(e){return v(JSON.stringify(e))}function Qo(e){let t=[];for(let n of e){if(!n)continue;let r=n.match(/https?:\/\/[^\s<>"'`)\]}]+/giu)??[];for(let s of r){let o=s.replace(/[.,;:!?]+$/gu,"").trim();o&&t.push(o)}}return C(t,30)}function vn(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(S=>S.status==="completed").map(S=>S.title),i=r.tasks.filter(S=>S.status==="completed").map(S=>S.title),c=r.phases.filter(S=>S.status!=="completed"&&S.status!=="cancelled").map(S=>S.title),a=r.tasks.filter(S=>S.status!=="completed"&&S.status!=="cancelled").map(S=>S.title),u=new Set(r.tasks.filter(S=>S.status==="completed").map(S=>S.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),f=C(r.nextActions.filter(S=>!u.has(S.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=C([...a,...f],15),p=C(r.tests.slice().reverse(),10),l=C([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),g={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:Sn(r.currentPhase),task:Sn(r.currentTask),file:s},completed:{phases:C(o,20),tasks:C(i,30)},remaining:{phases:C(c,20),tasks:C(a,30),todos:d},nextAction:f[0],blockers:C(r.blockers.slice().reverse(),10),decisions:C(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:C(r.activeFiles??[],10),modified:C(r.modifiedFiles??[],20),created:C(r.createdFiles??[],20),deleted:C(r.deletedFiles??[],20)},tests:{status:Uo(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(S=>({kind:S.kind,status:S.status,command:S.command}))},evidence:{commands:C((r.commands??[]).slice().reverse(),20),references:Qo([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(S=>S.command)])},attention:C(e.attention??[],20),progress:r.progress},{capturedAt:k,source:h,...y}=g;return{...g,stateDigest:Yo(y)}}function ei(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 wn(e,t,n,r,s){if(!ei(n))return null;let o=Ke(e,!1),c=[...o?o.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),a=vn({project:e,identity:t,state:n,reason:r,sequence:s,attention:c}),u=a.stateDigest;return{version:1,id:v([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:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),incompleteTasks:n.tasks.filter(d=>d.status!=="completed"&&d.status!=="cancelled"),nextActions:a.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:c,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:a}}function bn(e,t){let n=mt(e.rootPath,".toolnet","work","handoffs");Zo(n,{recursive:!0});let r=mt(n,`${t.id}.json`);Xo(r)||P(r,t),P(mt(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function xn(e){let t=wn(e.project,e.identity,e.state,e.reason,e.sequence);return t?(bn(e.project,t),t):null}var Le=class{constructor(t){this.options=t}options;async capture(t,n){let r=ge(this.options.project);r||(r=await re(this.options.project,this.options.storage)),r||(r=await _e(this.options.project,this.options.storage));let s=wn(this.options.project,this.options.identity,r,t,n);if(!s)return null;bn(this.options.project,s);let o=`projects/${this.options.project.id}/work/handoffs/${s.id}.json`;return await this.options.storage.exists(o)||await this.options.storage.put(o,JSON.stringify(s,null,2)+`
57
57
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
58
- `,"application/json"),s}};async function An(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 ni}from"node:fs";import{join as In}from"node:path";function ri(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function si(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 q(e,t){return si(t,e)?t:e}function U(e,t=30){let n=new Set,r=[];for(let s of e){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-t)}async function oi(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await t.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}function ii(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function jn(e,t){let r=(await oi(e,t)).flatMap(k=>k.observations).sort((k,h)=>{let y=k.evidence.occurredAt.localeCompare(h.evidence.occurredAt);return y!==0?y:k.evidence.sessionKey===h.evidence.sessionKey?k.evidence.sequence-h.evidence.sequence:k.id.localeCompare(h.id)}),s,o,i,c,a,u=new Map,f=[],d=[],p=[];for(let k of r){let h=ri(k);if(k.scope==="phase"&&k.scopeKey){let y=u.get(k.scopeKey)??ii(k);switch(k.kind){case"phase_objective":y.objective=q(y.objective,h);break;case"phase_why":y.why=q(y.why,h);break;case"phase_deliverable":y.deliverable=q(y.deliverable,h);break;case"acceptance_criterion":y.acceptanceCriteria.push(h);break;case"dependency":y.dependencies.push(h);break;case"open_question":y.openQuestions.push(h);break;case"constraint":y.constraints.push(h);break;case"note":y.notes.push(h);break}u.set(y.key,y);continue}switch(k.kind){case"mission":s=q(s,h);break;case"objective":o=q(o,h);break;case"why":i=q(i,h);break;case"desired_outcome":c=q(c,h);break;case"plan_rationale":a=q(a,h);break;case"open_question":f.push(h);break;case"constraint":d.push(h);break;case"note":p.push(h);break}}for(let k of u.values())k.acceptanceCriteria=U(k.acceptanceCriteria,20),k.dependencies=U(k.dependencies,15),k.openQuestions=U(k.openQuestions,15),k.constraints=U(k.constraints,15),k.notes=U(k.notes,20);let l={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:c,planRationale:a,phases:Array.from(u.values()).sort((k,h)=>k.order-h.order),openQuestions:U(f,20),constraints:U(d,20),notes:U(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=In(e.rootPath,".toolnet","work");return ni(g,{recursive:!0}),M(In(g,"semantic-current.json"),l),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
59
- `,"application/json"),l}async function Pn(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 gt(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 A(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 ai(e){let t=[],n=!1;for(let r of e.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&t.push(A(s,280)),t.length>=16))break}return t}function ci(e){let t=[],n=[];for(let r of e.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),c=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>o.startsWith(u));if(!c)continue;let a=s.slice(c.length).trim();a&&(c.includes("enforce")?t.push(a):n.push(a))}return{enforce:t,advisory:n}}function ui(e,t){let n=[];for(let r of e){let s=[...n,r].join(`
58
+ `,"application/json"),s}};async function jn(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 ti}from"node:fs";import{join as An}from"node:path";function ni(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function ri(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 B(e,t){return ri(t,e)?t:e}function V(e,t=30){let n=new Set,r=[];for(let s of e){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-t)}async function si(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await t.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}function oi(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function In(e,t){let r=(await si(e,t)).flatMap(k=>k.observations).sort((k,h)=>{let y=k.evidence.occurredAt.localeCompare(h.evidence.occurredAt);return y!==0?y:k.evidence.sessionKey===h.evidence.sessionKey?k.evidence.sequence-h.evidence.sequence:k.id.localeCompare(h.id)}),s,o,i,c,a,u=new Map,f=[],d=[],p=[];for(let k of r){let h=ni(k);if(k.scope==="phase"&&k.scopeKey){let y=u.get(k.scopeKey)??oi(k);switch(k.kind){case"phase_objective":y.objective=B(y.objective,h);break;case"phase_why":y.why=B(y.why,h);break;case"phase_deliverable":y.deliverable=B(y.deliverable,h);break;case"acceptance_criterion":y.acceptanceCriteria.push(h);break;case"dependency":y.dependencies.push(h);break;case"open_question":y.openQuestions.push(h);break;case"constraint":y.constraints.push(h);break;case"note":y.notes.push(h);break}u.set(y.key,y);continue}switch(k.kind){case"mission":s=B(s,h);break;case"objective":o=B(o,h);break;case"why":i=B(i,h);break;case"desired_outcome":c=B(c,h);break;case"plan_rationale":a=B(a,h);break;case"open_question":f.push(h);break;case"constraint":d.push(h);break;case"note":p.push(h);break}}for(let k of u.values())k.acceptanceCriteria=V(k.acceptanceCriteria,20),k.dependencies=V(k.dependencies,15),k.openQuestions=V(k.openQuestions,15),k.constraints=V(k.constraints,15),k.notes=V(k.notes,20);let l={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:c,planRationale:a,phases:Array.from(u.values()).sort((k,h)=>k.order-h.order),openQuestions:V(f,20),constraints:V(d,20),notes:V(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=An(e.rootPath,".toolnet","work");return ti(g,{recursive:!0}),P(An(g,"semantic-current.json"),l),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
59
+ `,"application/json"),l}async function Cn(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 gt(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 j(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 ii(e){let t=[],n=!1;for(let r of e.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&t.push(j(s,280)),t.length>=16))break}return t}function ai(e){let t=[],n=[];for(let r of e.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),c=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(u=>o.startsWith(u));if(!c)continue;let a=s.slice(c.length).trim();a&&(c.includes("enforce")?t.push(a):n.push(a))}return{enforce:t,advisory:n}}function ci(e,t){let n=[];for(let r of e){let s=[...n,r].join(`
60
60
  `);if(gt(s)<=t){n.push(r);continue}let o=gt(n.join(`
61
- `)),i=Math.max(0,t-o);if(i>=16){let c=Math.floor(i*3.2),a=A(r,c);a&&n.push(a)}break}return n.join(`
62
- `).trim()}async function En(e){let t=Math.max(256,Math.min(2e3,e.maxTokens??1e3)),n=Fe(e.project,!1),r=n?.content??"";r||(r=await e.storage.getText(`projects/${e.project.id}/project/manual.md`)??"");let s=ci(r),o=n?n.rules.filter(l=>l.mode==="enforce").map(l=>l.text):s.enforce,i=n?n.rules.filter(l=>l.mode==="advisory").map(l=>l.text):s.advisory,c=r?ai(r):[],a=await re(e.project,e.storage),u=await Pn(e.project,e.storage),f=await An(e.project,e.storage),d=[];if(d.push("[TOOLNET PROJECT CONTEXT]"),d.push(`Project: ${e.project.name}`),d.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&d.push(`Full operating manual: ${Ke(e.project)}`),o.length){d.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let l of o.slice(0,24))d.push(`- [ENFORCE] ${A(l,240)}`)}if(i.length){d.push("","PROJECT PREFERENCES");for(let l of i.slice(0,10))d.push(`- ${A(l,220)}`)}if(u&&(u.mission&&d.push("","MISSION",A(u.mission.value,420)),u.activeObjective&&d.push("","CURRENT OBJECTIVE",A(u.activeObjective.value,420)),u.why&&d.push("","WHY THIS WORK MATTERS",A(u.why.value,420)),u.desiredOutcome&&d.push("","DESIRED OUTCOME",A(u.desiredOutcome.value,420)),u.planRationale&&d.push("","WHY THIS APPROACH",A(u.planRationale.value,420))),a){if(d.push("","ACTIVE WORK"),a.goal&&d.push(`Goal: ${A(a.goal,320)}`),a.plan&&d.push(`Plan: ${A(a.plan,320)}`),d.push(`Progress: phases ${a.progress.phasesCompleted}/${a.progress.phasesTotal}; tasks ${a.progress.tasksCompleted}/${a.progress.tasksTotal}; blocked ${a.progress.blocked}`),a.currentPhase&&d.push(`Current phase: ${a.currentPhase.title} [${a.currentPhase.status}]`),a.currentPhase&&u){let l=u.phases.find(g=>g.order===a.currentPhase?.order);l&&(l.objective&&d.push(`Phase objective: ${A(l.objective.value,340)}`),l.why?d.push(`Why this phase: ${A(l.why.value,340)}`):d.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),l.deliverable&&d.push(`Deliverable: ${A(l.deliverable.value,340)}`),l.dependencies.length&&d.push(`Depends on: ${l.dependencies.slice(0,4).map(g=>A(g.value,180)).join("; ")}`),l.acceptanceCriteria.length&&(d.push("","DEFINITION OF DONE"),l.acceptanceCriteria.slice(0,6).forEach(g=>{d.push(`- ${A(g.value,260)}`)})),l.openQuestions.length&&(d.push("","OPEN QUESTIONS FOR CURRENT PHASE"),l.openQuestions.slice(0,4).forEach(g=>{d.push(`- ${A(g.value,260)}`)})))}a.currentTask&&d.push(`Current task: ${a.currentTask.title} [${a.currentTask.status}]`),a.nextActions.length&&(d.push("","NEXT ACTIONS"),a.nextActions.slice(0,6).forEach((l,g)=>{d.push(`${g+1}. ${A(l,260)}`)})),a.blockers.length&&(d.push("","BLOCKERS"),a.blockers.slice(0,5).forEach(l=>{d.push(`- ${A(l,260)}`)})),a.warnings.length&&(d.push("","ATTENTION"),a.warnings.slice(-5).forEach(l=>{d.push(`- ${A(l,260)}`)})),a.decisions.length&&(d.push("","RECENT DECISIONS"),a.decisions.slice(-5).forEach(l=>{d.push(`- ${A(l,260)}`)})),a.lastSession&&d.push("",`Last work session: ${a.lastSession.agent} / ${a.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(d.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(l=>{d.push(`- ${A(l.value,260)}`)})),f&&d.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),c.length){d.push("","OPERATING NOTES");for(let l of c)d.push(`- ${l}`)}d.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=ui(d,t);return{version:1,projectId:e.project.id,projectName:e.project.name,text:p,estimatedTokens:gt(p),maxTokens:t,hasManual:!!r,hasWorkState:!!a,hasHandoff:!!f,generatedAt:new Date().toISOString()}}var li=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function se(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function ht(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))ht(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(li.has(r)||["data","payload","parts","messages"].includes(r))&&ht(s,t,n+1)}}function R(e,t,n,r,s,o=.95){let i=se(r);return{version:1,id:v([e.projectId,n,s.type,s.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,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 s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return se(e.slice(r.length+1))}return null}function di(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function pi(e){return se(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Mn(e,t){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of t){let i=[];ht(o.data,i);for(let c of i){let a={type:"project"},u=null;for(let f of c.split(/\r?\n/u)){let d=se(f);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let w=Number(p[1]);a={type:"phase",key:`phase:${w}`,order:w,title:se(p[2]??"")},u=null;continue}let l=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let w=Number(l[1]);a={type:"task",key:`task:${w}`,order:w,title:se(l[2]??"")},u=null;continue}let g=K(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(R(e,o,"mission",g,{type:"project"},.99)),u=null;continue}let k=K(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(k){s(R(e,o,a.type==="phase"?"phase_objective":"objective",k,a,.98)),u=null;continue}let h=K(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(h){s(R(e,o,a.type==="phase"?"phase_why":"why",h,a,.98)),u=null;continue}let y=K(d,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(y){s(R(e,o,"desired_outcome",y,{type:"project"},.98)),u=null;continue}let S=K(d,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(S){s(R(e,o,"plan_rationale",S,{type:"project"},.98)),u=null;continue}let C=K(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(C){s(R(e,o,"phase_deliverable",C,a,.97)),u=null;continue}let T=K(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(T){s(R(e,o,"acceptance_criterion",T,a,.98)),u="acceptance_criterion";continue}let E=K(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(E){s(R(e,o,"dependency",E,a,.97)),u="dependency";continue}let O=K(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(O){s(R(e,o,"open_question",O,a,.95)),u="open_question";continue}let x=K(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(R(e,o,"constraint",x,a,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&di(f)){s(R(e,o,u,pi(f),a,.96));continue}u=null}}}return n}function Cn(e){return String(e).padStart(12,"0")}var We=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.evidence.sequence)),s=Math.max(...n.map(a=>a.evidence.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(a=>a.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","semantic","observations",t.agent,t.nativeSessionId,`${Cn(r)}-${Cn(s)}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
63
- `,"application/json"),c}};import{closeSync as fi,existsSync as mi,openSync as gi,readSync as hi,statSync as yi}from"node:fs";function ki(e,t){if(!mi(e))return{events:[],nextOffset:t};let n=yi(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=gi(e,"r");try{hi(o,s,0,s.length,r)}finally{fi(o)}let i=s.toString("utf8"),c=i.lastIndexOf(`
61
+ `)),i=Math.max(0,t-o);if(i>=16){let c=Math.floor(i*3.2),a=j(r,c);a&&n.push(a)}break}return n.join(`
62
+ `).trim()}async function Mn(e){let t=Math.max(256,Math.min(2e3,e.maxTokens??1e3)),n=Ke(e.project,!1),r=n?.content??"";r||(r=await e.storage.getText(`projects/${e.project.id}/project/manual.md`)??"");let s=ai(r),o=n?n.rules.filter(l=>l.mode==="enforce").map(l=>l.text):s.enforce,i=n?n.rules.filter(l=>l.mode==="advisory").map(l=>l.text):s.advisory,c=r?ii(r):[],a=await re(e.project,e.storage),u=await Cn(e.project,e.storage),f=await jn(e.project,e.storage),d=[];if(d.push("[TOOLNET PROJECT CONTEXT]"),d.push(`Project: ${e.project.name}`),d.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&d.push(`Full operating manual: ${Fe(e.project)}`),o.length){d.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let l of o.slice(0,24))d.push(`- [ENFORCE] ${j(l,240)}`)}if(i.length){d.push("","PROJECT PREFERENCES");for(let l of i.slice(0,10))d.push(`- ${j(l,220)}`)}if(u&&(u.mission&&d.push("","MISSION",j(u.mission.value,420)),u.activeObjective&&d.push("","CURRENT OBJECTIVE",j(u.activeObjective.value,420)),u.why&&d.push("","WHY THIS WORK MATTERS",j(u.why.value,420)),u.desiredOutcome&&d.push("","DESIRED OUTCOME",j(u.desiredOutcome.value,420)),u.planRationale&&d.push("","WHY THIS APPROACH",j(u.planRationale.value,420))),a){if(d.push("","ACTIVE WORK"),a.goal&&d.push(`Goal: ${j(a.goal,320)}`),a.plan&&d.push(`Plan: ${j(a.plan,320)}`),d.push(`Progress: phases ${a.progress.phasesCompleted}/${a.progress.phasesTotal}; tasks ${a.progress.tasksCompleted}/${a.progress.tasksTotal}; blocked ${a.progress.blocked}`),a.currentPhase&&d.push(`Current phase: ${a.currentPhase.title} [${a.currentPhase.status}]`),a.currentPhase&&u){let l=u.phases.find(g=>g.order===a.currentPhase?.order);l&&(l.objective&&d.push(`Phase objective: ${j(l.objective.value,340)}`),l.why?d.push(`Why this phase: ${j(l.why.value,340)}`):d.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),l.deliverable&&d.push(`Deliverable: ${j(l.deliverable.value,340)}`),l.dependencies.length&&d.push(`Depends on: ${l.dependencies.slice(0,4).map(g=>j(g.value,180)).join("; ")}`),l.acceptanceCriteria.length&&(d.push("","DEFINITION OF DONE"),l.acceptanceCriteria.slice(0,6).forEach(g=>{d.push(`- ${j(g.value,260)}`)})),l.openQuestions.length&&(d.push("","OPEN QUESTIONS FOR CURRENT PHASE"),l.openQuestions.slice(0,4).forEach(g=>{d.push(`- ${j(g.value,260)}`)})))}a.currentTask&&d.push(`Current task: ${a.currentTask.title} [${a.currentTask.status}]`),a.nextActions.length&&(d.push("","NEXT ACTIONS"),a.nextActions.slice(0,6).forEach((l,g)=>{d.push(`${g+1}. ${j(l,260)}`)})),a.blockers.length&&(d.push("","BLOCKERS"),a.blockers.slice(0,5).forEach(l=>{d.push(`- ${j(l,260)}`)})),a.warnings.length&&(d.push("","ATTENTION"),a.warnings.slice(-5).forEach(l=>{d.push(`- ${j(l,260)}`)})),a.decisions.length&&(d.push("","RECENT DECISIONS"),a.decisions.slice(-5).forEach(l=>{d.push(`- ${j(l,260)}`)})),a.lastSession&&d.push("",`Last work session: ${a.lastSession.agent} / ${a.lastSession.nativeSessionId}`)}if(u&&u.openQuestions.length&&(d.push("","UNRESOLVED QUESTIONS"),u.openQuestions.slice(0,5).forEach(l=>{d.push(`- ${j(l.value,260)}`)})),f&&d.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),c.length){d.push("","OPERATING NOTES");for(let l of c)d.push(`- ${l}`)}d.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let p=ci(d,t);return{version:1,projectId:e.project.id,projectName:e.project.name,text:p,estimatedTokens:gt(p),maxTokens:t,hasManual:!!r,hasWorkState:!!a,hasHandoff:!!f,generatedAt:new Date().toISOString()}}var ui=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function se(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function ht(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))ht(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(ui.has(r)||["data","payload","parts","messages"].includes(r))&&ht(s,t,n+1)}}function N(e,t,n,r,s,o=.95){let i=se(r);return{version:1,id:v([e.projectId,n,s.type,s.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function F(e,t){let n=e.toLowerCase();for(let r of t){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return se(e.slice(r.length+1))}return null}function li(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function di(e){return se(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Pn(e,t){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of t){let i=[];ht(o.data,i);for(let c of i){let a={type:"project"},u=null;for(let f of c.split(/\r?\n/u)){let d=se(f);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let w=Number(p[1]);a={type:"phase",key:`phase:${w}`,order:w,title:se(p[2]??"")},u=null;continue}let l=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let w=Number(l[1]);a={type:"task",key:`task:${w}`,order:w,title:se(l[2]??"")},u=null;continue}let g=F(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(g){s(N(e,o,"mission",g,{type:"project"},.99)),u=null;continue}let k=F(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(k){s(N(e,o,a.type==="phase"?"phase_objective":"objective",k,a,.98)),u=null;continue}let h=F(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(h){s(N(e,o,a.type==="phase"?"phase_why":"why",h,a,.98)),u=null;continue}let y=F(d,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(y){s(N(e,o,"desired_outcome",y,{type:"project"},.98)),u=null;continue}let S=F(d,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(S){s(N(e,o,"plan_rationale",S,{type:"project"},.98)),u=null;continue}let T=F(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(T){s(N(e,o,"phase_deliverable",T,a,.97)),u=null;continue}let E=F(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(E){s(N(e,o,"acceptance_criterion",E,a,.98)),u="acceptance_criterion";continue}let M=F(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(M){s(N(e,o,"dependency",M,a,.97)),u="dependency";continue}let O=F(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(O){s(N(e,o,"open_question",O,a,.95)),u="open_question";continue}let x=F(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(N(e,o,"constraint",x,a,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&li(f)){s(N(e,o,u,di(f),a,.96));continue}u=null}}}return n}function Tn(e){return String(e).padStart(12,"0")}var De=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.evidence.sequence)),s=Math.max(...n.map(a=>a.evidence.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(a=>a.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","semantic","observations",t.agent,t.nativeSessionId,`${Tn(r)}-${Tn(s)}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
63
+ `,"application/json"),c}};import{closeSync as pi,existsSync as fi,openSync as mi,readSync as gi,statSync as hi}from"node:fs";function yi(e,t){if(!fi(e))return{events:[],nextOffset:t};let n=hi(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=mi(e,"r");try{gi(o,s,0,s.length,r)}finally{pi(o)}let i=s.toString("utf8"),c=i.lastIndexOf(`
64
64
  `);if(c<0)return{events:[],nextOffset:r};let a=i.slice(0,c+1);return{events:a.split(`
65
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var Be=class{constructor(t){this.options=t;this.journal=new We(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=ki(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Mn(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await jn(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as Si,mkdirSync as vi,readFileSync as wi,writeFileSync as bi}from"node:fs";import{dirname as xi,join as Tn}from"node:path";function ze(e){return e?Math.ceil(e.length/3.5):0}function qe(e,t){if(!e)return"";if(ze(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
66
- `),c=Math.max(o,i);return c>r*.7?s.slice(0,c+1):s}function On(e){return Tn(e.rootPath,".toolnet","context","startup.md")}function Ai(e){return Tn(e.rootPath,".toolnet","context","startup.json")}function _n(e,t){let n=On(e);vi(xi(n),{recursive:!0}),bi(n,t.text.endsWith(`
65
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var ze=class{constructor(t){this.options=t;this.journal=new De(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=yi(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Pn(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await In(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{existsSync as ki,mkdirSync as Si,readFileSync as vi,writeFileSync as wi}from"node:fs";import{dirname as bi,join as En}from"node:path";function qe(e){return e?Math.ceil(e.length/3.5):0}function Be(e,t){if(!e)return"";if(qe(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
66
+ `),c=Math.max(o,i);return c>r*.7?s.slice(0,c+1):s}function On(e){return En(e.rootPath,".toolnet","context","startup.md")}function xi(e){return En(e.rootPath,".toolnet","context","startup.json")}function Rn(e,t){let n=On(e);Si(bi(n),{recursive:!0}),wi(n,t.text.endsWith(`
67
67
  `)?t.text:t.text+`
68
- `,{encoding:"utf8",mode:384}),M(Ai(e),t)}async function yt(e,t,n=800){let s=(await En({project:e,storage:t,maxTokens:n})).text;ze(s)>n&&(s=qe(s,n),s+=`
68
+ `,{encoding:"utf8",mode:384}),P(xi(e),t)}async function yt(e,t,n=800){let s=(await Mn({project:e,storage:t,maxTokens:n})).text;qe(s)>n&&(s=Be(s,n),s+=`
69
69
 
70
70
  [Context trimmed by ToolNet Memory token budget]
71
- `);let i={version:1,projectId:e.id,projectName:e.name,text:s,digest:v(s),estimatedTokens:ze(s),generatedAt:new Date().toISOString()};return _n(e,i),await t.put(`projects/${e.id}/context/startup.md`,i.text+`
71
+ `);let i={version:1,projectId:e.id,projectName:e.name,text:s,digest:v(s),estimatedTokens:qe(s),generatedAt:new Date().toISOString()};return Rn(e,i),await t.put(`projects/${e.id}/context/startup.md`,i.text+`
72
72
  `,"text/markdown"),await t.put(`projects/${e.id}/context/startup.json`,JSON.stringify(i,null,2)+`
73
- `,"application/json"),i}async function Rn(e,t,n=900){try{let s=await t.getText(`projects/${e.id}/context/startup.md`);if(s&&s.trim()){let o=s.trim(),i={version:1,projectId:e.id,projectName:e.name,text:o,digest:v(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return _n(e,i),i}}catch{}let r=On(e);if(Si(r))try{let s=wi(r,"utf8").trim();if(s)return{version:1,projectId:e.id,projectName:e.name,text:s,digest:v(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await yt(e,t,n)}catch{return null}}import{existsSync as Vn,mkdirSync as Bi,readFileSync as Gn}from"node:fs";import{homedir as zi}from"node:os";import{dirname as qi,join as bt}from"node:path";var kt="memory_agent_ask";function Nn(){return`
73
+ `,"application/json"),i}async function Nn(e,t,n=900){try{let s=await t.getText(`projects/${e.id}/context/startup.md`);if(s&&s.trim()){let o=s.trim(),i={version:1,projectId:e.id,projectName:e.name,text:o,digest:v(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return Rn(e,i),i}}catch{}let r=On(e);if(ki(r))try{let s=vi(r,"utf8").trim();if(s)return{version:1,projectId:e.id,projectName:e.name,text:s,digest:v(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await yt(e,t,n)}catch{return null}}import{existsSync as Jn,mkdirSync as Di,readFileSync as Hn}from"node:fs";import{homedir as zi}from"node:os";import{dirname as qi,join as bt}from"node:path";var kt="memory_agent_ask";function _n(){return`
74
74
  [TOOLNET MEMORY AGENT]
75
75
 
76
76
  Tool:
@@ -95,38 +95,38 @@ Use:
95
95
  - mode="ai" for ambiguous or combined continuity questions.
96
96
 
97
97
  Current repository evidence overrides stale memory.
98
- `.trim()}import{createHash as Ii}from"node:crypto";import{chmodSync as Kn,existsSync as ji,mkdirSync as Pi,readFileSync as Ei,renameSync as Mi,writeFileSync as Fn}from"node:fs";import{dirname as $n,join as Ue}from"node:path";var wt="toolnet.context-offload.v1",Ci="toolnet.context-offload-asset.v1",Ti=256,Oi=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Dn(e){return Ue(e,".toolnet","offload")}function _i(e){return Ue(Dn(e),"assets")}function Wn(e){return Ue(Dn(e),"graph.json")}function Bn(e){Pi(e,{recursive:!0,mode:448});try{Kn(e,448)}catch{}}function Ri(e,t){Bn($n(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;Fn(n,t,{encoding:"utf8",mode:384}),Mi(n,e);try{Kn(e,384)}catch{}}function vt(e){return Array.isArray(e)?e.map(vt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,vt(n)])):e}function Ni(e){return Ii("sha256").update(JSON.stringify(vt(e)),"utf8").digest("hex")}function St(){return{schema:wt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function zn(e){let t=Wn(e);if(!ji(t))return St();try{let n=JSON.parse(Ei(t,"utf8"));return n.schema!==wt||n.version!==1||!Array.isArray(n.nodes)?St():n}catch{return St()}}function Li(e,t){Ri(Wn(e),JSON.stringify(t,null,2)+`
99
- `)}function Ki(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Fi(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=Ki(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function $i(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Di(e,t){Bn($n(e));try{return Fn(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Wi(e,t){let n=e.nodes.find(s=>s.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:wt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-Ti)}}function qn(e,t){let n=zn(e),r=0,s=0,o=0,i=[];for(let c of t){if(!Oi.has(c.type))continue;r+=1;let a=Ni({type:c.type,data:c.data}),u={schema:Ci,version:1,assetId:a,event:{type:c.type,agent:c.agent,nativeSessionId:c.nativeSessionId,timestamp:c.timestamp,sourceEventId:c.sourceEventId,provenance:c.provenance,data:c.data}},f=JSON.stringify(u,null,2)+`
100
- `;Di(Ue(_i(e),`${a}.json`),f)?s+=1:o+=1,i.push(a),n=Wi(n,{id:a,kind:c.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:c.timestamp,sourceRefs:[$i(c)],files:Fi(c)})}return r>0&&Li(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function Ln(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function Un(e,t={}){let n=zn(e);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,t.maxAssets??6)),s=Math.max(320,Math.min(2400,t.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let c=Ln(i.sourceRefs.at(-1)??"unknown",72),a=i.files.length>0?` files=${Ln(i.files.join(","),120)}`:"",u=`event:${c} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${a}`;if([...o,u].join(`
98
+ `.trim()}import{createHash as ji}from"node:crypto";import{chmodSync as Fn,existsSync as Ai,mkdirSync as Ii,readFileSync as Ci,renameSync as Mi,writeFileSync as Kn}from"node:fs";import{dirname as Wn,join as Ve}from"node:path";var wt="toolnet.context-offload.v1",Pi="toolnet.context-offload-asset.v1",Ti=256,Ei=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Ln(e){return Ve(e,".toolnet","offload")}function Oi(e){return Ve(Ln(e),"assets")}function Dn(e){return Ve(Ln(e),"graph.json")}function zn(e){Ii(e,{recursive:!0,mode:448});try{Fn(e,448)}catch{}}function Ri(e,t){zn(Wn(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;Kn(n,t,{encoding:"utf8",mode:384}),Mi(n,e);try{Fn(e,384)}catch{}}function vt(e){return Array.isArray(e)?e.map(vt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,vt(n)])):e}function Ni(e){return ji("sha256").update(JSON.stringify(vt(e)),"utf8").digest("hex")}function St(){return{schema:wt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function qn(e){let t=Dn(e);if(!Ai(t))return St();try{let n=JSON.parse(Ci(t,"utf8"));return n.schema!==wt||n.version!==1||!Array.isArray(n.nodes)?St():n}catch{return St()}}function _i(e,t){Ri(Dn(e),JSON.stringify(t,null,2)+`
99
+ `)}function $i(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Fi(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=$i(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Ki(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Wi(e,t){zn(Wn(e));try{return Kn(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Li(e,t){let n=e.nodes.find(s=>s.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:wt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-Ti)}}function Bn(e,t){let n=qn(e),r=0,s=0,o=0,i=[];for(let c of t){if(!Ei.has(c.type))continue;r+=1;let a=Ni({type:c.type,data:c.data}),u={schema:Pi,version:1,assetId:a,event:{type:c.type,agent:c.agent,nativeSessionId:c.nativeSessionId,timestamp:c.timestamp,sourceEventId:c.sourceEventId,provenance:c.provenance,data:c.data}},f=JSON.stringify(u,null,2)+`
100
+ `;Wi(Ve(Oi(e),`${a}.json`),f)?s+=1:o+=1,i.push(a),n=Li(n,{id:a,kind:c.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:c.timestamp,sourceRefs:[Ki(c)],files:Fi(c)})}return r>0&&_i(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}function $n(e,t){let n=e.replace(/\s+/gu," ").trim();return n.length<=t?n:n.slice(0,t-1).trimEnd()+"\u2026"}function Vn(e,t={}){let n=qn(e);if(n.nodes.length===0)return"";let r=Math.max(1,Math.min(12,t.maxAssets??6)),s=Math.max(320,Math.min(2400,t.maxChars??900)),o=["[TOOLNET CONTEXT OFFLOAD GRAPH]","Large tool/file payloads stay outside prompt context.","Read only a needed asset with MCP context_offload_read."];for(let i of n.nodes.slice(-r).reverse()){let c=$n(i.sourceRefs.at(-1)??"unknown",72),a=i.files.length>0?` files=${$n(i.files.join(","),120)}`:"",u=`event:${c} --offloads--> asset:${i.id.slice(0,12)} kind=${i.kind} bytes=${i.bytes}${a}`;if([...o,u].join(`
101
101
  `).length>s)break;o.push(u)}return o.join(`
102
- `)}function Ui(e,t,n){let r=n??bt(zi(),".config","toolnet-memory","injections","agy");return bt(r,`${e.id}-${t}.json`)}function Vi(e){if(!Vn(e))return null;try{return JSON.parse(Gn(e,"utf8"))}catch{return null}}function V(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 Gi(e){let t=bt(e.rootPath,".toolnet","work","current.json");if(!Vn(t))return null;try{let n=JSON.parse(Gn(t,"utf8"));if(n.version===1&&n.projectId===e.id)return n}catch{}return null}function Hi(e,t){let n=t.tasks.filter(i=>i.status==="completed").slice(-3).map(i=>V(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=>V(i,220)).filter(Boolean))),s=t.filesTouched.at(-1),o=["[TOOLNET CONTINUITY HANDOFF]",`Project: ${e.name}`];return t.currentTask?.title?o.push(`Task: ${V(t.currentTask.title)}`):t.currentPhase?.title?o.push(`Task: ${V(t.currentPhase.title)}`):t.goal&&o.push(`Task: ${V(t.goal)}`),n.length&&o.push(`Completed: ${n.join("; ")}`),s&&o.push(`Current file: ${V(s,260)}`),r.length&&o.push(`TODO: ${r.join("; ")}`),t.nextActions.length&&o.push(`Next action: ${V(t.nextActions[0])}`),t.blockers.length&&o.push(`Blocker: ${V(t.blockers[0])}`),o.push("","CONTINUATION CONTRACT:","- Continue from this compact handoff; do not reconstruct the prior session.","- NEVER inspect .toolnet/sessions/**, 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."),o.join(`
103
- `)}async function Ji(e){let t=Gi(e.project);if(!t)try{t=await re(e.project,e.storage)}catch{t=null}let n=t?Hi(e.project,t):"";if(!n)try{n=(await Rn(e.project,e.storage,700))?.text??""}catch{n=""}let r=Un(e.project.rootPath,{maxAssets:6,maxChars:900});return[n,r,Nn()].filter(Boolean).join(`
102
+ `)}function Bi(e,t,n){let r=n??bt(zi(),".config","toolnet-memory","injections","agy");return bt(r,`${e.id}-${t}.json`)}function Vi(e){if(!Jn(e))return null;try{return JSON.parse(Hn(e,"utf8"))}catch{return null}}function J(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 Ji(e){let t=bt(e.rootPath,".toolnet","work","current.json");if(!Jn(t))return null;try{let n=JSON.parse(Hn(t,"utf8"));if(n.version===1&&n.projectId===e.id)return n}catch{}return null}function Hi(e,t){let n=t.tasks.filter(i=>i.status==="completed").slice(-3).map(i=>J(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=>J(i,220)).filter(Boolean))),s=t.filesTouched.at(-1),o=["[TOOLNET CONTINUITY HANDOFF]",`Project: ${e.name}`];return t.currentTask?.title?o.push(`Task: ${J(t.currentTask.title)}`):t.currentPhase?.title?o.push(`Task: ${J(t.currentPhase.title)}`):t.goal&&o.push(`Task: ${J(t.goal)}`),n.length&&o.push(`Completed: ${n.join("; ")}`),s&&o.push(`Current file: ${J(s,260)}`),r.length&&o.push(`TODO: ${r.join("; ")}`),t.nextActions.length&&o.push(`Next action: ${J(t.nextActions[0])}`),t.blockers.length&&o.push(`Blocker: ${J(t.blockers[0])}`),o.push("","CONTINUATION CONTRACT:","- Continue from this compact handoff; do not reconstruct the prior session.","- NEVER inspect .toolnet/sessions/**, 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."),o.join(`
103
+ `)}async function Gi(e){let t=Ji(e.project);if(!t)try{t=await re(e.project,e.storage)}catch{t=null}let n=t?Hi(e.project,t):"";if(!n)try{n=(await Nn(e.project,e.storage,700))?.text??""}catch{n=""}let r=Vn(e.project.rootPath,{maxAssets:6,maxChars:900});return[n,r,_n()].filter(Boolean).join(`
104
104
 
105
- `).trim()}async function Hn(e){let t=e.now??Date.now(),n=e.resumeAfterMs??360*60*1e3,r=Ui(e.project,e.conversationId,e.markerDirectory),s=Vi(r),o=s?Date.parse(s.injectedAt):0,i=o?t-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let c=e.invocationNum===0,a=i>=n;if(s&&!c&&!a)return{};let u=await Ji({project:e.project,storage:e.storage});return u?(Bi(qi(r),{recursive:!0}),M(r,{digest:v(u),injectedAt:new Date(t).toISOString()}),{injectSteps:[{ephemeralMessage:u}]}):{}}import{existsSync as Xp,mkdirSync as Yi,readFileSync as Zp,renameSync as Qi,writeFileSync as Xi}from"node:fs";import{dirname as Zi,join as ea}from"node:path";function ta(e){return ea(e.rootPath,".toolnet","context","session-origin.json")}function na(e,t){Yi(Zi(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Xi(n,`${JSON.stringify(t,null,2)}
106
- `,{encoding:"utf8",mode:384}),Qi(n,e)}function Ve(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function Jn(e,t){let n=Ve(t.observations,"file"),r=Ve(t.observations,"next_action"),s=Ve(t.observations,"blocker"),o=Ve(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:s?.text??t.workState.blockers.at(-1),latestDecision:o?.text??t.workState.decisions.at(-1)};return na(ta(e),i),i}import{existsSync as ra,readFileSync as sa,writeFileSync as oa}from"node:fs";import{join as ia}from"node:path";var Qn="<!-- TOOLNET:STABLE-WORK:BEGIN -->",xt="<!-- TOOLNET:STABLE-WORK:END -->";function At(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function F(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Yn(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${At(n)} ${n.title}`)]:[]}function aa(e){let t=[Qn,"# 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:",`${At(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${At(e.currentTask)} ${e.currentTask.title}`),t.push(...Yn("Phases",e.phases)),t.push(...Yn("TODO / Tasks",e.tasks)),t.push(...F("Next actions",e.nextActions)),t.push(...F("Blockers",e.blockers)),t.push(...F("Important decisions",e.decisions)),t.push(...F("Active files",e.activeFiles??[])),t.push(...F("Modified files",e.modifiedFiles??[])),t.push(...F("Created files",e.createdFiles??[])),t.push(...F("Deleted files",e.deletedFiles??[])),t.push(...F("Files touched",e.filesTouched)),t.push(...F("Recent commands",e.commands??[])),t.push(...F("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.",xt),t.join(`
107
- `)}function Xn(e,t){let n=ia(e.rootPath,".toolnet","current.md"),r="";if(ra(n))try{r=sa(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=aa(t),o=r.indexOf(Qn),i=r.indexOf(xt),c;o>=0&&i>=o?c=[r.slice(0,o).trimEnd(),s,r.slice(i+xt.length).trimStart()].filter(Boolean).join(`
105
+ `).trim()}async function Gn(e){let t=e.now??Date.now(),n=e.resumeAfterMs??360*60*1e3,r=Bi(e.project,e.conversationId,e.markerDirectory),s=Vi(r),o=s?Date.parse(s.injectedAt):0,i=o?t-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let c=e.invocationNum===0,a=i>=n;if(s&&!c&&!a)return{};let u=await Gi({project:e.project,storage:e.storage});return u?(Di(qi(r),{recursive:!0}),P(r,{digest:v(u),injectedAt:new Date(t).toISOString()}),{injectSteps:[{ephemeralMessage:u}]}):{}}import{existsSync as Gp,mkdirSync as Ui,readFileSync as Up,renameSync as Yi,writeFileSync as Qi}from"node:fs";import{dirname as Xi,join as Zi}from"node:path";function ea(e){return Zi(e.rootPath,".toolnet","context","session-origin.json")}function ta(e,t){Ui(Xi(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Qi(n,`${JSON.stringify(t,null,2)}
106
+ `,{encoding:"utf8",mode:384}),Yi(n,e)}function Je(e,t){return[...e].filter(n=>n.kind===t).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function Un(e,t){let n=Je(t.observations,"file"),r=Je(t.observations,"next_action"),s=Je(t.observations,"blocker"),o=Je(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:s?.text??t.workState.blockers.at(-1),latestDecision:o?.text??t.workState.decisions.at(-1)};return ta(ea(e),i),i}import{existsSync as na,readFileSync as ra,writeFileSync as sa}from"node:fs";import{join as oa}from"node:path";var Qn="<!-- TOOLNET:STABLE-WORK:BEGIN -->",xt="<!-- TOOLNET:STABLE-WORK:END -->";function jt(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function K(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Yn(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${jt(n)} ${n.title}`)]:[]}function ia(e){let t=[Qn,"# 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:",`${jt(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${jt(e.currentTask)} ${e.currentTask.title}`),t.push(...Yn("Phases",e.phases)),t.push(...Yn("TODO / Tasks",e.tasks)),t.push(...K("Next actions",e.nextActions)),t.push(...K("Blockers",e.blockers)),t.push(...K("Important decisions",e.decisions)),t.push(...K("Active files",e.activeFiles??[])),t.push(...K("Modified files",e.modifiedFiles??[])),t.push(...K("Created files",e.createdFiles??[])),t.push(...K("Deleted files",e.deletedFiles??[])),t.push(...K("Files touched",e.filesTouched)),t.push(...K("Recent commands",e.commands??[])),t.push(...K("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.",xt),t.join(`
107
+ `)}function Xn(e,t){let n=oa(e.rootPath,".toolnet","current.md"),r="";if(na(n))try{r=ra(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=ia(t),o=r.indexOf(Qn),i=r.indexOf(xt),c;o>=0&&i>=o?c=[r.slice(0,o).trimEnd(),s,r.slice(i+xt.length).trimStart()].filter(Boolean).join(`
108
108
 
109
109
  `):c=r.trim()?`${r.trim()}
110
110
 
111
- ${s}`:s,oa(n,`${c.trim()}
112
- `,{encoding:"utf8",mode:384})}import{existsSync as hr,mkdirSync as za,readFileSync as qa}from"node:fs";import{join as Pt}from"node:path";function er(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 sr=[/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],da=[/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],pa=[/\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],fa=[/\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],ma=[/đã 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],tr=[/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],ga=[/\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],ha=[/đườ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],ya=[/\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],nr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ka=new Set(["payload","data","content","message","messages","parts","summary"]);function N(e,t){return t.some(n=>n.test(e))}function or(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Sa(e){return or(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function va(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 It(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||nr.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))It(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(nr.has(s)||ka.has(s))&&It(o,s,n,r+1)}}function wa(e){let t=[];It(e.data,void 0,t);let n=[],r=new Set;for(let s of t)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=or(o);if(va(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function rr(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function ba(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",s=t==="assistant"||n.type==="assistant_message";return r&&N(e,sr)?{kind:"rule",confidence:.98}:r&&N(e,da)?{kind:"rule",confidence:.92}:N(e,pa)?{kind:N(e,tr)?"architecture":"decision",confidence:r?.93:.86}:r&&N(e,fa)?{kind:"todo",confidence:.87}:N(e,tr)&&N(e,ga)?{kind:"architecture",confidence:r?.88:.82}:s&&N(e,ma)?{kind:"fix",confidence:.8}:r&&N(e,ha)&&N(e,ya)?{kind:"context",confidence:.79}:null}function xa(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Aa(e,t,n){return e==="rule"&&N(n,sr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":er(t,n)}function ir(e,t){let n=[],r=new Set,s=new Map;for(let o of t){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,c=rr(o);i&&c&&s.set(i,c)}for(let o of t){let i=rr(o),c=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&c&&(i=s.get(c)??"");for(let a of wa(o)){let u=ba(a,i,o);if(!u||u.confidence<.75)continue;let f=xa(u.kind),d=Sa(a),p=v([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:f,content:a,confidence:u.confidence,importance:Aa(u.kind,f,a),tags:[f],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as Ia}from"node:crypto";var ja=["project-knowledge","implementation","continuation","session-context"],Pa={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function jt(e){return Ia("sha256").update(e).digest("hex")}function Ge(e,t){return`${e}:${jt(t).slice(0,24)}`}function Ea(e){try{return jt(JSON.stringify(e))}catch{return jt(String(e))}}function Q(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 cr(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 Ma(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function ar(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Ca(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=>cr(t.content)).join(" | ")}function Ta(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=>cr(t.content)).join(`
113
- `)}function ur(e,t){let n=e.slice().sort((p,l)=>p.sequence-l.sequence||p.timestamp.localeCompare(l.timestamp)||p.id.localeCompare(l.id)),r=n.map(p=>({id:Ge("raw",[p.projectId,p.agent,p.nativeSessionId,p.id,String(p.sequence)].join("|")),level:"raw",eventId:p.id,sourceEventId:p.sourceEventId,sequence:p.sequence,type:p.type,role:p.role,timestamp:p.timestamp,sourcePath:p.provenance.sourcePath,payloadDigest:Ea(p.data)})),s=new Map,o=new Map;n.forEach((p,l)=>{let g=r[l];g&&(s.set(p.id,g.id),p.sourceEventId&&o.set(p.sourceEventId,g.id))});let i=t.map(p=>{let l=Q([...p.provenance.eventIds.map(g=>s.get(g)),...p.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:Ge("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:Q([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:l,sourcePaths:Q(p.provenance.sourcePaths)}}),c=new Map;for(let p of i){let l=Ma(p.kind),g=c.get(l)??[];g.push(p),c.set(l,g)}let a=[];for(let p of ja){let l=c.get(p);if(!l?.length)continue;let g=l.slice().sort((h,y)=>y.importanceScore-h.importanceScore||y.confidence-h.confidence||h.id.localeCompare(y.id)),k=g.map(h=>h.id);a.push({id:Ge("scene",`${p}|${k.join("|")}`),level:"scene",kind:p,title:Pa[p],summary:Ca(g),factIds:k,importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:ar(g.map(h=>h.confidence)),tags:Q(["level:scene",`scene:${p}`,...g.flatMap(h=>h.tags)]),sourcePaths:Q(g.flatMap(h=>h.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),f=[];for(let p of a){let g=p.factIds.map(y=>u.get(y)).filter(y=>!!y).filter(y=>(y.knowledgeClass==="permanent"||y.knowledgeClass==="task")&&y.importanceScore>=.55);if(g.length===0)continue;let k=g.some(y=>y.knowledgeClass==="permanent")?"permanent":"task",h=Ta(g);f.push({id:Ge("knowledge",`${p.id}|${k}|${g.map(y=>y.id).join("|")}`),level:"knowledge",knowledgeClass:k,title:p.title,content:h,sceneIds:[p.id],factIds:g.map(y=>y.id),importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:ar(g.map(y=>y.confidence)),tags:Q(["level:knowledge",`class:${k}`,`scene:${p.kind}`,...g.flatMap(y=>y.tags)]),sourcePaths:Q(g.flatMap(y=>y.sourcePaths))})}let d=[];for(let p of i)for(let l of p.rawIds)d.push({from:l,to:p.id,type:"supports"});for(let p of a)for(let l of p.factIds)d.push({from:l,to:p.id,type:"belongs_to"});for(let p of f)for(let l of p.sceneIds)d.push({from:l,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:a,knowledge:f,links:d,stats:{raw:r.length,facts:i.length,scenes:a.length,knowledge:f.length,links:d.length}}}function X(){let e=Ie(),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",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),c=n,a=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:c,archiveRemote:a}}function lr(e){return(e||X()).rawTranscript}function dr(e){return(e||X()).durableMemoryMaxItemsPerSession}function pr(e){return(e||X()).sessionSummaryMaxTokens}function fr(e){return(e||X()).archiveRemote}var mr=new H;function gr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(mr.sanitizeValue(r))}catch{}let n=mr.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 Oa(e,t){let n=e.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);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 o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function _a(e,t){let n=[],r=new Set;for(let i of e){let c=i.split(`
114
- `).filter(a=>a.trim());for(let a of c){let u=a.trim();if(u.length<15)continue;let f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=Oa(u,d);if(p<.3)continue;let l=gr(u);n.push({category:d,text:l,importance:p,sourceSessionId:t})}}let s=X(),o=dr(s);return n.sort((i,c)=>c.importance-i.importance).slice(0,o)}function Ra(e){let t=X(),n=pr(t),o=e.join(`
111
+ ${s}`:s,sa(n,`${c.trim()}
112
+ `,{encoding:"utf8",mode:384})}import{existsSync as gr,mkdirSync as La,readFileSync as Da}from"node:fs";import{join as Ct}from"node:path";function Zn(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 rr=[/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],ca=[/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],ua=[/\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],la=[/\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],da=[/đã 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],er=[/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],pa=[/\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],fa=[/đườ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],ma=[/\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],tr=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),ga=new Set(["payload","data","content","message","messages","parts","summary"]);function _(e,t){return t.some(n=>n.test(e))}function sr(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function ha(e){return sr(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function ya(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 At(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||tr.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))At(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(tr.has(s)||ga.has(s))&&At(o,s,n,r+1)}}function ka(e){let t=[];At(e.data,void 0,t);let n=[],r=new Set;for(let s of t)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=sr(o);if(ya(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function nr(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Sa(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",s=t==="assistant"||n.type==="assistant_message";return r&&_(e,rr)?{kind:"rule",confidence:.98}:r&&_(e,ca)?{kind:"rule",confidence:.92}:_(e,ua)?{kind:_(e,er)?"architecture":"decision",confidence:r?.93:.86}:r&&_(e,la)?{kind:"todo",confidence:.87}:_(e,er)&&_(e,pa)?{kind:"architecture",confidence:r?.88:.82}:s&&_(e,da)?{kind:"fix",confidence:.8}:r&&_(e,fa)&&_(e,ma)?{kind:"context",confidence:.79}:null}function va(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function wa(e,t,n){return e==="rule"&&_(n,rr)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Zn(t,n)}function or(e,t){let n=[],r=new Set,s=new Map;for(let o of t){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,c=nr(o);i&&c&&s.set(i,c)}for(let o of t){let i=nr(o),c=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&c&&(i=s.get(c)??"");for(let a of ka(o)){let u=Sa(a,i,o);if(!u||u.confidence<.75)continue;let f=va(u.kind),d=ha(a),p=v([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:p,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:f,content:a,confidence:u.confidence,importance:wa(u.kind,f,a),tags:[f],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as ba}from"node:crypto";var xa=["project-knowledge","implementation","continuation","session-context"],ja={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function It(e){return ba("sha256").update(e).digest("hex")}function He(e,t){return`${e}:${It(t).slice(0,24)}`}function Aa(e){try{return It(JSON.stringify(e))}catch{return It(String(e))}}function Q(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 ar(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 Ia(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function ir(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Ca(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=>ar(t.content)).join(" | ")}function Ma(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=>ar(t.content)).join(`
113
+ `)}function cr(e,t){let n=e.slice().sort((p,l)=>p.sequence-l.sequence||p.timestamp.localeCompare(l.timestamp)||p.id.localeCompare(l.id)),r=n.map(p=>({id:He("raw",[p.projectId,p.agent,p.nativeSessionId,p.id,String(p.sequence)].join("|")),level:"raw",eventId:p.id,sourceEventId:p.sourceEventId,sequence:p.sequence,type:p.type,role:p.role,timestamp:p.timestamp,sourcePath:p.provenance.sourcePath,payloadDigest:Aa(p.data)})),s=new Map,o=new Map;n.forEach((p,l)=>{let g=r[l];g&&(s.set(p.id,g.id),p.sourceEventId&&o.set(p.sourceEventId,g.id))});let i=t.map(p=>{let l=Q([...p.provenance.eventIds.map(g=>s.get(g)),...p.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:He("fact",p.fingerprint),level:"fact",fingerprint:p.fingerprint,kind:p.kind,type:p.type,content:p.content,knowledgeClass:p.knowledgeClass,importanceScore:p.importanceScore,confidence:p.confidence,tags:Q([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:l,sourcePaths:Q(p.provenance.sourcePaths)}}),c=new Map;for(let p of i){let l=Ia(p.kind),g=c.get(l)??[];g.push(p),c.set(l,g)}let a=[];for(let p of xa){let l=c.get(p);if(!l?.length)continue;let g=l.slice().sort((h,y)=>y.importanceScore-h.importanceScore||y.confidence-h.confidence||h.id.localeCompare(y.id)),k=g.map(h=>h.id);a.push({id:He("scene",`${p}|${k.join("|")}`),level:"scene",kind:p,title:ja[p],summary:Ca(g),factIds:k,importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:ir(g.map(h=>h.confidence)),tags:Q(["level:scene",`scene:${p}`,...g.flatMap(h=>h.tags)]),sourcePaths:Q(g.flatMap(h=>h.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),f=[];for(let p of a){let g=p.factIds.map(y=>u.get(y)).filter(y=>!!y).filter(y=>(y.knowledgeClass==="permanent"||y.knowledgeClass==="task")&&y.importanceScore>=.55);if(g.length===0)continue;let k=g.some(y=>y.knowledgeClass==="permanent")?"permanent":"task",h=Ma(g);f.push({id:He("knowledge",`${p.id}|${k}|${g.map(y=>y.id).join("|")}`),level:"knowledge",knowledgeClass:k,title:p.title,content:h,sceneIds:[p.id],factIds:g.map(y=>y.id),importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:ir(g.map(y=>y.confidence)),tags:Q(["level:knowledge",`class:${k}`,`scene:${p.kind}`,...g.flatMap(y=>y.tags)]),sourcePaths:Q(g.flatMap(y=>y.sourcePaths))})}let d=[];for(let p of i)for(let l of p.rawIds)d.push({from:l,to:p.id,type:"supports"});for(let p of a)for(let l of p.factIds)d.push({from:l,to:p.id,type:"belongs_to"});for(let p of f)for(let l of p.sceneIds)d.push({from:l,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:a,knowledge:f,links:d,stats:{raw:r.length,facts:i.length,scenes:a.length,knowledge:f.length,links:d.length}}}function X(){let e=Ae(),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",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),c=n,a=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:c,archiveRemote:a}}function ur(e){return(e||X()).rawTranscript}function lr(e){return(e||X()).durableMemoryMaxItemsPerSession}function dr(e){return(e||X()).sessionSummaryMaxTokens}function pr(e){return(e||X()).archiveRemote}var fr=new G;function mr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(fr.sanitizeValue(r))}catch{}let n=fr.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 Pa(e,t){let n=e.toLowerCase(),r=.5,s=["nh\u1EDB","remember","quy t\u1EAFc","rule","t\u1EEB gi\u1EDD","from now","kh\xF4ng \u0111\u01B0\u1EE3c","must not","lu\xF4n lu\xF4n","always","never","critical","important","blocker","deploy","production","architecture"];for(let i of s)n.includes(i)&&(r+=.15);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 o=[/npm (notice|warn|ERR)/i,/\d+ packages? in \d+/i,/found \d+ vulnerabilities/i,/up to date/i,/added \d+ packages/i,/^(ok|done|success|error|warning)$/i];for(let i of o)i.test(e)&&(r-=.4);return Math.max(0,Math.min(1,r))}function Ta(e,t){let n=[],r=new Set;for(let i of e){let c=i.split(`
114
+ `).filter(a=>a.trim());for(let a of c){let u=a.trim();if(u.length<15)continue;let f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=Pa(u,d);if(p<.3)continue;let l=mr(u);n.push({category:d,text:l,importance:p,sourceSessionId:t})}}let s=X(),o=lr(s);return n.sort((i,c)=>c.importance-i.importance).slice(0,o)}function Ea(e){let t=X(),n=dr(t),o=e.join(`
115
115
 
116
116
  `).split(`
117
- `).filter(i=>{let c=i.trim();return c.length>20&&!c.startsWith("npm")&&!c.startsWith("\u2713")&&!c.startsWith("Error:")}).slice(0,20).map(i=>gr(i)).join(`
118
- `);return qe(o,n)}function He(e,t){let r=(Array.isArray(e)?e:e.split(`
117
+ `).filter(i=>{let c=i.trim();return c.length>20&&!c.startsWith("npm")&&!c.startsWith("\u2713")&&!c.startsWith("Error:")}).slice(0,20).map(i=>mr(i)).join(`
118
+ `);return Be(o,n)}function Ge(e,t){let r=(Array.isArray(e)?e:e.split(`
119
119
 
120
- `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=_a(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),c=s.filter(l=>l.category==="file").map(l=>l.text),a=s.filter(l=>l.category==="fix").map(l=>l.text),u=s.filter(l=>l.category==="blocker").map(l=>l.text),f=s.filter(l=>l.category==="next_action").map(l=>l.text),d=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Ra(r),decisions:o,projectRules:i,filesChanged:c,bugsFixed:a,commands:d,blockers:u,nextActions:f,durableFacts:s}}function G(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Na(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,s=t.get(r);(!s||n.sequence>s.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function La(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Ka(e){let t=La(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function Fa(e){return e.importance==="temporary"||e.confidence<.78?"transient":e.kind==="rule"||e.kind==="architecture"?"permanent":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function $a(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 Da(e){let t=Fa(e),n=Ka(e),r=$a(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:G([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Wa(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 Ba(e,t,n){let r=He(Wa(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),c=G([...s,...r.nextActions]),a=G([...r.nextActions,...s]);return{summary:r.summary,state:{task:a[0]??c[0],decisions:G(r.decisions),files:G([...r.filesChanged,...o]),todos:c,completed:G(r.bugsFixed),blockers:G(r.blockers),nextActions:a,architecture:G(i)}}}function Je(e,t){let n=Na(t),r=ir(e,n).map(Da),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,d)=>d.importanceScore-f.importanceScore),{summary:o,state:i}=Ba(e,n,s),c=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),a=ur(n,s),u=f=>r.filter(d=>d.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:c,hierarchy:a,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}function yr(e){return Pt(e.rootPath,".toolnet","memory","checkpoints")}function kr(e){return Pt(yr(e),"latest.json")}function Ua(e){let t=kr(e);if(!hr(t))return null;try{let n=JSON.parse(qa(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function Va(e){return["rule","architecture","decision","fix"].includes(e)}function Ga(e,t){return t.length===0?[]:Je(e,t).candidates.filter(r=>Va(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 Ha(e,t){let n=new Map;for(let r of[...e,...t]){let s=n.get(r.fingerprint);(!s||r.importanceScore>s.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,s)=>s.importanceScore-r.importanceScore||s.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Ja(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 Sr(e,t,n,r){let s=Ua(e),o=Ha(s?.durableFacts??[],Ga(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,c=r.phases.filter(h=>h.status==="completed").map(h=>h.title),a=r.tasks.filter(h=>h.status==="completed").map(h=>h.title),u=r.phases.filter(h=>h.status!=="completed"&&h.status!=="cancelled").map(h=>h.title),f=r.tasks.filter(h=>h.status!=="completed"&&h.status!=="cancelled").map(h=>h.title),d={work:Ja(r),durableFacts:o.map(h=>h.fingerprint).sort()},p=v(JSON.stringify(d)).slice(0,32),l={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:c,tasks:a},remaining:{phases:u,tasks:f},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:p},g=yr(e);za(g,{recursive:!0,mode:448});let k=Pt(g,`${p}.json`);return hr(k)||M(k,l),M(kr(e),l),l}import{existsSync as Qa}from"node:fs";import{dirname as Xa,join as Za,parse as ec,resolve as tc}from"node:path";function vr(e){for(let t of e){let n=tc(t),r=ec(n).root;for(;;){if(Qa(Za(n,".toolnet","project.json")))return new Pe().detect(n);if(n===r)break;let s=Xa(n);if(s===n)break;n=s}}return null}import{homedir as cs}from"node:os";import{join as Eu,resolve as Mu}from"node:path";import{join as nc}from"node:path";function wr(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function br(e,t,n){let r=t.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=wr(r.toLowerCase(),"agent"),i=wr(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"sessions",o,i].join("/"),localDirectory:nc(e.rootPath,".toolnet","sessions",o,i)}}function xr(e){return String(e).padStart(12,"0")}var Ye=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)+`
120
+ `).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Ta(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),c=s.filter(l=>l.category==="file").map(l=>l.text),a=s.filter(l=>l.category==="fix").map(l=>l.text),u=s.filter(l=>l.category==="blocker").map(l=>l.text),f=s.filter(l=>l.category==="next_action").map(l=>l.text),d=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Ea(r),decisions:o,projectRules:i,filesChanged:c,bugsFixed:a,commands:d,blockers:u,nextActions:f,durableFacts:s}}function H(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Oa(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,s=t.get(r);(!s||n.sequence>s.sequence)&&t.set(r,n)}return[...t.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function Ra(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Na(e){let t=Ra(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function _a(e){return e.importance==="temporary"||e.confidence<.78?"transient":e.kind==="rule"||e.kind==="architecture"?"permanent":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function $a(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 Fa(e){let t=_a(e),n=Na(e),r=$a(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:H([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Ka(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 Wa(e,t,n){let r=Ge(Ka(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),c=H([...s,...r.nextActions]),a=H([...r.nextActions,...s]);return{summary:r.summary,state:{task:a[0]??c[0],decisions:H(r.decisions),files:H([...r.filesChanged,...o]),todos:c,completed:H(r.bugsFixed),blockers:H(r.blockers),nextActions:a,architecture:H(i)}}}function Ue(e,t){let n=Oa(t),r=or(e,n).map(Fa),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,d)=>d.importanceScore-f.importanceScore),{summary:o,state:i}=Wa(e,n,s),c=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),a=cr(n,s),u=f=>r.filter(d=>d.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:c,hierarchy:a,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}function hr(e){return Ct(e.rootPath,".toolnet","memory","checkpoints")}function yr(e){return Ct(hr(e),"latest.json")}function za(e){let t=yr(e);if(!gr(t))return null;try{let n=JSON.parse(Da(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function qa(e){return["rule","architecture","decision","fix"].includes(e)}function Ba(e,t){return t.length===0?[]:Ue(e,t).candidates.filter(r=>qa(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 Va(e,t){let n=new Map;for(let r of[...e,...t]){let s=n.get(r.fingerprint);(!s||r.importanceScore>s.importanceScore)&&n.set(r.fingerprint,r)}return Array.from(n.values()).sort((r,s)=>s.importanceScore-r.importanceScore||s.createdAt.localeCompare(r.createdAt)).slice(0,80)}function Ja(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 kr(e,t,n,r){let s=za(e),o=Va(s?.durableFacts??[],Ba(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,c=r.phases.filter(h=>h.status==="completed").map(h=>h.title),a=r.tasks.filter(h=>h.status==="completed").map(h=>h.title),u=r.phases.filter(h=>h.status!=="completed"&&h.status!=="cancelled").map(h=>h.title),f=r.tasks.filter(h=>h.status!=="completed"&&h.status!=="cancelled").map(h=>h.title),d={work:Ja(r),durableFacts:o.map(h=>h.fingerprint).sort()},p=v(JSON.stringify(d)).slice(0,32),l={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:c,tasks:a},remaining:{phases:u,tasks:f},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:p},g=hr(e);La(g,{recursive:!0,mode:448});let k=Ct(g,`${p}.json`);return gr(k)||P(k,l),P(yr(e),l),l}import{existsSync as Ha}from"node:fs";import{dirname as Ga,join as Ua,parse as Ya,resolve as Qa}from"node:path";function Sr(e){for(let t of e){let n=Qa(t),r=Ya(n).root;for(;;){if(Ha(Ua(n,".toolnet","project.json")))return new Ce().detect(n);if(n===r)break;let s=Ga(n);if(s===n)break;n=s}}return null}import{homedir as as}from"node:os";import{join as ju,resolve as Au}from"node:path";import{join as Xa}from"node:path";function vr(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function wr(e,t,n){let r=t.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=vr(r.toLowerCase(),"agent"),i=vr(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"sessions",o,i].join("/"),localDirectory:Xa(e.rootPath,".toolnet","sessions",o,i)}}function br(e){return String(e).padStart(12,"0")}var Ye=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)+`
121
121
  `,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let c=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!c)continue;let a=Number(c[1]),u=Number(c[2]);!Number.isFinite(a)||!Number.isFinite(u)||(s.push({key:i.key,start:a,end:u}),o=Math.max(o,u))}return s.sort((i,c)=>i.start-c.start),{chunks:s,maxSequence:o}}split(t){let n=[],r=[],s=0;for(let o of t){let i=Buffer.byteLength(JSON.stringify(o)+`
122
- `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(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,s={}){let o=await this.loadManifest(t),i=await this.scan(t),c=n.filter(h=>h.sequence>i.maxSequence),a=0;for(let h of this.split(c)){let y=h[0],S=h[h.length-1],C=h.map(O=>JSON.stringify(O)).join(`
122
+ `,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(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,s={}){let o=await this.loadManifest(t),i=await this.scan(t),c=n.filter(h=>h.sequence>i.maxSequence),a=0;for(let h of this.split(c)){let y=h[0],S=h[h.length-1],T=h.map(O=>JSON.stringify(O)).join(`
123
123
  `)+`
124
- `,T=v(C).slice(0,16),E=[t.remotePrefix,"events",`${xr(y.sequence)}-${xr(S.sequence)}-${T}.jsonl`].join("/");await this.storage.exists(E)||await this.storage.put(E,C,"application/x-ndjson"),a+=h.length}let u=await this.scan(t),f=n[n.length-1],d=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?d="idle":f?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),l=n[0],g={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:o?.createdAt??l?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:f?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(g.title=s.title??o?.title);let 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:p};return await this.putJson(`${t.remotePrefix}/cursor.json`,k),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:a,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:d}}};import{closeSync as Mt,existsSync as cc,fsyncSync as uc,mkdirSync as lc,openSync as Ct,readSync as dc,rmSync as Ir,statSync as jr,writeSync as pc}from"node:fs";import{join as Tt}from"node:path";var rc=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),sc=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function oc(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function ic(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(sc.has(r))return n}}return null}function Et(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>Et(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=ic(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))rc.has(oc(o))||(s[o]=Et(i,t+1));return s}function ac(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function Z(e){return e?.trim()||void 0}function Ar(e,t={}){let n={...e.provenance??{}},r=Z(e.source)??Z(t.source)??Z(n.source);return{...e,timestamp:ac(e.timestamp),source:r,turnId:Z(e.turnId)??Z(t.turnId),cwd:Z(e.cwd)??Z(t.cwd),data:Et(e.data??{}),provenance:n}}var fc=12e4,mc=80,gc=2e3;function hc(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}var Qe=class{constructor(t,n={}){this.identity=t;this.eventContext=n;lc(t.localDirectory,{recursive:!0}),this.eventsFile=Tt(t.localDirectory,"events.jsonl"),this.stateFile=Tt(t.localDirectory,"state.json"),this.lockFile=Tt(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 Zt(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(t){M(this.stateFile,t)}acquireLock(){for(let t=0;t<mc;t+=1)try{return Ct(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-jr(this.lockFile).mtimeMs>fc){Ir(this.lockFile,{force:!0});continue}}catch{}hc(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Mt(n),Ir(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let d of t){let p=Ar(d,this.eventContext),l=p.timestamp??new Date().toISOString(),g=p.data??{},k=p.provenance?.rawDigest??v(Xt(g)),h=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,p.type,l,k].join("|"),y=v(h).slice(0,32);if(r.has(y))continue;s+=1;let S={version:1,id:y,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:l,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:k}};p.role!==void 0&&(S.role=p.role),p.turnId!==void 0&&(S.turnId=p.turnId),p.cwd!==void 0&&(S.cwd=p.cwd),p.sourceEventId!==void 0&&(S.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(S.sourceSequence=p.sourceSequence),o.push(S),r.add(y)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
124
+ `,E=v(T).slice(0,16),M=[t.remotePrefix,"events",`${br(y.sequence)}-${br(S.sequence)}-${E}.jsonl`].join("/");await this.storage.exists(M)||await this.storage.put(M,T,"application/x-ndjson"),a+=h.length}let u=await this.scan(t),f=n[n.length-1],d=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?d="idle":f?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),l=n[0],g={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:o?.createdAt??l?.timestamp??p,updatedAt:f?.timestamp??p,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:f?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(g.title=s.title??o?.title);let 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:p};return await this.putJson(`${t.remotePrefix}/cursor.json`,k),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:a,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:d}}};import{closeSync as Pt,existsSync as sc,fsyncSync as oc,mkdirSync as ic,openSync as Tt,readSync as ac,rmSync as jr,statSync as Ar,writeSync as cc}from"node:fs";import{join as Et}from"node:path";var Za=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),ec=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function tc(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function nc(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(ec.has(r))return n}}return null}function Mt(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>Mt(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=nc(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))Za.has(tc(o))||(s[o]=Mt(i,t+1));return s}function rc(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function Z(e){return e?.trim()||void 0}function xr(e,t={}){let n={...e.provenance??{}},r=Z(e.source)??Z(t.source)??Z(n.source);return{...e,timestamp:rc(e.timestamp),source:r,turnId:Z(e.turnId)??Z(t.turnId),cwd:Z(e.cwd)??Z(t.cwd),data:Mt(e.data??{}),provenance:n}}var uc=12e4,lc=80,dc=2e3;function pc(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}var Qe=class{constructor(t,n={}){this.identity=t;this.eventContext=n;ic(t.localDirectory,{recursive:!0}),this.eventsFile=Et(t.localDirectory,"events.jsonl"),this.stateFile=Et(t.localDirectory,"state.json"),this.lockFile=Et(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 Zt(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(t){P(this.stateFile,t)}acquireLock(){for(let t=0;t<lc;t+=1)try{return Tt(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Ar(this.lockFile).mtimeMs>uc){jr(this.lockFile,{force:!0});continue}}catch{}pc(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Pt(n),jr(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let d of t){let p=xr(d,this.eventContext),l=p.timestamp??new Date().toISOString(),g=p.data??{},k=p.provenance?.rawDigest??v(Xt(g)),h=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,p.type,l,k].join("|"),y=v(h).slice(0,32);if(r.has(y))continue;s+=1;let S={version:1,id:y,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:l,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:k}};p.role!==void 0&&(S.role=p.role),p.turnId!==void 0&&(S.turnId=p.turnId),p.cwd!==void 0&&(S.cwd=p.cwd),p.sourceEventId!==void 0&&(S.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(S.sourceSequence=p.sourceSequence),o.push(S),r.add(y)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
125
125
  `)+`
126
- `,c=Ct(this.eventsFile,"a",384);try{pc(c,i,null,"utf8"),uc(c)}finally{Mt(c)}let a=o[o.length-1],u="active";a.type==="session_end"||a.type==="session_idle"?u="idle":a.type==="error"&&(u="error");let f=Array.from(r).slice(-gc);return this.saveStateUnsafe({...n,status:u,updatedAt:a.timestamp,lastLocalEventAt:a.timestamp,lastSequence:a.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let t=this.loadStateUnsafe();if(!cc(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=jr(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=Ct(this.eventsFile,"r");try{dc(i,o,0,s,r)}finally{Mt(i)}return{events:o.toString("utf8").split(`
127
- `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.loadStateUnsafe(),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.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as uu,existsSync as lu,openSync as du,readSync as pu,statSync as fu}from"node:fs";import{createHash as Ac}from"node:crypto";import{existsSync as Ic,readdirSync as jc,readFileSync as Pc}from"node:fs";import{basename as Ec,join as zr}from"node:path";import{randomUUID as Mr}from"node:crypto";var I=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function he(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 te(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new I("Invalid Wiki slug",400);return t}function Pr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(te(r))}return he(t)}function yc(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Er(e){return{id:`revision-${Mr()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function ee(e){return structuredClone(e)}var Xe=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:he(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 ee([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=te(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new I(`Wiki page not found: ${t}`,404);return ee(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new I("Wiki title is required",400);let o=te(t.slug??r);if(n.pages.some(a=>a.slug===o))throw new I(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),c={id:`wiki-${Mr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:he(t.tags??[]),links:Pr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(c),n.revisions.push(Er(c)),ee(c)})}async updatePage(t,n){return this.mutate(r=>{let s=te(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new I(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new I("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=Pr(o.content)),n.tags!==void 0&&(o.tags=he(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Er(o)),ee(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return ee(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 ee(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=he(yc(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let c of r.pages){let a=c.title.toLowerCase(),u=c.slug.toLowerCase(),f=c.summary?.toLowerCase()??"",d=c.content.toLowerCase(),p=c.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),a===g&&(l+=10),a.includes(g)&&(l+=6),u.includes(g)&&(l+=5),p.some(k=>k===g)?l+=5:p.some(k=>k.includes(g))&&(l+=3),f.includes(g)&&(l+=2),d.includes(g)&&(l+=1);l>0&&i.push({page:ee(c),score:l})}return i.sort((c,a)=>a.score-c.score||a.page.updatedAt.localeCompare(c.page.updatedAt)).slice(0,o)}};var Cr="wiki/state.v1.json";function kc(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Sc(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 Ze=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Cr);if(!t){let n=kc(this.project);return await this.save(n),n}return Sc(t,this.project)}async save(t){await this.storage.put(Cr,JSON.stringify(t,null,2),"application/json")}};import{createHash as vc,randomUUID as Tr}from"node:crypto";var Or="wiki/governance.v1.json",Lr="toolnet.knowledge-governance.v1",_r=500,ye={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function wc(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Ot(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Rr(e){return vc("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function bc(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 xc(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),wc(t)}function Nr(e){let t=new Date().toISOString();return{schema:Lr,version:1,projectId:e,policy:{...ye},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Kr(e){let t=e.autoApproveThreshold??ye.autoApproveThreshold,n=e.criticalApproveThreshold??ye.criticalApproveThreshold,r=e.staleAfterDays??ye.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new I("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new I("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new I("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var et=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Or);if(!t){let n=Nr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Lr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Kr(n.policy??ye)}}catch{let n=Nr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Or,JSON.stringify(t,null,2),"application/json")}},tt=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:Tr(),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>_r&&(t.audit=t.audit.slice(-_r))}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=Kr({...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=xc(t),o=Ot(t.title),i=n.filter(f=>f.slug!==t.slug&&Ot(f.title)===o&&Rr(f.content)!==Rr(t.content)).map(f=>f.slug),c=bc(t),a=[];s<r.policy.autoApproveThreshold&&a.push(`confidence:${s.toFixed(2)}`),c&&s<r.policy.criticalApproveThreshold&&a.push("critical-knowledge"),i.length>0&&a.push("conflicting-knowledge");let u=i.length>0?"conflict":c?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||c&&s<r.policy.criticalApproveThreshold,reasons:a,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(a=>a.sourceKey===t.sourceKey&&a.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(),c={id:Tr(),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(c),this.audit(s,"knowledge:review-requested","system",{reviewId:c.id,sourceKey:c.sourceKey,metadata:{confidence:c.confidence,risk:c.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(c)}})}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 I(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new I("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId: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 I("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new I("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let a=(await r.listPages()).find(u=>u.slug===o.slug);if(a&&!a.tags.includes(o.marker))throw new I(`Wiki page '${o.slug}' is manually managed`,409);return a?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 d=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(f=>f.stale).map(({stale:f,...d})=>d),c=new Map;for(let f of r){let d=Ot(f.title),p=c.get(d)??[];p.push(f),c.set(d,p)}let a=[...c.entries()].filter(([,f])=>f.length>1).map(([f,d])=>({title:f,pages:d.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(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:a,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 qr="wiki/automation.v1.json",Ur="toolnet.wiki-automation.v1",Nt=8e3,Fr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Se(e){return Ac("sha256").update(JSON.stringify(e)).digest("hex")}function ke(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function $r(e){return Array.isArray(e)?e:[]}function Vr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function _t(e){return Array.isArray(e)?e.map(Vr).filter(t=>!!t):[]}function $(e,t){for(let n of t){let r=Vr(e[n]);if(r)return r}}function ve(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 nt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Fr.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=>nt(i,t+1,n));let s=ke(e);if(!s)return[];let o=[];for(let[i,c]of Object.entries(s)){let a=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Fr.has(a)||o.push(...nt(c,t+1,i))}return o}function Dr(e){let n=ve(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>nt(e[s],0,s)));return(n.length>0?n:ve(nt(e))).join(`
126
+ `,c=Tt(this.eventsFile,"a",384);try{cc(c,i,null,"utf8"),oc(c)}finally{Pt(c)}let a=o[o.length-1],u="active";a.type==="session_end"||a.type==="session_idle"?u="idle":a.type==="error"&&(u="error");let f=Array.from(r).slice(-dc);return this.saveStateUnsafe({...n,status:u,updatedAt:a.timestamp,lastLocalEventAt:a.timestamp,lastSequence:a.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let t=this.loadStateUnsafe();if(!sc(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Ar(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=Tt(this.eventsFile,"r");try{ac(i,o,0,s,r)}finally{Pt(i)}return{events:o.toString("utf8").split(`
127
+ `).filter(Boolean).map(u=>JSON.parse(u)),startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.loadStateUnsafe(),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.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ou,existsSync as iu,openSync as au,readSync as cu,statSync as uu}from"node:fs";import{createHash as vc}from"node:crypto";import{existsSync as wc,readdirSync as bc,readFileSync as xc}from"node:fs";import{basename as jc,join as zr}from"node:path";import{randomUUID as Mr}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function he(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 te(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new A("Invalid Wiki slug",400);return t}function Ir(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(te(r))}return he(t)}function fc(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Cr(e){return{id:`revision-${Mr()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function ee(e){return structuredClone(e)}var Xe=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:he(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 ee([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=te(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new A(`Wiki page not found: ${t}`,404);return ee(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=te(t.slug??r);if(n.pages.some(a=>a.slug===o))throw new A(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),c={id:`wiki-${Mr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:he(t.tags??[]),links:Ir(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(c),n.revisions.push(Cr(c)),ee(c)})}async updatePage(t,n){return this.mutate(r=>{let s=te(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=Ir(o.content)),n.tags!==void 0&&(o.tags=he(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Cr(o)),ee(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return ee(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 ee(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=he(fc(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let c of r.pages){let a=c.title.toLowerCase(),u=c.slug.toLowerCase(),f=c.summary?.toLowerCase()??"",d=c.content.toLowerCase(),p=c.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),a===g&&(l+=10),a.includes(g)&&(l+=6),u.includes(g)&&(l+=5),p.some(k=>k===g)?l+=5:p.some(k=>k.includes(g))&&(l+=3),f.includes(g)&&(l+=2),d.includes(g)&&(l+=1);l>0&&i.push({page:ee(c),score:l})}return i.sort((c,a)=>a.score-c.score||a.page.updatedAt.localeCompare(c.page.updatedAt)).slice(0,o)}};var Pr="wiki/state.v1.json";function mc(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function gc(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 Ze=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Pr);if(!t){let n=mc(this.project);return await this.save(n),n}return gc(t,this.project)}async save(t){await this.storage.put(Pr,JSON.stringify(t,null,2),"application/json")}};import{createHash as hc,randomUUID as Tr}from"node:crypto";var Er="wiki/governance.v1.json",_r="toolnet.knowledge-governance.v1",Or=500,ye={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function yc(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Ot(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Rr(e){return hc("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function kc(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 Sc(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),yc(t)}function Nr(e){let t=new Date().toISOString();return{schema:_r,version:1,projectId:e,policy:{...ye},reviews:[],audit:[],createdAt:t,updatedAt:t}}function $r(e){let t=e.autoApproveThreshold??ye.autoApproveThreshold,n=e.criticalApproveThreshold??ye.criticalApproveThreshold,r=e.staleAfterDays??ye.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 et=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Er);if(!t){let n=Nr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==_r||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:$r(n.policy??ye)}}catch{let n=Nr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Er,JSON.stringify(t,null,2),"application/json")}},tt=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:Tr(),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>Or&&(t.audit=t.audit.slice(-Or))}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=$r({...r.policy,...t}),this.audit(r,"policy:update",n,{metadata:{...r.policy}}),{...r.policy}))}async summary(){let t=await this.ensureState(),n=r=>t.reviews.filter(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=Sc(t),o=Ot(t.title),i=n.filter(f=>f.slug!==t.slug&&Ot(f.title)===o&&Rr(f.content)!==Rr(t.content)).map(f=>f.slug),c=kc(t),a=[];s<r.policy.autoApproveThreshold&&a.push(`confidence:${s.toFixed(2)}`),c&&s<r.policy.criticalApproveThreshold&&a.push("critical-knowledge"),i.length>0&&a.push("conflicting-knowledge");let u=i.length>0?"conflict":c?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||c&&s<r.policy.criticalApproveThreshold,reasons:a,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(a=>a.sourceKey===t.sourceKey&&a.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(),c={id:Tr(),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(c),this.audit(s,"knowledge:review-requested","system",{reviewId:c.id,sourceKey:c.sourceKey,metadata:{confidence:c.confidence,risk:c.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(c)}})}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 a=(await r.listPages()).find(u=>u.slug===o.slug);if(a&&!a.tags.includes(o.marker))throw new A(`Wiki page '${o.slug}' is manually managed`,409);return a?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 d=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(f=>f.stale).map(({stale:f,...d})=>d),c=new Map;for(let f of r){let d=Ot(f.title),p=c.get(d)??[];p.push(f),c.set(d,p)}let a=[...c.entries()].filter(([,f])=>f.length>1).map(([f,d])=>({title:f,pages:d.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(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:a,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 qr="wiki/automation.v1.json",Br="toolnet.wiki-automation.v1",_t=8e3,Fr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function Se(e){return vc("sha256").update(JSON.stringify(e)).digest("hex")}function ke(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Kr(e){return Array.isArray(e)?e:[]}function Vr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Rt(e){return Array.isArray(e)?e.map(Vr).filter(t=>!!t):[]}function W(e,t){for(let n of t){let r=Vr(e[n]);if(r)return r}}function ve(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 nt(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Fr.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=>nt(i,t+1,n));let s=ke(e);if(!s)return[];let o=[];for(let[i,c]of Object.entries(s)){let a=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Fr.has(a)||o.push(...nt(c,t+1,i))}return o}function Wr(e){let n=ve(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>nt(e[s],0,s)));return(n.length>0?n:ve(nt(e))).join(`
128
128
 
129
- `).slice(0,Nt)}function Wr(e,t){return $(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Br(e,t){return $(e,["title","name","topic","label","task","kind","type"])??t}function Mc(e){return($(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Cc(e){return($(e,["kind","sceneKind","type"])??"").toLowerCase()}function Tc(e){let t=ke(e);if(!t)return[];let n=[],r=$r(t.knowledge);for(let[o,i]of r.entries()){let c=ke(i);if(!c)continue;let a=Mc(c);if(a==="session"||a==="transient")continue;let u=Dr(c);if(u.length<20)continue;let f=Wr(c,Se(c).slice(0,16)),d=Br(c,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:d,summary:$(c,["summary","description"]),content:u,tags:ve(["toolnet","auto","memory",...a?[a]:[]])})}let s=$r(t.scenes);for(let[o,i]of s.entries()){let c=ke(i);if(!c)continue;let a=Cc(c);if(a==="session-context")continue;let u=Dr(c);if(u.length<20)continue;let f=Wr(c,Se(c).slice(0,16)),d=Br(c,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:d,summary:$(c,["summary","description"]),content:u,tags:ve(["toolnet","auto","scene",...a?[a]:[]])})}return n}function Oc(e){return zr(e,".toolnet","memory","skills")}function _c(e){let t=Oc(e);if(!Ic(t))return{candidates:[],failed:0};let n=[],r=0,s=jc(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Pc(zr(t,o),"utf8")),c=ke(i);if(!c||c.schema!=="toolnet.skill-memory.v1")continue;let a=$(c,["id","fingerprint"])??Ec(o,".json"),u=$(c,["task"])??"",f=$(c,["title"])||u||`Reusable Skill ${a.slice(0,8)}`,d=$(c,["summary"])??void 0,p=_t(c.steps),l=_t(c.verification),g=_t(c.files),k=[];u&&k.push(`## Task
129
+ `).slice(0,_t)}function Lr(e,t){return W(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Dr(e,t){return W(e,["title","name","topic","label","task","kind","type"])??t}function Ac(e){return(W(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Ic(e){return(W(e,["kind","sceneKind","type"])??"").toLowerCase()}function Cc(e){let t=ke(e);if(!t)return[];let n=[],r=Kr(t.knowledge);for(let[o,i]of r.entries()){let c=ke(i);if(!c)continue;let a=Ac(c);if(a==="session"||a==="transient")continue;let u=Wr(c);if(u.length<20)continue;let f=Lr(c,Se(c).slice(0,16)),d=Dr(c,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:d,summary:W(c,["summary","description"]),content:u,tags:ve(["toolnet","auto","memory",...a?[a]:[]])})}let s=Kr(t.scenes);for(let[o,i]of s.entries()){let c=ke(i);if(!c)continue;let a=Ic(c);if(a==="session-context")continue;let u=Wr(c);if(u.length<20)continue;let f=Lr(c,Se(c).slice(0,16)),d=Dr(c,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:d,summary:W(c,["summary","description"]),content:u,tags:ve(["toolnet","auto","scene",...a?[a]:[]])})}return n}function Mc(e){return zr(e,".toolnet","memory","skills")}function Pc(e){let t=Mc(e);if(!wc(t))return{candidates:[],failed:0};let n=[],r=0,s=bc(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(xc(zr(t,o),"utf8")),c=ke(i);if(!c||c.schema!=="toolnet.skill-memory.v1")continue;let a=W(c,["id","fingerprint"])??jc(o,".json"),u=W(c,["task"])??"",f=W(c,["title"])||u||`Reusable Skill ${a.slice(0,8)}`,d=W(c,["summary"])??void 0,p=Rt(c.steps),l=Rt(c.verification),g=Rt(c.files),k=[];u&&k.push(`## Task
130
130
  ${u}`),d&&k.push(`## Summary
131
131
  ${d}`),p.length>0&&k.push(`## Procedure
132
132
  ${p.map((y,S)=>`${S+1}. ${y}`).join(`
@@ -136,13 +136,13 @@ ${l.map(y=>`- ${y}`).join(`
136
136
  ${g.map(y=>`- \`${y}\``).join(`
137
137
  `)}`);let h=k.join(`
138
138
 
139
- `).slice(0,Nt);if(h.length<20)continue;n.push({sourceKey:`skill:${a}`,sourceType:"skill",title:f,summary:d,content:h,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Rt(e){let t=new Date().toISOString();return{schema:Ur,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Rc(e,t){let n=await e.getText(qr);if(!n)return Rt(t);try{let r=JSON.parse(n);return r.schema!==Ur||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Rt(t):r}catch{return Rt(t)}}async function Nc(e,t){await e.put(qr,JSON.stringify(t,null,2),"application/json")}function Lc(e){return`toolnet-auto-${Se(e).slice(0,12)}`}function Kc(e){let t=te(e.title).slice(0,72),n=Se(e.sourceKey).slice(0,10);return te(`auto-${e.sourceType}-${t}-${n}`)}function Fc(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(`
140
- `).slice(0,Nt)}function $c(e){return Se({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Dc(e,t){return e.tags.includes(t)}async function Gr(e){let t=Tc(e.hierarchy),n=_c(e.project.rootPath),r=new Map;for(let l of[...t,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new Xe(new Ze(e.storage,e.project));await i.initialize();let c=new tt(new et(e.storage,e.project));await c.initialize();let a=await Rc(e.storage,e.project.id),u=await i.listPages(),f=new Map(u.map(l=>[l.slug,l])),d=new Map(a.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=Lc(l.sourceKey),k=$c(l),h=d.get(l.sourceKey),y=h?.slug??Kc(l),S=f.get(y);if(S&&!Dc(S,g)){o.skipped+=1;continue}let C=ve([...l.tags,g]),T=Fc(l),E=await c.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,marker:g,digest:k,title:l.title,...l.summary?{summary:l.summary}:{},content:T,tags:C},[...f.values()]);if(!E.allowed){E.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}E.mode==="auto-approved"?o.autoApproved+=1:E.mode==="review-approved"&&(o.reviewApproved+=1),S?h?.digest!==k?(S=await i.updatePage(y,{title:l.title,summary:l.summary??"",content:T,tags:C}),f.set(S.slug,S),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,action:"unchanged"})):(S=await i.createPage({slug:y,title:l.title,summary:l.summary,content:T,tags:C}),f.set(S.slug,S),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S.slug,action:"created"}));let O=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,digest:k,marker:g,updatedAt:O},w=a.entries.findIndex(D=>D.sourceKey===l.sourceKey);w>=0?a.entries[w]=x:a.entries.push(x),d.set(l.sourceKey,x),await c.markApplied(l.sourceKey,k)}catch(g){if(g instanceof I&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return a.updatedAt=p,a.lastRunAt=p,a.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Nc(e.storage,a),o}import{createHash as Wc}from"node:crypto";import{chmodSync as Jr,existsSync as Bc,mkdirSync as zc,readFileSync as Lg,readdirSync as Kg,renameSync as qc,statSync as Fg,writeFileSync as Uc}from"node:fs";import{join as Yr}from"node:path";var Vc="toolnet.skill-memory.v1",Hr=5,Gc=16,Hc=24,Jc=32;function Yc(e){return Wc("sha256").update(e).digest("hex")}function be(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function Lt(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 Qc(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 B(e,t=360){return e&&Lt(Qc(e),t)||void 0}function xe(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Qr(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 Xr(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function Zr(e){let t=e.data??{};if(Xr(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Qr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=xe(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function we(e){let t=e.data??{};if(Zr(e))return!1;if(Xr(t,["passed","pass","success","succeeded","ok"])===!0||Qr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=xe(t,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:e.type==="commit"||e.type==="deploy"}function es(e){let t=e.data??{},n=xe(t,["path","file","filePath","filename","target"]);if(n)return B(n,260);let r=e.provenance?.files;return B(r?.[0],260)}function Kt(e){return B(xe(e.data??{},["command","cmd","script"]),420)}function oe(e){return B(xe(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Xc(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(we(n)){if(n.type==="test"){let r=oe(n)??Kt(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=oe(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=oe(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return be(t,10)}function Zc(e,t){let n=[];for(let r of[...e].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=es(r);s&&n.push(`Update ${s}`);break}case"command":{if(Zr(r))break;let s=Kt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!we(r))break;let s=oe(r)??Kt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!we(r))break;let s=oe(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!we(r))break;let s=oe(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let s=B(r,260);s&&n.push(`Update ${s}`)}return be(n,Gc)}function eu(e,t){let n=[...t.files];for(let r of e){let s=es(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=B(o,260);i&&n.push(i)}}return be(n,Hc)}function tu(e){return be(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Jc)}function nu(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function ts(e,t,n){if(t.length===0)return[];let r=Xc(t),s=be(n.completed.map(g=>B(g,280)??""),Hr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&we(g))))return[];let i=B(n.task,280)??B(n.nextActions[0],280),c=s.length>0?s:i?[i]:[];if(c.length===0)return[];let a=Zc(t,n);if(a.length===0)return[];let u=eu(t,n),f=tu(t),d=Math.min(...t.map(g=>g.sequence)),p=Math.max(...t.map(g=>g.sequence)),l=nu(t);return c.slice(0,Hr).map(g=>{let k=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),h=JSON.stringify({projectId:e.projectId,task:g,steps:a,verification:r,files:u}),y=Yc(h);return{schema:Vc,version:1,id:`skill-${y.slice(0,24)}`,fingerprint:y,projectId:e.projectId,title:Lt(`SOP: ${g}`,180),task:g,summary:Lt(k.join(" "),900),steps:a,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:f},createdAt:l}})}function ru(e){return Yr(e.rootPath,".toolnet","memory","skills")}function su(e){let t=ru(e);return zc(t,{recursive:!0,mode:448}),Jr(t,448),t}function ns(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=su(e),r=0,s=0,o=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let c=Yr(n,`${i.id}.json`);if(o.push(c),Bc(c)){s+=1;continue}let a=`${c}.${process.pid}.${Date.now()}.tmp`;Uc(a,JSON.stringify(i,null,2)+`
141
- `,{encoding:"utf8",mode:384}),qc(a,c),Jr(c,384),r+=1}return{written:r,deduped:s,files:o}}function rs(e){return String(e).padStart(12,"0")}function ou(e){return e.remotePrefix.replace("/sessions/","/memory/learned/")}var rt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(f=>f.sequence)),o=Math.max(...n.map(f=>f.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},c=JSON.stringify(i,null,2)+`
142
- `,a=v(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[ou(t),"batches",`${rs(s)}-${rs(o)}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,c,"application/json"),u}};import{createHash as iu}from"node:crypto";function ss(e){return String(e).padStart(12,"0")}function au(e){return iu("sha256").update(e).digest("hex")}function cu(e){return e.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var st=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},c=au([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),a=[cu(t),"batches",`${ss(s)}-${ss(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,`${JSON.stringify(i,null,2)}
143
- `,"application/json"),a}};function mu(e,t){if(!lu(e))return{events:[],nextOffset:t};let n=fu(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=du(e,"r");try{pu(i,o,0,s,r)}finally{uu(i)}let c=o.toString("utf8"),a=c.lastIndexOf(`
139
+ `).slice(0,_t);if(h.length<20)continue;n.push({sourceKey:`skill:${a}`,sourceType:"skill",title:f,summary:d,content:h,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Nt(e){let t=new Date().toISOString();return{schema:Br,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Tc(e,t){let n=await e.getText(qr);if(!n)return Nt(t);try{let r=JSON.parse(n);return r.schema!==Br||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Nt(t):r}catch{return Nt(t)}}async function Ec(e,t){await e.put(qr,JSON.stringify(t,null,2),"application/json")}function Oc(e){return`toolnet-auto-${Se(e).slice(0,12)}`}function Rc(e){let t=te(e.title).slice(0,72),n=Se(e.sourceKey).slice(0,10);return te(`auto-${e.sourceType}-${t}-${n}`)}function Nc(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(`
140
+ `).slice(0,_t)}function _c(e){return Se({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function $c(e,t){return e.tags.includes(t)}async function Jr(e){let t=Cc(e.hierarchy),n=Pc(e.project.rootPath),r=new Map;for(let l of[...t,...n.candidates])r.set(l.sourceKey,l);let s=[...r.values()].sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),o={schema:"toolnet.wiki-automation-result.v1",scanned:t.length+n.candidates.length,eligible:s.length,created:0,updated:0,unchanged:0,skipped:0,failed:n.failed,reviewPending:0,autoApproved:0,reviewApproved:0,pages:[]},i=new Xe(new Ze(e.storage,e.project));await i.initialize();let c=new tt(new et(e.storage,e.project));await c.initialize();let a=await Tc(e.storage,e.project.id),u=await i.listPages(),f=new Map(u.map(l=>[l.slug,l])),d=new Map(a.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=Oc(l.sourceKey),k=_c(l),h=d.get(l.sourceKey),y=h?.slug??Rc(l),S=f.get(y);if(S&&!$c(S,g)){o.skipped+=1;continue}let T=ve([...l.tags,g]),E=Nc(l),M=await c.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,marker:g,digest:k,title:l.title,...l.summary?{summary:l.summary}:{},content:E,tags:T},[...f.values()]);if(!M.allowed){M.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}M.mode==="auto-approved"?o.autoApproved+=1:M.mode==="review-approved"&&(o.reviewApproved+=1),S?h?.digest!==k?(S=await i.updatePage(y,{title:l.title,summary:l.summary??"",content:E,tags:T}),f.set(S.slug,S),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,action:"unchanged"})):(S=await i.createPage({slug:y,title:l.title,summary:l.summary,content:E,tags:T}),f.set(S.slug,S),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:S.slug,action:"created"}));let O=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:y,digest:k,marker:g,updatedAt:O},w=a.entries.findIndex(L=>L.sourceKey===l.sourceKey);w>=0?a.entries[w]=x:a.entries.push(x),d.set(l.sourceKey,x),await c.markApplied(l.sourceKey,k)}catch(g){if(g instanceof A&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return a.updatedAt=p,a.lastRunAt=p,a.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await Ec(e.storage,a),o}import{createHash as Fc}from"node:crypto";import{chmodSync as Gr,existsSync as Kc,mkdirSync as Wc,readFileSync as Qm,readdirSync as Xm,renameSync as Lc,statSync as Zm,writeFileSync as Dc}from"node:fs";import{join as Ur}from"node:path";var zc="toolnet.skill-memory.v1",Hr=5,qc=16,Bc=24,Vc=32;function Jc(e){return Fc("sha256").update(e).digest("hex")}function be(e,t=Number.MAX_SAFE_INTEGER){let n=new Set,r=[];for(let s of e){let o=s.replace(/\s+/gu," ").trim();if(!o)continue;let i=o.normalize("NFKC").toLowerCase();if(!n.has(i)&&(n.add(i),r.push(o),r.length>=t))break}return r}function $t(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 Hc(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 z(e,t=360){return e&&$t(Hc(e),t)||void 0}function xe(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Yr(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 Qr(e,t){for(let n of t){let r=e[n];if(typeof r=="boolean")return r;if(typeof r=="string"){let s=r.trim().toLowerCase();if(["true","yes","pass","passed","success","succeeded","ok"].includes(s))return!0;if(["false","no","fail","failed","error"].includes(s))return!1}}}function Xr(e){let t=e.data??{};if(Qr(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Yr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=xe(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function we(e){let t=e.data??{};if(Xr(e))return!1;if(Qr(t,["passed","pass","success","succeeded","ok"])===!0||Yr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=xe(t,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:e.type==="commit"||e.type==="deploy"}function Zr(e){let t=e.data??{},n=xe(t,["path","file","filePath","filename","target"]);if(n)return z(n,260);let r=e.provenance?.files;return z(r?.[0],260)}function Ft(e){return z(xe(e.data??{},["command","cmd","script"]),420)}function oe(e){return z(xe(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Gc(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(we(n)){if(n.type==="test"){let r=oe(n)??Ft(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=oe(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=oe(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return be(t,10)}function Uc(e,t){let n=[];for(let r of[...e].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=Zr(r);s&&n.push(`Update ${s}`);break}case"command":{if(Xr(r))break;let s=Ft(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!we(r))break;let s=oe(r)??Ft(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!we(r))break;let s=oe(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!we(r))break;let s=oe(r);n.push(s?`Deploy: ${s}`:"Deploy verified build");break}default:break}if(n.length===0)for(let r of t.files.slice(0,8)){let s=z(r,260);s&&n.push(`Update ${s}`)}return be(n,qc)}function Yc(e,t){let n=[...t.files];for(let r of e){let s=Zr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=z(o,260);i&&n.push(i)}}return be(n,Bc)}function Qc(e){return be(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Vc)}function Xc(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function es(e,t,n){if(t.length===0)return[];let r=Gc(t),s=be(n.completed.map(g=>z(g,280)??""),Hr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&we(g))))return[];let i=z(n.task,280)??z(n.nextActions[0],280),c=s.length>0?s:i?[i]:[];if(c.length===0)return[];let a=Uc(t,n);if(a.length===0)return[];let u=Yc(t,n),f=Qc(t),d=Math.min(...t.map(g=>g.sequence)),p=Math.max(...t.map(g=>g.sequence)),l=Xc(t);return c.slice(0,Hr).map(g=>{let k=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),h=JSON.stringify({projectId:e.projectId,task:g,steps:a,verification:r,files:u}),y=Jc(h);return{schema:zc,version:1,id:`skill-${y.slice(0,24)}`,fingerprint:y,projectId:e.projectId,title:$t(`SOP: ${g}`,180),task:g,summary:$t(k.join(" "),900),steps:a,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:f},createdAt:l}})}function Zc(e){return Ur(e.rootPath,".toolnet","memory","skills")}function eu(e){let t=Zc(e);return Wc(t,{recursive:!0,mode:448}),Gr(t,448),t}function ts(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=eu(e),r=0,s=0,o=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let c=Ur(n,`${i.id}.json`);if(o.push(c),Kc(c)){s+=1;continue}let a=`${c}.${process.pid}.${Date.now()}.tmp`;Dc(a,JSON.stringify(i,null,2)+`
141
+ `,{encoding:"utf8",mode:384}),Lc(a,c),Gr(c,384),r+=1}return{written:r,deduped:s,files:o}}function ns(e){return String(e).padStart(12,"0")}function tu(e){return e.remotePrefix.replace("/sessions/","/memory/learned/")}var rt=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(f=>f.sequence)),o=Math.max(...n.map(f=>f.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},c=JSON.stringify(i,null,2)+`
142
+ `,a=v(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[tu(t),"batches",`${ns(s)}-${ns(o)}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,c,"application/json"),u}};import{createHash as nu}from"node:crypto";function rs(e){return String(e).padStart(12,"0")}function ru(e){return nu("sha256").update(e).digest("hex")}function su(e){return e.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var st=class{constructor(t){this.storage=t}storage;async write(t,n,r){if(n.length===0||r.facts.length===0)return null;let s=Math.min(...n.map(u=>u.sequence)),o=Math.max(...n.map(u=>u.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},c=ru([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),a=[su(t),"batches",`${rs(s)}-${rs(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,`${JSON.stringify(i,null,2)}
143
+ `,"application/json"),a}};function lu(e,t){if(!iu(e))return{events:[],nextOffset:t};let n=uu(e).size,r=Number.isFinite(t)?Math.max(0,t):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=au(e,"r");try{cu(i,o,0,s,r)}finally{ou(i)}let c=o.toString("utf8"),a=c.lastIndexOf(`
144
144
  `);if(a<0)return{events:[],nextOffset:r};let u=c.slice(0,a+1);return{events:u.split(`
145
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var ot=class{constructor(t){this.options=t;this.journal=new rt(t.storage),this.hierarchyJournal=new st(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,s=mu(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Je(this.options.identity,s.events),i=o.candidates,c=!1;i.length>0&&(c=!!await this.journal.write(this.options.identity,s.events,i));let a=!1;o.hierarchy.facts.length>0&&(a=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=ts(this.options.identity,s.events,o.state),f=ns(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",a?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let d=qn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",d.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",d.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",d.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",d.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let d=await Gr({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",d.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",d.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",d.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",d.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",d.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",d.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",d.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",d.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",d.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",d.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:c,nextOffset:s.nextOffset}}};function os(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=_e(t,n);if(r.length===0)return{updated:!1,observations:0};let s=kn(e,r);Xn(e,s),Jn(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Sr(e,t,n,s)}catch{}try{xn({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var it=class{identity;wal;remote;sanitizer=new H;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=br(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new Qe(this.identity,t.eventContext),this.remote=new Ye(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new ot({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Le({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new Be({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new De({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{os(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 s=t.events[t.events.length-1];this.wal.markRemote(s.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 s=t.events[t.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(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 gu,openSync as hu,closeSync as yu,readSync as ku,statSync as Su}from"node:fs";function vu(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 wu(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 s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function is(e,t={offset:0}){if(!gu(e))return{events:[],nextOffset:t.offset,reset:!1};let n=Su(e).size,r=t.offset>n,s=r?0:t.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),c=hu(e,"r");try{ku(c,i,0,o,s)}finally{yu(c)}let a=i.toString("utf8"),u=a.lastIndexOf(`
145
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var ot=class{constructor(t){this.options=t;this.journal=new rt(t.storage),this.hierarchyJournal=new st(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,s=lu(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Ue(this.options.identity,s.events),i=o.candidates,c=!1;i.length>0&&(c=!!await this.journal.write(this.options.identity,s.events,i));let a=!1;o.hierarchy.facts.length>0&&(a=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=es(this.options.identity,s.events,o.state),f=ts(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",a?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let d=Bn(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",d.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",d.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",d.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",d.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let d=await Jr({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",d.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",d.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",d.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",d.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",d.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",d.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",d.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",d.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",d.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",d.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:c,nextOffset:s.nextOffset}}};function ss(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Re(t,n);if(r.length===0)return{updated:!1,observations:0};let s=kn(e,r);Xn(e,s),Un(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{kr(e,t,n,s)}catch{}try{xn({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var it=class{identity;wal;remote;sanitizer=new G;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=wr(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new Qe(this.identity,t.eventContext),this.remote=new Ye(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new ot({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new $e({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new ze({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new Le({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{ss(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 s=t.events[t.events.length-1];this.wal.markRemote(s.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 s=t.events[t.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(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 du,openSync as pu,closeSync as fu,readSync as mu,statSync as gu}from"node:fs";function hu(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 yu(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 s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function os(e,t={offset:0}){if(!du(e))return{events:[],nextOffset:t.offset,reset:!1};let n=gu(e).size,r=t.offset>n,s=r?0:t.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),c=pu(e,"r");try{mu(c,i,0,o,s)}finally{fu(c)}let a=i.toString("utf8"),u=a.lastIndexOf(`
146
146
  `);if(u<0)return{events:[],nextOffset:s,reset:r};let f=a.slice(0,u+1),d=Buffer.byteLength(f,"utf8"),p=[],l=0;for(let g of f.split(`
147
147
  `)){if(!g)continue;let k=Buffer.byteLength(g+`
148
- `,"utf8"),h=s+l;l+=k;let y;try{y=JSON.parse(g)}catch{p.push({type:"custom",sourceEventId:`transcript:${h}`,sourceSequence:h,data:{format:"raw-line",content:g},provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:h}});continue}let S=y&&typeof y=="object"&&!Array.isArray(y)?y:{value:y};p.push({type:vu(S),timestamp:wu(S),role:typeof S.role=="string"?S.role:void 0,sourceEventId:`transcript:${h}`,sourceSequence:h,data:S,provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:h}})}return{events:p,nextOffset:s+d,reset:r}}var bu=[/^<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*$/],xu=[/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],Au=["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 Iu(e){let t=e.toLowerCase();return Au.some(n=>t.includes(n))}function ju(e){if(!e.trim())return!0;for(let t of bu)if(t.test(e))return!0;return Iu(e),!1}function Pu(e){let t=e;for(let n of xu)t=t.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return t}function Ft(e){let t=e.trim();return t?ju(t)?{content:"",filtered:!0,reason:"noise"}:{content:Pu(t),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function at(e){let t={};for(let[n,r]of Object.entries(e))if(typeof r=="string"){let s=Ft(r);s.filtered||(t[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?t[n]=at(r):Array.isArray(r)?t[n]=r.map(s=>{if(typeof s=="string"){let o=Ft(s);return o.filtered?null:o.content}return s&&typeof s=="object"?at(s):s}).filter(s=>s!==null):t[n]=r;return t}function as(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&&Ft(r).filtered)return!0}return!1}function Cu(e){return e==="~"?cs():e.startsWith("~/")?Eu(cs(),e.slice(2)):e}async function us(e){let t=e.conversationId.trim();if(!t)throw new Error("Agy conversationId is required");let n=Mu(Cu(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}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,c=is(n,{offset:Number.isFinite(i)?i:0}),a=[];s.lastSequence===0&&a.push({type:"session_start",sourceEventId:`agy:${t}:start`,data:{workspacePaths:e.workspacePaths??[],transcriptPath:n,modelName:e.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),c.reset&&a.push({type:"custom",sourceEventId:`agy:${t}:transcript-reset:${c.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=c.events.filter(p=>!as(p.data)).map(p=>({...p,data:at(p.data)}));a.push(...u),e.phase==="stop"&&(e.error&&a.push({type:"error",sourceEventId:["agy",t,"stop-error",e.terminationReason??"",c.nextOffset].join(":"),data:{error:e.error,terminationReason:e.terminationReason,fullyIdle:e.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),e.fullyIdle&&a.push({type:"session_idle",sourceEventId:["agy",t,"idle",c.nextOffset].join(":"),data:{terminationReason:e.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let f=r.recordMany(a);if(r.setSourceCursor("agy.transcript.offset",c.nextOffset),e.phase&&r.setSourceCursor("agy.last.phase",e.phase),u.length>0)try{let p=u.map(g=>JSON.stringify(g.data)),l=He(p,t);r.setSourceCursor("agy.session.summary",l.summary),r.setSourceCursor("agy.session.facts_count",l.durableFacts.length),lr()&&(fr()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let d=await r.flush();return{conversationId:t,imported:f.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:c.nextOffset,reset:c.reset}}async function Tu(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}function Ae(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function Ou(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:{},s=typeof e.stop_hook_args=="object"&&e.stop_hook_args!==null?e.stop_hook_args:{},o=(typeof t.conversation_id=="string"?t.conversation_id:"")||(typeof e.conversationId=="string"?e.conversationId:"")||(typeof e.conversation_id=="string"?e.conversation_id:""),i=(typeof t.transcript_path=="string"?t.transcript_path:"")||(typeof e.transcriptPath=="string"?e.transcriptPath:"")||(typeof e.transcript_path=="string"?e.transcript_path:""),c=Ae(t.workspace_paths).length>0?Ae(t.workspace_paths):Ae(e.workspacePaths).length>0?Ae(e.workspacePaths):Ae(e.workspace_paths),a=typeof n.invocation_num=="number"?n.invocation_num:typeof e.invocationNum=="number"?e.invocationNum:typeof e.invocation_num=="number"?e.invocation_num:void 0,u=(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||(typeof e.artifactDirectoryPath=="string"?e.artifactDirectoryPath:"")||(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||void 0,f=(typeof t.model_name=="string"?t.model_name:"")||(typeof e.modelName=="string"?e.modelName:"")||(typeof e.model_name=="string"?e.model_name:"")||void 0,d=s.fully_idle===!0||e.fullyIdle===!0||e.fully_idle===!0,p=(typeof s.termination_reason=="string"?s.termination_reason:"")||(typeof e.terminationReason=="string"?e.terminationReason:"")||(typeof e.termination_reason=="string"?e.termination_reason:"")||void 0,l=(typeof s.error=="string"&&s.error?s.error:"")||(typeof e.error=="string"&&e.error?e.error:"")||void 0;return{conversationId:o,transcriptPath:i,workspacePaths:c,invocationNum:a,artifactDirectoryPath:u,modelName:f,fullyIdle:d,terminationReason:p,error:l}}function _u(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/sessions")?{decision:"deny",reason:"ToolNet continuity guard: do not replay raw .toolnet/sessions history. Use the injected continuity handoff. If deeper history is required, invoke memory_agent_ask directly."}:{decision:"allow"}}async function Ru(){let e=process.argv[2]??"post",t=await Tu();if(e==="pre-tool"){process.stdout.write(JSON.stringify(_u(t)));return}let n=Ou(t),r=n.conversationId,s=n.transcriptPath,o=n.workspacePaths,i=vr(o),c={};if(i&&r)try{let a=Ie(),u=Jt(Gt({provider:a.storage.provider,huggingface:a.storage.huggingface,localRoot:a.storage.localRoot}),{attempts:2}),f=new Te(u,i.id,i.name,i.remote??i.name);if(s)try{await us({project:i,storage:f,conversationId:r,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:n.artifactDirectoryPath,modelName:n.modelName,phase:e,fullyIdle:n.fullyIdle,terminationReason:n.terminationReason,error:n.error})}catch{}if(e==="pre")try{c=await Hn({project:i,storage:f,conversationId:r,invocationNum:n.invocationNum})}catch{c={}}if(e==="stop")try{await yt(i,f,800)}catch{}}catch{}if(e==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(c))}Ru().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{_u as buildAgyPreToolUseOutput,Ou as normalizeAgyInput};
148
+ `,"utf8"),h=s+l;l+=k;let y;try{y=JSON.parse(g)}catch{p.push({type:"custom",sourceEventId:`transcript:${h}`,sourceSequence:h,data:{format:"raw-line",content:g},provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:h}});continue}let S=y&&typeof y=="object"&&!Array.isArray(y)?y:{value:y};p.push({type:hu(S),timestamp:yu(S),role:typeof S.role=="string"?S.role:void 0,sourceEventId:`transcript:${h}`,sourceSequence:h,data:S,provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:h}})}return{events:p,nextOffset:s+d,reset:r}}var ku=[/^<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*$/],Su=[/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],vu=["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 wu(e){let t=e.toLowerCase();return vu.some(n=>t.includes(n))}function bu(e){if(!e.trim())return!0;for(let t of ku)if(t.test(e))return!0;return wu(e),!1}function xu(e){let t=e;for(let n of Su)t=t.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return t}function Kt(e){let t=e.trim();return t?bu(t)?{content:"",filtered:!0,reason:"noise"}:{content:xu(t),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function at(e){let t={};for(let[n,r]of Object.entries(e))if(typeof r=="string"){let s=Kt(r);s.filtered||(t[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?t[n]=at(r):Array.isArray(r)?t[n]=r.map(s=>{if(typeof s=="string"){let o=Kt(s);return o.filtered?null:o.content}return s&&typeof s=="object"?at(s):s}).filter(s=>s!==null):t[n]=r;return t}function is(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&&Kt(r).filtered)return!0}return!1}function Iu(e){return e==="~"?as():e.startsWith("~/")?ju(as(),e.slice(2)):e}async function cs(e){let t=e.conversationId.trim();if(!t)throw new Error("Agy conversationId is required");let n=Au(Iu(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}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,c=os(n,{offset:Number.isFinite(i)?i:0}),a=[];s.lastSequence===0&&a.push({type:"session_start",sourceEventId:`agy:${t}:start`,data:{workspacePaths:e.workspacePaths??[],transcriptPath:n,modelName:e.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),c.reset&&a.push({type:"custom",sourceEventId:`agy:${t}:transcript-reset:${c.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=c.events.filter(p=>!is(p.data)).map(p=>({...p,data:at(p.data)}));a.push(...u),e.phase==="stop"&&(e.error&&a.push({type:"error",sourceEventId:["agy",t,"stop-error",e.terminationReason??"",c.nextOffset].join(":"),data:{error:e.error,terminationReason:e.terminationReason,fullyIdle:e.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),e.fullyIdle&&a.push({type:"session_idle",sourceEventId:["agy",t,"idle",c.nextOffset].join(":"),data:{terminationReason:e.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let f=r.recordMany(a);if(r.setSourceCursor("agy.transcript.offset",c.nextOffset),e.phase&&r.setSourceCursor("agy.last.phase",e.phase),u.length>0)try{let p=u.map(g=>JSON.stringify(g.data)),l=Ge(p,t);r.setSourceCursor("agy.session.summary",l.summary),r.setSourceCursor("agy.session.facts_count",l.durableFacts.length),ur()&&(pr()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let d=await r.flush();return{conversationId:t,imported:f.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:c.nextOffset,reset:c.reset}}async function Cu(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}function je(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function Mu(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:{},s=typeof e.stop_hook_args=="object"&&e.stop_hook_args!==null?e.stop_hook_args:{},o=(typeof t.conversation_id=="string"?t.conversation_id:"")||(typeof e.conversationId=="string"?e.conversationId:"")||(typeof e.conversation_id=="string"?e.conversation_id:""),i=(typeof t.transcript_path=="string"?t.transcript_path:"")||(typeof e.transcriptPath=="string"?e.transcriptPath:"")||(typeof e.transcript_path=="string"?e.transcript_path:""),c=je(t.workspace_paths).length>0?je(t.workspace_paths):je(e.workspacePaths).length>0?je(e.workspacePaths):je(e.workspace_paths),a=typeof n.invocation_num=="number"?n.invocation_num:typeof e.invocationNum=="number"?e.invocationNum:typeof e.invocation_num=="number"?e.invocation_num:void 0,u=(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||(typeof e.artifactDirectoryPath=="string"?e.artifactDirectoryPath:"")||(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||void 0,f=(typeof t.model_name=="string"?t.model_name:"")||(typeof e.modelName=="string"?e.modelName:"")||(typeof e.model_name=="string"?e.model_name:"")||void 0,d=s.fully_idle===!0||e.fullyIdle===!0||e.fully_idle===!0,p=(typeof s.termination_reason=="string"?s.termination_reason:"")||(typeof e.terminationReason=="string"?e.terminationReason:"")||(typeof e.termination_reason=="string"?e.termination_reason:"")||void 0,l=(typeof s.error=="string"&&s.error?s.error:"")||(typeof e.error=="string"&&e.error?e.error:"")||void 0;return{conversationId:o,transcriptPath:i,workspacePaths:c,invocationNum:a,artifactDirectoryPath:u,modelName:f,fullyIdle:d,terminationReason:p,error:l}}function Pu(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/sessions")?{decision:"deny",reason:"ToolNet continuity guard: do not replay raw .toolnet/sessions history. Use the injected continuity handoff. If deeper history is required, invoke memory_agent_ask directly."}:{decision:"allow"}}async function Tu(){let e=process.argv[2]??"post",t=await Cu();if(e==="pre-tool"){process.stdout.write(JSON.stringify(Pu(t)));return}let n=Mu(t),r=n.conversationId,s=n.transcriptPath,o=n.workspacePaths,i=Sr(o),c={};if(i&&r)try{let a=Ae(),u=Ut(Ht({provider:a.storage.provider,huggingface:a.storage.huggingface,localRoot:a.storage.localRoot}),{attempts:2}),f=new Ee(u,i.id,i.name,i.remote??i.name);if(s)try{await cs({project:i,storage:f,conversationId:r,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:n.artifactDirectoryPath,modelName:n.modelName,phase:e,fullyIdle:n.fullyIdle,terminationReason:n.terminationReason,error:n.error})}catch{}if(e==="pre")try{c=await Gn({project:i,storage:f,conversationId:r,invocationNum:n.invocationNum})}catch{c={}}if(e==="stop")try{await yt(i,f,800)}catch{}}catch{}if(e==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(c))}Tu().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{Pu as buildAgyPreToolUseOutput,Mu as normalizeAgyInput};